KEYCLOAK-14552 Realm Map Store
This commit is contained in:
parent
ec5c256562
commit
185075d373
50 changed files with 5366 additions and 283 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -160,7 +160,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
declare -A PARAMS TESTGROUP
|
declare -A PARAMS TESTGROUP
|
||||||
PARAMS["quarkus"]="-Pauth-server-quarkus"
|
PARAMS["quarkus"]="-Pauth-server-quarkus"
|
||||||
PARAMS["undertow-map"]="-Pauth-server-undertow -Dkeycloak.client.provider=map -Dkeycloak.group.provider=map -Dkeycloak.role.provider=map -Dkeycloak.authSession.provider=map -Dkeycloak.user.provider=map -Dkeycloak.clientScope.provider=map"
|
PARAMS["undertow-map"]="-Pauth-server-undertow -Dkeycloak.client.provider=map -Dkeycloak.group.provider=map -Dkeycloak.role.provider=map -Dkeycloak.authSession.provider=map -Dkeycloak.user.provider=map -Dkeycloak.clientScope.provider=map -Dkeycloak.realm.provider=map"
|
||||||
PARAMS["wildfly"]="-Pauth-server-wildfly"
|
PARAMS["wildfly"]="-Pauth-server-wildfly"
|
||||||
TESTGROUP["group1"]="-Dtest=!**.crossdc.**,!**.cluster.**,%regex[org.keycloak.testsuite.(a[abc]|ad[a-l]|[^a-q]).*]" # Tests alphabetically before admin tests and those after "r"
|
TESTGROUP["group1"]="-Dtest=!**.crossdc.**,!**.cluster.**,%regex[org.keycloak.testsuite.(a[abc]|ad[a-l]|[^a-q]).*]" # Tests alphabetically before admin tests and those after "r"
|
||||||
TESTGROUP["group2"]="-Dtest=!**.crossdc.**,!**.cluster.**,%regex[org.keycloak.testsuite.(ad[^a-l]|a[^a-d]|b).*]" # Admin tests and those starting with "b"
|
TESTGROUP["group2"]="-Dtest=!**.crossdc.**,!**.cluster.**,%regex[org.keycloak.testsuite.(ad[^a-l]|a[^a-d]|b).*]" # Admin tests and those starting with "b"
|
||||||
|
|
|
@ -1620,6 +1620,7 @@ public class RealmAdapter implements CachedRealmModel {
|
||||||
return cached.getComponents().get(id);
|
return cached.getComponents().get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setAttribute(String name, String value) {
|
public void setAttribute(String name, String value) {
|
||||||
getDelegateForUpdate();
|
getDelegateForUpdate();
|
||||||
updated.setAttribute(name, value);
|
updated.setAttribute(name, value);
|
||||||
|
@ -1712,6 +1713,32 @@ public class RealmAdapter implements CachedRealmModel {
|
||||||
return cacheSession.getRealmDelegate().getRealm(cached.getId());
|
return cacheSession.getRealmDelegate().getRealm(cached.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientInitialAccessModel createClientInitialAccessModel(int expiration, int count) {
|
||||||
|
getDelegateForUpdate();
|
||||||
|
return updated.createClientInitialAccessModel(expiration, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientInitialAccessModel getClientInitialAccessModel(String id) {
|
||||||
|
return getDelegateForUpdate().getClientInitialAccessModel(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeClientInitialAccessModel(String id) {
|
||||||
|
getDelegateForUpdate().removeClientInitialAccessModel(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<ClientInitialAccessModel> getClientInitialAccesses() {
|
||||||
|
return getDelegateForUpdate().getClientInitialAccesses();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decreaseRemainingCount(ClientInitialAccessModel clientInitialAccess) {
|
||||||
|
getDelegateForUpdate().decreaseRemainingCount(clientInitialAccess);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("%s@%08x", getId(), hashCode());
|
return String.format("%s@%08x", getId(), hashCode());
|
||||||
|
|
|
@ -20,7 +20,6 @@ package org.keycloak.models.cache.infinispan;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.cluster.ClusterProvider;
|
import org.keycloak.cluster.ClusterProvider;
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.migration.MigrationModel;
|
|
||||||
import org.keycloak.models.*;
|
import org.keycloak.models.*;
|
||||||
import org.keycloak.models.cache.CacheRealmProvider;
|
import org.keycloak.models.cache.CacheRealmProvider;
|
||||||
import org.keycloak.models.cache.CachedRealmModel;
|
import org.keycloak.models.cache.CachedRealmModel;
|
||||||
|
@ -143,11 +142,6 @@ public class RealmCacheSession implements CacheRealmProvider {
|
||||||
cluster.notify(InfinispanCacheRealmProviderFactory.REALM_CLEAR_CACHE_EVENTS, new ClearCacheEvent(), false, ClusterProvider.DCNotify.ALL_DCS);
|
cluster.notify(InfinispanCacheRealmProviderFactory.REALM_CLEAR_CACHE_EVENTS, new ClearCacheEvent(), false, ClusterProvider.DCNotify.ALL_DCS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public MigrationModel getMigrationModel() {
|
|
||||||
return getRealmDelegate().getMigrationModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RealmProvider getRealmDelegate() {
|
public RealmProvider getRealmDelegate() {
|
||||||
if (!transactionActive) throw new IllegalStateException("Cannot access delegate without a transaction");
|
if (!transactionActive) throw new IllegalStateException("Cannot access delegate without a transaction");
|
||||||
|
@ -1377,11 +1371,6 @@ public class RealmCacheSession implements CacheRealmProvider {
|
||||||
getRealmDelegate().removeExpiredClientInitialAccess();
|
getRealmDelegate().removeExpiredClientInitialAccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decreaseRemainingCount(RealmModel realm, ClientInitialAccessModel clientInitialAccess) {
|
|
||||||
getRealmDelegate().decreaseRemainingCount(realm, clientInitialAccess);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveLocalizationText(RealmModel realm, String locale, String key, String text) {
|
public void saveLocalizationText(RealmModel realm, String locale, String key, String text) {
|
||||||
getRealmDelegate().saveLocalizationText(realm, locale, key, text);
|
getRealmDelegate().saveLocalizationText(realm, locale, key, text);
|
||||||
|
|
|
@ -39,7 +39,6 @@ import org.jboss.logging.Logger;
|
||||||
import org.keycloak.common.util.Time;
|
import org.keycloak.common.util.Time;
|
||||||
import org.keycloak.connections.jpa.util.JpaUtils;
|
import org.keycloak.connections.jpa.util.JpaUtils;
|
||||||
import org.keycloak.migration.MigrationModel;
|
import org.keycloak.migration.MigrationModel;
|
||||||
import org.keycloak.models.ClientInitialAccessModel;
|
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.ClientProvider;
|
import org.keycloak.models.ClientProvider;
|
||||||
import org.keycloak.models.ClientScopeModel;
|
import org.keycloak.models.ClientScopeModel;
|
||||||
|
@ -55,6 +54,7 @@ import org.keycloak.models.RoleContainerModel;
|
||||||
import org.keycloak.models.RoleContainerModel.RoleRemovedEvent;
|
import org.keycloak.models.RoleContainerModel.RoleRemovedEvent;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.RoleProvider;
|
import org.keycloak.models.RoleProvider;
|
||||||
|
import org.keycloak.models.ServerInfoProvider;
|
||||||
import org.keycloak.models.jpa.entities.ClientEntity;
|
import org.keycloak.models.jpa.entities.ClientEntity;
|
||||||
import org.keycloak.models.jpa.entities.ClientInitialAccessEntity;
|
import org.keycloak.models.jpa.entities.ClientInitialAccessEntity;
|
||||||
import org.keycloak.models.jpa.entities.ClientScopeClientMappingEntity;
|
import org.keycloak.models.jpa.entities.ClientScopeClientMappingEntity;
|
||||||
|
@ -70,7 +70,7 @@ import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class JpaRealmProvider implements RealmProvider, ClientProvider, ClientScopeProvider, GroupProvider, RoleProvider {
|
public class JpaRealmProvider implements RealmProvider, ClientProvider, ClientScopeProvider, GroupProvider, RoleProvider, ServerInfoProvider {
|
||||||
protected static final Logger logger = Logger.getLogger(JpaRealmProvider.class);
|
protected static final Logger logger = Logger.getLogger(JpaRealmProvider.class);
|
||||||
private final KeycloakSession session;
|
private final KeycloakSession session;
|
||||||
protected EntityManager em;
|
protected EntityManager em;
|
||||||
|
@ -214,8 +214,6 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, ClientSc
|
||||||
RoleEntity entity = new RoleEntity();
|
RoleEntity entity = new RoleEntity();
|
||||||
entity.setId(id);
|
entity.setId(id);
|
||||||
entity.setName(name);
|
entity.setName(name);
|
||||||
RealmEntity ref = em.getReference(RealmEntity.class, realm.getId());
|
|
||||||
entity.setRealm(ref);
|
|
||||||
entity.setRealmId(realm.getId());
|
entity.setRealmId(realm.getId());
|
||||||
em.persist(entity);
|
em.persist(entity);
|
||||||
em.flush();
|
em.flush();
|
||||||
|
@ -619,8 +617,7 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, ClientSc
|
||||||
entity.setClientId(clientId);
|
entity.setClientId(clientId);
|
||||||
entity.setEnabled(true);
|
entity.setEnabled(true);
|
||||||
entity.setStandardFlowEnabled(true);
|
entity.setStandardFlowEnabled(true);
|
||||||
RealmEntity realmRef = em.getReference(RealmEntity.class, realm.getId());
|
entity.setRealmId(realm.getId());
|
||||||
entity.setRealm(realmRef);
|
|
||||||
em.persist(entity);
|
em.persist(entity);
|
||||||
|
|
||||||
final ClientModel resource = new ClientAdapter(realm, em, session, entity);
|
final ClientModel resource = new ClientAdapter(realm, em, session, entity);
|
||||||
|
@ -657,11 +654,11 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, ClientSc
|
||||||
public ClientModel getClientById(RealmModel realm, String id) {
|
public ClientModel getClientById(RealmModel realm, String id) {
|
||||||
logger.tracef("getClientById(%s, %s)%s", realm, id, getShortStackTrace());
|
logger.tracef("getClientById(%s, %s)%s", realm, id, getShortStackTrace());
|
||||||
|
|
||||||
ClientEntity app = em.find(ClientEntity.class, id);
|
ClientEntity client = em.find(ClientEntity.class, id);
|
||||||
// Check if application belongs to this realm
|
// Check if client belongs to this realm
|
||||||
if (app == null || !realm.getId().equals(app.getRealm().getId())) return null;
|
if (client == null || !realm.getId().equals(client.getRealmId())) return null;
|
||||||
ClientAdapter client = new ClientAdapter(realm, em, session, app);
|
ClientAdapter adapter = new ClientAdapter(realm, em, session, client);
|
||||||
return client;
|
return adapter;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -744,7 +741,7 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, ClientSc
|
||||||
ClientScopeEntity clientScope = em.find(ClientScopeEntity.class, id);
|
ClientScopeEntity clientScope = em.find(ClientScopeEntity.class, id);
|
||||||
|
|
||||||
// Check if client scope belongs to this realm
|
// Check if client scope belongs to this realm
|
||||||
if (clientScope == null || !realm.getId().equals(clientScope.getRealm().getId())) return null;
|
if (clientScope == null || !realm.getId().equals(clientScope.getRealmId())) return null;
|
||||||
ClientScopeAdapter adapter = new ClientScopeAdapter(realm, em, session, clientScope);
|
ClientScopeAdapter adapter = new ClientScopeAdapter(realm, em, session, clientScope);
|
||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
|
@ -767,8 +764,7 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, ClientSc
|
||||||
entity.setId(id);
|
entity.setId(id);
|
||||||
name = KeycloakModelUtils.convertClientScopeName(name);
|
name = KeycloakModelUtils.convertClientScopeName(name);
|
||||||
entity.setName(name);
|
entity.setName(name);
|
||||||
RealmEntity ref = em.getReference(RealmEntity.class, realm.getId());
|
entity.setRealmId(realm.getId());
|
||||||
entity.setRealm(ref);
|
|
||||||
em.persist(entity);
|
em.persist(entity);
|
||||||
em.flush();
|
em.flush();
|
||||||
return new ClientScopeAdapter(realm, em, session, entity);
|
return new ClientScopeAdapter(realm, em, session, entity);
|
||||||
|
@ -863,52 +859,6 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, ClientSc
|
||||||
}).sorted(GroupModel.COMPARE_BY_NAME).distinct());
|
}).sorted(GroupModel.COMPARE_BY_NAME).distinct());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClientInitialAccessModel createClientInitialAccessModel(RealmModel realm, int expiration, int count) {
|
|
||||||
RealmEntity realmEntity = em.find(RealmEntity.class, realm.getId());
|
|
||||||
|
|
||||||
ClientInitialAccessEntity entity = new ClientInitialAccessEntity();
|
|
||||||
entity.setId(KeycloakModelUtils.generateId());
|
|
||||||
entity.setRealm(realmEntity);
|
|
||||||
|
|
||||||
entity.setCount(count);
|
|
||||||
entity.setRemainingCount(count);
|
|
||||||
|
|
||||||
int currentTime = Time.currentTime();
|
|
||||||
entity.setTimestamp(currentTime);
|
|
||||||
entity.setExpiration(expiration);
|
|
||||||
|
|
||||||
em.persist(entity);
|
|
||||||
|
|
||||||
return entityToModel(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClientInitialAccessModel getClientInitialAccessModel(RealmModel realm, String id) {
|
|
||||||
ClientInitialAccessEntity entity = em.find(ClientInitialAccessEntity.class, id);
|
|
||||||
if (entity == null) return null;
|
|
||||||
if (!entity.getRealm().getId().equals(realm.getId())) return null;
|
|
||||||
return entityToModel(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeClientInitialAccessModel(RealmModel realm, String id) {
|
|
||||||
ClientInitialAccessEntity entity = em.find(ClientInitialAccessEntity.class, id, LockModeType.PESSIMISTIC_WRITE);
|
|
||||||
if (entity == null) return;
|
|
||||||
if (!entity.getRealm().getId().equals(realm.getId())) return;
|
|
||||||
em.remove(entity);
|
|
||||||
em.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<ClientInitialAccessModel> listClientInitialAccessStream(RealmModel realm) {
|
|
||||||
RealmEntity realmEntity = em.find(RealmEntity.class, realm.getId());
|
|
||||||
|
|
||||||
TypedQuery<ClientInitialAccessEntity> query = em.createNamedQuery("findClientInitialAccessByRealm", ClientInitialAccessEntity.class);
|
|
||||||
query.setParameter("realm", realmEntity);
|
|
||||||
return closing(query.getResultStream().map(this::entityToModel));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeExpiredClientInitialAccess() {
|
public void removeExpiredClientInitialAccess() {
|
||||||
int currentTime = Time.currentTime();
|
int currentTime = Time.currentTime();
|
||||||
|
@ -918,13 +868,6 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, ClientSc
|
||||||
.executeUpdate();
|
.executeUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decreaseRemainingCount(RealmModel realm, ClientInitialAccessModel clientInitialAccess) {
|
|
||||||
em.createNamedQuery("decreaseClientInitialAccessRemainingCount")
|
|
||||||
.setParameter("id", clientInitialAccess.getId())
|
|
||||||
.executeUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private RealmLocalizationTextsEntity getRealmLocalizationTextsEntity(String locale, String realmId) {
|
private RealmLocalizationTextsEntity getRealmLocalizationTextsEntity(String locale, String realmId) {
|
||||||
RealmLocalizationTextsEntity.RealmLocalizationTextEntityKey key = new RealmLocalizationTextsEntity.RealmLocalizationTextEntityKey();
|
RealmLocalizationTextsEntity.RealmLocalizationTextEntityKey key = new RealmLocalizationTextsEntity.RealmLocalizationTextEntityKey();
|
||||||
key.setRealmId(realmId);
|
key.setRealmId(realmId);
|
||||||
|
@ -1006,15 +949,4 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, ClientSc
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClientInitialAccessModel entityToModel(ClientInitialAccessEntity entity) {
|
|
||||||
ClientInitialAccessModel model = new ClientInitialAccessModel();
|
|
||||||
model.setId(entity.getId());
|
|
||||||
model.setCount(entity.getCount());
|
|
||||||
model.setRemainingCount(entity.getRemainingCount());
|
|
||||||
model.setExpiration(entity.getExpiration());
|
|
||||||
model.setTimestamp(entity.getTimestamp());
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.jpa;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import org.keycloak.Config;
|
||||||
|
import org.keycloak.connections.jpa.JpaConnectionProvider;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
|
import org.keycloak.models.ServerInfoProvider;
|
||||||
|
import org.keycloak.models.ServerInfoProviderFactory;
|
||||||
|
|
||||||
|
public class JpaServerInfoProviderFactory implements ServerInfoProviderFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Config.Scope config) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postInit(KeycloakSessionFactory factory) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return "jpa";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerInfoProvider create(KeycloakSession session) {
|
||||||
|
EntityManager em = session.getProvider(JpaConnectionProvider.class).getEntityManager();
|
||||||
|
return new JpaRealmProvider(session, em);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import org.keycloak.Config;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.common.enums.SslRequired;
|
import org.keycloak.common.enums.SslRequired;
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
import org.keycloak.common.util.MultivaluedHashMap;
|
||||||
|
import org.keycloak.common.util.Time;
|
||||||
import org.keycloak.component.ComponentFactory;
|
import org.keycloak.component.ComponentFactory;
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.models.*;
|
import org.keycloak.models.*;
|
||||||
|
@ -185,21 +186,6 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
realm.getAttributes().add(attr);
|
realm.getAttributes().add(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAttribute(String name, Boolean value) {
|
|
||||||
setAttribute(name, value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAttribute(String name, Integer value) {
|
|
||||||
setAttribute(name, value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAttribute(String name, Long value) {
|
|
||||||
setAttribute(name, value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeAttribute(String name) {
|
public void removeAttribute(String name) {
|
||||||
Iterator<RealmAttributeEntity> it = realm.getAttributes().iterator();
|
Iterator<RealmAttributeEntity> it = realm.getAttributes().iterator();
|
||||||
|
@ -222,27 +208,6 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getAttribute(String name, Integer defaultValue) {
|
|
||||||
String v = getAttribute(name);
|
|
||||||
return v != null ? Integer.parseInt(v) : defaultValue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long getAttribute(String name, Long defaultValue) {
|
|
||||||
String v = getAttribute(name);
|
|
||||||
return v != null ? Long.parseLong(v) : defaultValue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean getAttribute(String name, Boolean defaultValue) {
|
|
||||||
String v = getAttribute(name);
|
|
||||||
return v != null ? Boolean.parseBoolean(v) : defaultValue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> getAttributes() {
|
public Map<String, String> getAttributes() {
|
||||||
// should always return a copy
|
// should always return a copy
|
||||||
|
@ -1566,9 +1531,10 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthenticationFlowModel getFlowByAlias(String alias) {
|
public AuthenticationFlowModel getFlowByAlias(String alias) {
|
||||||
return getAuthenticationFlowsStream()
|
return realm.getAuthenticationFlows().stream()
|
||||||
.filter(flow -> Objects.equals(flow.getAlias(), alias))
|
.filter(flow -> Objects.equals(flow.getAlias(), alias))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
|
.map(this::entityToModel)
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2241,6 +2207,69 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientInitialAccessModel createClientInitialAccessModel(int expiration, int count) {
|
||||||
|
RealmEntity realmEntity = em.find(RealmEntity.class, realm.getId());
|
||||||
|
|
||||||
|
ClientInitialAccessEntity entity = new ClientInitialAccessEntity();
|
||||||
|
entity.setId(KeycloakModelUtils.generateId());
|
||||||
|
entity.setRealm(realmEntity);
|
||||||
|
|
||||||
|
entity.setCount(count);
|
||||||
|
entity.setRemainingCount(count);
|
||||||
|
|
||||||
|
int currentTime = Time.currentTime();
|
||||||
|
entity.setTimestamp(currentTime);
|
||||||
|
entity.setExpiration(expiration);
|
||||||
|
|
||||||
|
em.persist(entity);
|
||||||
|
|
||||||
|
return entityToModel(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientInitialAccessModel getClientInitialAccessModel(String id) {
|
||||||
|
ClientInitialAccessEntity entity = em.find(ClientInitialAccessEntity.class, id);
|
||||||
|
if (entity == null) return null;
|
||||||
|
if (!entity.getRealm().getId().equals(realm.getId())) return null;
|
||||||
|
return entityToModel(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeClientInitialAccessModel(String id) {
|
||||||
|
ClientInitialAccessEntity entity = em.find(ClientInitialAccessEntity.class, id, LockModeType.PESSIMISTIC_WRITE);
|
||||||
|
if (entity == null) return;
|
||||||
|
if (!entity.getRealm().getId().equals(realm.getId())) return;
|
||||||
|
em.remove(entity);
|
||||||
|
em.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<ClientInitialAccessModel> getClientInitialAccesses() {
|
||||||
|
RealmEntity realmEntity = em.find(RealmEntity.class, realm.getId());
|
||||||
|
|
||||||
|
TypedQuery<ClientInitialAccessEntity> query = em.createNamedQuery("findClientInitialAccessByRealm", ClientInitialAccessEntity.class);
|
||||||
|
query.setParameter("realm", realmEntity);
|
||||||
|
return closing(query.getResultStream().map(this::entityToModel));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decreaseRemainingCount(ClientInitialAccessModel clientInitialAccess) {
|
||||||
|
em.createNamedQuery("decreaseClientInitialAccessRemainingCount")
|
||||||
|
.setParameter("id", clientInitialAccess.getId())
|
||||||
|
.executeUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClientInitialAccessModel entityToModel(ClientInitialAccessEntity entity) {
|
||||||
|
ClientInitialAccessModel model = new ClientInitialAccessModel();
|
||||||
|
model.setId(entity.getId());
|
||||||
|
model.setCount(entity.getCount());
|
||||||
|
model.setRemainingCount(entity.getRemainingCount());
|
||||||
|
model.setExpiration(entity.getExpiration());
|
||||||
|
model.setTimestamp(entity.getTimestamp());
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("%s@%08x", getId(), hashCode());
|
return String.format("%s@%08x", getId(), hashCode());
|
||||||
|
|
|
@ -26,10 +26,8 @@ import javax.persistence.CollectionTable;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.ElementCollection;
|
import javax.persistence.ElementCollection;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.FetchType;
|
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.MapKeyColumn;
|
import javax.persistence.MapKeyColumn;
|
||||||
import javax.persistence.NamedQueries;
|
import javax.persistence.NamedQueries;
|
||||||
import javax.persistence.NamedQuery;
|
import javax.persistence.NamedQuery;
|
||||||
|
@ -50,14 +48,14 @@ import java.util.Set;
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name="CLIENT", uniqueConstraints = {@UniqueConstraint(columnNames = {"REALM_ID", "CLIENT_ID"})})
|
@Table(name="CLIENT", uniqueConstraints = {@UniqueConstraint(columnNames = {"REALM_ID", "CLIENT_ID"})})
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
@NamedQuery(name="getClientsByRealm", query="select client from ClientEntity client where client.realm = :realm"),
|
@NamedQuery(name="getClientsByRealm", query="select client from ClientEntity client where client.realmId = :realm"),
|
||||||
@NamedQuery(name="getClientById", query="select client from ClientEntity client where client.id = :id and client.realm.id = :realm"),
|
@NamedQuery(name="getClientById", query="select client from ClientEntity client where client.id = :id and client.realmId = :realm"),
|
||||||
@NamedQuery(name="getClientIdsByRealm", query="select client.id from ClientEntity client where client.realm.id = :realm order by client.clientId"),
|
@NamedQuery(name="getClientIdsByRealm", query="select client.id from ClientEntity client where client.realmId = :realm order by client.clientId"),
|
||||||
@NamedQuery(name="getAlwaysDisplayInConsoleClients", query="select client.id from ClientEntity client where client.alwaysDisplayInConsole = true and client.realm.id = :realm order by client.clientId"),
|
@NamedQuery(name="getAlwaysDisplayInConsoleClients", query="select client.id from ClientEntity client where client.alwaysDisplayInConsole = true and client.realmId = :realm order by client.clientId"),
|
||||||
@NamedQuery(name="findClientIdByClientId", query="select client.id from ClientEntity client where client.clientId = :clientId and client.realm.id = :realm"),
|
@NamedQuery(name="findClientIdByClientId", query="select client.id from ClientEntity client where client.clientId = :clientId and client.realmId = :realm"),
|
||||||
@NamedQuery(name="searchClientsByClientId", query="select client.id from ClientEntity client where lower(client.clientId) like lower(concat('%',:clientId,'%')) and client.realm.id = :realm order by client.clientId"),
|
@NamedQuery(name="searchClientsByClientId", query="select client.id from ClientEntity client where lower(client.clientId) like lower(concat('%',:clientId,'%')) and client.realmId = :realm order by client.clientId"),
|
||||||
@NamedQuery(name="getRealmClientsCount", query="select count(client) from ClientEntity client where client.realm.id = :realm"),
|
@NamedQuery(name="getRealmClientsCount", query="select count(client) from ClientEntity client where client.realmId = :realm"),
|
||||||
@NamedQuery(name="findClientByClientId", query="select client from ClientEntity client where client.clientId = :clientId and client.realm.id = :realm"),
|
@NamedQuery(name="findClientByClientId", query="select client from ClientEntity client where client.clientId = :clientId and client.realmId = :realm"),
|
||||||
})
|
})
|
||||||
public class ClientEntity {
|
public class ClientEntity {
|
||||||
|
|
||||||
|
@ -94,9 +92,8 @@ public class ClientEntity {
|
||||||
@Column(name="FULL_SCOPE_ALLOWED")
|
@Column(name="FULL_SCOPE_ALLOWED")
|
||||||
private boolean fullScopeAllowed;
|
private boolean fullScopeAllowed;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@Column(name = "REALM_ID")
|
||||||
@JoinColumn(name = "REALM_ID")
|
protected String realmId;
|
||||||
protected RealmEntity realm;
|
|
||||||
|
|
||||||
@ElementCollection
|
@ElementCollection
|
||||||
@Column(name="VALUE")
|
@Column(name="VALUE")
|
||||||
|
@ -164,12 +161,12 @@ public class ClientEntity {
|
||||||
@CollectionTable(name="CLIENT_NODE_REGISTRATIONS", joinColumns={ @JoinColumn(name="CLIENT_ID") })
|
@CollectionTable(name="CLIENT_NODE_REGISTRATIONS", joinColumns={ @JoinColumn(name="CLIENT_ID") })
|
||||||
Map<String, Integer> registeredNodes;
|
Map<String, Integer> registeredNodes;
|
||||||
|
|
||||||
public RealmEntity getRealm() {
|
public String getRealmId() {
|
||||||
return realm;
|
return realmId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealm(RealmEntity realm) {
|
public void setRealmId(String realmId) {
|
||||||
this.realm = realm;
|
this.realmId = realmId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
|
|
@ -29,10 +29,8 @@ import javax.persistence.CollectionTable;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.ElementCollection;
|
import javax.persistence.ElementCollection;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.FetchType;
|
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.NamedQueries;
|
import javax.persistence.NamedQueries;
|
||||||
import javax.persistence.NamedQuery;
|
import javax.persistence.NamedQuery;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
|
@ -48,7 +46,7 @@ import org.hibernate.annotations.Nationalized;
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name="CLIENT_SCOPE", uniqueConstraints = {@UniqueConstraint(columnNames = {"REALM_ID", "NAME"})})
|
@Table(name="CLIENT_SCOPE", uniqueConstraints = {@UniqueConstraint(columnNames = {"REALM_ID", "NAME"})})
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
@NamedQuery(name="getClientScopeIds", query="select scope.id from ClientScopeEntity scope where scope.realm.id = :realm")
|
@NamedQuery(name="getClientScopeIds", query="select scope.id from ClientScopeEntity scope where scope.realmId = :realm")
|
||||||
})
|
})
|
||||||
public class ClientScopeEntity {
|
public class ClientScopeEntity {
|
||||||
|
|
||||||
|
@ -63,14 +61,13 @@ public class ClientScopeEntity {
|
||||||
private String description;
|
private String description;
|
||||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "clientScope")
|
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "clientScope")
|
||||||
Collection<ProtocolMapperEntity> protocolMappers;
|
Collection<ProtocolMapperEntity> protocolMappers;
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "REALM_ID")
|
@Column(name = "REALM_ID")
|
||||||
protected RealmEntity realm;
|
protected String realmId;
|
||||||
|
|
||||||
@Column(name="PROTOCOL")
|
@Column(name="PROTOCOL")
|
||||||
private String protocol;
|
private String protocol;
|
||||||
|
|
||||||
|
|
||||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "clientScope")
|
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "clientScope")
|
||||||
protected Collection<ClientScopeAttributeEntity> attributes;
|
protected Collection<ClientScopeAttributeEntity> attributes;
|
||||||
|
|
||||||
|
@ -79,12 +76,12 @@ public class ClientScopeEntity {
|
||||||
@CollectionTable(name="CLIENT_SCOPE_ROLE_MAPPING", joinColumns = { @JoinColumn(name="SCOPE_ID")})
|
@CollectionTable(name="CLIENT_SCOPE_ROLE_MAPPING", joinColumns = { @JoinColumn(name="SCOPE_ID")})
|
||||||
private Set<String> scopeMappingIds = new HashSet<>();
|
private Set<String> scopeMappingIds = new HashSet<>();
|
||||||
|
|
||||||
public RealmEntity getRealm() {
|
public String getRealmId() {
|
||||||
return realm;
|
return realmId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRealm(RealmEntity realm) {
|
public void setRealmId(String realmId) {
|
||||||
this.realm = realm;
|
this.realmId = realmId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
|
|
@ -148,10 +148,6 @@ public class RealmEntity {
|
||||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
||||||
Collection<UserFederationMapperEntity> userFederationMappers;
|
Collection<UserFederationMapperEntity> userFederationMappers;
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
|
||||||
Collection<ClientScopeEntity> clientScopes;
|
|
||||||
|
|
||||||
@ElementCollection
|
@ElementCollection
|
||||||
@MapKeyColumn(name="NAME")
|
@MapKeyColumn(name="NAME")
|
||||||
@Column(name="VALUE")
|
@Column(name="VALUE")
|
||||||
|
@ -814,19 +810,6 @@ public class RealmEntity {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public Collection<ClientScopeEntity> getClientScopes() {
|
|
||||||
if (clientScopes == null) {
|
|
||||||
clientScopes = new LinkedList<>();
|
|
||||||
}
|
|
||||||
return clientScopes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void setClientScopes(Collection<ClientScopeEntity> clientScopes) {
|
|
||||||
this.clientScopes = clientScopes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAllowUserManagedAccess(boolean allowUserManagedAccess) {
|
public void setAllowUserManagedAccess(boolean allowUserManagedAccess) {
|
||||||
this.allowUserManagedAccess = allowUserManagedAccess;
|
this.allowUserManagedAccess = allowUserManagedAccess;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import javax.persistence.Id;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.JoinTable;
|
import javax.persistence.JoinTable;
|
||||||
import javax.persistence.ManyToMany;
|
import javax.persistence.ManyToMany;
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.NamedQueries;
|
import javax.persistence.NamedQueries;
|
||||||
import javax.persistence.NamedQuery;
|
import javax.persistence.NamedQuery;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
|
@ -59,11 +58,11 @@ import java.util.Set;
|
||||||
@NamedQuery(name="getClientRoleByName", query="select role from RoleEntity role where role.name = :name and role.clientId = :client"),
|
@NamedQuery(name="getClientRoleByName", query="select role from RoleEntity role where role.name = :name and role.clientId = :client"),
|
||||||
@NamedQuery(name="getClientRoleIdByName", query="select role.id from RoleEntity role where role.name = :name and role.clientId = :client"),
|
@NamedQuery(name="getClientRoleIdByName", query="select role.id from RoleEntity role where role.name = :name and role.clientId = :client"),
|
||||||
@NamedQuery(name="searchForClientRoles", query="select role from RoleEntity role where role.clientId = :client and ( lower(role.name) like :search or lower(role.description) like :search ) order by role.name"),
|
@NamedQuery(name="searchForClientRoles", query="select role from RoleEntity role where role.clientId = :client and ( lower(role.name) like :search or lower(role.description) like :search ) order by role.name"),
|
||||||
@NamedQuery(name="getRealmRoles", query="select role from RoleEntity role where role.clientRole = false and role.realm.id = :realm order by role.name"),
|
@NamedQuery(name="getRealmRoles", query="select role from RoleEntity role where role.clientRole = false and role.realmId = :realm order by role.name"),
|
||||||
@NamedQuery(name="getRealmRoleIds", query="select role.id from RoleEntity role where role.clientRole = false and role.realm.id = :realm"),
|
@NamedQuery(name="getRealmRoleIds", query="select role.id from RoleEntity role where role.clientRole = false and role.realmId = :realm"),
|
||||||
@NamedQuery(name="getRealmRoleByName", query="select role from RoleEntity role where role.clientRole = false and role.name = :name and role.realm = :realm"),
|
@NamedQuery(name="getRealmRoleByName", query="select role from RoleEntity role where role.clientRole = false and role.name = :name and role.realmId = :realm"),
|
||||||
@NamedQuery(name="getRealmRoleIdByName", query="select role.id from RoleEntity role where role.clientRole = false and role.name = :name and role.realm.id = :realm"),
|
@NamedQuery(name="getRealmRoleIdByName", query="select role.id from RoleEntity role where role.clientRole = false and role.name = :name and role.realmId = :realm"),
|
||||||
@NamedQuery(name="searchForRealmRoles", query="select role from RoleEntity role where role.clientRole = false and role.realm.id = :realm and ( lower(role.name) like :search or lower(role.description) like :search ) order by role.name"),
|
@NamedQuery(name="searchForRealmRoles", query="select role from RoleEntity role where role.clientRole = false and role.realmId = :realm and ( lower(role.name) like :search or lower(role.description) like :search ) order by role.name"),
|
||||||
})
|
})
|
||||||
|
|
||||||
public class RoleEntity {
|
public class RoleEntity {
|
||||||
|
@ -83,10 +82,6 @@ public class RoleEntity {
|
||||||
@Column(name = "REALM_ID")
|
@Column(name = "REALM_ID")
|
||||||
private String realmId;
|
private String realmId;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "REALM")
|
|
||||||
private RealmEntity realm;
|
|
||||||
|
|
||||||
@Column(name="CLIENT_ROLE")
|
@Column(name="CLIENT_ROLE")
|
||||||
private boolean clientRole;
|
private boolean clientRole;
|
||||||
|
|
||||||
|
@ -168,15 +163,6 @@ public class RoleEntity {
|
||||||
this.clientRole = clientRole;
|
this.clientRole = clientRole;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RealmEntity getRealm() {
|
|
||||||
return realm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRealm(RealmEntity realm) {
|
|
||||||
this.realm = realm;
|
|
||||||
this.clientRealmConstraint = realm.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientId() {
|
public String getClientId() {
|
||||||
return clientId;
|
return clientId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,9 @@
|
||||||
<dropForeignKeyConstraint baseTableName="DEFAULT_CLIENT_SCOPE" constraintName="FK_R_DEF_CLI_SCOPE_SCOPE"/>
|
<dropForeignKeyConstraint baseTableName="DEFAULT_CLIENT_SCOPE" constraintName="FK_R_DEF_CLI_SCOPE_SCOPE"/>
|
||||||
<dropForeignKeyConstraint baseTableName="CLIENT_SCOPE_CLIENT" constraintName="FK_C_CLI_SCOPE_SCOPE"/>
|
<dropForeignKeyConstraint baseTableName="CLIENT_SCOPE_CLIENT" constraintName="FK_C_CLI_SCOPE_SCOPE"/>
|
||||||
<dropForeignKeyConstraint baseTableName="CLIENT_SCOPE_CLIENT" constraintName="FK_C_CLI_SCOPE_CLIENT"/>
|
<dropForeignKeyConstraint baseTableName="CLIENT_SCOPE_CLIENT" constraintName="FK_C_CLI_SCOPE_CLIENT"/>
|
||||||
|
<dropForeignKeyConstraint baseTableName="CLIENT" constraintName="FK_P56CTINXXB9GSK57FO49F9TAC"/>
|
||||||
|
<dropForeignKeyConstraint baseTableName="CLIENT_SCOPE" constraintName="FK_REALM_CLI_SCOPE"/>
|
||||||
|
<dropForeignKeyConstraint baseTableName="KEYCLOAK_GROUP" constraintName="FK_GROUP_REALM"/>
|
||||||
</changeSet>
|
</changeSet>
|
||||||
|
|
||||||
<changeSet author="keycloak" id="13.0.0-increase-column-size-federated">
|
<changeSet author="keycloak" id="13.0.0-increase-column-size-federated">
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
#
|
||||||
|
# Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
# and other contributors as indicated by the @author tags.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
org.keycloak.models.jpa.JpaServerInfoProviderFactory
|
|
@ -20,13 +20,8 @@ package org.keycloak.models.map.common;
|
||||||
*
|
*
|
||||||
* @author hmlnarik
|
* @author hmlnarik
|
||||||
*/
|
*/
|
||||||
public interface AbstractEntity<K> {
|
public interface AbstractEntity<K> extends UpdatableEntity {
|
||||||
|
|
||||||
K getId();
|
K getId();
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag signalizing that any of the setters has been meaningfully used.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
boolean isUpdated();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class Serialization {
|
||||||
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
|
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
|
||||||
.setVisibility(PropertyAccessor.ALL, Visibility.NONE)
|
.setVisibility(PropertyAccessor.ALL, Visibility.NONE)
|
||||||
.setVisibility(PropertyAccessor.FIELD, Visibility.ANY)
|
.setVisibility(PropertyAccessor.FIELD, Visibility.ANY)
|
||||||
.addMixIn(AbstractEntity.class, IgnoreUpdatedMixIn.class);
|
.addMixIn(UpdatableEntity.class, IgnoreUpdatedMixIn.class);
|
||||||
|
|
||||||
public static final ConcurrentHashMap<Class<?>, ObjectReader> READERS = new ConcurrentHashMap<>();
|
public static final ConcurrentHashMap<Class<?>, ObjectReader> READERS = new ConcurrentHashMap<>();
|
||||||
public static final ConcurrentHashMap<Class<?>, ObjectWriter> WRITERS = new ConcurrentHashMap<>();
|
public static final ConcurrentHashMap<Class<?>, ObjectWriter> WRITERS = new ConcurrentHashMap<>();
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.keycloak.models.map.common;
|
||||||
|
|
||||||
|
public interface UpdatableEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag signalizing that any of the setters has been meaningfully used.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean isUpdated();
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.keycloak.models.map.realm;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.map.common.AbstractEntity;
|
||||||
|
|
||||||
|
public abstract class AbstractRealmModel<E extends AbstractEntity> implements RealmModel {
|
||||||
|
|
||||||
|
protected final KeycloakSession session;
|
||||||
|
protected final E entity;
|
||||||
|
|
||||||
|
public AbstractRealmModel(KeycloakSession session, E entity) {
|
||||||
|
Objects.requireNonNull(entity, "entity");
|
||||||
|
|
||||||
|
this.session = session;
|
||||||
|
this.entity = entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof RealmModel)) return false;
|
||||||
|
|
||||||
|
RealmModel that = (RealmModel) o;
|
||||||
|
return Objects.equals(that.getId(), getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getId().hashCode();
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.keycloak.models.map.realm;
|
||||||
|
|
||||||
|
public class MapRealmEntity extends AbstractRealmEntity<String> {
|
||||||
|
|
||||||
|
protected MapRealmEntity() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MapRealmEntity(String id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,492 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.realm;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
import static org.keycloak.common.util.StackUtil.getShortStackTrace;
|
||||||
|
import org.keycloak.models.ClientModel;
|
||||||
|
import org.keycloak.models.ClientScopeModel;
|
||||||
|
import org.keycloak.models.GroupModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.ModelDuplicateException;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RealmModel.SearchableFields;
|
||||||
|
import org.keycloak.models.RealmProvider;
|
||||||
|
import org.keycloak.models.RoleModel;
|
||||||
|
import org.keycloak.models.map.common.Serialization;
|
||||||
|
import org.keycloak.models.map.storage.MapKeycloakTransaction;
|
||||||
|
import org.keycloak.models.map.storage.MapStorage;
|
||||||
|
import org.keycloak.models.map.storage.ModelCriteriaBuilder;
|
||||||
|
import org.keycloak.models.map.storage.ModelCriteriaBuilder.Operator;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
|
public class MapRealmProvider implements RealmProvider {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(MapRealmProvider.class);
|
||||||
|
private final KeycloakSession session;
|
||||||
|
final MapKeycloakTransaction<String, MapRealmEntity, RealmModel> tx;
|
||||||
|
private final MapStorage<String, MapRealmEntity, RealmModel> realmStore;
|
||||||
|
|
||||||
|
public MapRealmProvider(KeycloakSession session, MapStorage<String, MapRealmEntity, RealmModel> realmStore) {
|
||||||
|
this.session = session;
|
||||||
|
this.realmStore = realmStore;
|
||||||
|
this.tx = realmStore.createTransaction(session);
|
||||||
|
session.getTransactionManager().enlist(tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RealmModel entityToAdapter(MapRealmEntity entity) {
|
||||||
|
// Clone entity before returning back, to avoid giving away a reference to the live object to the caller
|
||||||
|
|
||||||
|
return new MapRealmAdapter(session, registerEntityForChanges(entity));
|
||||||
|
}
|
||||||
|
|
||||||
|
private MapRealmEntity registerEntityForChanges(MapRealmEntity origEntity) {
|
||||||
|
final MapRealmEntity res = Serialization.from(origEntity);
|
||||||
|
tx.updateIfChanged(origEntity.getId(), res, MapRealmEntity::isUpdated);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RealmModel createRealm(String name) {
|
||||||
|
return createRealm(KeycloakModelUtils.generateId(), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RealmModel createRealm(String id, String name) {
|
||||||
|
if (getRealmByName(name) != null) {
|
||||||
|
throw new ModelDuplicateException("Realm with given name exists: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id != null) {
|
||||||
|
if (tx.read(id) != null) {
|
||||||
|
throw new ModelDuplicateException("Realm exists: " + id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id = KeycloakModelUtils.generateId();
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG.tracef("createRealm(%s, %s)%s", id, name, getShortStackTrace());
|
||||||
|
|
||||||
|
MapRealmEntity entity = new MapRealmEntity(id);
|
||||||
|
entity.setName(name);
|
||||||
|
|
||||||
|
tx.create(id, entity);
|
||||||
|
return entityToAdapter(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RealmModel getRealm(String id) {
|
||||||
|
if (id == null) return null;
|
||||||
|
|
||||||
|
LOG.tracef("getRealm(%s)%s", id, getShortStackTrace());
|
||||||
|
|
||||||
|
MapRealmEntity entity = tx.read(id);
|
||||||
|
return entity == null ? null : entityToAdapter(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RealmModel getRealmByName(String name) {
|
||||||
|
if (name == null) return null;
|
||||||
|
|
||||||
|
LOG.tracef("getRealmByName(%s)%s", name, getShortStackTrace());
|
||||||
|
|
||||||
|
ModelCriteriaBuilder<RealmModel> mcb = realmStore.createCriteriaBuilder()
|
||||||
|
.compare(SearchableFields.NAME, Operator.EQ, name);
|
||||||
|
|
||||||
|
String realmId = tx.getUpdatedNotRemoved(mcb)
|
||||||
|
.findFirst()
|
||||||
|
.map(MapRealmEntity::getId)
|
||||||
|
.orElse(null);
|
||||||
|
//we need to go via session.realms() not to bypass cache
|
||||||
|
return realmId == null ? null : session.realms().getRealm(realmId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<RealmModel> getRealmsStream() {
|
||||||
|
return getRealmsStream(realmStore.createCriteriaBuilder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<RealmModel> getRealmsWithProviderTypeStream(Class<?> type) {
|
||||||
|
ModelCriteriaBuilder<RealmModel> mcb = realmStore.createCriteriaBuilder()
|
||||||
|
.compare(SearchableFields.COMPONENT_PROVIDER_TYPE, Operator.EQ, type.getName());
|
||||||
|
|
||||||
|
return getRealmsStream(mcb);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Stream<RealmModel> getRealmsStream(ModelCriteriaBuilder<RealmModel> mcb) {
|
||||||
|
return tx.getUpdatedNotRemoved(mcb)
|
||||||
|
.map(this::entityToAdapter)
|
||||||
|
.sorted(RealmModel.COMPARE_BY_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeRealm(String id) {
|
||||||
|
LOG.tracef("removeRealm(%s)%s", id, getShortStackTrace());
|
||||||
|
|
||||||
|
RealmModel realm = getRealm(id);
|
||||||
|
|
||||||
|
if (realm == null) return false;
|
||||||
|
|
||||||
|
session.users().preRemove(realm);
|
||||||
|
session.clients().removeClients(realm);
|
||||||
|
session.clientScopes().removeClientScopes(realm);
|
||||||
|
session.roles().removeRoles(realm);
|
||||||
|
realm.getTopLevelGroupsStream().forEach(realm::removeGroup);
|
||||||
|
|
||||||
|
// TODO: Sending an event should be extracted to store layer
|
||||||
|
session.getKeycloakSessionFactory().publish(new RealmModel.RealmRemovedEvent() {
|
||||||
|
@Override
|
||||||
|
public RealmModel getRealm() {
|
||||||
|
return realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeycloakSession getKeycloakSession() {
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// TODO: ^^^^^^^ Up to here
|
||||||
|
|
||||||
|
tx.delete(id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeExpiredClientInitialAccess() {
|
||||||
|
ModelCriteriaBuilder<RealmModel> mcb = realmStore.createCriteriaBuilder()
|
||||||
|
.compare(SearchableFields.CLIENT_INITIAL_ACCESS, Operator.EXISTS);
|
||||||
|
|
||||||
|
tx.getUpdatedNotRemoved(mcb)
|
||||||
|
.map(this::registerEntityForChanges)
|
||||||
|
.forEach(MapRealmEntity::removeExpiredClientInitialAccesses);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO move the following method to adapter
|
||||||
|
@Override
|
||||||
|
public void saveLocalizationText(RealmModel realm, String locale, String key, String text) {
|
||||||
|
// implemented according to behaviour in JpaRealmProvider (as java-doc was not added)
|
||||||
|
if (! updateLocalizationText(realm, locale, key, text)) {
|
||||||
|
Map<String, String> texts = new HashMap<>();
|
||||||
|
texts.put(key, text);
|
||||||
|
realm.patchRealmLocalizationTexts(locale, texts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO move the following method to adapter
|
||||||
|
@Override
|
||||||
|
public void saveLocalizationTexts(RealmModel realm, String locale, Map<String, String> localizationTexts) {
|
||||||
|
if (locale == null || localizationTexts == null) return;
|
||||||
|
realm.patchRealmLocalizationTexts(locale, localizationTexts);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO move the following method to adapter
|
||||||
|
@Override
|
||||||
|
public boolean updateLocalizationText(RealmModel realm, String locale, String key, String text) {
|
||||||
|
if (locale == null || key == null || text == null || (! realm.getRealmLocalizationTextsByLocale(locale).containsKey(key))) return false;
|
||||||
|
Map<String, String> texts = new HashMap<>(realm.getRealmLocalizationTextsByLocale(locale));
|
||||||
|
texts.replace(key, text);
|
||||||
|
realm.patchRealmLocalizationTexts(locale, texts);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO move the following method to adapter
|
||||||
|
@Override
|
||||||
|
public boolean deleteLocalizationTextsByLocale(RealmModel realm, String locale) {
|
||||||
|
return realm.removeRealmLocalizationTexts(locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO move the following method to adapter
|
||||||
|
@Override
|
||||||
|
public boolean deleteLocalizationText(RealmModel realm, String locale, String key) {
|
||||||
|
if (locale == null || key == null || (! realm.getRealmLocalizationTextsByLocale(locale).containsKey(key))) return false;
|
||||||
|
|
||||||
|
Map<String, String> texts = new HashMap<>(realm.getRealmLocalizationTextsByLocale(locale));
|
||||||
|
texts.remove(key);
|
||||||
|
realm.removeRealmLocalizationTexts(locale);
|
||||||
|
realm.patchRealmLocalizationTexts(locale, texts);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO move the following method to adapter
|
||||||
|
@Override
|
||||||
|
public String getLocalizationTextsById(RealmModel realm, String locale, String key) {
|
||||||
|
if (locale == null || key == null || (! realm.getRealmLocalizationTextsByLocale(locale).containsKey(key))) return null;
|
||||||
|
return realm.getRealmLocalizationTextsByLocale(locale).get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public ClientModel addClient(RealmModel realm, String id, String clientId) {
|
||||||
|
return session.clients().addClient(realm, id, clientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public long getClientsCount(RealmModel realm) {
|
||||||
|
return session.clients().getClientsCount(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Stream<ClientModel> getClientsStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
|
return session.clients().getClientsStream(realm, firstResult, maxResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Stream<ClientModel> getAlwaysDisplayInConsoleClientsStream(RealmModel realm) {
|
||||||
|
return session.clients().getAlwaysDisplayInConsoleClientsStream(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public boolean removeClient(RealmModel realm, String id) {
|
||||||
|
return session.clients().removeClient(realm, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public void removeClients(RealmModel realm) {
|
||||||
|
session.clients().removeClients(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public ClientModel getClientById(RealmModel realm, String id) {
|
||||||
|
return session.clients().getClientById(realm, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public ClientModel getClientByClientId(RealmModel realm, String clientId) {
|
||||||
|
return session.clients().getClientByClientId(realm, clientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Stream<ClientModel> searchClientsByClientIdStream(RealmModel realm, String clientId, Integer firstResult, Integer maxResults) {
|
||||||
|
return session.clients().searchClientsByClientIdStream(realm, clientId, firstResult, maxResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public void addClientScopes(RealmModel realm, ClientModel client, Set<ClientScopeModel> clientScopes, boolean defaultScope) {
|
||||||
|
session.clients().addClientScopes(realm, client, clientScopes, defaultScope);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public void removeClientScope(RealmModel realm, ClientModel client, ClientScopeModel clientScope) {
|
||||||
|
session.clients().removeClientScope(realm, client, clientScope);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Map<String, ClientScopeModel> getClientScopes(RealmModel realm, ClientModel client, boolean defaultScopes) {
|
||||||
|
return session.clients().getClientScopes(realm, client, defaultScopes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public ClientScopeModel getClientScopeById(RealmModel realm, String id) {
|
||||||
|
return session.clientScopes().getClientScopeById(realm, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Stream<ClientScopeModel> getClientScopesStream(RealmModel realm) {
|
||||||
|
return session.clientScopes().getClientScopesStream(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public ClientScopeModel addClientScope(RealmModel realm, String id, String name) {
|
||||||
|
return session.clientScopes().addClientScope(realm, id, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public boolean removeClientScope(RealmModel realm, String id) {
|
||||||
|
return session.clientScopes().removeClientScope(realm, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public void removeClientScopes(RealmModel realm) {
|
||||||
|
session.clientScopes().removeClientScopes(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public void moveGroup(RealmModel realm, GroupModel group, GroupModel toParent) {
|
||||||
|
session.groups().moveGroup(realm, group, toParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public GroupModel getGroupById(RealmModel realm, String id) {
|
||||||
|
return session.groups().getGroupById(realm, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Long getGroupsCount(RealmModel realm, Boolean onlyTopGroups) {
|
||||||
|
return session.groups().getGroupsCount(realm, onlyTopGroups);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Long getGroupsCountByNameContaining(RealmModel realm, String search) {
|
||||||
|
return session.groups().getGroupsCountByNameContaining(realm, search);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public boolean removeGroup(RealmModel realm, GroupModel group) {
|
||||||
|
return session.groups().removeGroup(realm, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public GroupModel createGroup(RealmModel realm, String id, String name, GroupModel toParent) {
|
||||||
|
return session.groups().createGroup(realm, id, name, toParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public void addTopLevelGroup(RealmModel realm, GroupModel subGroup) {
|
||||||
|
session.groups().addTopLevelGroup(realm, subGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Stream<GroupModel> getGroupsStream(RealmModel realm) {
|
||||||
|
return session.groups().getGroupsStream(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Stream<GroupModel> getGroupsStream(RealmModel realm, Stream<String> ids, String search, Integer first, Integer max) {
|
||||||
|
return session.groups().getGroupsStream(realm,ids, search, first, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Stream<GroupModel> getGroupsByRoleStream(RealmModel realm, RoleModel role, Integer firstResult, Integer maxResults) {
|
||||||
|
return session.groups().getGroupsByRoleStream(realm, role, firstResult, maxResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Stream<GroupModel> getTopLevelGroupsStream(RealmModel realm) {
|
||||||
|
return session.groups().getTopLevelGroupsStream(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Stream<GroupModel> getTopLevelGroupsStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
|
return session.groups().getTopLevelGroupsStream(realm, firstResult, maxResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Stream<GroupModel> searchForGroupByNameStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
|
||||||
|
return session.groups().searchForGroupByNameStream(realm, search, firstResult, maxResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public RoleModel addRealmRole(RealmModel realm, String id, String name) {
|
||||||
|
return session.roles().addRealmRole(realm, id, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public RoleModel getRealmRole(RealmModel realm, String name) {
|
||||||
|
return session.roles().getRealmRole(realm, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Stream<RoleModel> getRealmRolesStream(RealmModel realm, Integer first, Integer max) {
|
||||||
|
return session.roles().getRealmRolesStream(realm, first, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public boolean removeRole(RoleModel role) {
|
||||||
|
return session.roles().removeRole(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public void removeRoles(RealmModel realm) {
|
||||||
|
session.roles().removeRoles(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public RoleModel addClientRole(ClientModel client, String id, String name) {
|
||||||
|
return session.roles().addClientRole(client, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Stream<RoleModel> getClientRolesStream(ClientModel client, Integer first, Integer max) {
|
||||||
|
return session.roles().getClientRolesStream(client, first, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public void removeRoles(ClientModel client) {
|
||||||
|
session.roles().removeRoles(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public RoleModel getRoleById(RealmModel realm, String id) {
|
||||||
|
return session.roles().getRoleById(realm, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Stream<RoleModel> searchForRolesStream(RealmModel realm, String search, Integer first, Integer max) {
|
||||||
|
return session.roles().searchForRolesStream(realm, search, first, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public RoleModel getClientRole(ClientModel client, String name) {
|
||||||
|
return session.roles().getClientRole(client, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Stream<RoleModel> searchForClientRolesStream(ClientModel client, String search, Integer first, Integer max) {
|
||||||
|
return session.roles().searchForClientRolesStream(client, search, first, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.keycloak.models.map.realm;
|
||||||
|
|
||||||
|
import org.keycloak.models.map.common.AbstractMapProviderFactory;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RealmProvider;
|
||||||
|
import org.keycloak.models.RealmProviderFactory;
|
||||||
|
import org.keycloak.models.map.storage.MapStorageProvider;
|
||||||
|
import org.keycloak.models.map.storage.MapStorage;
|
||||||
|
|
||||||
|
public class MapRealmProviderFactory extends AbstractMapProviderFactory<RealmProvider> implements RealmProviderFactory {
|
||||||
|
|
||||||
|
//for now we have to support String ids
|
||||||
|
private MapStorage<String, MapRealmEntity, RealmModel> store;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postInit(KeycloakSessionFactory factory) {
|
||||||
|
MapStorageProvider sp = (MapStorageProvider) factory.getProviderFactory(MapStorageProvider.class);
|
||||||
|
this.store = sp.getStorage("realm", String.class, MapRealmEntity.class, RealmModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RealmProvider create(KeycloakSession session) {
|
||||||
|
return new MapRealmProvider(session, store);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.realm.entity;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.keycloak.models.AuthenticationExecutionModel;
|
||||||
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
|
public class MapAuthenticationExecutionEntity implements UpdatableEntity {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String authenticator;
|
||||||
|
private String authenticatorConfig;
|
||||||
|
private String flowId;
|
||||||
|
private String parentFlowId;
|
||||||
|
private AuthenticationExecutionModel.Requirement requirement;
|
||||||
|
private Boolean autheticatorFlow = false;
|
||||||
|
private Integer priority = 0;
|
||||||
|
|
||||||
|
private boolean updated;
|
||||||
|
|
||||||
|
private MapAuthenticationExecutionEntity() {}
|
||||||
|
|
||||||
|
public static MapAuthenticationExecutionEntity fromModel(AuthenticationExecutionModel model) {
|
||||||
|
if (model == null) return null;
|
||||||
|
MapAuthenticationExecutionEntity entity = new MapAuthenticationExecutionEntity();
|
||||||
|
String id = model.getId() == null ? KeycloakModelUtils.generateId() : model.getId();
|
||||||
|
entity.setId(id);
|
||||||
|
entity.setAuthenticator(model.getAuthenticator());
|
||||||
|
entity.setAuthenticatorConfig(model.getAuthenticatorConfig());
|
||||||
|
entity.setFlowId(model.getFlowId());
|
||||||
|
entity.setParentFlowId(model.getParentFlow());
|
||||||
|
entity.setRequirement(model.getRequirement());
|
||||||
|
entity.setAutheticatorFlow(model.isAuthenticatorFlow());
|
||||||
|
entity.setPriority(model.getPriority());
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AuthenticationExecutionModel toModel(MapAuthenticationExecutionEntity entity) {
|
||||||
|
if (entity == null) return null;
|
||||||
|
AuthenticationExecutionModel model = new AuthenticationExecutionModel();
|
||||||
|
model.setId(entity.getId());
|
||||||
|
model.setAuthenticator(entity.getAuthenticator());
|
||||||
|
model.setAuthenticatorConfig(entity.getAuthenticatorConfig());
|
||||||
|
model.setFlowId(entity.getFlowId());
|
||||||
|
model.setParentFlow(entity.getParentFlowId());
|
||||||
|
model.setRequirement(entity.getRequirement());
|
||||||
|
model.setAuthenticatorFlow(entity.isAutheticatorFlow());
|
||||||
|
model.setPriority(entity.getPriority());
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUpdated() {
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.updated = !Objects.equals(this.id, id);
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthenticator() {
|
||||||
|
return authenticator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthenticator(String authenticator) {
|
||||||
|
this.updated = !Objects.equals(this.authenticator, authenticator);
|
||||||
|
this.authenticator = authenticator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthenticatorConfig() {
|
||||||
|
return authenticatorConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthenticatorConfig(String authenticatorConfig) {
|
||||||
|
this.updated = !Objects.equals(this.authenticatorConfig, authenticatorConfig);
|
||||||
|
this.authenticatorConfig = authenticatorConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthenticationExecutionModel.Requirement getRequirement() {
|
||||||
|
return requirement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequirement(AuthenticationExecutionModel.Requirement requirement) {
|
||||||
|
this.updated = !Objects.equals(this.requirement, requirement);
|
||||||
|
this.requirement = requirement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isAutheticatorFlow() {
|
||||||
|
return autheticatorFlow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutheticatorFlow(boolean autheticatorFlow) {
|
||||||
|
this.updated = !Objects.equals(this.requirement, requirement);
|
||||||
|
this.autheticatorFlow = autheticatorFlow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFlowId() {
|
||||||
|
return flowId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFlowId(String flowId) {
|
||||||
|
this.updated = !Objects.equals(this.flowId, flowId);
|
||||||
|
this.flowId = flowId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getParentFlowId() {
|
||||||
|
return parentFlowId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParentFlowId(String parentFlowId) {
|
||||||
|
this.updated = !Objects.equals(this.parentFlowId, parentFlowId);
|
||||||
|
this.parentFlowId = parentFlowId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPriority(Integer priority) {
|
||||||
|
this.updated = !Objects.equals(this.priority, priority);
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getId().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (!(obj instanceof MapAuthenticationExecutionEntity)) return false;
|
||||||
|
final MapAuthenticationExecutionEntity other = (MapAuthenticationExecutionEntity) obj;
|
||||||
|
return Objects.equals(other.getId(), getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.realm.entity;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.keycloak.models.AuthenticationFlowModel;
|
||||||
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
|
public class MapAuthenticationFlowEntity implements UpdatableEntity {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String alias;
|
||||||
|
private String description;
|
||||||
|
private String providerId;
|
||||||
|
private Boolean builtIn = false;
|
||||||
|
private Boolean topLevel = false;
|
||||||
|
|
||||||
|
private boolean updated;
|
||||||
|
|
||||||
|
private MapAuthenticationFlowEntity() {}
|
||||||
|
|
||||||
|
public static MapAuthenticationFlowEntity fromModel(AuthenticationFlowModel model) {
|
||||||
|
if (model == null) return null;
|
||||||
|
MapAuthenticationFlowEntity entity = new MapAuthenticationFlowEntity();
|
||||||
|
String id = model.getId() == null ? KeycloakModelUtils.generateId() : model.getId();
|
||||||
|
entity.setId(id);
|
||||||
|
entity.setAlias(model.getAlias());
|
||||||
|
entity.setBuiltIn(model.isBuiltIn());
|
||||||
|
entity.setDescription(model.getDescription());
|
||||||
|
entity.setProviderId(model.getProviderId());
|
||||||
|
entity.setTopLevel(model.isTopLevel());
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AuthenticationFlowModel toModel(MapAuthenticationFlowEntity entity) {
|
||||||
|
if (entity == null) return null;
|
||||||
|
AuthenticationFlowModel model = new AuthenticationFlowModel();
|
||||||
|
model.setId(entity.getId());
|
||||||
|
model.setAlias(entity.getAlias());
|
||||||
|
model.setBuiltIn(entity.isBuiltIn());
|
||||||
|
model.setDescription(entity.getDescription());
|
||||||
|
model.setProviderId(entity.getProviderId());
|
||||||
|
model.setTopLevel(entity.isTopLevel());
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUpdated() {
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.updated = !Objects.equals(this.id, id);
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlias() {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlias(String alias) {
|
||||||
|
this.updated = !Objects.equals(this.alias, alias);
|
||||||
|
this.alias = alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.updated = !Objects.equals(this.description, description);
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProviderId() {
|
||||||
|
return providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProviderId(String providerId) {
|
||||||
|
this.updated = !Objects.equals(this.providerId, providerId);
|
||||||
|
this.providerId = providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isBuiltIn() {
|
||||||
|
return builtIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBuiltIn(boolean builtIn) {
|
||||||
|
this.updated = !Objects.equals(this.builtIn, builtIn);
|
||||||
|
this.builtIn = builtIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isTopLevel() {
|
||||||
|
return topLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTopLevel(boolean topLevel) {
|
||||||
|
this.updated = !Objects.equals(this.topLevel, topLevel);
|
||||||
|
this.topLevel = topLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getId().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (!(obj instanceof MapAuthenticationFlowEntity)) return false;
|
||||||
|
final MapAuthenticationFlowEntity other = (MapAuthenticationFlowEntity) obj;
|
||||||
|
return Objects.equals(other.getId(), getId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.realm.entity;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.keycloak.models.AuthenticatorConfigModel;
|
||||||
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
|
public class MapAuthenticatorConfigEntity implements UpdatableEntity {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String alias;
|
||||||
|
private Map<String, String> config = new HashMap<>();
|
||||||
|
|
||||||
|
private boolean updated;
|
||||||
|
|
||||||
|
private MapAuthenticatorConfigEntity() {}
|
||||||
|
|
||||||
|
public static MapAuthenticatorConfigEntity fromModel(AuthenticatorConfigModel model) {
|
||||||
|
if (model == null) return null;
|
||||||
|
MapAuthenticatorConfigEntity entity = new MapAuthenticatorConfigEntity();
|
||||||
|
String id = model.getId() == null ? KeycloakModelUtils.generateId() : model.getId();
|
||||||
|
entity.setId(id);
|
||||||
|
entity.setAlias(model.getAlias());
|
||||||
|
entity.setConfig(model.getConfig());
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AuthenticatorConfigModel toModel(MapAuthenticatorConfigEntity entity) {
|
||||||
|
if (entity == null) return null;
|
||||||
|
AuthenticatorConfigModel model = new AuthenticatorConfigModel();
|
||||||
|
model.setId(entity.getId());
|
||||||
|
model.setAlias(entity.getAlias());
|
||||||
|
model.setConfig(entity.getConfig());
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUpdated() {
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.updated = !Objects.equals(this.id, id);
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlias() {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlias(String alias) {
|
||||||
|
this.updated = !Objects.equals(this.alias, alias);
|
||||||
|
this.alias = alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfig(Map<String, String> config) {
|
||||||
|
this.updated = !Objects.equals(this.config, config);
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getId().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (!(obj instanceof MapAuthenticatorConfigEntity)) return false;
|
||||||
|
final MapAuthenticatorConfigEntity other = (MapAuthenticatorConfigEntity) obj;
|
||||||
|
return Objects.equals(other.getId(), getId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.realm.entity;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.keycloak.common.util.Time;
|
||||||
|
import org.keycloak.models.ClientInitialAccessModel;
|
||||||
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
|
public class MapClientInitialAccessEntity implements UpdatableEntity {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private Integer timestamp = 0;
|
||||||
|
private Integer expiration = 0;
|
||||||
|
private Integer count = 0;
|
||||||
|
private Integer remainingCount = 0;
|
||||||
|
|
||||||
|
private boolean updated;
|
||||||
|
|
||||||
|
private MapClientInitialAccessEntity() {}
|
||||||
|
|
||||||
|
public static MapClientInitialAccessEntity createEntity(int expiration, int count) {
|
||||||
|
int currentTime = Time.currentTime();
|
||||||
|
|
||||||
|
MapClientInitialAccessEntity entity = new MapClientInitialAccessEntity();
|
||||||
|
entity.setId(KeycloakModelUtils.generateId());
|
||||||
|
entity.setTimestamp(currentTime);
|
||||||
|
entity.setExpiration(expiration);
|
||||||
|
entity.setCount(count);
|
||||||
|
entity.setRemainingCount(count);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClientInitialAccessModel toModel(MapClientInitialAccessEntity entity) {
|
||||||
|
if (entity == null) return null;
|
||||||
|
ClientInitialAccessModel model = new ClientInitialAccessModel();
|
||||||
|
model.setId(entity.getId());
|
||||||
|
model.setTimestamp(entity.getTimestamp());
|
||||||
|
model.setExpiration(entity.getExpiration());
|
||||||
|
model.setCount(entity.getCount());
|
||||||
|
model.setRemainingCount(entity.getRemainingCount());
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUpdated() {
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.updated = !Objects.equals(this.id, id);
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimestamp(int timestamp) {
|
||||||
|
this.updated = !Objects.equals(this.timestamp, timestamp);
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getExpiration() {
|
||||||
|
return expiration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpiration(int expiration) {
|
||||||
|
this.updated = !Objects.equals(this.expiration, expiration);
|
||||||
|
this.expiration = expiration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCount(int count) {
|
||||||
|
this.updated = !Objects.equals(this.count, count);
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getRemainingCount() {
|
||||||
|
return remainingCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemainingCount(int remainingCount) {
|
||||||
|
this.updated = !Objects.equals(this.remainingCount, remainingCount);
|
||||||
|
this.remainingCount = remainingCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getId().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (!(obj instanceof MapClientInitialAccessEntity)) return false;
|
||||||
|
final MapClientInitialAccessEntity other = (MapClientInitialAccessEntity) obj;
|
||||||
|
return Objects.equals(other.getId(), getId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.realm.entity;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.keycloak.common.util.MultivaluedHashMap;
|
||||||
|
import org.keycloak.component.ComponentModel;
|
||||||
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
|
public class MapComponentEntity implements UpdatableEntity {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private String providerId;
|
||||||
|
private String providerType;
|
||||||
|
private String subType;
|
||||||
|
private String parentId;
|
||||||
|
private MultivaluedHashMap<String, String> config = new MultivaluedHashMap<>();
|
||||||
|
|
||||||
|
private boolean updated;
|
||||||
|
|
||||||
|
private MapComponentEntity() {}
|
||||||
|
|
||||||
|
public static MapComponentEntity fromModel(ComponentModel model) {
|
||||||
|
if (model == null) return null;
|
||||||
|
MapComponentEntity entity = new MapComponentEntity();
|
||||||
|
String id = model.getId() == null ? KeycloakModelUtils.generateId() : model.getId();
|
||||||
|
entity.setId(id);
|
||||||
|
entity.setName(model.getName());
|
||||||
|
entity.setProviderId(model.getProviderId());
|
||||||
|
entity.setProviderType(model.getProviderType());
|
||||||
|
entity.setSubType(model.getSubType());
|
||||||
|
entity.setParentId(model.getParentId());
|
||||||
|
entity.setConfig(model.getConfig());
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ComponentModel toModel(MapComponentEntity entity) {
|
||||||
|
if (entity == null) return null;
|
||||||
|
ComponentModel model = new ComponentModel();
|
||||||
|
model.setId(entity.getId());
|
||||||
|
model.setName(entity.getName());
|
||||||
|
model.setProviderId(entity.getProviderId());
|
||||||
|
model.setProviderType(entity.getProviderType());
|
||||||
|
model.setSubType(entity.getSubType());
|
||||||
|
model.setParentId(entity.getParentId());
|
||||||
|
model.setConfig(entity.getConfig());
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUpdated() {
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.updated = !Objects.equals(this.id, id);
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.updated = !Objects.equals(this.name, name);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProviderId() {
|
||||||
|
return providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProviderId(String providerId) {
|
||||||
|
this.updated = !Objects.equals(this.providerId, providerId);
|
||||||
|
this.providerId = providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProviderType() {
|
||||||
|
return providerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProviderType(String providerType) {
|
||||||
|
this.updated = !Objects.equals(this.providerType, providerType);
|
||||||
|
this.providerType = providerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubType() {
|
||||||
|
return subType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubType(String subType) {
|
||||||
|
this.updated = !Objects.equals(this.subType, subType);
|
||||||
|
this.subType = subType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getParentId() {
|
||||||
|
return parentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParentId(String parentId) {
|
||||||
|
this.updated = !Objects.equals(this.parentId, parentId);
|
||||||
|
this.parentId = parentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultivaluedHashMap<String, String> getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfig(MultivaluedHashMap<String, String> config) {
|
||||||
|
this.updated = !Objects.equals(this.config, config);
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getId().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (!(obj instanceof MapComponentEntity)) return false;
|
||||||
|
final MapComponentEntity other = (MapComponentEntity) obj;
|
||||||
|
return Objects.equals(other.getId(), getId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,220 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.realm.entity;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.keycloak.models.IdentityProviderModel;
|
||||||
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
|
public class MapIdentityProviderEntity implements UpdatableEntity {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String alias;
|
||||||
|
private String displayName;
|
||||||
|
private String providerId;
|
||||||
|
private String firstBrokerLoginFlowId;
|
||||||
|
private String postBrokerLoginFlowId;
|
||||||
|
private Boolean enabled = false;
|
||||||
|
private Boolean trustEmail = false;
|
||||||
|
private Boolean storeToken = false;
|
||||||
|
private Boolean linkOnly = false;
|
||||||
|
private Boolean addReadTokenRoleOnCreate = false;
|
||||||
|
private Boolean authenticateByDefault = false;
|
||||||
|
private Map<String, String> config = new HashMap<>();
|
||||||
|
|
||||||
|
private boolean updated;
|
||||||
|
|
||||||
|
private MapIdentityProviderEntity() {}
|
||||||
|
|
||||||
|
public static MapIdentityProviderEntity fromModel(IdentityProviderModel model) {
|
||||||
|
if (model == null) return null;
|
||||||
|
MapIdentityProviderEntity entity = new MapIdentityProviderEntity();
|
||||||
|
String id = model.getInternalId() == null ? KeycloakModelUtils.generateId() : model.getInternalId();
|
||||||
|
entity.setId(id);
|
||||||
|
entity.setAlias(model.getAlias());
|
||||||
|
entity.setDisplayName(model.getDisplayName());
|
||||||
|
entity.setProviderId(model.getProviderId());
|
||||||
|
entity.setFirstBrokerLoginFlowId(model.getFirstBrokerLoginFlowId());
|
||||||
|
entity.setPostBrokerLoginFlowId(model.getPostBrokerLoginFlowId());
|
||||||
|
entity.setEnabled(model.isEnabled());
|
||||||
|
entity.setTrustEmail(model.isTrustEmail());
|
||||||
|
entity.setStoreToken(model.isStoreToken());
|
||||||
|
entity.setLinkOnly(model.isLinkOnly());
|
||||||
|
entity.setAddReadTokenRoleOnCreate(model.isAddReadTokenRoleOnCreate());
|
||||||
|
entity.setAuthenticateByDefault(model.isAuthenticateByDefault());
|
||||||
|
entity.setConfig(model.getConfig());
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IdentityProviderModel toModel(MapIdentityProviderEntity entity) {
|
||||||
|
if (entity == null) return null;
|
||||||
|
IdentityProviderModel model = new IdentityProviderModel();
|
||||||
|
model.setInternalId(entity.getId());
|
||||||
|
model.setAlias(entity.getAlias());
|
||||||
|
model.setDisplayName(entity.getDisplayName());
|
||||||
|
model.setProviderId(entity.getProviderId());
|
||||||
|
model.setFirstBrokerLoginFlowId(entity.getFirstBrokerLoginFlowId());
|
||||||
|
model.setPostBrokerLoginFlowId(entity.getPostBrokerLoginFlowId());
|
||||||
|
model.setEnabled(entity.isEnabled());
|
||||||
|
model.setTrustEmail(entity.isTrustEmail());
|
||||||
|
model.setStoreToken(entity.isStoreToken());
|
||||||
|
model.setLinkOnly(entity.isLinkOnly());
|
||||||
|
model.setAddReadTokenRoleOnCreate(entity.isAddReadTokenRoleOnCreate());
|
||||||
|
model.setAuthenticateByDefault(entity.isAuthenticateByDefault());
|
||||||
|
model.setConfig(entity.getConfig());
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUpdated() {
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.updated = !Objects.equals(this.id, id);
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlias() {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlias(String alias) {
|
||||||
|
this.updated = !Objects.equals(this.alias, alias);
|
||||||
|
this.alias = alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplayName(String displayName) {
|
||||||
|
this.updated = !Objects.equals(this.displayName, displayName);
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProviderId() {
|
||||||
|
return providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProviderId(String providerId) {
|
||||||
|
this.updated = !Objects.equals(this.providerId, providerId);
|
||||||
|
this.providerId = providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstBrokerLoginFlowId() {
|
||||||
|
return firstBrokerLoginFlowId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstBrokerLoginFlowId(String firstBrokerLoginFlowId) {
|
||||||
|
this.updated = !Objects.equals(this.firstBrokerLoginFlowId, firstBrokerLoginFlowId);
|
||||||
|
this.firstBrokerLoginFlowId = firstBrokerLoginFlowId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPostBrokerLoginFlowId() {
|
||||||
|
return postBrokerLoginFlowId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPostBrokerLoginFlowId(String postBrokerLoginFlowId) {
|
||||||
|
this.updated = !Objects.equals(this.postBrokerLoginFlowId, postBrokerLoginFlowId);
|
||||||
|
this.postBrokerLoginFlowId = postBrokerLoginFlowId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.updated = !Objects.equals(this.enabled, enabled);
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isTrustEmail() {
|
||||||
|
return trustEmail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTrustEmail(boolean trustEmail) {
|
||||||
|
this.updated = !Objects.equals(this.trustEmail, trustEmail);
|
||||||
|
this.trustEmail = trustEmail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isStoreToken() {
|
||||||
|
return storeToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStoreToken(boolean storeToken) {
|
||||||
|
this.updated = !Objects.equals(this.storeToken, storeToken);
|
||||||
|
this.storeToken = storeToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isLinkOnly() {
|
||||||
|
return linkOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLinkOnly(boolean linkOnly) {
|
||||||
|
this.updated = !Objects.equals(this.linkOnly, linkOnly);
|
||||||
|
this.linkOnly = linkOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isAddReadTokenRoleOnCreate() {
|
||||||
|
return addReadTokenRoleOnCreate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddReadTokenRoleOnCreate(boolean addReadTokenRoleOnCreate) {
|
||||||
|
this.updated = !Objects.equals(this.addReadTokenRoleOnCreate, addReadTokenRoleOnCreate);
|
||||||
|
this.addReadTokenRoleOnCreate = addReadTokenRoleOnCreate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isAuthenticateByDefault() {
|
||||||
|
return authenticateByDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthenticateByDefault(boolean authenticateByDefault) {
|
||||||
|
this.updated = !Objects.equals(this.authenticateByDefault, authenticateByDefault);
|
||||||
|
this.authenticateByDefault = authenticateByDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfig(Map<String, String> config) {
|
||||||
|
this.updated = !Objects.equals(this.config, config);
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getId().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (!(obj instanceof MapIdentityProviderEntity)) return false;
|
||||||
|
final MapIdentityProviderEntity other = (MapIdentityProviderEntity) obj;
|
||||||
|
return Objects.equals(other.getId(), getId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.realm.entity;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.keycloak.models.IdentityProviderMapperModel;
|
||||||
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
|
public class MapIdentityProviderMapperEntity implements UpdatableEntity {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private String identityProviderAlias;
|
||||||
|
private String identityProviderMapper;
|
||||||
|
private Map<String, String> config = new HashMap<>();
|
||||||
|
|
||||||
|
private boolean updated;
|
||||||
|
|
||||||
|
private MapIdentityProviderMapperEntity() {}
|
||||||
|
|
||||||
|
public static MapIdentityProviderMapperEntity fromModel(IdentityProviderMapperModel model) {
|
||||||
|
if (model == null) return null;
|
||||||
|
MapIdentityProviderMapperEntity entity = new MapIdentityProviderMapperEntity();
|
||||||
|
String id = model.getId() == null ? KeycloakModelUtils.generateId() : model.getId();
|
||||||
|
entity.setId(id);
|
||||||
|
entity.setName(model.getName());
|
||||||
|
entity.setIdentityProviderAlias(model.getIdentityProviderAlias());
|
||||||
|
entity.setIdentityProviderMapper(model.getIdentityProviderMapper());
|
||||||
|
entity.setConfig(model.getConfig());
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IdentityProviderMapperModel toModel(MapIdentityProviderMapperEntity entity) {
|
||||||
|
if (entity == null) return null;
|
||||||
|
IdentityProviderMapperModel model = new IdentityProviderMapperModel();
|
||||||
|
model.setId(entity.getId());
|
||||||
|
model.setName(entity.getName());
|
||||||
|
model.setIdentityProviderAlias(entity.getIdentityProviderAlias());
|
||||||
|
model.setIdentityProviderMapper(entity.getIdentityProviderMapper());
|
||||||
|
model.setConfig(entity.getConfig());
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUpdated() {
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.updated = !Objects.equals(this.id, id);
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.updated = !Objects.equals(this.name, name);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIdentityProviderAlias() {
|
||||||
|
return identityProviderAlias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdentityProviderAlias(String identityProviderAlias) {
|
||||||
|
this.updated = !Objects.equals(this.identityProviderAlias, identityProviderAlias);
|
||||||
|
this.identityProviderAlias = identityProviderAlias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIdentityProviderMapper() {
|
||||||
|
return identityProviderMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdentityProviderMapper(String identityProviderMapper) {
|
||||||
|
this.updated = !Objects.equals(this.identityProviderMapper, identityProviderMapper);
|
||||||
|
this.identityProviderMapper = identityProviderMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfig(Map<String, String> config) {
|
||||||
|
this.updated = !Objects.equals(this.config, config);
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getId().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (!(obj instanceof MapIdentityProviderMapperEntity)) return false;
|
||||||
|
final MapIdentityProviderMapperEntity other = (MapIdentityProviderMapperEntity) obj;
|
||||||
|
return Objects.equals(other.getId(), getId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,145 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.realm.entity;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.keycloak.models.OTPPolicy;
|
||||||
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
|
|
||||||
|
public class MapOTPPolicyEntity implements UpdatableEntity {
|
||||||
|
|
||||||
|
private Integer otpPolicyInitialCounter = 0;
|
||||||
|
private Integer otpPolicyDigits = 0;
|
||||||
|
private Integer otpPolicyLookAheadWindow = 0;
|
||||||
|
private Integer otpPolicyPeriod = 0;
|
||||||
|
private String otpPolicyType;
|
||||||
|
private String otpPolicyAlgorithm;
|
||||||
|
|
||||||
|
private boolean updated;
|
||||||
|
|
||||||
|
private MapOTPPolicyEntity() {}
|
||||||
|
|
||||||
|
public static MapOTPPolicyEntity fromModel(OTPPolicy model) {
|
||||||
|
if (model == null) return null;
|
||||||
|
MapOTPPolicyEntity entity = new MapOTPPolicyEntity();
|
||||||
|
entity.setOtpPolicyAlgorithm(model.getAlgorithm());
|
||||||
|
entity.setOtpPolicyDigits(model.getDigits());
|
||||||
|
entity.setOtpPolicyInitialCounter(model.getInitialCounter());
|
||||||
|
entity.setOtpPolicyLookAheadWindow(model.getLookAheadWindow());
|
||||||
|
entity.setOtpPolicyType(model.getType());
|
||||||
|
entity.setOtpPolicyPeriod(model.getPeriod());
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OTPPolicy toModel(MapOTPPolicyEntity entity) {
|
||||||
|
if (entity == null) return null;
|
||||||
|
OTPPolicy model = new OTPPolicy();
|
||||||
|
model.setDigits(entity.getOtpPolicyDigits());
|
||||||
|
model.setAlgorithm(entity.getOtpPolicyAlgorithm());
|
||||||
|
model.setInitialCounter(entity.getOtpPolicyInitialCounter());
|
||||||
|
model.setLookAheadWindow(entity.getOtpPolicyLookAheadWindow());
|
||||||
|
model.setType(entity.getOtpPolicyType());
|
||||||
|
model.setPeriod(entity.getOtpPolicyPeriod());
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUpdated() {
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getOtpPolicyInitialCounter() {
|
||||||
|
return otpPolicyInitialCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOtpPolicyInitialCounter(int otpPolicyInitialCounter) {
|
||||||
|
this.updated = !Objects.equals(this.otpPolicyInitialCounter, otpPolicyInitialCounter);
|
||||||
|
this.otpPolicyInitialCounter = otpPolicyInitialCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getOtpPolicyDigits() {
|
||||||
|
return otpPolicyDigits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOtpPolicyDigits(int otpPolicyDigits) {
|
||||||
|
this.updated = !Objects.equals(this.otpPolicyDigits, otpPolicyDigits);
|
||||||
|
this.otpPolicyDigits = otpPolicyDigits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getOtpPolicyLookAheadWindow() {
|
||||||
|
return otpPolicyLookAheadWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOtpPolicyLookAheadWindow(int otpPolicyLookAheadWindow) {
|
||||||
|
this.updated = !Objects.equals(this.otpPolicyLookAheadWindow, otpPolicyLookAheadWindow);
|
||||||
|
this.otpPolicyLookAheadWindow = otpPolicyLookAheadWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getOtpPolicyPeriod() {
|
||||||
|
return otpPolicyPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOtpPolicyPeriod(int otpPolicyPeriod) {
|
||||||
|
this.updated = !Objects.equals(this.otpPolicyPeriod, otpPolicyPeriod);
|
||||||
|
this.otpPolicyPeriod = otpPolicyPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOtpPolicyType() {
|
||||||
|
return otpPolicyType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOtpPolicyType(String otpPolicyType) {
|
||||||
|
this.updated = !Objects.equals(this.otpPolicyType, otpPolicyType);
|
||||||
|
this.otpPolicyType = otpPolicyType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOtpPolicyAlgorithm() {
|
||||||
|
return otpPolicyAlgorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOtpPolicyAlgorithm(String otpPolicyAlgorithm) {
|
||||||
|
this.updated = !Objects.equals(this.otpPolicyAlgorithm, otpPolicyAlgorithm);
|
||||||
|
this.otpPolicyAlgorithm = otpPolicyAlgorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 5;
|
||||||
|
hash = 59 * hash + this.otpPolicyInitialCounter;
|
||||||
|
hash = 59 * hash + this.otpPolicyDigits;
|
||||||
|
hash = 59 * hash + this.otpPolicyLookAheadWindow;
|
||||||
|
hash = 59 * hash + this.otpPolicyPeriod;
|
||||||
|
hash = 59 * hash + Objects.hashCode(this.otpPolicyType);
|
||||||
|
hash = 59 * hash + Objects.hashCode(this.otpPolicyAlgorithm);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (!(obj instanceof MapOTPPolicyEntity)) return false;
|
||||||
|
final MapOTPPolicyEntity other = (MapOTPPolicyEntity) obj;
|
||||||
|
return Objects.equals(other.getOtpPolicyAlgorithm(), getOtpPolicyAlgorithm()) &&
|
||||||
|
Objects.equals(other.getOtpPolicyDigits(), getOtpPolicyDigits()) &&
|
||||||
|
Objects.equals(other.getOtpPolicyInitialCounter(), getOtpPolicyInitialCounter()) &&
|
||||||
|
Objects.equals(other.getOtpPolicyLookAheadWindow(), getOtpPolicyLookAheadWindow()) &&
|
||||||
|
Objects.equals(other.getOtpPolicyPeriod(), getOtpPolicyPeriod()) &&
|
||||||
|
Objects.equals(other.getOtpPolicyType(), getOtpPolicyType());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.realm.entity;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.keycloak.models.RequiredActionProviderModel;
|
||||||
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
|
public class MapRequiredActionProviderEntity implements UpdatableEntity {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String alias;
|
||||||
|
private String name;
|
||||||
|
private String providerId;
|
||||||
|
private Integer priority = 0;
|
||||||
|
private Boolean enabled = false;
|
||||||
|
private Boolean defaultAction = false;
|
||||||
|
private Map<String, String> config = new HashMap<>();
|
||||||
|
|
||||||
|
private boolean updated;
|
||||||
|
|
||||||
|
private MapRequiredActionProviderEntity() {}
|
||||||
|
|
||||||
|
public static MapRequiredActionProviderEntity fromModel(RequiredActionProviderModel model) {
|
||||||
|
if (model == null) return null;
|
||||||
|
MapRequiredActionProviderEntity entity = new MapRequiredActionProviderEntity();
|
||||||
|
String id = model.getId() == null ? KeycloakModelUtils.generateId() : model.getId();
|
||||||
|
entity.setId(id);
|
||||||
|
entity.setAlias(model.getAlias());
|
||||||
|
entity.setName(model.getName());
|
||||||
|
entity.setProviderId(model.getProviderId());
|
||||||
|
entity.setPriority(model.getPriority());
|
||||||
|
entity.setEnabled(model.isEnabled());
|
||||||
|
entity.setDefaultAction(model.isDefaultAction());
|
||||||
|
entity.setConfig(model.getConfig());
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RequiredActionProviderModel toModel(MapRequiredActionProviderEntity entity) {
|
||||||
|
if (entity == null) return null;
|
||||||
|
RequiredActionProviderModel model = new RequiredActionProviderModel();
|
||||||
|
model.setId(entity.getId());
|
||||||
|
model.setAlias(entity.getAlias());
|
||||||
|
model.setName(entity.getName());
|
||||||
|
model.setProviderId(entity.getProviderId());
|
||||||
|
model.setPriority(entity.getPriority());
|
||||||
|
model.setEnabled(entity.isEnabled());
|
||||||
|
model.setDefaultAction(entity.isDefaultAction());
|
||||||
|
model.setConfig(entity.getConfig());
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUpdated() {
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.updated = !Objects.equals(this.id, id);
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlias() {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlias(String alias) {
|
||||||
|
this.updated = !Objects.equals(this.alias, alias);
|
||||||
|
this.alias = alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.updated = !Objects.equals(this.name, name);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProviderId() {
|
||||||
|
return providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProviderId(String providerId) {
|
||||||
|
this.updated = !Objects.equals(this.providerId, providerId);
|
||||||
|
this.providerId = providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPriority(int priority) {
|
||||||
|
this.updated = !Objects.equals(this.priority, priority);
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.updated = !Objects.equals(this.enabled, enabled);
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isDefaultAction() {
|
||||||
|
return defaultAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultAction(boolean defaultAction) {
|
||||||
|
this.updated = !Objects.equals(this.defaultAction, defaultAction);
|
||||||
|
this.defaultAction = defaultAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfig(Map<String, String> config) {
|
||||||
|
this.updated = !Objects.equals(this.config, config);
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getId().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (!(obj instanceof MapRequiredActionProviderEntity)) return false;
|
||||||
|
final MapRequiredActionProviderEntity other = (MapRequiredActionProviderEntity) obj;
|
||||||
|
return Objects.equals(other.getId(), getId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.realm.entity;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.keycloak.models.RequiredCredentialModel;
|
||||||
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
|
|
||||||
|
public class MapRequiredCredentialEntity implements UpdatableEntity {
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
private String formLabel;
|
||||||
|
private Boolean input = false;
|
||||||
|
private Boolean secret = false;
|
||||||
|
|
||||||
|
private boolean updated;
|
||||||
|
|
||||||
|
private MapRequiredCredentialEntity() {}
|
||||||
|
|
||||||
|
public static MapRequiredCredentialEntity fromModel(RequiredCredentialModel model) {
|
||||||
|
if (model == null) return null;
|
||||||
|
MapRequiredCredentialEntity entity = new MapRequiredCredentialEntity();
|
||||||
|
entity.setFormLabel(model.getFormLabel());
|
||||||
|
entity.setType(model.getType());
|
||||||
|
entity.setInput(model.isInput());
|
||||||
|
entity.setSecret(model.isSecret());
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RequiredCredentialModel toModel(MapRequiredCredentialEntity entity) {
|
||||||
|
if (entity == null) return null;
|
||||||
|
RequiredCredentialModel model = new RequiredCredentialModel();
|
||||||
|
model.setFormLabel(entity.getFormLabel());
|
||||||
|
model.setType(entity.getType());
|
||||||
|
model.setSecret(entity.isSecret());
|
||||||
|
model.setInput(entity.isInput());
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUpdated() {
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.updated = !Objects.equals(this.type, type);
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormLabel() {
|
||||||
|
return formLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFormLabel(String formLabel) {
|
||||||
|
this.updated = !Objects.equals(this.formLabel, formLabel);
|
||||||
|
this.formLabel = formLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isSecret() {
|
||||||
|
return secret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecret(boolean secret) {
|
||||||
|
this.updated = !Objects.equals(this.formLabel, formLabel);
|
||||||
|
this.secret = secret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isInput() {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInput(boolean input) {
|
||||||
|
this.updated = !Objects.equals(this.input, input);
|
||||||
|
this.input = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getType().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (!(obj instanceof MapRequiredCredentialEntity)) return false;
|
||||||
|
final MapRequiredCredentialEntity other = (MapRequiredCredentialEntity) obj;
|
||||||
|
return Objects.equals(other.getType(), getType());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,202 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models.map.realm.entity;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
|
import org.keycloak.models.WebAuthnPolicy;
|
||||||
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
|
|
||||||
|
public class MapWebAuthnPolicyEntity implements UpdatableEntity {
|
||||||
|
|
||||||
|
// mandatory
|
||||||
|
private String rpEntityName;
|
||||||
|
private List<String> signatureAlgorithms = new LinkedList<>();
|
||||||
|
|
||||||
|
// optional
|
||||||
|
private String rpId;
|
||||||
|
private String attestationConveyancePreference;
|
||||||
|
private String authenticatorAttachment;
|
||||||
|
private String requireResidentKey;
|
||||||
|
private String userVerificationRequirement;
|
||||||
|
private Integer createTimeout = 0;
|
||||||
|
private Boolean avoidSameAuthenticatorRegister = false;
|
||||||
|
private List<String> acceptableAaguids = new LinkedList<>();
|
||||||
|
|
||||||
|
private boolean updated;
|
||||||
|
|
||||||
|
private MapWebAuthnPolicyEntity() {}
|
||||||
|
|
||||||
|
public static MapWebAuthnPolicyEntity fromModel(WebAuthnPolicy model) {
|
||||||
|
if (model == null) return null;
|
||||||
|
MapWebAuthnPolicyEntity entity = new MapWebAuthnPolicyEntity();
|
||||||
|
entity.setRpEntityName(model.getRpEntityName());
|
||||||
|
entity.setSignatureAlgorithms(model.getSignatureAlgorithm());
|
||||||
|
entity.setRpId(model.getRpId());
|
||||||
|
entity.setAttestationConveyancePreference(model.getAttestationConveyancePreference());
|
||||||
|
entity.setAuthenticatorAttachment(model.getAuthenticatorAttachment());
|
||||||
|
entity.setRequireResidentKey(model.getRequireResidentKey());
|
||||||
|
entity.setUserVerificationRequirement(model.getUserVerificationRequirement());
|
||||||
|
entity.setCreateTimeout(model.getCreateTimeout());
|
||||||
|
entity.setAvoidSameAuthenticatorRegister(model.isAvoidSameAuthenticatorRegister());
|
||||||
|
entity.setAcceptableAaguids(model.getAcceptableAaguids());
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WebAuthnPolicy toModel(MapWebAuthnPolicyEntity entity) {
|
||||||
|
if (entity == null) return null;
|
||||||
|
WebAuthnPolicy model = new WebAuthnPolicy();
|
||||||
|
model.setRpEntityName(entity.getRpEntityName());
|
||||||
|
model.setSignatureAlgorithm(entity.getSignatureAlgorithms());
|
||||||
|
model.setRpId(entity.getRpId());
|
||||||
|
model.setAttestationConveyancePreference(entity.getAttestationConveyancePreference());
|
||||||
|
model.setAuthenticatorAttachment(entity.getAuthenticatorAttachment());
|
||||||
|
model.setRequireResidentKey(entity.getRequireResidentKey());
|
||||||
|
model.setUserVerificationRequirement(entity.getUserVerificationRequirement());
|
||||||
|
model.setCreateTimeout(entity.getCreateTimeout());
|
||||||
|
model.setAvoidSameAuthenticatorRegister(entity.isAvoidSameAuthenticatorRegister());
|
||||||
|
model.setAcceptableAaguids(entity.getAcceptableAaguids());
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MapWebAuthnPolicyEntity defaultWebAuthnPolicy() {
|
||||||
|
MapWebAuthnPolicyEntity entity = new MapWebAuthnPolicyEntity();
|
||||||
|
entity.setRpEntityName(Constants.DEFAULT_WEBAUTHN_POLICY_RP_ENTITY_NAME);
|
||||||
|
entity.setSignatureAlgorithms(Arrays.asList(Constants.DEFAULT_WEBAUTHN_POLICY_SIGNATURE_ALGORITHMS.split(",")));
|
||||||
|
entity.setRpId("");
|
||||||
|
entity.setAttestationConveyancePreference(Constants.DEFAULT_WEBAUTHN_POLICY_NOT_SPECIFIED);
|
||||||
|
entity.setAuthenticatorAttachment(Constants.DEFAULT_WEBAUTHN_POLICY_NOT_SPECIFIED);
|
||||||
|
entity.setRequireResidentKey(Constants.DEFAULT_WEBAUTHN_POLICY_NOT_SPECIFIED);
|
||||||
|
entity.setUserVerificationRequirement(Constants.DEFAULT_WEBAUTHN_POLICY_NOT_SPECIFIED);
|
||||||
|
entity.setCreateTimeout(0);
|
||||||
|
entity.setAvoidSameAuthenticatorRegister(false);
|
||||||
|
entity.setAcceptableAaguids(new LinkedList<>());
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUpdated() {
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRpEntityName() {
|
||||||
|
return rpEntityName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRpEntityName(String rpEntityName) {
|
||||||
|
this.updated = !Objects.equals(this.rpEntityName, rpEntityName);
|
||||||
|
this.rpEntityName = rpEntityName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getSignatureAlgorithms() {
|
||||||
|
return signatureAlgorithms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSignatureAlgorithms(List<String> signatureAlgorithms) {
|
||||||
|
this.updated = !Objects.equals(this.signatureAlgorithms, signatureAlgorithms);
|
||||||
|
this.signatureAlgorithms = signatureAlgorithms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRpId() {
|
||||||
|
return rpId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRpId(String rpId) {
|
||||||
|
this.updated = !Objects.equals(this.rpId, rpId);
|
||||||
|
this.rpId = rpId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAttestationConveyancePreference() {
|
||||||
|
return attestationConveyancePreference;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttestationConveyancePreference(String attestationConveyancePreference) {
|
||||||
|
this.updated = !Objects.equals(this.attestationConveyancePreference, attestationConveyancePreference);
|
||||||
|
this.attestationConveyancePreference = attestationConveyancePreference;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthenticatorAttachment() {
|
||||||
|
return authenticatorAttachment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthenticatorAttachment(String authenticatorAttachment) {
|
||||||
|
this.updated = !Objects.equals(this.authenticatorAttachment, authenticatorAttachment);
|
||||||
|
this.authenticatorAttachment = authenticatorAttachment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRequireResidentKey() {
|
||||||
|
return requireResidentKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequireResidentKey(String requireResidentKey) {
|
||||||
|
this.updated = !Objects.equals(this.requireResidentKey, requireResidentKey);
|
||||||
|
this.requireResidentKey = requireResidentKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserVerificationRequirement() {
|
||||||
|
return userVerificationRequirement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserVerificationRequirement(String userVerificationRequirement) {
|
||||||
|
this.updated = !Objects.equals(this.userVerificationRequirement, userVerificationRequirement);
|
||||||
|
this.userVerificationRequirement = userVerificationRequirement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCreateTimeout() {
|
||||||
|
return createTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTimeout(int createTimeout) {
|
||||||
|
this.updated = !Objects.equals(this.createTimeout, createTimeout);
|
||||||
|
this.createTimeout = createTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isAvoidSameAuthenticatorRegister() {
|
||||||
|
return avoidSameAuthenticatorRegister;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvoidSameAuthenticatorRegister(boolean avoidSameAuthenticatorRegister) {
|
||||||
|
this.updated = !Objects.equals(this.avoidSameAuthenticatorRegister, avoidSameAuthenticatorRegister);
|
||||||
|
this.avoidSameAuthenticatorRegister = avoidSameAuthenticatorRegister;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getAcceptableAaguids() {
|
||||||
|
return acceptableAaguids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAcceptableAaguids(List<String> acceptableAaguids) {
|
||||||
|
this.updated = !Objects.equals(this.acceptableAaguids, acceptableAaguids);
|
||||||
|
this.acceptableAaguids = acceptableAaguids;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getRpEntityName().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (!(obj instanceof MapWebAuthnPolicyEntity)) return false;
|
||||||
|
final MapWebAuthnPolicyEntity other = (MapWebAuthnPolicyEntity) obj;
|
||||||
|
return Objects.equals(other.getRpEntityName(), getRpEntityName());
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ package org.keycloak.models.map.storage;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.ClientScopeModel;
|
import org.keycloak.models.ClientScopeModel;
|
||||||
import org.keycloak.models.GroupModel;
|
import org.keycloak.models.GroupModel;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.map.authSession.AbstractRootAuthenticationSessionEntity;
|
import org.keycloak.models.map.authSession.AbstractRootAuthenticationSessionEntity;
|
||||||
|
@ -26,6 +27,7 @@ import org.keycloak.models.map.client.AbstractClientEntity;
|
||||||
import org.keycloak.models.map.clientscope.AbstractClientScopeEntity;
|
import org.keycloak.models.map.clientscope.AbstractClientScopeEntity;
|
||||||
import org.keycloak.models.map.common.AbstractEntity;
|
import org.keycloak.models.map.common.AbstractEntity;
|
||||||
import org.keycloak.models.map.group.AbstractGroupEntity;
|
import org.keycloak.models.map.group.AbstractGroupEntity;
|
||||||
|
import org.keycloak.models.map.realm.AbstractRealmEntity;
|
||||||
import org.keycloak.models.map.role.AbstractRoleEntity;
|
import org.keycloak.models.map.role.AbstractRoleEntity;
|
||||||
import org.keycloak.storage.SearchableModelField;
|
import org.keycloak.storage.SearchableModelField;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -49,6 +51,7 @@ import java.util.function.Predicate;
|
||||||
*/
|
*/
|
||||||
public class MapFieldPredicates {
|
public class MapFieldPredicates {
|
||||||
|
|
||||||
|
public static final Map<SearchableModelField<RealmModel>, UpdatePredicatesFunc<Object, AbstractRealmEntity<Object>, RealmModel>> REALM_PREDICATES = basePredicates(RealmModel.SearchableFields.ID);
|
||||||
public static final Map<SearchableModelField<ClientModel>, UpdatePredicatesFunc<Object, AbstractClientEntity<Object>, ClientModel>> CLIENT_PREDICATES = basePredicates(ClientModel.SearchableFields.ID);
|
public static final Map<SearchableModelField<ClientModel>, UpdatePredicatesFunc<Object, AbstractClientEntity<Object>, ClientModel>> CLIENT_PREDICATES = basePredicates(ClientModel.SearchableFields.ID);
|
||||||
public static final Map<SearchableModelField<ClientScopeModel>, UpdatePredicatesFunc<Object, AbstractClientScopeEntity<Object>, ClientScopeModel>> CLIENT_SCOPE_PREDICATES = basePredicates(ClientScopeModel.SearchableFields.ID);
|
public static final Map<SearchableModelField<ClientScopeModel>, UpdatePredicatesFunc<Object, AbstractClientScopeEntity<Object>, ClientScopeModel>> CLIENT_SCOPE_PREDICATES = basePredicates(ClientScopeModel.SearchableFields.ID);
|
||||||
public static final Map<SearchableModelField<GroupModel>, UpdatePredicatesFunc<Object, AbstractGroupEntity<Object>, GroupModel>> GROUP_PREDICATES = basePredicates(GroupModel.SearchableFields.ID);
|
public static final Map<SearchableModelField<GroupModel>, UpdatePredicatesFunc<Object, AbstractGroupEntity<Object>, GroupModel>> GROUP_PREDICATES = basePredicates(GroupModel.SearchableFields.ID);
|
||||||
|
@ -60,6 +63,10 @@ public class MapFieldPredicates {
|
||||||
private static final Map<Class<?>, Map> PREDICATES = new HashMap<>();
|
private static final Map<Class<?>, Map> PREDICATES = new HashMap<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
put(REALM_PREDICATES, RealmModel.SearchableFields.NAME, AbstractRealmEntity::getName);
|
||||||
|
put(REALM_PREDICATES, RealmModel.SearchableFields.CLIENT_INITIAL_ACCESS, MapFieldPredicates::checkRealmsWithClientInitialAccess);
|
||||||
|
put(REALM_PREDICATES, RealmModel.SearchableFields.COMPONENT_PROVIDER_TYPE, MapFieldPredicates::checkRealmsWithComponentType);
|
||||||
|
|
||||||
put(CLIENT_PREDICATES, ClientModel.SearchableFields.REALM_ID, AbstractClientEntity::getRealmId);
|
put(CLIENT_PREDICATES, ClientModel.SearchableFields.REALM_ID, AbstractClientEntity::getRealmId);
|
||||||
put(CLIENT_PREDICATES, ClientModel.SearchableFields.CLIENT_ID, AbstractClientEntity::getClientId);
|
put(CLIENT_PREDICATES, ClientModel.SearchableFields.CLIENT_ID, AbstractClientEntity::getClientId);
|
||||||
put(CLIENT_PREDICATES, ClientModel.SearchableFields.SCOPE_MAPPING_ROLE, MapFieldPredicates::checkScopeMappingRole);
|
put(CLIENT_PREDICATES, ClientModel.SearchableFields.SCOPE_MAPPING_ROLE, MapFieldPredicates::checkScopeMappingRole);
|
||||||
|
@ -101,6 +108,7 @@ public class MapFieldPredicates {
|
||||||
}
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
PREDICATES.put(RealmModel.class, REALM_PREDICATES);
|
||||||
PREDICATES.put(ClientModel.class, CLIENT_PREDICATES);
|
PREDICATES.put(ClientModel.class, CLIENT_PREDICATES);
|
||||||
PREDICATES.put(ClientScopeModel.class, CLIENT_SCOPE_PREDICATES);
|
PREDICATES.put(ClientScopeModel.class, CLIENT_SCOPE_PREDICATES);
|
||||||
PREDICATES.put(RoleModel.class, ROLE_PREDICATES);
|
PREDICATES.put(RoleModel.class, ROLE_PREDICATES);
|
||||||
|
@ -245,6 +253,21 @@ public class MapFieldPredicates {
|
||||||
return mcb.fieldCompare(Boolean.TRUE::equals, getter);
|
return mcb.fieldCompare(Boolean.TRUE::equals, getter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static MapModelCriteriaBuilder<Object, AbstractRealmEntity<Object>, RealmModel> checkRealmsWithClientInitialAccess(MapModelCriteriaBuilder<Object, AbstractRealmEntity<Object>, RealmModel> mcb, Operator op, Object[] values) {
|
||||||
|
if (op != Operator.EXISTS) {
|
||||||
|
throw new CriterionNotSupportedException(RealmModel.SearchableFields.CLIENT_INITIAL_ACCESS, op);
|
||||||
|
}
|
||||||
|
Function<AbstractRealmEntity<Object>, ?> getter = AbstractRealmEntity::hasClientInitialAccess;
|
||||||
|
return mcb.fieldCompare(Boolean.TRUE::equals, getter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MapModelCriteriaBuilder<Object, AbstractRealmEntity<Object>, RealmModel> checkRealmsWithComponentType(MapModelCriteriaBuilder<Object, AbstractRealmEntity<Object>, RealmModel> mcb, Operator op, Object[] values) {
|
||||||
|
String providerType = ensureEqSingleValue(RealmModel.SearchableFields.COMPONENT_PROVIDER_TYPE, "component_provider_type", op, values);
|
||||||
|
Function<AbstractRealmEntity<Object>, ?> getter = realmEntity -> realmEntity.getComponents().anyMatch(component -> component.getProviderType().equals(providerType));
|
||||||
|
|
||||||
|
return mcb.fieldCompare(Boolean.TRUE::equals, getter);
|
||||||
|
}
|
||||||
|
|
||||||
protected static <K, V extends AbstractEntity<K>, M> Map<SearchableModelField<M>, UpdatePredicatesFunc<K, V, M>> basePredicates(SearchableModelField<M> idField) {
|
protected static <K, V extends AbstractEntity<K>, M> Map<SearchableModelField<M>, UpdatePredicatesFunc<K, V, M>> basePredicates(SearchableModelField<M> idField) {
|
||||||
Map<SearchableModelField<M>, UpdatePredicatesFunc<K, V, M>> fieldPredicates = new HashMap<>();
|
Map<SearchableModelField<M>, UpdatePredicatesFunc<K, V, M>> fieldPredicates = new HashMap<>();
|
||||||
fieldPredicates.put(idField, (o, op, values) -> o.idCompare(op, values));
|
fieldPredicates.put(idField, (o, op, values) -> o.idCompare(op, values));
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.keycloak.models.ClientScopeModel;
|
||||||
import org.keycloak.models.ModelException;
|
import org.keycloak.models.ModelException;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserConsentModel;
|
import org.keycloak.models.UserConsentModel;
|
||||||
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -30,7 +31,7 @@ import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
||||||
public class UserConsentEntity {
|
public class UserConsentEntity implements UpdatableEntity {
|
||||||
|
|
||||||
private String clientId;
|
private String clientId;
|
||||||
private final Set<String> grantedClientScopesIds = new HashSet<>();
|
private final Set<String> grantedClientScopesIds = new HashSet<>();
|
||||||
|
@ -77,6 +78,7 @@ public class UserConsentEntity {
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isUpdated() {
|
public boolean isUpdated() {
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,11 @@ package org.keycloak.models.map.user;
|
||||||
|
|
||||||
import org.keycloak.credential.CredentialModel;
|
import org.keycloak.credential.CredentialModel;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class UserCredentialEntity {
|
public class UserCredentialEntity implements UpdatableEntity {
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
private String type;
|
private String type;
|
||||||
|
@ -112,6 +113,7 @@ public class UserCredentialEntity {
|
||||||
this.credentialData = credentialData;
|
this.credentialData = credentialData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isUpdated() {
|
public boolean isUpdated() {
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,11 @@
|
||||||
package org.keycloak.models.map.user;
|
package org.keycloak.models.map.user;
|
||||||
|
|
||||||
import org.keycloak.models.FederatedIdentityModel;
|
import org.keycloak.models.FederatedIdentityModel;
|
||||||
|
import org.keycloak.models.map.common.UpdatableEntity;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class UserFederatedIdentityEntity {
|
public class UserFederatedIdentityEntity implements UpdatableEntity {
|
||||||
private String token;
|
private String token;
|
||||||
private String userId;
|
private String userId;
|
||||||
private String identityProvider;
|
private String identityProvider;
|
||||||
|
@ -82,6 +83,7 @@ public class UserFederatedIdentityEntity {
|
||||||
this.userName = userName;
|
this.userName = userName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isUpdated() {
|
public boolean isUpdated() {
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
#
|
||||||
|
# Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
# and other contributors as indicated by the @author tags.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
org.keycloak.models.map.realm.MapRealmProviderFactory
|
|
@ -55,6 +55,7 @@ import org.keycloak.migration.migrators.Migration;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.ServerInfoProvider;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,7 +100,7 @@ public class MigrationModelManager {
|
||||||
public static void migrate(KeycloakSession session) {
|
public static void migrate(KeycloakSession session) {
|
||||||
session.setAttribute(Constants.STORAGE_BATCH_ENABLED, Boolean.getBoolean("keycloak.migration.batch-enabled"));
|
session.setAttribute(Constants.STORAGE_BATCH_ENABLED, Boolean.getBoolean("keycloak.migration.batch-enabled"));
|
||||||
session.setAttribute(Constants.STORAGE_BATCH_SIZE, Integer.getInteger("keycloak.migration.batch-size"));
|
session.setAttribute(Constants.STORAGE_BATCH_SIZE, Integer.getInteger("keycloak.migration.batch-size"));
|
||||||
MigrationModel model = session.realms().getMigrationModel();
|
MigrationModel model = session.getProvider(ServerInfoProvider.class).getMigrationModel();
|
||||||
|
|
||||||
ModelVersion currentVersion = new ModelVersion(Version.VERSION_KEYCLOAK);
|
ModelVersion currentVersion = new ModelVersion(Version.VERSION_KEYCLOAK);
|
||||||
ModelVersion latestUpdate = migrations[migrations.length-1].getVersion();
|
ModelVersion latestUpdate = migrations[migrations.length-1].getVersion();
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models;
|
||||||
|
|
||||||
|
import org.keycloak.migration.MigrationModel;
|
||||||
|
import org.keycloak.provider.Provider;
|
||||||
|
|
||||||
|
public interface ServerInfoProvider extends Provider {
|
||||||
|
|
||||||
|
MigrationModel getMigrationModel();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models;
|
||||||
|
|
||||||
|
import org.keycloak.provider.ProviderFactory;
|
||||||
|
|
||||||
|
public interface ServerInfoProviderFactory extends ProviderFactory<ServerInfoProvider> {
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.models;
|
||||||
|
|
||||||
|
import org.keycloak.provider.Provider;
|
||||||
|
import org.keycloak.provider.ProviderFactory;
|
||||||
|
import org.keycloak.provider.Spi;
|
||||||
|
|
||||||
|
public class ServerInfoSpi implements Spi {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInternal() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "serverInfo";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends Provider> getProviderClass() {
|
||||||
|
return ServerInfoProvider.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||||
|
return ServerInfoProviderFactory.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -19,8 +19,6 @@ package org.keycloak.models.dblock;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmProvider;
|
|
||||||
import org.keycloak.models.RealmProviderFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
@ -35,7 +33,6 @@ public class DBLockManager {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void checkForcedUnlock() {
|
public void checkForcedUnlock() {
|
||||||
if (Boolean.getBoolean("keycloak.dblock.forceUnlock")) {
|
if (Boolean.getBoolean("keycloak.dblock.forceUnlock")) {
|
||||||
DBLockProvider lock = getDBLock();
|
DBLockProvider lock = getDBLock();
|
||||||
|
@ -48,21 +45,11 @@ public class DBLockManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Try to detect ID from realmProvider
|
|
||||||
public DBLockProvider getDBLock() {
|
public DBLockProvider getDBLock() {
|
||||||
String realmProviderId = getRealmProviderId();
|
return session.getProvider(DBLockProvider.class);
|
||||||
return session.getProvider(DBLockProvider.class, realmProviderId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DBLockProviderFactory getDBLockFactory() {
|
public DBLockProviderFactory getDBLockFactory() {
|
||||||
String realmProviderId = getRealmProviderId();
|
return (DBLockProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(DBLockProvider.class);
|
||||||
return (DBLockProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(DBLockProvider.class, realmProviderId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getRealmProviderId() {
|
|
||||||
RealmProviderFactory realmProviderFactory = (RealmProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(RealmProvider.class);
|
|
||||||
return realmProviderFactory.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ org.keycloak.models.ClientScopeSpi
|
||||||
org.keycloak.models.GroupSpi
|
org.keycloak.models.GroupSpi
|
||||||
org.keycloak.models.RealmSpi
|
org.keycloak.models.RealmSpi
|
||||||
org.keycloak.models.RoleSpi
|
org.keycloak.models.RoleSpi
|
||||||
|
org.keycloak.models.ServerInfoSpi
|
||||||
org.keycloak.models.ActionTokenStoreSpi
|
org.keycloak.models.ActionTokenStoreSpi
|
||||||
org.keycloak.models.CodeToTokenStoreSpi
|
org.keycloak.models.CodeToTokenStoreSpi
|
||||||
org.keycloak.models.OAuth2DeviceTokenStoreSpi
|
org.keycloak.models.OAuth2DeviceTokenStoreSpi
|
||||||
|
|
|
@ -17,10 +17,12 @@
|
||||||
|
|
||||||
package org.keycloak.models;
|
package org.keycloak.models;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
import org.keycloak.common.enums.SslRequired;
|
import org.keycloak.common.enums.SslRequired;
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.provider.Provider;
|
import org.keycloak.provider.Provider;
|
||||||
import org.keycloak.provider.ProviderEvent;
|
import org.keycloak.provider.ProviderEvent;
|
||||||
|
import org.keycloak.storage.SearchableModelField;
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
import org.keycloak.storage.UserStorageProvider;
|
||||||
import org.keycloak.storage.UserStorageProviderModel;
|
import org.keycloak.storage.UserStorageProviderModel;
|
||||||
import org.keycloak.storage.client.ClientStorageProvider;
|
import org.keycloak.storage.client.ClientStorageProvider;
|
||||||
|
@ -39,6 +41,22 @@ import java.util.stream.Stream;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public interface RealmModel extends RoleContainerModel {
|
public interface RealmModel extends RoleContainerModel {
|
||||||
|
|
||||||
|
Comparator<RealmModel> COMPARE_BY_NAME = Comparator.comparing(RealmModel::getName);
|
||||||
|
|
||||||
|
public static class SearchableFields {
|
||||||
|
public static final SearchableModelField<RealmModel> ID = new SearchableModelField<>("id", String.class);
|
||||||
|
public static final SearchableModelField<RealmModel> NAME = new SearchableModelField<>("name", String.class);
|
||||||
|
/**
|
||||||
|
* Search for realms that have some client initial access set.
|
||||||
|
*/
|
||||||
|
public static final SearchableModelField<RealmModel> CLIENT_INITIAL_ACCESS = new SearchableModelField<>("clientInitialAccess", Boolean.class);
|
||||||
|
/**
|
||||||
|
* Search for realms that have some component with
|
||||||
|
*/
|
||||||
|
public static final SearchableModelField<RealmModel> COMPONENT_PROVIDER_TYPE = new SearchableModelField<>("componentProviderType", String.class);
|
||||||
|
}
|
||||||
|
|
||||||
interface RealmCreationEvent extends ProviderEvent {
|
interface RealmCreationEvent extends ProviderEvent {
|
||||||
RealmModel getCreatedRealm();
|
RealmModel getCreatedRealm();
|
||||||
KeycloakSession getKeycloakSession();
|
KeycloakSession getKeycloakSession();
|
||||||
|
@ -66,6 +84,7 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
KeycloakSession getKeycloakSession();
|
KeycloakSession getKeycloakSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
String getId();
|
String getId();
|
||||||
|
|
||||||
String getName();
|
String getName();
|
||||||
|
@ -109,14 +128,29 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
void setUserManagedAccessAllowed(boolean userManagedAccessAllowed);
|
void setUserManagedAccessAllowed(boolean userManagedAccessAllowed);
|
||||||
|
|
||||||
void setAttribute(String name, String value);
|
void setAttribute(String name, String value);
|
||||||
void setAttribute(String name, Boolean value);
|
default void setAttribute(String name, Boolean value) {
|
||||||
void setAttribute(String name, Integer value);
|
setAttribute(name, value.toString());
|
||||||
void setAttribute(String name, Long value);
|
}
|
||||||
|
default void setAttribute(String name, Integer value) {
|
||||||
|
setAttribute(name, value.toString());
|
||||||
|
}
|
||||||
|
default void setAttribute(String name, Long value) {
|
||||||
|
setAttribute(name, value.toString());
|
||||||
|
}
|
||||||
void removeAttribute(String name);
|
void removeAttribute(String name);
|
||||||
String getAttribute(String name);
|
String getAttribute(String name);
|
||||||
Integer getAttribute(String name, Integer defaultValue);
|
default Integer getAttribute(String name, Integer defaultValue) {
|
||||||
Long getAttribute(String name, Long defaultValue);
|
String v = getAttribute(name);
|
||||||
Boolean getAttribute(String name, Boolean defaultValue);
|
return v != null ? Integer.parseInt(v) : defaultValue;
|
||||||
|
}
|
||||||
|
default Long getAttribute(String name, Long defaultValue) {
|
||||||
|
String v = getAttribute(name);
|
||||||
|
return v != null ? Long.parseLong(v) : defaultValue;
|
||||||
|
}
|
||||||
|
default Boolean getAttribute(String name, Boolean defaultValue) {
|
||||||
|
String v = getAttribute(name);
|
||||||
|
return v != null ? Boolean.parseBoolean(v) : defaultValue;
|
||||||
|
}
|
||||||
Map<String, String> getAttributes();
|
Map<String, String> getAttributes();
|
||||||
|
|
||||||
//--- brute force settings
|
//--- brute force settings
|
||||||
|
@ -430,7 +464,7 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns sorted {@link AuthenticationExecutionModel AuthenticationExecutionModel} as a stream.
|
* Returns sorted (according to priority) {@link AuthenticationExecutionModel AuthenticationExecutionModel} as a stream.
|
||||||
* It should be used with forEachOrdered if the ordering is required.
|
* It should be used with forEachOrdered if the ordering is required.
|
||||||
* @param flowId {@code String} Id of the flow.
|
* @param flowId {@code String} Id of the flow.
|
||||||
* @return Sorted stream of {@link AuthenticationExecutionModel}. Never returns {@code null}.
|
* @return Sorted stream of {@link AuthenticationExecutionModel}. Never returns {@code null}.
|
||||||
|
@ -555,8 +589,24 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
*/
|
*/
|
||||||
ComponentModel importComponentModel(ComponentModel model);
|
ComponentModel importComponentModel(ComponentModel model);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates component model. Will call onUpdate() method of ComponentFactory
|
||||||
|
* @param component to be updated
|
||||||
|
*/
|
||||||
void updateComponent(ComponentModel component);
|
void updateComponent(ComponentModel component);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes given component. Will call preRemove() method of ComponentFactory.
|
||||||
|
* Also calls {@code this.removeComponents(component.getId())}.
|
||||||
|
*
|
||||||
|
* @param component to be removed
|
||||||
|
*/
|
||||||
void removeComponent(ComponentModel component);
|
void removeComponent(ComponentModel component);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all components with given {@code parentId}
|
||||||
|
* @param parentId {@code String} id of parent
|
||||||
|
*/
|
||||||
void removeComponents(String parentId);
|
void removeComponents(String parentId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -567,7 +617,6 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
return getComponentsStream(parentId, providerType).collect(Collectors.toList());
|
return getComponentsStream(parentId, providerType).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns stream of ComponentModels for specific parentId and providerType.
|
* Returns stream of ComponentModels for specific parentId and providerType.
|
||||||
* @param parentId {@code String} id of parent
|
* @param parentId {@code String} id of parent
|
||||||
|
@ -882,7 +931,7 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns client's scopes as a stream.
|
* Returns all client scopes of this realm as a stream.
|
||||||
* @return Stream of {@link ClientScopeModel}. Never returns {@code null}.
|
* @return Stream of {@link ClientScopeModel}. Never returns {@code null}.
|
||||||
*/
|
*/
|
||||||
Stream<ClientScopeModel> getClientScopesStream();
|
Stream<ClientScopeModel> getClientScopesStream();
|
||||||
|
@ -920,7 +969,7 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
ClientScopeModel getClientScopeById(String id);
|
ClientScopeModel getClientScopeById(String id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds given client scopes among default/optional client scopes of this realm.
|
* Adds given client scope among default/optional client scopes of this realm.
|
||||||
* The scope will be assigned to each new client.
|
* The scope will be assigned to each new client.
|
||||||
* @param clientScope to be added
|
* @param clientScope to be added
|
||||||
* @param defaultScope if {@code true} the scope will be added among default client scopes,
|
* @param defaultScope if {@code true} the scope will be added among default client scopes,
|
||||||
|
@ -952,8 +1001,9 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns client's scopes with ability to specify whether default client's scopes are desired.
|
* Returns default client scopes of this realm either default ones or optional ones.
|
||||||
* @param defaultScope {@code boolean} Flag to include default client's scopes.
|
* @param defaultScope if {@code true} default client scopes are returned,
|
||||||
|
* if {@code false} optional client scopes are returned.
|
||||||
* @return Stream of {@link ClientScopeModel}. Never returns {@code null}.
|
* @return Stream of {@link ClientScopeModel}. Never returns {@code null}.
|
||||||
*/
|
*/
|
||||||
Stream<ClientScopeModel> getDefaultClientScopesStream(boolean defaultScope);
|
Stream<ClientScopeModel> getDefaultClientScopesStream(boolean defaultScope);
|
||||||
|
@ -965,4 +1015,10 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
default void addToDefaultRoles(RoleModel role) {
|
default void addToDefaultRoles(RoleModel role) {
|
||||||
getDefaultRole().addCompositeRole(role);
|
getDefaultRole().addCompositeRole(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClientInitialAccessModel createClientInitialAccessModel(int expiration, int count);
|
||||||
|
ClientInitialAccessModel getClientInitialAccessModel(String id);
|
||||||
|
void removeClientInitialAccessModel(String id);
|
||||||
|
Stream<ClientInitialAccessModel> getClientInitialAccesses();
|
||||||
|
void decreaseRemainingCount(ClientInitialAccessModel clientInitialAccess);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
package org.keycloak.models;
|
package org.keycloak.models;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.keycloak.migration.MigrationModel;
|
|
||||||
import org.keycloak.provider.Provider;
|
import org.keycloak.provider.Provider;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -32,31 +31,34 @@ import java.util.stream.Stream;
|
||||||
*/
|
*/
|
||||||
public interface RealmProvider extends Provider /* TODO: Remove in future version */, ClientProvider, ClientScopeProvider, GroupProvider, RoleProvider /* up to here */ {
|
public interface RealmProvider extends Provider /* TODO: Remove in future version */, ClientProvider, ClientScopeProvider, GroupProvider, RoleProvider /* up to here */ {
|
||||||
|
|
||||||
// Note: The reason there are so many query methods here is for layering a cache on top of an persistent KeycloakSession
|
|
||||||
MigrationModel getMigrationModel();
|
|
||||||
RealmModel createRealm(String name);
|
|
||||||
RealmModel createRealm(String id, String name);
|
|
||||||
RealmModel getRealm(String id);
|
|
||||||
RealmModel getRealmByName(String name);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use the corresponding method from {@link ClientScopeProvider}. */
|
* Creates new realm with the given name. The internal ID will be generated automatically.
|
||||||
default ClientScopeModel getClientScopeById(String id, RealmModel realm) {
|
* @param name String name of the realm
|
||||||
return getClientScopeById(realm, id);
|
* @return Model of the created realm.
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use the corresponding method from {@link ClientScopeProvider}. */
|
|
||||||
@Override
|
|
||||||
ClientScopeModel getClientScopeById(RealmModel realm, String id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use {@link #getRealmsStream() getRealmsStream} instead.
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
RealmModel createRealm(String name);
|
||||||
default List<RealmModel> getRealms() {
|
|
||||||
return getRealmsStream().collect(Collectors.toList());
|
/**
|
||||||
}
|
* Created new realm with given ID and name.
|
||||||
|
* @param id Internal ID of the realm or {@code null} if one is to be created by the underlying store
|
||||||
|
* @param name String name of the realm
|
||||||
|
* @return Model of the created realm.
|
||||||
|
*/
|
||||||
|
RealmModel createRealm(String id, String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exact search for a realm by its internal ID.
|
||||||
|
* @param id Internal ID of the realm.
|
||||||
|
* @return Model of the realm
|
||||||
|
*/
|
||||||
|
RealmModel getRealm(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exact search for a realm by its name.
|
||||||
|
* @param name String name of the realm
|
||||||
|
* @return Model of the realm
|
||||||
|
*/
|
||||||
|
RealmModel getRealmByName(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns realms as a stream.
|
* Returns realms as a stream.
|
||||||
|
@ -65,33 +67,27 @@ public interface RealmProvider extends Provider /* TODO: Remove in future versio
|
||||||
Stream<RealmModel> getRealmsStream();
|
Stream<RealmModel> getRealmsStream();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link #getRealmsWithProviderTypeStream(Class) getRealmsWithProviderTypeStream} instead.
|
* Returns stream of realms which has component with the given provider type.
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
default List<RealmModel> getRealmsWithProviderType(Class<?> type) {
|
|
||||||
return getRealmsWithProviderTypeStream(type).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns realms with the given provider type as a stream.
|
|
||||||
* @param type {@code Class<?>} Type of the provider.
|
* @param type {@code Class<?>} Type of the provider.
|
||||||
* @return Stream of {@link RealmModel}. Never returns {@code null}.
|
* @return Stream of {@link RealmModel}. Never returns {@code null}.
|
||||||
*/
|
*/
|
||||||
Stream<RealmModel> getRealmsWithProviderTypeStream(Class<?> type);
|
Stream<RealmModel> getRealmsWithProviderTypeStream(Class<?> type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes realm with the given id.
|
||||||
|
* @param id of realm.
|
||||||
|
* @return {@code true} if the realm was successfully removed.
|
||||||
|
*/
|
||||||
boolean removeRealm(String id);
|
boolean removeRealm(String id);
|
||||||
|
|
||||||
ClientInitialAccessModel createClientInitialAccessModel(RealmModel realm, int expiration, int count);
|
default ClientInitialAccessModel createClientInitialAccessModel(RealmModel realm, int expiration, int count) {
|
||||||
ClientInitialAccessModel getClientInitialAccessModel(RealmModel realm, String id);
|
return realm.createClientInitialAccessModel(expiration, count);
|
||||||
void removeClientInitialAccessModel(RealmModel realm, String id);
|
}
|
||||||
|
default ClientInitialAccessModel getClientInitialAccessModel(RealmModel realm, String id) {
|
||||||
/**
|
return realm.getClientInitialAccessModel(id);
|
||||||
* @deprecated Use {@link #listClientInitialAccessStream(RealmModel) listClientInitialAccessStream} instead.
|
}
|
||||||
*/
|
default void removeClientInitialAccessModel(RealmModel realm, String id) {
|
||||||
@Deprecated
|
realm.removeClientInitialAccessModel(id);
|
||||||
default List<ClientInitialAccessModel> listClientInitialAccess(RealmModel realm) {
|
|
||||||
return listClientInitialAccessStream(realm).collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,10 +95,18 @@ public interface RealmProvider extends Provider /* TODO: Remove in future versio
|
||||||
* @param realm {@link RealmModel} The realm where to list client's initial access.
|
* @param realm {@link RealmModel} The realm where to list client's initial access.
|
||||||
* @return Stream of {@link ClientInitialAccessModel}. Never returns {@code null}.
|
* @return Stream of {@link ClientInitialAccessModel}. Never returns {@code null}.
|
||||||
*/
|
*/
|
||||||
Stream<ClientInitialAccessModel> listClientInitialAccessStream(RealmModel realm);
|
default Stream<ClientInitialAccessModel> listClientInitialAccessStream(RealmModel realm) {
|
||||||
|
return realm.getClientInitialAccesses();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all expired client initial accesses from all realms.
|
||||||
|
*/
|
||||||
void removeExpiredClientInitialAccess();
|
void removeExpiredClientInitialAccess();
|
||||||
void decreaseRemainingCount(RealmModel realm, ClientInitialAccessModel clientInitialAccess); // Separate provider method to ensure we decrease remainingCount atomically instead of doing classic update
|
|
||||||
|
default void decreaseRemainingCount(RealmModel realm, ClientInitialAccessModel clientInitialAccess) { // Separate provider method to ensure we decrease remainingCount atomically instead of doing classic update
|
||||||
|
realm.decreaseRemainingCount(clientInitialAccess);
|
||||||
|
}
|
||||||
|
|
||||||
void saveLocalizationText(RealmModel realm, String locale, String key, String text);
|
void saveLocalizationText(RealmModel realm, String locale, String key, String text);
|
||||||
|
|
||||||
|
@ -120,6 +124,30 @@ public interface RealmProvider extends Provider /* TODO: Remove in future versio
|
||||||
// Sadly, we have to copy-paste the declarations from the respective interfaces
|
// Sadly, we have to copy-paste the declarations from the respective interfaces
|
||||||
// including the "default" body to be able to add a note on deprecation
|
// including the "default" body to be able to add a note on deprecation
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getRealmsStream() getRealmsStream} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default List<RealmModel> getRealms() {
|
||||||
|
return getRealmsStream().collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getRealmsWithProviderTypeStream(Class) getRealmsWithProviderTypeStream} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default List<RealmModel> getRealmsWithProviderType(Class<?> type) {
|
||||||
|
return getRealmsWithProviderTypeStream(type).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #listClientInitialAccessStream(RealmModel) listClientInitialAccessStream} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default List<ClientInitialAccessModel> listClientInitialAccess(RealmModel realm) {
|
||||||
|
return listClientInitialAccessStream(realm).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use the corresponding method from {@link ClientProvider}. */
|
* @deprecated Use the corresponding method from {@link ClientProvider}. */
|
||||||
@Override
|
@Override
|
||||||
|
@ -180,6 +208,17 @@ public interface RealmProvider extends Provider /* TODO: Remove in future versio
|
||||||
@Override
|
@Override
|
||||||
long getClientsCount(RealmModel realm);
|
long getClientsCount(RealmModel realm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use the corresponding method from {@link ClientScopeProvider}. */
|
||||||
|
default ClientScopeModel getClientScopeById(String id, RealmModel realm) {
|
||||||
|
return getClientScopeById(realm, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use the corresponding method from {@link ClientScopeProvider}. */
|
||||||
|
@Override
|
||||||
|
ClientScopeModel getClientScopeById(RealmModel realm, String id);
|
||||||
|
|
||||||
//Role-related methods
|
//Role-related methods
|
||||||
/**
|
/**
|
||||||
* @deprecated Use the corresponding method from {@link RoleProvider}. */
|
* @deprecated Use the corresponding method from {@link RoleProvider}. */
|
||||||
|
|
|
@ -26,7 +26,6 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.utils.DefaultKeyProviders;
|
|
||||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||||
import org.keycloak.services.ServicesLogger;
|
import org.keycloak.services.ServicesLogger;
|
||||||
|
|
||||||
|
|
|
@ -85,14 +85,20 @@ public class ComponentsTest extends AbstractAdminTest {
|
||||||
public void testConcurrencyWithoutChildren() throws InterruptedException {
|
public void testConcurrencyWithoutChildren() throws InterruptedException {
|
||||||
testConcurrency((s, i) -> s.submit(new CreateAndDeleteComponent(s, i)));
|
testConcurrency((s, i) -> s.submit(new CreateAndDeleteComponent(s, i)));
|
||||||
|
|
||||||
assertThat(realm.components().query(realm.toRepresentation().getId(), TestProvider.class.getName()), Matchers.hasSize(0));
|
// Data consistency is not guaranteed with concurrent access to entities in map store.
|
||||||
|
// For details see https://issues.redhat.com/browse/KEYCLOAK-17586
|
||||||
|
// The reason that this test remains here is to test whether it finishes in time (we need to test whether there is no slowness).
|
||||||
|
// assertThat(realm.components().query(realm.toRepresentation().getId(), TestProvider.class.getName()), Matchers.hasSize(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConcurrencyWithChildren() throws InterruptedException {
|
public void testConcurrencyWithChildren() throws InterruptedException {
|
||||||
testConcurrency((s, i) -> s.submit(new CreateAndDeleteComponentWithFlatChildren(s, i)));
|
testConcurrency((s, i) -> s.submit(new CreateAndDeleteComponentWithFlatChildren(s, i)));
|
||||||
|
|
||||||
assertThat(realm.components().query(realm.toRepresentation().getId(), TestProvider.class.getName()), Matchers.hasSize(0));
|
// Data consistency is not guaranteed with concurrent access to entities in map store.
|
||||||
|
// For details see https://issues.redhat.com/browse/KEYCLOAK-17586
|
||||||
|
// The reason that this test remains here is to test whether it finishes in time (we need to test whether there is no slowness).
|
||||||
|
// assertThat(realm.components().query(realm.toRepresentation().getId(), TestProvider.class.getName()), Matchers.hasSize(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
import org.keycloak.models.ServerInfoProvider;
|
||||||
|
|
||||||
import static org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer.REMOTE;
|
import static org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer.REMOTE;
|
||||||
|
|
||||||
|
@ -37,13 +38,13 @@ public class MigrationModelTest extends AbstractKeycloakTest {
|
||||||
Assert.assertTrue(l.get(0).getId().matches("[\\da-z]{5}"));
|
Assert.assertTrue(l.get(0).getId().matches("[\\da-z]{5}"));
|
||||||
Assert.assertEquals(currentVersion, l.get(0).getVersion());
|
Assert.assertEquals(currentVersion, l.get(0).getVersion());
|
||||||
|
|
||||||
MigrationModel m = session.realms().getMigrationModel();
|
MigrationModel m = session.getProvider(ServerInfoProvider.class).getMigrationModel();
|
||||||
Assert.assertEquals(currentVersion, m.getStoredVersion());
|
Assert.assertEquals(currentVersion, m.getStoredVersion());
|
||||||
Assert.assertEquals(m.getResourcesTag(), l.get(0).getId());
|
Assert.assertEquals(m.getResourcesTag(), l.get(0).getId());
|
||||||
|
|
||||||
Time.setOffset(-60000);
|
Time.setOffset(-60000);
|
||||||
|
|
||||||
session.realms().getMigrationModel().setStoredVersion("6.0.0");
|
session.getProvider(ServerInfoProvider.class).getMigrationModel().setStoredVersion("6.0.0");
|
||||||
em.flush();
|
em.flush();
|
||||||
|
|
||||||
Time.setOffset(0);
|
Time.setOffset(0);
|
||||||
|
@ -58,7 +59,7 @@ public class MigrationModelTest extends AbstractKeycloakTest {
|
||||||
Assert.assertTrue(l.get(1).getId().matches("[\\da-z]{5}"));
|
Assert.assertTrue(l.get(1).getId().matches("[\\da-z]{5}"));
|
||||||
Assert.assertEquals("6.0.0", l.get(1).getVersion());
|
Assert.assertEquals("6.0.0", l.get(1).getVersion());
|
||||||
|
|
||||||
m = session.realms().getMigrationModel();
|
m = session.getProvider(ServerInfoProvider.class).getMigrationModel();
|
||||||
Assert.assertEquals(l.get(0).getId(), m.getResourcesTag());
|
Assert.assertEquals(l.get(0).getId(), m.getResourcesTag());
|
||||||
Assert.assertEquals(currentVersion, m.getStoredVersion());
|
Assert.assertEquals(currentVersion, m.getStoredVersion());
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"realm": {
|
"realm": {
|
||||||
"provider": "${keycloak.realm.provider:}"
|
"provider": "${keycloak.realm.provider:jpa}"
|
||||||
},
|
},
|
||||||
|
|
||||||
"client": {
|
"client": {
|
||||||
|
|
Loading…
Reference in a new issue