keycloak-memoizeit
Changes
model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java 42(+21 -21)
model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java 253(+141 -112)
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java 30(+15 -15)
model/mongo/src/main/java/org/keycloak/storage/mongo/MongoUserFederatedStorageProvider.java 167(+102 -65)
server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapterFederatedStorage.java 34(+17 -17)
server-spi/src/main/java/org/keycloak/storage/federated/UserBrokerLinkFederatedStorage.java 10(+5 -5)
server-spi/src/main/java/org/keycloak/storage/federated/UserFederatedUserCredentialStore.java 38(+38 -0)
server-spi/src/main/java/org/keycloak/storage/federated/UserGroupMembershipFederatedStorage.java 6(+3 -3)
server-spi/src/main/java/org/keycloak/storage/federated/UserRequiredActionsFederatedStorage.java 6(+3 -3)
server-spi/src/main/java/org/keycloak/storage/federated/UserRoleMappingsFederatedStorage.java 6(+3 -3)
Details
diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
index bcbb02d..11ee08a 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
@@ -95,6 +95,7 @@ public class RealmRepresentation {
protected Integer otpPolicyPeriod;
protected List<UserRepresentation> users;
+ protected List<UserRepresentation> federatedUsers;
protected List<ScopeMappingRepresentation> scopeMappings;
protected Map<String, List<ScopeMappingRepresentation>> clientScopeMappings;
protected List<ClientRepresentation> clients;
@@ -883,4 +884,11 @@ public class RealmRepresentation {
return attributes;
}
+ public List<UserRepresentation> getFederatedUsers() {
+ return federatedUsers;
+ }
+
+ public void setFederatedUsers(List<UserRepresentation> federatedUsers) {
+ this.federatedUsers = federatedUsers;
+ }
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java
index cdb79a7..547419e 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java
@@ -475,15 +475,15 @@ public class UserCacheSession implements UserCache {
}
@Override
- public void updateConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
- invalidations.add(getConsentCacheKey(user.getId()));
- getDelegate().updateConsent(realm, user, consent);
+ public void updateConsent(RealmModel realm, String userId, UserConsentModel consent) {
+ invalidations.add(getConsentCacheKey(userId));
+ getDelegate().updateConsent(realm, userId, consent);
}
@Override
- public boolean revokeConsentForClient(RealmModel realm, UserModel user, String clientInternalId) {
- invalidations.add(getConsentCacheKey(user.getId()));
- return getDelegate().revokeConsentForClient(realm, user, clientInternalId);
+ public boolean revokeConsentForClient(RealmModel realm, String userId, String clientInternalId) {
+ invalidations.add(getConsentCacheKey(userId));
+ return getDelegate().revokeConsentForClient(realm, userId, clientInternalId);
}
public String getConsentCacheKey(String userId) {
@@ -492,25 +492,25 @@ public class UserCacheSession implements UserCache {
@Override
- public void addConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
- invalidations.add(getConsentCacheKey(user.getId()));
- getDelegate().addConsent(realm, user, consent);
+ public void addConsent(RealmModel realm, String userId, UserConsentModel consent) {
+ invalidations.add(getConsentCacheKey(userId));
+ getDelegate().addConsent(realm, userId, consent);
}
@Override
- public UserConsentModel getConsentByClient(RealmModel realm, UserModel user, String clientId) {
- logger.tracev("getConsentByClient: {0}", user.getUsername());
+ public UserConsentModel getConsentByClient(RealmModel realm, String userId, String clientId) {
+ logger.tracev("getConsentByClient: {0}", userId);
- String cacheKey = getConsentCacheKey(user.getId());
- if (realmInvalidations.contains(realm.getId()) || invalidations.contains(user.getId()) || invalidations.contains(cacheKey)) {
- return getDelegate().getConsentByClient(realm, user, clientId);
+ String cacheKey = getConsentCacheKey(userId);
+ if (realmInvalidations.contains(realm.getId()) || invalidations.contains(userId) || invalidations.contains(cacheKey)) {
+ return getDelegate().getConsentByClient(realm, userId, clientId);
}
CachedUserConsents cached = cache.get(cacheKey, CachedUserConsents.class);
if (cached == null) {
Long loaded = cache.getCurrentRevision(cacheKey);
- List<UserConsentModel> consents = getDelegate().getConsents(realm, user);
+ List<UserConsentModel> consents = getDelegate().getConsents(realm, userId);
cached = new CachedUserConsents(loaded, cacheKey, realm, consents);
cache.addRevisioned(cached, startupRevision);
}
@@ -520,19 +520,19 @@ public class UserCacheSession implements UserCache {
}
@Override
- public List<UserConsentModel> getConsents(RealmModel realm, UserModel user) {
- logger.tracev("getConsents: {0}", user.getUsername());
+ public List<UserConsentModel> getConsents(RealmModel realm, String userId) {
+ logger.tracev("getConsents: {0}", userId);
- String cacheKey = getConsentCacheKey(user.getId());
- if (realmInvalidations.contains(realm.getId()) || invalidations.contains(user.getId()) || invalidations.contains(cacheKey)) {
- return getDelegate().getConsents(realm, user);
+ String cacheKey = getConsentCacheKey(userId);
+ if (realmInvalidations.contains(realm.getId()) || invalidations.contains(userId) || invalidations.contains(cacheKey)) {
+ return getDelegate().getConsents(realm, userId);
}
CachedUserConsents cached = cache.get(cacheKey, CachedUserConsents.class);
if (cached == null) {
Long loaded = cache.getCurrentRevision(cacheKey);
- List<UserConsentModel> consents = getDelegate().getConsents(realm, user);
+ List<UserConsentModel> consents = getDelegate().getConsents(realm, userId);
cached = new CachedUserConsents(loaded, cacheKey, realm, consents);
cache.addRevisioned(cached, startupRevision);
return consents;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java
index 3aa71f0..bd03727 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java
@@ -194,19 +194,19 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
}
@Override
- public void addConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
+ public void addConsent(RealmModel realm, String userId, UserConsentModel consent) {
String clientId = consent.getClient().getId();
- UserConsentEntity consentEntity = getGrantedConsentEntity(user, clientId);
+ UserConsentEntity consentEntity = getGrantedConsentEntity(userId, clientId);
if (consentEntity != null) {
- throw new ModelDuplicateException("Consent already exists for client [" + clientId + "] and user [" + user.getId() + "]");
+ throw new ModelDuplicateException("Consent already exists for client [" + clientId + "] and user [" + userId + "]");
}
long currentTime = Time.currentTimeMillis();
consentEntity = new UserConsentEntity();
consentEntity.setId(KeycloakModelUtils.generateId());
- consentEntity.setUser(em.getReference(UserEntity.class, user.getId()));
+ consentEntity.setUser(em.getReference(UserEntity.class, userId));
consentEntity.setClientId(clientId);
consentEntity.setCreatedDate(currentTime);
consentEntity.setLastUpdatedDate(currentTime);
@@ -217,15 +217,15 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
}
@Override
- public UserConsentModel getConsentByClient(RealmModel realm, UserModel user, String clientId) {
- UserConsentEntity entity = getGrantedConsentEntity(user, clientId);
+ public UserConsentModel getConsentByClient(RealmModel realm, String userId, String clientId) {
+ UserConsentEntity entity = getGrantedConsentEntity(userId, clientId);
return toConsentModel(realm, entity);
}
@Override
- public List<UserConsentModel> getConsents(RealmModel realm, UserModel user) {
+ public List<UserConsentModel> getConsents(RealmModel realm, String userId) {
TypedQuery<UserConsentEntity> query = em.createNamedQuery("userConsentsByUser", UserConsentEntity.class);
- query.setParameter("userId", user.getId());
+ query.setParameter("userId", userId);
List<UserConsentEntity> results = query.getResultList();
List<UserConsentModel> consents = new ArrayList<UserConsentModel>();
@@ -237,19 +237,19 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
}
@Override
- public void updateConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
+ public void updateConsent(RealmModel realm, String userId, UserConsentModel consent) {
String clientId = consent.getClient().getId();
- UserConsentEntity consentEntity = getGrantedConsentEntity(user, clientId);
+ UserConsentEntity consentEntity = getGrantedConsentEntity(userId, clientId);
if (consentEntity == null) {
- throw new ModelException("Consent not found for client [" + clientId + "] and user [" + user.getId() + "]");
+ throw new ModelException("Consent not found for client [" + clientId + "] and user [" + userId + "]");
}
updateGrantedConsentEntity(consentEntity, consent);
}
- public boolean revokeConsentForClient(RealmModel realm, UserModel user, String clientId) {
- UserConsentEntity consentEntity = getGrantedConsentEntity(user, clientId);
+ public boolean revokeConsentForClient(RealmModel realm, String userId, String clientId) {
+ UserConsentEntity consentEntity = getGrantedConsentEntity(userId, clientId);
if (consentEntity == null) return false;
em.remove(consentEntity);
@@ -258,13 +258,13 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
}
- private UserConsentEntity getGrantedConsentEntity(UserModel user, String clientId) {
+ private UserConsentEntity getGrantedConsentEntity(String userId, String clientId) {
TypedQuery<UserConsentEntity> query = em.createNamedQuery("userConsentByUserAndClient", UserConsentEntity.class);
- query.setParameter("userId", user.getId());
+ query.setParameter("userId", userId);
query.setParameter("clientId", clientId);
List<UserConsentEntity> results = query.getResultList();
if (results.size() > 1) {
- throw new ModelException("More results found for user [" + user.getUsername() + "] and client [" + clientId + "]");
+ throw new ModelException("More results found for user [" + userId + "] and client [" + clientId + "]");
} else if (results.size() == 1) {
return results.get(0);
} else {
diff --git a/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUser.java b/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUser.java
index b5c958c..c74c630 100644
--- a/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUser.java
+++ b/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUser.java
@@ -31,6 +31,7 @@ import javax.persistence.Table;
*/
@NamedQueries({
@NamedQuery(name="getFederatedUserIds", query="select f.id from FederatedUser f where f.realmId=:realmId"),
+ @NamedQuery(name="getFederatedUserCount", query="select count(u) from FederatedUser u where u.realmId = :realmId"),
@NamedQuery(name="deleteFederatedUserByUser", query="delete from FederatedUser f where f.id = :userId and f.realmId=:realmId"),
@NamedQuery(name="deleteFederatedUsersByRealm", query="delete from FederatedUser f where f.realmId=:realmId"),
@NamedQuery(name="deleteFederatedUsersByStorageProvider", query="delete from FederatedUser f where f.storageProviderId=:storageProviderId"),
diff --git a/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java b/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java
index 713447b..e1f2bd4 100644
--- a/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java
@@ -70,12 +70,6 @@ import java.util.Set;
*/
public class JpaUserFederatedStorageProvider implements
UserFederatedStorageProvider,
- UserAttributeFederatedStorage,
- UserBrokerLinkFederatedStorage,
- UserConsentFederatedStorage,
- UserGroupMembershipFederatedStorage,
- UserRequiredActionsFederatedStorage,
- UserRoleMappingsFederatedStorage,
UserCredentialStore {
private final KeycloakSession session;
@@ -95,66 +89,66 @@ public class JpaUserFederatedStorageProvider implements
* We create an entry so that its easy to iterate over all things in the database. Specifically useful for export
*
*/
- protected void createIndex(RealmModel realm, UserModel user) {
- if (em.find(FederatedUser.class, user.getId()) == null) {
+ protected void createIndex(RealmModel realm, String userId) {
+ if (em.find(FederatedUser.class, userId) == null) {
FederatedUser fedUser = new FederatedUser();
- fedUser.setId(user.getId());
+ fedUser.setId(userId);
fedUser.setRealmId(realm.getId());
- fedUser.setStorageProviderId(StorageId.resolveProviderId(user));
+ fedUser.setStorageProviderId(new StorageId(userId).getProviderId());
em.persist(fedUser);
}
}
@Override
- public void setAttribute(RealmModel realm, UserModel user, String name, List<String> values) {
- createIndex(realm, user);
- deleteAttribute(realm, user, name);
+ public void setAttribute(RealmModel realm, String userId, String name, List<String> values) {
+ createIndex(realm, userId);
+ deleteAttribute(realm, userId, name);
em.flush();
for (String value : values) {
- persistAttributeValue(realm, user, name, value);
+ persistAttributeValue(realm, userId, name, value);
}
}
- private void deleteAttribute(RealmModel realm, UserModel user, String name) {
+ private void deleteAttribute(RealmModel realm, String userId, String name) {
em.createNamedQuery("deleteUserFederatedAttributesByUserAndName")
- .setParameter("userId", user.getId())
+ .setParameter("userId", userId)
.setParameter("realmId", realm.getId())
.setParameter("name", name)
.executeUpdate();
}
- private void persistAttributeValue(RealmModel realm, UserModel user, String name, String value) {
+ private void persistAttributeValue(RealmModel realm, String userId, String name, String value) {
FederatedUserAttributeEntity attr = new FederatedUserAttributeEntity();
attr.setId(KeycloakModelUtils.generateId());
attr.setName(name);
attr.setValue(value);
- attr.setUserId(user.getId());
+ attr.setUserId(userId);
attr.setRealmId(realm.getId());
- attr.setStorageProviderId(StorageId.resolveProviderId(user));
+ attr.setStorageProviderId(new StorageId(userId).getProviderId());
em.persist(attr);
}
@Override
- public void setSingleAttribute(RealmModel realm, UserModel user, String name, String value) {
- createIndex(realm, user);
- deleteAttribute(realm, user, name);
+ public void setSingleAttribute(RealmModel realm, String userId, String name, String value) {
+ createIndex(realm, userId);
+ deleteAttribute(realm, userId, name);
em.flush();
- persistAttributeValue(realm, user, name, value);
+ persistAttributeValue(realm, userId, name, value);
}
@Override
- public void removeAttribute(RealmModel realm, UserModel user, String name) {
+ public void removeAttribute(RealmModel realm, String userId, String name) {
// createIndex(realm, user); don't need to create an index for removal
- deleteAttribute(realm, user, name);
+ deleteAttribute(realm, userId, name);
em.flush();
}
@Override
- public MultivaluedHashMap<String, String> getAttributes(RealmModel realm, UserModel user) {
+ public MultivaluedHashMap<String, String> getAttributes(RealmModel realm, String userId) {
TypedQuery<FederatedUserAttributeEntity> query = em.createNamedQuery("getFederatedAttributesByUser", FederatedUserAttributeEntity.class);
List<FederatedUserAttributeEntity> list = query
- .setParameter("userId", user.getId())
+ .setParameter("userId", userId)
.setParameter("realmId", realm.getId())
.getResultList();
MultivaluedHashMap<String, String> result = new MultivaluedHashMap<>();
@@ -192,31 +186,31 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel link) {
- createIndex(realm, user);
+ public void addFederatedIdentity(RealmModel realm, String userId, FederatedIdentityModel link) {
+ createIndex(realm, userId);
BrokerLinkEntity entity = new BrokerLinkEntity();
entity.setRealmId(realm.getId());
- entity.setUserId(user.getId());
+ entity.setUserId(userId);
entity.setBrokerUserId(link.getUserId());
entity.setIdentityProvider(link.getIdentityProvider());
entity.setToken(link.getToken());
entity.setBrokerUserName(link.getUserName());
- entity.setStorageProviderId(StorageId.resolveProviderId(user));
+ entity.setStorageProviderId(new StorageId(userId).getProviderId());
em.persist(entity);
}
@Override
- public boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
- BrokerLinkEntity entity = getBrokerLinkEntity(realm, user, socialProvider);
+ public boolean removeFederatedIdentity(RealmModel realm, String userId, String socialProvider) {
+ BrokerLinkEntity entity = getBrokerLinkEntity(realm, userId, socialProvider);
if (entity == null) return false;
em.remove(entity);
return true;
}
- private BrokerLinkEntity getBrokerLinkEntity(RealmModel realm, UserModel user, String socialProvider) {
+ private BrokerLinkEntity getBrokerLinkEntity(RealmModel realm, String userId, String socialProvider) {
TypedQuery<BrokerLinkEntity> query = em.createNamedQuery("findBrokerLinkByUserAndProvider", BrokerLinkEntity.class)
- .setParameter("userId", user.getId())
+ .setParameter("userId", userId)
.setParameter("realmId", realm.getId())
.setParameter("identityProvider", socialProvider);
List<BrokerLinkEntity> results = query.getResultList();
@@ -224,9 +218,9 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public void updateFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel model) {
- createIndex(realm, user);
- BrokerLinkEntity entity = getBrokerLinkEntity(realm, user, model.getIdentityProvider());
+ public void updateFederatedIdentity(RealmModel realm, String userId, FederatedIdentityModel model) {
+ createIndex(realm, userId);
+ BrokerLinkEntity entity = getBrokerLinkEntity(realm, userId, model.getIdentityProvider());
if (entity == null) return;
entity.setBrokerUserName(model.getUserName());
entity.setBrokerUserId(model.getUserId());
@@ -237,9 +231,9 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm) {
+ public Set<FederatedIdentityModel> getFederatedIdentities(String userId, RealmModel realm) {
TypedQuery<BrokerLinkEntity> query = em.createNamedQuery("findBrokerLinkByUser", BrokerLinkEntity.class)
- .setParameter("userId", user.getId());
+ .setParameter("userId", userId);
List<BrokerLinkEntity> results = query.getResultList();
Set<FederatedIdentityModel> set = new HashSet<>();
for (BrokerLinkEntity entity : results) {
@@ -250,28 +244,28 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm) {
- BrokerLinkEntity entity = getBrokerLinkEntity(realm, user, socialProvider);
+ public FederatedIdentityModel getFederatedIdentity(String userId, String socialProvider, RealmModel realm) {
+ BrokerLinkEntity entity = getBrokerLinkEntity(realm, userId, socialProvider);
if (entity == null) return null;
return new FederatedIdentityModel(entity.getIdentityProvider(), entity.getBrokerUserId(), entity.getBrokerUserName(), entity.getToken());
}
@Override
- public void addConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
- createIndex(realm, user);
+ public void addConsent(RealmModel realm, String userId, UserConsentModel consent) {
+ createIndex(realm, userId);
String clientId = consent.getClient().getId();
- FederatedUserConsentEntity consentEntity = getGrantedConsentEntity(user, clientId);
+ FederatedUserConsentEntity consentEntity = getGrantedConsentEntity(userId, clientId);
if (consentEntity != null) {
- throw new ModelDuplicateException("Consent already exists for client [" + clientId + "] and user [" + user.getId() + "]");
+ throw new ModelDuplicateException("Consent already exists for client [" + clientId + "] and user [" + userId + "]");
}
consentEntity = new FederatedUserConsentEntity();
consentEntity.setId(KeycloakModelUtils.generateId());
- consentEntity.setUserId(user.getId());
+ consentEntity.setUserId(userId);
consentEntity.setClientId(clientId);
consentEntity.setRealmId(realm.getId());
- consentEntity.setStorageProviderId(StorageId.resolveProviderId(user));
+ consentEntity.setStorageProviderId(new StorageId(userId).getProviderId());
em.persist(consentEntity);
em.flush();
@@ -280,15 +274,15 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public UserConsentModel getConsentByClient(RealmModel realm, UserModel user, String clientInternalId) {
- FederatedUserConsentEntity entity = getGrantedConsentEntity(user, clientInternalId);
+ public UserConsentModel getConsentByClient(RealmModel realm, String userId, String clientInternalId) {
+ FederatedUserConsentEntity entity = getGrantedConsentEntity(userId, clientInternalId);
return toConsentModel(realm, entity);
}
@Override
- public List<UserConsentModel> getConsents(RealmModel realm, UserModel user) {
+ public List<UserConsentModel> getConsents(RealmModel realm, String userId) {
TypedQuery<FederatedUserConsentEntity> query = em.createNamedQuery("userFederatedConsentsByUser", FederatedUserConsentEntity.class);
- query.setParameter("userId", user.getId());
+ query.setParameter("userId", userId);
List<FederatedUserConsentEntity> results = query.getResultList();
List<UserConsentModel> consents = new ArrayList<UserConsentModel>();
@@ -300,13 +294,13 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public void updateConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
- createIndex(realm, user);
+ public void updateConsent(RealmModel realm, String userId, UserConsentModel consent) {
+ createIndex(realm, userId);
String clientId = consent.getClient().getId();
- FederatedUserConsentEntity consentEntity = getGrantedConsentEntity(user, clientId);
+ FederatedUserConsentEntity consentEntity = getGrantedConsentEntity(userId, clientId);
if (consentEntity == null) {
- throw new ModelException("Consent not found for client [" + clientId + "] and user [" + user.getId() + "]");
+ throw new ModelException("Consent not found for client [" + clientId + "] and user [" + userId + "]");
}
updateGrantedConsentEntity(consentEntity, consent);
@@ -314,8 +308,8 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public boolean revokeConsentForClient(RealmModel realm, UserModel user, String clientInternalId) {
- FederatedUserConsentEntity consentEntity = getGrantedConsentEntity(user, clientInternalId);
+ public boolean revokeConsentForClient(RealmModel realm, String userId, String clientInternalId) {
+ FederatedUserConsentEntity consentEntity = getGrantedConsentEntity(userId, clientInternalId);
if (consentEntity == null) return false;
em.remove(consentEntity);
@@ -323,13 +317,13 @@ public class JpaUserFederatedStorageProvider implements
return true;
}
- private FederatedUserConsentEntity getGrantedConsentEntity(UserModel user, String clientId) {
+ private FederatedUserConsentEntity getGrantedConsentEntity(String userId, String clientId) {
TypedQuery<FederatedUserConsentEntity> query = em.createNamedQuery("userFederatedConsentByUserAndClient", FederatedUserConsentEntity.class);
- query.setParameter("userId", user.getId());
+ query.setParameter("userId", userId);
query.setParameter("clientId", clientId);
List<FederatedUserConsentEntity> results = query.getResultList();
if (results.size() > 1) {
- throw new ModelException("More results found for user [" + user.getUsername() + "] and client [" + clientId + "]");
+ throw new ModelException("More results found for user [" + userId + "] and client [" + clientId + "]");
} else if (results.size() == 1) {
return results.get(0);
} else {
@@ -423,10 +417,10 @@ public class JpaUserFederatedStorageProvider implements
@Override
- public Set<GroupModel> getGroups(RealmModel realm, UserModel user) {
+ public Set<GroupModel> getGroups(RealmModel realm, String userId) {
Set<GroupModel> set = new HashSet<>();
TypedQuery<FederatedUserGroupMembershipEntity> query = em.createNamedQuery("feduserGroupMembership", FederatedUserGroupMembershipEntity.class);
- query.setParameter("userId", user.getId());
+ query.setParameter("userId", userId);
List<FederatedUserGroupMembershipEntity> results = query.getResultList();
if (results.size() == 0) return set;
for (FederatedUserGroupMembershipEntity entity : results) {
@@ -437,30 +431,24 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public void joinGroup(RealmModel realm, UserModel user, GroupModel group) {
- if (isMemberOf(realm, user, group)) return;
- createIndex(realm, user);
+ public void joinGroup(RealmModel realm, String userId, GroupModel group) {
+ createIndex(realm, userId);
FederatedUserGroupMembershipEntity entity = new FederatedUserGroupMembershipEntity();
- entity.setUserId(user.getId());
- entity.setStorageProviderId(StorageId.resolveProviderId(user));
+ entity.setUserId(userId);
+ entity.setStorageProviderId(new StorageId(userId).getProviderId());
entity.setGroupId(group.getId());
entity.setRealmId(realm.getId());
em.persist(entity);
}
- public boolean isMemberOf(RealmModel realm, UserModel user, GroupModel group) {
- Set<GroupModel> roles = user.getGroups();
- return KeycloakModelUtils.isMember(roles, group);
- }
-
@Override
- public void leaveGroup(RealmModel realm, UserModel user, GroupModel group) {
- if (user == null || group == null) return;
+ public void leaveGroup(RealmModel realm, String userId, GroupModel group) {
+ if (userId == null || group == null) return;
TypedQuery<FederatedUserGroupMembershipEntity> query1 = em.createNamedQuery("feduserMemberOf", FederatedUserGroupMembershipEntity.class);
- query1.setParameter("userId", user.getId());
+ query1.setParameter("userId", userId);
query1.setParameter("groupId", group.getId());
TypedQuery<FederatedUserGroupMembershipEntity> query = query1;
List<FederatedUserGroupMembershipEntity> results = query.getResultList();
@@ -483,9 +471,9 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public Set<String> getRequiredActions(RealmModel realm, UserModel user) {
+ public Set<String> getRequiredActions(RealmModel realm, String userId) {
Set<String> set = new HashSet<>();
- List<FederatedUserRequiredActionEntity> values = getRequiredActionEntities(realm, user);
+ List<FederatedUserRequiredActionEntity> values = getRequiredActionEntities(realm, userId);
for (FederatedUserRequiredActionEntity entity : values) {
set.add(entity.getAction());
}
@@ -494,29 +482,28 @@ public class JpaUserFederatedStorageProvider implements
}
- private List<FederatedUserRequiredActionEntity> getRequiredActionEntities(RealmModel realm, UserModel user) {
+ private List<FederatedUserRequiredActionEntity> getRequiredActionEntities(RealmModel realm, String userId) {
TypedQuery<FederatedUserRequiredActionEntity> query = em.createNamedQuery("getFederatedUserRequiredActionsByUser", FederatedUserRequiredActionEntity.class)
- .setParameter("userId", user.getId())
+ .setParameter("userId", userId)
.setParameter("realmId", realm.getId());
return query.getResultList();
}
@Override
- public void addRequiredAction(RealmModel realm, UserModel user, String action) {
- createIndex(realm, user);
- if (user.getRequiredActions().contains(action)) return;
+ public void addRequiredAction(RealmModel realm, String userId, String action) {
+ createIndex(realm, userId);
FederatedUserRequiredActionEntity entity = new FederatedUserRequiredActionEntity();
- entity.setUserId(user.getId());
+ entity.setUserId(userId);
entity.setRealmId(realm.getId());
- entity.setStorageProviderId(StorageId.resolveProviderId(user));
+ entity.setStorageProviderId(new StorageId(userId).getProviderId());
entity.setAction(action);
em.persist(entity);
}
@Override
- public void removeRequiredAction(RealmModel realm, UserModel user, String action) {
- List<FederatedUserRequiredActionEntity> values = getRequiredActionEntities(realm, user);
+ public void removeRequiredAction(RealmModel realm, String userId, String action) {
+ List<FederatedUserRequiredActionEntity> values = getRequiredActionEntities(realm, userId);
for (FederatedUserRequiredActionEntity entity : values) {
if (action.equals(entity.getAction())) em.remove(entity);
}
@@ -525,12 +512,11 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public void grantRole(RealmModel realm, UserModel user, RoleModel role) {
- if (user.hasRole(role)) return;
- createIndex(realm, user);
+ public void grantRole(RealmModel realm, String userId, RoleModel role) {
+ createIndex(realm, userId);
FederatedUserRoleMappingEntity entity = new FederatedUserRoleMappingEntity();
- entity.setUserId(user.getId());
- entity.setStorageProviderId(StorageId.resolveProviderId(user));
+ entity.setUserId(userId);
+ entity.setStorageProviderId(new StorageId(userId).getProviderId());
entity.setRealmId(realm.getId());
entity.setRoleId(role.getId());
em.persist(entity);
@@ -538,10 +524,10 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public Set<RoleModel> getRoleMappings(RealmModel realm, UserModel user) {
+ public Set<RoleModel> getRoleMappings(RealmModel realm, String userId) {
Set<RoleModel> set = new HashSet<>();
TypedQuery<FederatedUserRoleMappingEntity> query = em.createNamedQuery("feduserRoleMappings", FederatedUserRoleMappingEntity.class);
- query.setParameter("userId", user.getId());
+ query.setParameter("userId", userId);
List<FederatedUserRoleMappingEntity> results = query.getResultList();
if (results.size() == 0) return set;
for (FederatedUserRoleMappingEntity entity : results) {
@@ -552,9 +538,9 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public void deleteRoleMapping(RealmModel realm, UserModel user, RoleModel role) {
+ public void deleteRoleMapping(RealmModel realm, String userId, RoleModel role) {
TypedQuery<FederatedUserRoleMappingEntity> query = em.createNamedQuery("feduserRoleMappings", FederatedUserRoleMappingEntity.class);
- query.setParameter("userId", user.getId());
+ query.setParameter("userId", userId);
List<FederatedUserRoleMappingEntity> results = query.getResultList();
for (FederatedUserRoleMappingEntity entity : results) {
if (entity.getRoleId().equals(role.getId())) em.remove(entity);
@@ -564,10 +550,10 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public void updateCredential(RealmModel realm, UserModel user, CredentialModel cred) {
+ public void updateCredential(RealmModel realm, String userId, CredentialModel cred) {
FederatedUserCredentialEntity entity = em.find(FederatedUserCredentialEntity.class, cred.getId());
if (entity == null) return;
- createIndex(realm, user);
+ createIndex(realm, userId);
entity.setAlgorithm(cred.getAlgorithm());
entity.setCounter(cred.getCounter());
entity.setCreatedDate(cred.getCreatedDate());
@@ -618,8 +604,8 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public CredentialModel createCredential(RealmModel realm, UserModel user, CredentialModel cred) {
- createIndex(realm, user);
+ public CredentialModel createCredential(RealmModel realm, String userId, CredentialModel cred) {
+ createIndex(realm, userId);
FederatedUserCredentialEntity entity = new FederatedUserCredentialEntity();
String id = cred.getId() == null ? KeycloakModelUtils.generateId() : cred.getId();
entity.setId(id);
@@ -633,9 +619,9 @@ public class JpaUserFederatedStorageProvider implements
entity.setSalt(cred.getSalt());
entity.setType(cred.getType());
entity.setValue(cred.getValue());
- entity.setUserId(user.getId());
+ entity.setUserId(userId);
entity.setRealmId(realm.getId());
- entity.setStorageProviderId(StorageId.resolveProviderId(user));
+ entity.setStorageProviderId(new StorageId(userId).getProviderId());
em.persist(entity);
MultivaluedHashMap<String, String> config = cred.getConfig();
if (config != null && !config.isEmpty()) {
@@ -658,7 +644,7 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public boolean removeStoredCredential(RealmModel realm, UserModel user, String id) {
+ public boolean removeStoredCredential(RealmModel realm, String userId, String id) {
FederatedUserCredentialEntity entity = em.find(FederatedUserCredentialEntity.class, id);
if (entity == null) return false;
em.remove(entity);
@@ -666,7 +652,7 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public CredentialModel getStoredCredentialById(RealmModel realm, UserModel user, String id) {
+ public CredentialModel getStoredCredentialById(RealmModel realm, String userId, String id) {
FederatedUserCredentialEntity entity = em.find(FederatedUserCredentialEntity.class, id);
if (entity == null) return null;
CredentialModel model = toModel(entity);
@@ -695,9 +681,9 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public List<CredentialModel> getStoredCredentials(RealmModel realm, UserModel user) {
+ public List<CredentialModel> getStoredCredentials(RealmModel realm, String userId) {
TypedQuery<FederatedUserCredentialEntity> query = em.createNamedQuery("federatedUserCredentialByUser", FederatedUserCredentialEntity.class)
- .setParameter("userId", user.getId());
+ .setParameter("userId", userId);
List<FederatedUserCredentialEntity> results = query.getResultList();
List<CredentialModel> rtn = new LinkedList<>();
for (FederatedUserCredentialEntity entity : results) {
@@ -707,10 +693,10 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public List<CredentialModel> getStoredCredentialsByType(RealmModel realm, UserModel user, String type) {
+ public List<CredentialModel> getStoredCredentialsByType(RealmModel realm, String userId, String type) {
TypedQuery<FederatedUserCredentialEntity> query = em.createNamedQuery("federatedUserCredentialByUserAndType", FederatedUserCredentialEntity.class)
.setParameter("type", type)
- .setParameter("userId", user.getId());
+ .setParameter("userId", userId);
List<FederatedUserCredentialEntity> results = query.getResultList();
List<CredentialModel> rtn = new LinkedList<>();
for (FederatedUserCredentialEntity entity : results) {
@@ -720,11 +706,11 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
- public CredentialModel getStoredCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type) {
+ public CredentialModel getStoredCredentialByNameAndType(RealmModel realm, String userId, String name, String type) {
TypedQuery<FederatedUserCredentialEntity> query = em.createNamedQuery("federatedUserCredentialByNameAndType", FederatedUserCredentialEntity.class)
.setParameter("type", type)
.setParameter("device", name)
- .setParameter("userId", user.getId());
+ .setParameter("userId", userId);
List<FederatedUserCredentialEntity> results = query.getResultList();
if (results.isEmpty()) return null;
return toModel(results.get(0));
@@ -734,12 +720,55 @@ public class JpaUserFederatedStorageProvider implements
public List<String> getStoredUsers(RealmModel realm, int first, int max) {
TypedQuery<String> query = em.createNamedQuery("getFederatedUserIds", String.class)
.setParameter("realmId", realm.getId())
- .setFirstResult(first)
- .setMaxResults(max);
+ .setFirstResult(first);
+ if (max > 0) query.setMaxResults(max);
return query.getResultList();
}
@Override
+ public void updateCredential(RealmModel realm, UserModel user, CredentialModel cred) {
+ updateCredential(realm, user.getId(), cred);
+ }
+
+ @Override
+ public CredentialModel createCredential(RealmModel realm, UserModel user, CredentialModel cred) {
+ return createCredential(realm, user.getId(), cred);
+ }
+
+ @Override
+ public boolean removeStoredCredential(RealmModel realm, UserModel user, String id) {
+ return removeStoredCredential(realm, user.getId(), id);
+ }
+
+ @Override
+ public CredentialModel getStoredCredentialById(RealmModel realm, UserModel user, String id) {
+ return getStoredCredentialById(realm, user.getId(), id);
+ }
+
+ @Override
+ public List<CredentialModel> getStoredCredentials(RealmModel realm, UserModel user) {
+ return getStoredCredentials(realm, user.getId());
+ }
+
+ @Override
+ public List<CredentialModel> getStoredCredentialsByType(RealmModel realm, UserModel user, String type) {
+ return getStoredCredentialsByType(realm, user.getId(), type);
+ }
+
+ @Override
+ public CredentialModel getStoredCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type) {
+ return getStoredCredentialByNameAndType(realm, user.getId(), name, type);
+ }
+
+ @Override
+ public int getStoredUsersCount(RealmModel realm) {
+ Object count = em.createNamedQuery("getFederatedUserCount")
+ .setParameter("realmId", realm.getId())
+ .getSingleResult();
+ return ((Number)count).intValue();
+ }
+
+ @Override
public void preRemove(RealmModel realm) {
int num = em.createNamedQuery("deleteFederatedUserConsentRolesByRealm")
.setParameter("realmId", realm.getId()).executeUpdate();
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java
index af1b6be..7b46c0c 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserProvider.java
@@ -519,16 +519,16 @@ public class MongoUserProvider implements UserProvider, UserCredentialStore {
}
@Override
- public void addConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
+ public void addConsent(RealmModel realm, String userId, UserConsentModel consent) {
String clientId = consent.getClient().getId();
- if (getConsentEntityByClientId(user, clientId) != null) {
- throw new ModelDuplicateException("Consent already exists for client [" + clientId + "] and user [" + user.getId() + "]");
+ if (getConsentEntityByClientId(userId, clientId) != null) {
+ throw new ModelDuplicateException("Consent already exists for client [" + clientId + "] and user [" + userId + "]");
}
long currentTime = Time.currentTimeMillis();
MongoUserConsentEntity consentEntity = new MongoUserConsentEntity();
- consentEntity.setUserId(user.getId());
+ consentEntity.setUserId(userId);
consentEntity.setClientId(clientId);
consentEntity.setCreatedDate(currentTime);
consentEntity.setLastUpdatedDate(currentTime);
@@ -537,17 +537,17 @@ public class MongoUserProvider implements UserProvider, UserCredentialStore {
}
@Override
- public UserConsentModel getConsentByClient(RealmModel realm, UserModel user, String clientId) {
- UserConsentEntity consentEntity = getConsentEntityByClientId(user, clientId);
+ public UserConsentModel getConsentByClient(RealmModel realm, String userId, String clientId) {
+ UserConsentEntity consentEntity = getConsentEntityByClientId(userId, clientId);
return consentEntity!=null ? toConsentModel(realm, consentEntity) : null;
}
@Override
- public List<UserConsentModel> getConsents(RealmModel realm, UserModel user) {
+ public List<UserConsentModel> getConsents(RealmModel realm, String userId) {
List<UserConsentModel> result = new ArrayList<UserConsentModel>();
DBObject query = new QueryBuilder()
- .and("userId").is(user.getId())
+ .and("userId").is(userId)
.get();
List<MongoUserConsentEntity> grantedConsents = getMongoStore().loadEntities(MongoUserConsentEntity.class, query, invocationContext);
@@ -559,9 +559,9 @@ public class MongoUserProvider implements UserProvider, UserCredentialStore {
return result;
}
- private MongoUserConsentEntity getConsentEntityByClientId(UserModel user, String clientId) {
+ private MongoUserConsentEntity getConsentEntityByClientId(String userId, String clientId) {
DBObject query = new QueryBuilder()
- .and("userId").is(user.getId())
+ .and("userId").is(userId)
.and("clientId").is(clientId)
.get();
return getMongoStore().loadSingleEntity(MongoUserConsentEntity.class, query, invocationContext);
@@ -607,11 +607,11 @@ public class MongoUserProvider implements UserProvider, UserCredentialStore {
}
@Override
- public void updateConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
+ public void updateConsent(RealmModel realm, String userId, UserConsentModel consent) {
String clientId = consent.getClient().getId();
- MongoUserConsentEntity consentEntity = getConsentEntityByClientId(user, clientId);
+ MongoUserConsentEntity consentEntity = getConsentEntityByClientId(userId, clientId);
if (consentEntity == null) {
- throw new ModelException("Consent not found for client [" + clientId + "] and user [" + user.getId() + "]");
+ throw new ModelException("Consent not found for client [" + clientId + "] and user [" + userId + "]");
} else {
fillEntityFromModel(consent, consentEntity);
getMongoStore().updateEntity(consentEntity, invocationContext);
@@ -619,8 +619,8 @@ public class MongoUserProvider implements UserProvider, UserCredentialStore {
}
@Override
- public boolean revokeConsentForClient(RealmModel realm, UserModel user, String clientId) {
- MongoUserConsentEntity entity = getConsentEntityByClientId(user, clientId);
+ public boolean revokeConsentForClient(RealmModel realm, String userId, String clientId) {
+ MongoUserConsentEntity entity = getConsentEntityByClientId(userId, clientId);
if (entity == null) {
return false;
}
diff --git a/model/mongo/src/main/java/org/keycloak/storage/mongo/MongoUserFederatedStorageProvider.java b/model/mongo/src/main/java/org/keycloak/storage/mongo/MongoUserFederatedStorageProvider.java
index ec970bf..adc681e 100644
--- a/model/mongo/src/main/java/org/keycloak/storage/mongo/MongoUserFederatedStorageProvider.java
+++ b/model/mongo/src/main/java/org/keycloak/storage/mongo/MongoUserFederatedStorageProvider.java
@@ -64,12 +64,6 @@ import java.util.Set;
*/
public class MongoUserFederatedStorageProvider implements
UserFederatedStorageProvider,
- UserAttributeFederatedStorage,
- UserBrokerLinkFederatedStorage,
- UserConsentFederatedStorage,
- UserGroupMembershipFederatedStorage,
- UserRequiredActionsFederatedStorage,
- UserRoleMappingsFederatedStorage,
UserCredentialStore {
private final MongoStoreInvocationContext invocationContext;
@@ -108,8 +102,8 @@ public class MongoUserFederatedStorageProvider implements
@Override
- public boolean removeStoredCredential(RealmModel realm, UserModel user, String id) {
- FederatedUser userEntity = getUserById(user.getId());
+ public boolean removeStoredCredential(RealmModel realm, String userId, String id) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity == null) return false;
CredentialEntity ce = getCredentialEntity(id, userEntity);
if (ce != null) return getMongoStore().pullItemFromList(userEntity, "credentials", ce, invocationContext);
@@ -153,7 +147,7 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public CredentialModel getStoredCredentialById(RealmModel realm, UserModel user, String id) {
+ public CredentialModel getStoredCredentialById(RealmModel realm, String userId, String id) {
FederatedUser userEntity = getUserById(id);
if (userEntity != null && userEntity.getCredentials() != null) {
for (CredentialEntity credentialEntity : userEntity.getCredentials()) {
@@ -167,8 +161,8 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public List<CredentialModel> getStoredCredentials(RealmModel realm, UserModel user) {
- FederatedUser userEntity = getUserById(user.getId());
+ public List<CredentialModel> getStoredCredentials(RealmModel realm, String userId) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity != null && userEntity.getCredentials() != null) {
List<CredentialModel> list = new LinkedList<>();
for (CredentialEntity credentialEntity : userEntity.getCredentials()) {
@@ -180,8 +174,8 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public List<CredentialModel> getStoredCredentialsByType(RealmModel realm, UserModel user, String type) {
- FederatedUser userEntity = getUserById(user.getId());
+ public List<CredentialModel> getStoredCredentialsByType(RealmModel realm, String userId, String type) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity != null && userEntity.getCredentials() != null) {
List<CredentialModel> list = new LinkedList<>();
for (CredentialEntity credentialEntity : userEntity.getCredentials()) {
@@ -193,8 +187,8 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public CredentialModel getStoredCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type) {
- FederatedUser userEntity = getUserById(user.getId());
+ public CredentialModel getStoredCredentialByNameAndType(RealmModel realm, String userId, String name, String type) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity != null && userEntity.getCredentials() != null) {
for (CredentialEntity credentialEntity : userEntity.getCredentials()) {
if (credentialEntity.getDevice().equals(name) && type.equals(credentialEntity.getType())) {
@@ -285,8 +279,8 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public void setSingleAttribute(RealmModel realm, UserModel user, String name, String value) {
- FederatedUser userEntity = findOrCreate(realm, user.getId());
+ public void setSingleAttribute(RealmModel realm, String userId, String name, String value) {
+ FederatedUser userEntity = findOrCreate(realm, userId);
if (userEntity.getAttributes() == null) {
userEntity.setAttributes(new HashMap<>());
}
@@ -298,8 +292,8 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public void setAttribute(RealmModel realm, UserModel user, String name, List<String> values) {
- FederatedUser userEntity = findOrCreate(realm, user.getId());
+ public void setAttribute(RealmModel realm, String userId, String name, List<String> values) {
+ FederatedUser userEntity = findOrCreate(realm, userId);
if (userEntity.getAttributes() == null) {
userEntity.setAttributes(new HashMap<>());
}
@@ -310,8 +304,8 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public void removeAttribute(RealmModel realm, UserModel user, String name) {
- FederatedUser userEntity = getUserById(user.getId());
+ public void removeAttribute(RealmModel realm, String userId, String name) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity == null || userEntity.getAttributes() == null) return;
userEntity.getAttributes().remove(name);
@@ -319,8 +313,8 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public MultivaluedHashMap<String, String> getAttributes(RealmModel realm, UserModel user) {
- FederatedUser userEntity = getUserById(user.getId());
+ public MultivaluedHashMap<String, String> getAttributes(RealmModel realm, String userId) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity == null || userEntity.getAttributes() == null) return new MultivaluedHashMap<>();
MultivaluedHashMap<String, String> result = new MultivaluedHashMap<>();
result.putAll(userEntity.getAttributes());
@@ -351,8 +345,8 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel socialLink) {
- FederatedUser userEntity = findOrCreate(realm, user.getId());
+ public void addFederatedIdentity(RealmModel realm, String userId, FederatedIdentityModel socialLink) {
+ FederatedUser userEntity = findOrCreate(realm, userId);
FederatedIdentityEntity federatedIdentityEntity = new FederatedIdentityEntity();
federatedIdentityEntity.setIdentityProvider(socialLink.getIdentityProvider());
federatedIdentityEntity.setUserId(socialLink.getUserId());
@@ -363,8 +357,8 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
- FederatedUser userEntity = getUserById(user.getId());
+ public boolean removeFederatedIdentity(RealmModel realm, String userId, String socialProvider) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity == null) return false;
FederatedIdentityEntity federatedIdentityEntity = findFederatedIdentityLink(userEntity, socialProvider);
@@ -388,8 +382,8 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public void updateFederatedIdentity(RealmModel realm, UserModel federatedUser, FederatedIdentityModel federatedIdentityModel) {
- FederatedUser userEntity = getUserById(federatedUser.getId());
+ public void updateFederatedIdentity(RealmModel realm, String userId, FederatedIdentityModel federatedIdentityModel) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity == null) return;
FederatedIdentityEntity federatedIdentityEntity = findFederatedIdentityLink(userEntity, federatedIdentityModel.getIdentityProvider());
if (federatedIdentityEntity == null) return;
@@ -401,8 +395,8 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm) {
- FederatedUser userEntity = getUserById(user.getId());
+ public Set<FederatedIdentityModel> getFederatedIdentities(String userId, RealmModel realm) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity == null) return Collections.EMPTY_SET;
List<FederatedIdentityEntity> linkEntities = userEntity.getFederatedIdentities();
@@ -420,8 +414,8 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm) {
- FederatedUser userEntity = getUserById(user.getId());
+ public FederatedIdentityModel getFederatedIdentity(String userId, String socialProvider, RealmModel realm) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity == null) return null;
FederatedIdentityEntity federatedIdentityEntity = findFederatedIdentityLink(userEntity, socialProvider);
@@ -430,35 +424,35 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public void addConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
- session.userLocalStorage().addConsent(realm, user, consent);
+ public void addConsent(RealmModel realm, String userId, UserConsentModel consent) {
+ session.userLocalStorage().addConsent(realm, userId, consent);
}
@Override
- public UserConsentModel getConsentByClient(RealmModel realm, UserModel user, String clientInternalId) {
- return session.userLocalStorage().getConsentByClient(realm, user, clientInternalId);
+ public UserConsentModel getConsentByClient(RealmModel realm, String userId, String clientInternalId) {
+ return session.userLocalStorage().getConsentByClient(realm, userId, clientInternalId);
}
@Override
- public List<UserConsentModel> getConsents(RealmModel realm, UserModel user) {
- return session.userLocalStorage().getConsents(realm, user);
+ public List<UserConsentModel> getConsents(RealmModel realm, String userId) {
+ return session.userLocalStorage().getConsents(realm, userId);
}
@Override
- public void updateConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
- session.userLocalStorage().updateConsent(realm, user, consent);
+ public void updateConsent(RealmModel realm, String userId, UserConsentModel consent) {
+ session.userLocalStorage().updateConsent(realm, userId, consent);
}
@Override
- public boolean revokeConsentForClient(RealmModel realm, UserModel user, String clientInternalId) {
- return session.userLocalStorage().revokeConsentForClient(realm, user, clientInternalId);
+ public boolean revokeConsentForClient(RealmModel realm, String userId, String clientInternalId) {
+ return session.userLocalStorage().revokeConsentForClient(realm, userId, clientInternalId);
}
@Override
- public void updateCredential(RealmModel realm, UserModel user, CredentialModel cred) {
- FederatedUser userEntity = getUserById(user.getId());
+ public void updateCredential(RealmModel realm, String userId, CredentialModel cred) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity == null) return;
CredentialEntity entity = getCredentialEntity(cred.getId(), userEntity);
if (entity == null) return;
@@ -489,8 +483,8 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public CredentialModel createCredential(RealmModel realm, UserModel user, CredentialModel cred) {
- FederatedUser userEntity = findOrCreate(realm, user.getId());
+ public CredentialModel createCredential(RealmModel realm, String userId, CredentialModel cred) {
+ FederatedUser userEntity = findOrCreate(realm, userId);
CredentialEntity entity = new CredentialEntity();
entity.setId(KeycloakModelUtils.generateId());
toEntity(cred, entity);
@@ -500,8 +494,8 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public Set<GroupModel> getGroups(RealmModel realm, UserModel user) {
- FederatedUser userEntity = getUserById(user.getId());
+ public Set<GroupModel> getGroups(RealmModel realm, String userId) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity == null || userEntity.getGroupIds() == null || userEntity.getGroupIds().isEmpty()) return Collections.EMPTY_SET;
Set<GroupModel> groups = new HashSet<>();
for (String groupId : userEntity.getGroupIds()) {
@@ -513,16 +507,16 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public void joinGroup(RealmModel realm, UserModel user, GroupModel group) {
- FederatedUser userEntity = findOrCreate(realm, user.getId());
+ public void joinGroup(RealmModel realm, String userId, GroupModel group) {
+ FederatedUser userEntity = findOrCreate(realm, userId);
getMongoStore().pushItemToList(userEntity, "groupIds", group.getId(), true, invocationContext);
}
@Override
- public void leaveGroup(RealmModel realm, UserModel user, GroupModel group) {
- FederatedUser userEntity = getUserById(user.getId());
+ public void leaveGroup(RealmModel realm, String userId, GroupModel group) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity == null || group == null) return;
getMongoStore().pullItemFromList(userEntity, "groupIds", group.getId(), invocationContext);
@@ -542,8 +536,8 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public Set<String> getRequiredActions(RealmModel realm, UserModel user) {
- FederatedUser userEntity = getUserById(user.getId());
+ public Set<String> getRequiredActions(RealmModel realm, String userId) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity == null || userEntity.getRequiredActions() == null || userEntity.getRequiredActions().isEmpty()) return Collections.EMPTY_SET;
Set<String> set = new HashSet<>();
set.addAll(userEntity.getRequiredActions());
@@ -551,30 +545,30 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public void addRequiredAction(RealmModel realm, UserModel user, String action) {
- FederatedUser userEntity = findOrCreate(realm, user.getId());
+ public void addRequiredAction(RealmModel realm, String userId, String action) {
+ FederatedUser userEntity = findOrCreate(realm, userId);
getMongoStore().pushItemToList(userEntity, "requiredActions", action, true, invocationContext);
}
@Override
- public void removeRequiredAction(RealmModel realm, UserModel user, String action) {
- FederatedUser userEntity = getUserById(user.getId());
+ public void removeRequiredAction(RealmModel realm, String userId, String action) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity == null || userEntity.getRequiredActions() == null || userEntity.getRequiredActions().isEmpty()) return;
getMongoStore().pullItemFromList(userEntity, "requiredActions", action, invocationContext);
}
@Override
- public void grantRole(RealmModel realm, UserModel user, RoleModel role) {
- FederatedUser userEntity = findOrCreate(realm, user.getId());
+ public void grantRole(RealmModel realm, String userId, RoleModel role) {
+ FederatedUser userEntity = findOrCreate(realm, userId);
getMongoStore().pushItemToList(userEntity, "roleIds", role.getId(), true, invocationContext);
}
@Override
- public Set<RoleModel> getRoleMappings(RealmModel realm, UserModel user) {
- FederatedUser userEntity = getUserById(user.getId());
+ public Set<RoleModel> getRoleMappings(RealmModel realm, String userId) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity == null || userEntity.getRoleIds() == null || userEntity.getRoleIds().isEmpty()) return Collections.EMPTY_SET;
Set<RoleModel> roles = new HashSet<>();
for (String roleId : userEntity.getRoleIds()) {
@@ -585,10 +579,53 @@ public class MongoUserFederatedStorageProvider implements
}
@Override
- public void deleteRoleMapping(RealmModel realm, UserModel user, RoleModel role) {
- FederatedUser userEntity = getUserById(user.getId());
+ public void deleteRoleMapping(RealmModel realm, String userId, RoleModel role) {
+ FederatedUser userEntity = getUserById(userId);
if (userEntity == null || userEntity.getRoleIds() == null || userEntity.getRoleIds().isEmpty()) return;
getMongoStore().pullItemFromList(userEntity, "roleIds", role.getId(), invocationContext);
}
+
+ @Override
+ public void updateCredential(RealmModel realm, UserModel user, CredentialModel cred) {
+ updateCredential(realm, user.getId(), cred);
+ }
+
+ @Override
+ public CredentialModel createCredential(RealmModel realm, UserModel user, CredentialModel cred) {
+ return createCredential(realm, user.getId(), cred);
+ }
+
+ @Override
+ public boolean removeStoredCredential(RealmModel realm, UserModel user, String id) {
+ return removeStoredCredential(realm, user.getId(), id);
+ }
+
+ @Override
+ public CredentialModel getStoredCredentialById(RealmModel realm, UserModel user, String id) {
+ return getStoredCredentialById(realm, user.getId(), id);
+ }
+
+ @Override
+ public List<CredentialModel> getStoredCredentials(RealmModel realm, UserModel user) {
+ return getStoredCredentials(realm, user.getId());
+ }
+
+ @Override
+ public List<CredentialModel> getStoredCredentialsByType(RealmModel realm, UserModel user, String type) {
+ return getStoredCredentialsByType(realm, user.getId(), type);
+ }
+
+ @Override
+ public CredentialModel getStoredCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type) {
+ return getStoredCredentialByNameAndType(realm, user.getId(), name, type);
+ }
+
+ @Override
+ public int getStoredUsersCount(RealmModel realm) {
+ DBObject query = new QueryBuilder()
+ .and("realmId").is(realm.getId())
+ .get();
+ return getMongoStore().countEntities(FederatedUser.class, query, invocationContext);
+ }
}
diff --git a/server-spi/src/main/java/org/keycloak/models/UserFederationManager.java b/server-spi/src/main/java/org/keycloak/models/UserFederationManager.java
index c722aa4..1765bad 100755
--- a/server-spi/src/main/java/org/keycloak/models/UserFederationManager.java
+++ b/server-spi/src/main/java/org/keycloak/models/UserFederationManager.java
@@ -175,35 +175,30 @@ public class UserFederationManager implements UserProvider {
}
@Override
- public void addConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
- validateUser(realm, user);
- session.userStorage().addConsent(realm, user, consent);
+ public void addConsent(RealmModel realm, String userId, UserConsentModel consent) {
+ session.userStorage().addConsent(realm, userId, consent);
}
@Override
- public UserConsentModel getConsentByClient(RealmModel realm, UserModel user, String clientInternalId) {
- validateUser(realm, user);
- return session.userStorage().getConsentByClient(realm, user, clientInternalId);
+ public UserConsentModel getConsentByClient(RealmModel realm, String userId, String clientInternalId) {
+ return session.userStorage().getConsentByClient(realm, userId, clientInternalId);
}
@Override
- public List<UserConsentModel> getConsents(RealmModel realm, UserModel user) {
- validateUser(realm, user);
- return session.userStorage().getConsents(realm, user);
+ public List<UserConsentModel> getConsents(RealmModel realm, String userId) {
+ return session.userStorage().getConsents(realm, userId);
}
@Override
- public void updateConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
- validateUser(realm, user);
- session.userStorage().updateConsent(realm, user, consent);
+ public void updateConsent(RealmModel realm, String userId, UserConsentModel consent) {
+ session.userStorage().updateConsent(realm, userId, consent);
}
@Override
- public boolean revokeConsentForClient(RealmModel realm, UserModel user, String clientInternalId) {
- validateUser(realm, user);
- return session.userStorage().revokeConsentForClient(realm, user, clientInternalId);
+ public boolean revokeConsentForClient(RealmModel realm, String userId, String clientInternalId) {
+ return session.userStorage().revokeConsentForClient(realm, userId, clientInternalId);
}
@Override
diff --git a/server-spi/src/main/java/org/keycloak/models/UserProvider.java b/server-spi/src/main/java/org/keycloak/models/UserProvider.java
index 3c796b5..b8b240e 100755
--- a/server-spi/src/main/java/org/keycloak/models/UserProvider.java
+++ b/server-spi/src/main/java/org/keycloak/models/UserProvider.java
@@ -43,11 +43,11 @@ public interface UserProvider extends Provider,
FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm);
UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm);
- void addConsent(RealmModel realm, UserModel user, UserConsentModel consent);
- UserConsentModel getConsentByClient(RealmModel realm, UserModel user, String clientInternalId);
- List<UserConsentModel> getConsents(RealmModel realm, UserModel user);
- void updateConsent(RealmModel realm, UserModel user, UserConsentModel consent);
- boolean revokeConsentForClient(RealmModel realm, UserModel user, String clientInternalId);
+ void addConsent(RealmModel realm, String userId, UserConsentModel consent);
+ UserConsentModel getConsentByClient(RealmModel realm, String userId, String clientInternalId);
+ List<UserConsentModel> getConsents(RealmModel realm, String userId);
+ void updateConsent(RealmModel realm, String userId, UserConsentModel consent);
+ boolean revokeConsentForClient(RealmModel realm, String userId, String clientInternalId);
UserModel getServiceAccount(ClientModel client);
diff --git a/server-spi/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/server-spi/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
index c5e55a5..f1e4ea7 100755
--- a/server-spi/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/server-spi/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -101,6 +101,7 @@ import org.keycloak.representations.idm.authorization.ResourceOwnerRepresentatio
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
+import org.keycloak.storage.federated.UserFederatedStorageProvider;
import org.keycloak.util.JsonSerialization;
import java.io.IOException;
@@ -355,6 +356,13 @@ public class RepresentationToModel {
}
}
+ if (rep.getFederatedUsers() != null) {
+ for (UserRepresentation userRep : rep.getFederatedUsers()) {
+ importFederatedUser(session, newRealm, userRep);
+
+ }
+ }
+
if(rep.isInternationalizationEnabled() != null){
newRealm.setInternationalizationEnabled(rep.isInternationalizationEnabled());
}
@@ -1363,7 +1371,7 @@ public class RepresentationToModel {
if (userRep.getClientConsents() != null) {
for (UserConsentRepresentation consentRep : userRep.getClientConsents()) {
UserConsentModel consentModel = toModel(newRealm, consentRep);
- session.userStorage().addConsent(newRealm, user, consentModel);
+ session.userStorage().addConsent(newRealm, user.getId(), consentModel);
}
}
if (userRep.getServiceAccountClientId() != null) {
@@ -1451,6 +1459,32 @@ public class RepresentationToModel {
return credential;
}
+ public static CredentialModel toModel(CredentialRepresentation cred) {
+ CredentialModel model = new CredentialModel();
+ model.setHashIterations(cred.getHashIterations());
+ model.setCreatedDate(cred.getCreatedDate());
+ model.setType(cred.getType());
+ model.setDigits(cred.getDigits());
+ model.setConfig(cred.getConfig());
+ model.setDevice(cred.getDevice());
+ model.setAlgorithm(cred.getAlgorithm());
+ model.setCounter(cred.getCounter());
+ model.setPeriod(cred.getPeriod());
+ if (cred.getSalt() != null) {
+ try {
+ model.setSalt(Base64.decode(cred.getSalt()));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ model.setValue(cred.getValue());
+ if (cred.getHashedSaltedValue() != null) {
+ model.setValue(cred.getHashedSaltedValue());
+ }
+ return model;
+
+ }
+
// Role mappings
public static void createRoleMappings(UserRepresentation userRep, UserModel user, RealmModel realm) {
@@ -2188,4 +2222,99 @@ public class RepresentationToModel {
return model;
}
+
+ public static void importFederatedUser(KeycloakSession session, RealmModel newRealm, UserRepresentation userRep) {
+ UserFederatedStorageProvider federatedStorage = session.userFederatedStorage();
+ if (userRep.getAttributes() != null) {
+ for (Map.Entry<String, Object> entry : userRep.getAttributes().entrySet()) {
+ String key = entry.getKey();
+ Object value = entry.getValue();
+ if (value == null) continue;
+
+ if (value instanceof Collection) {
+ Collection<String> colVal = (Collection<String>) value;
+ List<String> list = new LinkedList<>();
+ list.addAll(colVal);
+ federatedStorage.setAttribute(newRealm, userRep.getId(), key, list);
+ } else if (value instanceof String) {
+ // TODO: This is here just for backwards compatibility with KC 1.3 and earlier
+ String stringVal = (String) value;
+ federatedStorage.setSingleAttribute(newRealm, userRep.getId(), key, stringVal);
+ }
+ }
+ }
+ if (userRep.getRequiredActions() != null) {
+ for (String action: userRep.getRequiredActions()) {
+ federatedStorage.addRequiredAction(newRealm, userRep.getId(), action);
+ }
+ }
+ if (userRep.getCredentials() != null) {
+ for (CredentialRepresentation cred : userRep.getCredentials()) {
+ federatedStorage.createCredential(newRealm, userRep.getId(), toModel(cred));
+ }
+ }
+ createFederatedRoleMappings(federatedStorage, userRep, newRealm);
+
+ if (userRep.getGroups() != null) {
+ for (String path : userRep.getGroups()) {
+ GroupModel group = KeycloakModelUtils.findGroupByPath(newRealm, path);
+ if (group == null) {
+ throw new RuntimeException("Unable to find group specified by path: " + path);
+
+ }
+ federatedStorage.joinGroup(newRealm, userRep.getId(), group);
+ }
+ }
+
+ if (userRep.getFederatedIdentities() != null) {
+ for (FederatedIdentityRepresentation identity : userRep.getFederatedIdentities()) {
+ FederatedIdentityModel mappingModel = new FederatedIdentityModel(identity.getIdentityProvider(), identity.getUserId(), identity.getUserName());
+ federatedStorage.addFederatedIdentity(newRealm, userRep.getId(), mappingModel);
+ }
+ }
+ if (userRep.getClientConsents() != null) {
+ for (UserConsentRepresentation consentRep : userRep.getClientConsents()) {
+ UserConsentModel consentModel = toModel(newRealm, consentRep);
+ federatedStorage.addConsent(newRealm, userRep.getId(), consentModel);
+ }
+ }
+
+
+ }
+
+ public static void createFederatedRoleMappings(UserFederatedStorageProvider federatedStorage, UserRepresentation userRep, RealmModel realm) {
+ if (userRep.getRealmRoles() != null) {
+ for (String roleString : userRep.getRealmRoles()) {
+ RoleModel role = realm.getRole(roleString.trim());
+ if (role == null) {
+ role = realm.addRole(roleString.trim());
+ }
+ federatedStorage.grantRole(realm, userRep.getId(), role);
+ }
+ }
+ if (userRep.getClientRoles() != null) {
+ for (Map.Entry<String, List<String>> entry : userRep.getClientRoles().entrySet()) {
+ ClientModel client = realm.getClientByClientId(entry.getKey());
+ if (client == null) {
+ throw new RuntimeException("Unable to find client role mappings for client: " + entry.getKey());
+ }
+ createFederatedClientRoleMappings(federatedStorage, realm, client, userRep, entry.getValue());
+ }
+ }
+ }
+
+ public static void createFederatedClientRoleMappings(UserFederatedStorageProvider federatedStorage, RealmModel realm, ClientModel clientModel, UserRepresentation userRep, List<String> roleNames) {
+ if (userRep == null) {
+ throw new RuntimeException("User not found");
+ }
+
+ for (String roleName : roleNames) {
+ RoleModel role = clientModel.getRole(roleName.trim());
+ if (role == null) {
+ role = clientModel.addRole(roleName.trim());
+ }
+ federatedStorage.grantRole(realm, userRep.getId(), role);
+
+ }
+ }
}
diff --git a/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapterFederatedStorage.java b/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapterFederatedStorage.java
index ed8759b..865f454 100644
--- a/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapterFederatedStorage.java
+++ b/server-spi/src/main/java/org/keycloak/storage/adapter/AbstractUserAdapterFederatedStorage.java
@@ -70,30 +70,30 @@ public abstract class AbstractUserAdapterFederatedStorage implements UserModel {
@Override
public Set<String> getRequiredActions() {
- return getFederatedStorage().getRequiredActions(realm, this);
+ return getFederatedStorage().getRequiredActions(realm, this.getId());
}
@Override
public void addRequiredAction(String action) {
- getFederatedStorage().addRequiredAction(realm, this, action);
+ getFederatedStorage().addRequiredAction(realm, this.getId(), action);
}
@Override
public void removeRequiredAction(String action) {
- getFederatedStorage().removeRequiredAction(realm, this, action);
+ getFederatedStorage().removeRequiredAction(realm, this.getId(), action);
}
@Override
public void addRequiredAction(RequiredAction action) {
- getFederatedStorage().addRequiredAction(realm, this, action.name());
+ getFederatedStorage().addRequiredAction(realm, this.getId(), action.name());
}
@Override
public void removeRequiredAction(RequiredAction action) {
- getFederatedStorage().removeRequiredAction(realm, this, action.name());
+ getFederatedStorage().removeRequiredAction(realm, this.getId(), action.name());
}
/**
@@ -119,7 +119,7 @@ public abstract class AbstractUserAdapterFederatedStorage implements UserModel {
@Override
public Set<GroupModel> getGroups() {
Set<GroupModel> set = new HashSet<>();
- set.addAll(getFederatedStorage().getGroups(realm, this));
+ set.addAll(getFederatedStorage().getGroups(realm, this.getId()));
if (appendDefaultGroups()) set.addAll(realm.getDefaultGroups());
set.addAll(getGroupsInternal());
return set;
@@ -127,13 +127,13 @@ public abstract class AbstractUserAdapterFederatedStorage implements UserModel {
@Override
public void joinGroup(GroupModel group) {
- getFederatedStorage().joinGroup(realm, this, group);
+ getFederatedStorage().joinGroup(realm, this.getId(), group);
}
@Override
public void leaveGroup(GroupModel group) {
- getFederatedStorage().leaveGroup(realm, this, group);
+ getFederatedStorage().leaveGroup(realm, this.getId(), group);
}
@@ -183,7 +183,7 @@ public abstract class AbstractUserAdapterFederatedStorage implements UserModel {
@Override
public void grantRole(RoleModel role) {
- getFederatedStorage().grantRole(realm, this, role);
+ getFederatedStorage().grantRole(realm, this.getId(), role);
}
@@ -212,12 +212,12 @@ public abstract class AbstractUserAdapterFederatedStorage implements UserModel {
}
protected Set<RoleModel> getFederatedRoleMappings() {
- return getFederatedStorage().getRoleMappings(realm, this);
+ return getFederatedStorage().getRoleMappings(realm, this.getId());
}
@Override
public void deleteRoleMapping(RoleModel role) {
- getFederatedStorage().deleteRoleMapping(realm, this, role);
+ getFederatedStorage().deleteRoleMapping(realm, this.getId(), role);
}
@@ -307,35 +307,35 @@ public abstract class AbstractUserAdapterFederatedStorage implements UserModel {
@Override
public void setSingleAttribute(String name, String value) {
- getFederatedStorage().setSingleAttribute(realm, this, name, value);
+ getFederatedStorage().setSingleAttribute(realm, this.getId(), name, value);
}
@Override
public void removeAttribute(String name) {
- getFederatedStorage().removeAttribute(realm, this, name);
+ getFederatedStorage().removeAttribute(realm, this.getId(), name);
}
@Override
public void setAttribute(String name, List<String> values) {
- getFederatedStorage().setAttribute(realm, this, name, values);
+ getFederatedStorage().setAttribute(realm, this.getId(), name, values);
}
@Override
public String getFirstAttribute(String name) {
- return getFederatedStorage().getAttributes(realm, this).getFirst(name);
+ return getFederatedStorage().getAttributes(realm, this.getId()).getFirst(name);
}
@Override
public Map<String, List<String>> getAttributes() {
- return getFederatedStorage().getAttributes(realm, this);
+ return getFederatedStorage().getAttributes(realm, this.getId());
}
@Override
public List<String> getAttribute(String name) {
- return getFederatedStorage().getAttributes(realm, this).get(name);
+ return getFederatedStorage().getAttributes(realm, this.getId()).get(name);
}
@Override
diff --git a/server-spi/src/main/java/org/keycloak/storage/federated/UserAttributeFederatedStorage.java b/server-spi/src/main/java/org/keycloak/storage/federated/UserAttributeFederatedStorage.java
index 6c04521..28ab594 100644
--- a/server-spi/src/main/java/org/keycloak/storage/federated/UserAttributeFederatedStorage.java
+++ b/server-spi/src/main/java/org/keycloak/storage/federated/UserAttributeFederatedStorage.java
@@ -27,9 +27,9 @@ import java.util.List;
* @version $Revision: 1 $
*/
public interface UserAttributeFederatedStorage {
- void setSingleAttribute(RealmModel realm, UserModel user, String name, String value);
- void setAttribute(RealmModel realm, UserModel user, String name, List<String> values);
- void removeAttribute(RealmModel realm, UserModel user, String name);
- MultivaluedHashMap<String, String> getAttributes(RealmModel realm, UserModel user);
+ void setSingleAttribute(RealmModel realm, String userId, String name, String value);
+ void setAttribute(RealmModel realm, String userId, String name, List<String> values);
+ void removeAttribute(RealmModel realm, String userId, String name);
+ MultivaluedHashMap<String, String> getAttributes(RealmModel realm, String userId);
List<String> getUsersByUserAttribute(RealmModel realm, String name, String value);
}
diff --git a/server-spi/src/main/java/org/keycloak/storage/federated/UserBrokerLinkFederatedStorage.java b/server-spi/src/main/java/org/keycloak/storage/federated/UserBrokerLinkFederatedStorage.java
index 6fcbabf..5624061 100644
--- a/server-spi/src/main/java/org/keycloak/storage/federated/UserBrokerLinkFederatedStorage.java
+++ b/server-spi/src/main/java/org/keycloak/storage/federated/UserBrokerLinkFederatedStorage.java
@@ -28,9 +28,9 @@ import java.util.Set;
*/
public interface UserBrokerLinkFederatedStorage {
String getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm);
- public void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel socialLink);
- public boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider);
- void updateFederatedIdentity(RealmModel realm, UserModel federatedUser, FederatedIdentityModel federatedIdentityModel);
- Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm);
- FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm);
+ public void addFederatedIdentity(RealmModel realm, String userId, FederatedIdentityModel socialLink);
+ public boolean removeFederatedIdentity(RealmModel realm, String userId, String socialProvider);
+ void updateFederatedIdentity(RealmModel realm, String userId, FederatedIdentityModel federatedIdentityModel);
+ Set<FederatedIdentityModel> getFederatedIdentities(String userId, RealmModel realm);
+ FederatedIdentityModel getFederatedIdentity(String userId, String socialProvider, RealmModel realm);
}
diff --git a/server-spi/src/main/java/org/keycloak/storage/federated/UserConsentFederatedStorage.java b/server-spi/src/main/java/org/keycloak/storage/federated/UserConsentFederatedStorage.java
index 7a14b14..21e79ca 100644
--- a/server-spi/src/main/java/org/keycloak/storage/federated/UserConsentFederatedStorage.java
+++ b/server-spi/src/main/java/org/keycloak/storage/federated/UserConsentFederatedStorage.java
@@ -27,9 +27,9 @@ import java.util.List;
* @version $Revision: 1 $
*/
public interface UserConsentFederatedStorage {
- void addConsent(RealmModel realm, UserModel user, UserConsentModel consent);
- UserConsentModel getConsentByClient(RealmModel realm, UserModel user, String clientInternalId);
- List<UserConsentModel> getConsents(RealmModel realm, UserModel user);
- void updateConsent(RealmModel realm, UserModel user, UserConsentModel consent);
- boolean revokeConsentForClient(RealmModel realm, UserModel user, String clientInternalId);
+ void addConsent(RealmModel realm, String userId, UserConsentModel consent);
+ UserConsentModel getConsentByClient(RealmModel realm, String userId, String clientInternalId);
+ List<UserConsentModel> getConsents(RealmModel realm, String userId);
+ void updateConsent(RealmModel realm, String userId, UserConsentModel consent);
+ boolean revokeConsentForClient(RealmModel realm, String userId, String clientInternalId);
}
diff --git a/server-spi/src/main/java/org/keycloak/storage/federated/UserFederatedStorageProvider.java b/server-spi/src/main/java/org/keycloak/storage/federated/UserFederatedStorageProvider.java
index b8d4e35..12847bc 100755
--- a/server-spi/src/main/java/org/keycloak/storage/federated/UserFederatedStorageProvider.java
+++ b/server-spi/src/main/java/org/keycloak/storage/federated/UserFederatedStorageProvider.java
@@ -39,9 +39,11 @@ public interface UserFederatedStorageProvider extends Provider,
UserConsentFederatedStorage,
UserGroupMembershipFederatedStorage,
UserRequiredActionsFederatedStorage,
- UserRoleMappingsFederatedStorage {
+ UserRoleMappingsFederatedStorage,
+ UserFederatedUserCredentialStore {
List<String> getStoredUsers(RealmModel realm, int first, int max);
+ int getStoredUsersCount(RealmModel realm);
void preRemove(RealmModel realm);
diff --git a/server-spi/src/main/java/org/keycloak/storage/federated/UserFederatedUserCredentialStore.java b/server-spi/src/main/java/org/keycloak/storage/federated/UserFederatedUserCredentialStore.java
new file mode 100644
index 0000000..0df895b
--- /dev/null
+++ b/server-spi/src/main/java/org/keycloak/storage/federated/UserFederatedUserCredentialStore.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016 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.storage.federated;
+
+import org.keycloak.credential.CredentialModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.provider.Provider;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public interface UserFederatedUserCredentialStore extends Provider {
+ void updateCredential(RealmModel realm, String userId, CredentialModel cred);
+ CredentialModel createCredential(RealmModel realm, String userId, CredentialModel cred);
+ boolean removeStoredCredential(RealmModel realm, String userId, String id);
+ CredentialModel getStoredCredentialById(RealmModel realm, String userId, String id);
+ List<CredentialModel> getStoredCredentials(RealmModel realm, String userId);
+ List<CredentialModel> getStoredCredentialsByType(RealmModel realm, String userId, String type);
+ CredentialModel getStoredCredentialByNameAndType(RealmModel realm, String userId, String name, String type);
+}
diff --git a/server-spi/src/main/java/org/keycloak/storage/federated/UserGroupMembershipFederatedStorage.java b/server-spi/src/main/java/org/keycloak/storage/federated/UserGroupMembershipFederatedStorage.java
index dad2399..696ff84 100644
--- a/server-spi/src/main/java/org/keycloak/storage/federated/UserGroupMembershipFederatedStorage.java
+++ b/server-spi/src/main/java/org/keycloak/storage/federated/UserGroupMembershipFederatedStorage.java
@@ -28,9 +28,9 @@ import java.util.Set;
* @version $Revision: 1 $
*/
public interface UserGroupMembershipFederatedStorage {
- Set<GroupModel> getGroups(RealmModel realm, UserModel user);
- void joinGroup(RealmModel realm,UserModel user, GroupModel group);
- void leaveGroup(RealmModel realm,UserModel user, GroupModel group);
+ Set<GroupModel> getGroups(RealmModel realm, String userId);
+ void joinGroup(RealmModel realm, String userId, GroupModel group);
+ void leaveGroup(RealmModel realm, String userId, GroupModel group);
List<String> getMembership(RealmModel realm, GroupModel group, int firstResult, int max);
}
diff --git a/server-spi/src/main/java/org/keycloak/storage/federated/UserRequiredActionsFederatedStorage.java b/server-spi/src/main/java/org/keycloak/storage/federated/UserRequiredActionsFederatedStorage.java
index 1e14f78..e58c0a0 100644
--- a/server-spi/src/main/java/org/keycloak/storage/federated/UserRequiredActionsFederatedStorage.java
+++ b/server-spi/src/main/java/org/keycloak/storage/federated/UserRequiredActionsFederatedStorage.java
@@ -26,7 +26,7 @@ import java.util.Set;
* @version $Revision: 1 $
*/
public interface UserRequiredActionsFederatedStorage {
- Set<String> getRequiredActions(RealmModel realm, UserModel user);
- void addRequiredAction(RealmModel realm,UserModel user, String action);
- void removeRequiredAction(RealmModel realm,UserModel user, String action);
+ Set<String> getRequiredActions(RealmModel realm, String userId);
+ void addRequiredAction(RealmModel realm, String userId, String action);
+ void removeRequiredAction(RealmModel realm, String userId, String action);
}
diff --git a/server-spi/src/main/java/org/keycloak/storage/federated/UserRoleMappingsFederatedStorage.java b/server-spi/src/main/java/org/keycloak/storage/federated/UserRoleMappingsFederatedStorage.java
index f63d9ec..446898b 100644
--- a/server-spi/src/main/java/org/keycloak/storage/federated/UserRoleMappingsFederatedStorage.java
+++ b/server-spi/src/main/java/org/keycloak/storage/federated/UserRoleMappingsFederatedStorage.java
@@ -28,9 +28,9 @@ import java.util.Set;
*/
public interface UserRoleMappingsFederatedStorage {
- void grantRole(RealmModel realm,UserModel user, RoleModel role);
+ void grantRole(RealmModel realm, String userId, RoleModel role);
- Set<RoleModel> getRoleMappings(RealmModel realm,UserModel user);
+ Set<RoleModel> getRoleMappings(RealmModel realm,String userId);
- void deleteRoleMapping(RealmModel realm, UserModel user, RoleModel role);
+ void deleteRoleMapping(RealmModel realm, String userId, RoleModel role);
}
diff --git a/server-spi/src/main/java/org/keycloak/storage/StorageId.java b/server-spi/src/main/java/org/keycloak/storage/StorageId.java
index e7ada01..97bbc74 100644
--- a/server-spi/src/main/java/org/keycloak/storage/StorageId.java
+++ b/server-spi/src/main/java/org/keycloak/storage/StorageId.java
@@ -75,6 +75,9 @@ public class StorageId implements Serializable {
public static boolean isLocalStorage(UserModel user) {
return new StorageId(user.getId()).getProviderId() == null;
}
+ public static boolean isLocalStorage(String userId) {
+ return new StorageId(userId).getProviderId() == null;
+ }
public String getId() {
return id;
diff --git a/services/src/main/java/org/keycloak/exportimport/dir/DirExportProvider.java b/services/src/main/java/org/keycloak/exportimport/dir/DirExportProvider.java
index 906d246..7efd3f3 100755
--- a/services/src/main/java/org/keycloak/exportimport/dir/DirExportProvider.java
+++ b/services/src/main/java/org/keycloak/exportimport/dir/DirExportProvider.java
@@ -86,6 +86,13 @@ public class DirExportProvider extends MultipleStepsExportProvider {
}
@Override
+ protected void writeFederatedUsers(String fileName, KeycloakSession session, RealmModel realm, List<String> users) throws IOException {
+ File file = new File(this.rootDirectory, fileName);
+ FileOutputStream os = new FileOutputStream(file);
+ ExportUtils.exportFederatedUsersToStream(session, realm, users, JsonSerialization.prettyMapper, os);
+ }
+
+ @Override
public void close() {
}
}
diff --git a/services/src/main/java/org/keycloak/exportimport/dir/DirImportProvider.java b/services/src/main/java/org/keycloak/exportimport/dir/DirImportProvider.java
index 391d9a6..0555218 100755
--- a/services/src/main/java/org/keycloak/exportimport/dir/DirImportProvider.java
+++ b/services/src/main/java/org/keycloak/exportimport/dir/DirImportProvider.java
@@ -115,6 +115,13 @@ public class DirImportProvider implements ImportProvider {
return name.matches(realmName + "-users-[0-9]+\\.json");
}
});
+ File[] federatedUserFiles = this.rootDirectory.listFiles(new FilenameFilter() {
+
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.matches(realmName + "-federated-users-[0-9]+\\.json");
+ }
+ });
// Import realm first
FileInputStream is = new FileInputStream(realmFile);
@@ -143,6 +150,16 @@ public class DirImportProvider implements ImportProvider {
}
});
}
+ for (final File userFile : federatedUserFiles) {
+ final FileInputStream fis = new FileInputStream(userFile);
+ KeycloakModelUtils.runJobInTransaction(factory, new ExportImportSessionTask() {
+ @Override
+ protected void runExportImportTask(KeycloakSession session) throws IOException {
+ ImportUtils.importFederatedUsersFromStream(session, realmName, JsonSerialization.mapper, fis);
+ logger.infof("Imported federated users from %s", userFile.getAbsolutePath());
+ }
+ });
+ }
}
}
diff --git a/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
index ffdec2f..96d514c 100755
--- a/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
+++ b/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
@@ -213,7 +213,7 @@ public class ExportUtils {
// Finally users if needed
if (includeUsers) {
List<UserModel> allUsers = session.users().getUsers(realm, true);
- List<UserRepresentation> users = new ArrayList<UserRepresentation>();
+ List<UserRepresentation> users = new LinkedList<>();
for (UserModel user : allUsers) {
UserRepresentation userRep = exportUser(session, realm, user);
users.add(userRep);
@@ -222,6 +222,16 @@ public class ExportUtils {
if (users.size() > 0) {
rep.setUsers(users);
}
+
+ List<UserRepresentation> federatedUsers = new LinkedList<>();
+ for (String userId : session.userFederatedStorage().getStoredUsers(realm, 0, -1)) {
+ UserRepresentation userRep = exportFederatedUser(session, realm, userId);
+ federatedUsers.add(userRep);
+ }
+ if (federatedUsers.size() > 0) {
+ rep.setFederatedUsers(federatedUsers);
+ }
+
}
// components
@@ -510,7 +520,7 @@ public class ExportUtils {
userRep.setFederationLink(user.getFederationLink());
// Grants
- List<UserConsentModel> consents = session.users().getConsents(realm, user);
+ List<UserConsentModel> consents = session.users().getConsents(realm, user.getId());
LinkedList<UserConsentRepresentation> consentReps = new LinkedList<UserConsentRepresentation>();
for (UserConsentModel consent : consents) {
UserConsentRepresentation consentRep = ModelToRepresentation.toRepresentation(consent);
@@ -558,6 +568,7 @@ public class ExportUtils {
credRep.setDigits(userCred.getDigits());
credRep.setCreatedDate(userCred.getCreatedDate());
credRep.setConfig(userCred.getConfig());
+ credRep.setPeriod(userCred.getPeriod());
return credRep;
}
@@ -587,4 +598,122 @@ public class ExportUtils {
generator.close();
}
}
+
+ public static void exportFederatedUsersToStream(KeycloakSession session, RealmModel realm, List<String> usersToExport, ObjectMapper mapper, OutputStream os) throws IOException {
+ JsonFactory factory = mapper.getFactory();
+ JsonGenerator generator = factory.createGenerator(os, JsonEncoding.UTF8);
+ try {
+ if (mapper.isEnabled(SerializationFeature.INDENT_OUTPUT)) {
+ generator.useDefaultPrettyPrinter();
+ }
+ generator.writeStartObject();
+ generator.writeStringField("realm", realm.getName());
+ // generator.writeStringField("strategy", strategy.toString());
+ generator.writeFieldName("federatedUsers");
+ generator.writeStartArray();
+
+ for (String userId : usersToExport) {
+ UserRepresentation userRep = ExportUtils.exportFederatedUser(session, realm, userId);
+ generator.writeObject(userRep);
+ }
+
+ generator.writeEndArray();
+ generator.writeEndObject();
+ } finally {
+ generator.close();
+ }
+ }
+
+ /**
+ * Full export of user data stored in federated storage (including role mappings and credentials)
+ *
+ * @param id
+ * @return fully exported user representation
+ */
+ public static UserRepresentation exportFederatedUser(KeycloakSession session, RealmModel realm, String id) {
+ UserRepresentation userRep = new UserRepresentation();
+ userRep.setId(id);
+ MultivaluedHashMap<String, String> attributes = session.userFederatedStorage().getAttributes(realm, id);
+ if (attributes.size() > 0) {
+ Map<String, Object> attrs = new HashMap<>();
+ attrs.putAll(attributes);
+ userRep.setAttributes(attrs);
+ }
+
+ Set<String> requiredActions = session.userFederatedStorage().getRequiredActions(realm, id);
+ if (requiredActions.size() > 0) {
+ List<String> actions = new LinkedList<>();
+ actions.addAll(requiredActions);
+ userRep.setRequiredActions(actions);
+ }
+
+
+ // Social links
+ Set<FederatedIdentityModel> socialLinks = session.userFederatedStorage().getFederatedIdentities(id, realm);
+ List<FederatedIdentityRepresentation> socialLinkReps = new ArrayList<FederatedIdentityRepresentation>();
+ for (FederatedIdentityModel socialLink : socialLinks) {
+ FederatedIdentityRepresentation socialLinkRep = exportSocialLink(socialLink);
+ socialLinkReps.add(socialLinkRep);
+ }
+ if (socialLinkReps.size() > 0) {
+ userRep.setFederatedIdentities(socialLinkReps);
+ }
+
+ // Role mappings
+ Set<RoleModel> roles = session.userFederatedStorage().getRoleMappings(realm, id);
+ List<String> realmRoleNames = new ArrayList<>();
+ Map<String, List<String>> clientRoleNames = new HashMap<>();
+ for (RoleModel role : roles) {
+ if (role.getContainer() instanceof RealmModel) {
+ realmRoleNames.add(role.getName());
+ } else {
+ ClientModel client = (ClientModel)role.getContainer();
+ String clientId = client.getClientId();
+ List<String> currentClientRoles = clientRoleNames.get(clientId);
+ if (currentClientRoles == null) {
+ currentClientRoles = new ArrayList<>();
+ clientRoleNames.put(clientId, currentClientRoles);
+ }
+
+ currentClientRoles.add(role.getName());
+ }
+ }
+
+ if (realmRoleNames.size() > 0) {
+ userRep.setRealmRoles(realmRoleNames);
+ }
+ if (clientRoleNames.size() > 0) {
+ userRep.setClientRoles(clientRoleNames);
+ }
+
+ // Credentials
+ List<CredentialModel> creds = session.userFederatedStorage().getStoredCredentials(realm, id);
+ List<CredentialRepresentation> credReps = new ArrayList<CredentialRepresentation>();
+ for (CredentialModel cred : creds) {
+ CredentialRepresentation credRep = exportCredential(cred);
+ credReps.add(credRep);
+ }
+ userRep.setCredentials(credReps);
+
+ // Grants
+ List<UserConsentModel> consents = session.users().getConsents(realm, id);
+ LinkedList<UserConsentRepresentation> consentReps = new LinkedList<UserConsentRepresentation>();
+ for (UserConsentModel consent : consents) {
+ UserConsentRepresentation consentRep = ModelToRepresentation.toRepresentation(consent);
+ consentReps.add(consentRep);
+ }
+ if (consentReps.size() > 0) {
+ userRep.setClientConsents(consentReps);
+ }
+
+
+ List<String> groups = new LinkedList<>();
+ for (GroupModel group : session.userFederatedStorage().getGroups(realm, id)) {
+ groups.add(ModelToRepresentation.buildGroupPath(group));
+ }
+ userRep.setGroups(groups);
+
+ return userRep;
+ }
+
}
diff --git a/services/src/main/java/org/keycloak/exportimport/util/ImportUtils.java b/services/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
index 044e89c..1ea4092 100755
--- a/services/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
+++ b/services/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
@@ -215,6 +215,48 @@ public class ImportUtils {
}
}
+ // Assuming that it's invoked inside transaction
+ public static void importFederatedUsersFromStream(KeycloakSession session, String realmName, ObjectMapper mapper, InputStream is) throws IOException {
+ RealmProvider model = session.realms();
+ JsonFactory factory = mapper.getJsonFactory();
+ JsonParser parser = factory.createJsonParser(is);
+ try {
+ parser.nextToken();
+
+ while (parser.nextToken() == JsonToken.FIELD_NAME) {
+ if ("realm".equals(parser.getText())) {
+ parser.nextToken();
+ String currRealmName = parser.getText();
+ if (!currRealmName.equals(realmName)) {
+ throw new IllegalStateException("Trying to import users into invalid realm. Realm name: " + realmName + ", Expected realm name: " + currRealmName);
+ }
+ } else if ("federatedUsers".equals(parser.getText())) {
+ parser.nextToken();
+
+ if (parser.getCurrentToken() == JsonToken.START_ARRAY) {
+ parser.nextToken();
+ }
+
+ // TODO: support for more transactions per single users file (if needed)
+ List<UserRepresentation> userReps = new ArrayList<UserRepresentation>();
+ while (parser.getCurrentToken() == JsonToken.START_OBJECT) {
+ UserRepresentation user = parser.readValueAs(UserRepresentation.class);
+ userReps.add(user);
+ parser.nextToken();
+ }
+
+ importFederatedUsers(session, model, realmName, userReps);
+
+ if (parser.getCurrentToken() == JsonToken.END_ARRAY) {
+ parser.nextToken();
+ }
+ }
+ }
+ } finally {
+ parser.close();
+ }
+ }
+
private static void importUsers(KeycloakSession session, RealmProvider model, String realmName, List<UserRepresentation> userReps) {
RealmModel realm = model.getRealmByName(realmName);
for (UserRepresentation user : userReps) {
@@ -222,4 +264,13 @@ public class ImportUtils {
}
}
+
+ private static void importFederatedUsers(KeycloakSession session, RealmProvider model, String realmName, List<UserRepresentation> userReps) {
+ RealmModel realm = model.getRealmByName(realmName);
+ for (UserRepresentation user : userReps) {
+ RepresentationToModel.importFederatedUser(session, realm, user);
+ }
+ }
+
+
}
diff --git a/services/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java b/services/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java
index 4537169..e1038c1 100755
--- a/services/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java
+++ b/services/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java
@@ -68,6 +68,7 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
final int usersPerFile = ExportImportConfig.getUsersPerFile();
final UsersHolder usersHolder = new UsersHolder();
final boolean exportUsersIntoRealmFile = usersExportStrategy == UsersExportStrategy.REALM_FILE;
+ FederatedUsersHolder federatedUsersHolder = new FederatedUsersHolder();
KeycloakModelUtils.runJobInTransaction(factory, new ExportImportSessionTask() {
@@ -81,6 +82,7 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
// Count total number of users
if (!exportUsersIntoRealmFile) {
usersHolder.totalCount = session.users().getUsersCount(realm);
+ federatedUsersHolder.totalCount = session.userFederatedStorage().getStoredUsersCount(realm);
}
}
@@ -117,11 +119,43 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
usersHolder.currentPageStart = usersHolder.currentPageEnd;
}
}
+ if (usersExportStrategy != UsersExportStrategy.SKIP && !exportUsersIntoRealmFile) {
+ // We need to export users now
+ federatedUsersHolder.currentPageStart = 0;
+
+ // usersExportStrategy==SAME_FILE means exporting all users into single file (but separate to realm)
+ final int countPerPage = (usersExportStrategy == UsersExportStrategy.SAME_FILE) ? federatedUsersHolder.totalCount : usersPerFile;
+
+ while (federatedUsersHolder.currentPageStart < federatedUsersHolder.totalCount) {
+ if (federatedUsersHolder.currentPageStart + countPerPage < federatedUsersHolder.totalCount) {
+ federatedUsersHolder.currentPageEnd = federatedUsersHolder.currentPageStart + countPerPage;
+ } else {
+ federatedUsersHolder.currentPageEnd = federatedUsersHolder.totalCount;
+ }
+
+ KeycloakModelUtils.runJobInTransaction(factory, new ExportImportSessionTask() {
+
+ @Override
+ protected void runExportImportTask(KeycloakSession session) throws IOException {
+ RealmModel realm = session.realms().getRealmByName(realmName);
+ federatedUsersHolder.users = session.userFederatedStorage().getStoredUsers(realm, federatedUsersHolder.currentPageStart, federatedUsersHolder.currentPageEnd - federatedUsersHolder.currentPageStart);
+
+ writeFederatedUsers(realmName + "-federated-users-" + (federatedUsersHolder.currentPageStart / countPerPage) + ".json", session, realm, federatedUsersHolder.users);
+
+ logger.info("Users " + federatedUsersHolder.currentPageStart + "-" + (federatedUsersHolder.currentPageEnd -1) + " exported");
+ }
+
+ });
+
+ federatedUsersHolder.currentPageStart = federatedUsersHolder.currentPageEnd;
+ }
+ }
}
protected abstract void writeRealm(String fileName, RealmRepresentation rep) throws IOException;
protected abstract void writeUsers(String fileName, KeycloakSession session, RealmModel realm, List<UserModel> users) throws IOException;
+ protected abstract void writeFederatedUsers(String fileName, KeycloakSession session, RealmModel realm, List<String> users) throws IOException;
public static class RealmsHolder {
List<RealmModel> realms;
@@ -134,4 +168,10 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
int currentPageStart;
int currentPageEnd;
}
+ public static class FederatedUsersHolder {
+ List<String> users;
+ int totalCount;
+ int currentPageStart;
+ int currentPageEnd;
+ }
}
diff --git a/services/src/main/java/org/keycloak/forms/account/freemarker/model/ApplicationsBean.java b/services/src/main/java/org/keycloak/forms/account/freemarker/model/ApplicationsBean.java
index 82d7fb3..de5fd93 100755
--- a/services/src/main/java/org/keycloak/forms/account/freemarker/model/ApplicationsBean.java
+++ b/services/src/main/java/org/keycloak/forms/account/freemarker/model/ApplicationsBean.java
@@ -64,7 +64,7 @@ public class ApplicationsBean {
MultivaluedHashMap<String, ClientRoleEntry> resourceRolesGranted = new MultivaluedHashMap<String, ClientRoleEntry>();
List<String> claimsGranted = new LinkedList<String>();
if (client.isConsentRequired()) {
- UserConsentModel consent = session.users().getConsentByClient(realm, user, client.getId());
+ UserConsentModel consent = session.users().getConsentByClient(realm, user.getId(), client.getId());
if (consent != null) {
processRoles(consent.getGrantedRoles(), realmRolesGranted, resourceRolesGranted);
diff --git a/services/src/main/java/org/keycloak/services/DefaultKeycloakContext.java b/services/src/main/java/org/keycloak/services/DefaultKeycloakContext.java
index f58f4ca..99f2559 100755
--- a/services/src/main/java/org/keycloak/services/DefaultKeycloakContext.java
+++ b/services/src/main/java/org/keycloak/services/DefaultKeycloakContext.java
@@ -61,6 +61,7 @@ public class DefaultKeycloakContext implements KeycloakContext {
@Override
public String getContextPath() {
KeycloakApplication app = getContextObject(KeycloakApplication.class);
+ if (app == null) return null;
return app.getContextPath();
}
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index 35636ea..d0eb66b 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -491,7 +491,7 @@ public class AuthenticationManager {
if (client.isConsentRequired()) {
- UserConsentModel grantedConsent = session.users().getConsentByClient(realm, user, client.getId());
+ UserConsentModel grantedConsent = session.users().getConsentByClient(realm, user.getId(), client.getId());
ClientSessionCode accessCode = new ClientSessionCode(session, realm, clientSession);
for (RoleModel r : accessCode.getRequestedRoles()) {
@@ -545,7 +545,7 @@ public class AuthenticationManager {
if (client.isConsentRequired()) {
- UserConsentModel grantedConsent = session.users().getConsentByClient(realm, user, client.getId());
+ UserConsentModel grantedConsent = session.users().getConsentByClient(realm, user.getId(), client.getId());
List<RoleModel> realmRoles = new LinkedList<>();
MultivaluedMap<String, RoleModel> resourceRoles = new MultivaluedMapImpl<>();
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index bb3bb11..2684483 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -496,7 +496,7 @@ public class AccountService extends AbstractSecuredLocalService {
// Revoke grant in UserModel
UserModel user = auth.getUser();
- session.users().revokeConsentForClient(realm, user, client.getId());
+ session.users().revokeConsentForClient(realm, user.getId(), client.getId());
new UserSessionManager(session).revokeOfflineToken(user, client);
// Logout clientSessions for this user and client
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
index 9ef005d..f76761f 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
@@ -525,7 +525,7 @@ public class UsersResource {
Set<ClientModel> offlineClients = new UserSessionManager(session).findClientsWithOfflineToken(realm, user);
for (ClientModel client : realm.getClients()) {
- UserConsentModel consent = session.users().getConsentByClient(realm, user, client.getId());
+ UserConsentModel consent = session.users().getConsentByClient(realm, user.getId(), client.getId());
boolean hasOfflineToken = offlineClients.contains(client);
if (consent == null && !hasOfflineToken) {
@@ -576,7 +576,7 @@ public class UsersResource {
}
ClientModel client = realm.getClientByClientId(clientId);
- boolean revokedConsent = session.users().revokeConsentForClient(realm, user, client.getId());
+ boolean revokedConsent = session.users().revokeConsentForClient(realm, user.getId(), client.getId());
boolean revokedOfflineToken = new UserSessionManager(session).revokeOfflineToken(user, client);
if (revokedConsent) {
diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
index b22e792..2e2641c 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -667,10 +667,10 @@ public class LoginActionsService {
return response;
}
- UserConsentModel grantedConsent = session.users().getConsentByClient(realm, user, client.getId());
+ UserConsentModel grantedConsent = session.users().getConsentByClient(realm, user.getId(), client.getId());
if (grantedConsent == null) {
grantedConsent = new UserConsentModel(client);
- session.users().addConsent(realm, user, grantedConsent);
+ session.users().addConsent(realm, user.getId(), grantedConsent);
}
for (RoleModel role : accessCode.getRequestedRoles()) {
grantedConsent.addGrantedRole(role);
@@ -680,7 +680,7 @@ public class LoginActionsService {
grantedConsent.addGrantedProtocolMapper(protocolMapper);
}
}
- session.users().updateConsent(realm, user, grantedConsent);
+ session.users().updateConsent(realm, user.getId(), grantedConsent);
event.detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED);
event.success();
diff --git a/services/src/main/java/org/keycloak/storage/UserStorageManager.java b/services/src/main/java/org/keycloak/storage/UserStorageManager.java
index 995043a..8394bbb 100755
--- a/services/src/main/java/org/keycloak/storage/UserStorageManager.java
+++ b/services/src/main/java/org/keycloak/storage/UserStorageManager.java
@@ -157,7 +157,7 @@ public class UserStorageManager implements UserProvider, OnUserCache {
if (StorageId.isLocalStorage(user)) {
localStorage().addFederatedIdentity(realm, user, socialLink);
} else {
- getFederatedStorage().addFederatedIdentity(realm, user, socialLink);
+ getFederatedStorage().addFederatedIdentity(realm, user.getId(), socialLink);
}
}
@@ -166,7 +166,7 @@ public class UserStorageManager implements UserProvider, OnUserCache {
localStorage().updateFederatedIdentity(realm, federatedUser, federatedIdentityModel);
} else {
- getFederatedStorage().updateFederatedIdentity(realm, federatedUser, federatedIdentityModel);
+ getFederatedStorage().updateFederatedIdentity(realm, federatedUser.getId(), federatedIdentityModel);
}
}
@@ -175,55 +175,55 @@ public class UserStorageManager implements UserProvider, OnUserCache {
if (StorageId.isLocalStorage(user)) {
return localStorage().removeFederatedIdentity(realm, user, socialProvider);
} else {
- return getFederatedStorage().removeFederatedIdentity(realm, user, socialProvider);
+ return getFederatedStorage().removeFederatedIdentity(realm, user.getId(), socialProvider);
}
}
@Override
- public void addConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
- if (StorageId.isLocalStorage(user)) {
- localStorage().addConsent(realm, user, consent);
+ public void addConsent(RealmModel realm, String userId, UserConsentModel consent) {
+ if (StorageId.isLocalStorage(userId)) {
+ localStorage().addConsent(realm, userId, consent);
} else {
- getFederatedStorage().addConsent(realm, user, consent);
+ getFederatedStorage().addConsent(realm, userId, consent);
}
}
@Override
- public UserConsentModel getConsentByClient(RealmModel realm, UserModel user, String clientInternalId) {
- if (StorageId.isLocalStorage(user)) {
- return localStorage().getConsentByClient(realm, user, clientInternalId);
+ public UserConsentModel getConsentByClient(RealmModel realm, String userId, String clientInternalId) {
+ if (StorageId.isLocalStorage(userId)) {
+ return localStorage().getConsentByClient(realm, userId, clientInternalId);
} else {
- return getFederatedStorage().getConsentByClient(realm, user, clientInternalId);
+ return getFederatedStorage().getConsentByClient(realm, userId, clientInternalId);
}
}
@Override
- public List<UserConsentModel> getConsents(RealmModel realm, UserModel user) {
- if (StorageId.isLocalStorage(user)) {
- return localStorage().getConsents(realm, user);
+ public List<UserConsentModel> getConsents(RealmModel realm, String userId) {
+ if (StorageId.isLocalStorage(userId)) {
+ return localStorage().getConsents(realm, userId);
} else {
- return getFederatedStorage().getConsents(realm, user);
+ return getFederatedStorage().getConsents(realm, userId);
}
}
@Override
- public void updateConsent(RealmModel realm, UserModel user, UserConsentModel consent) {
- if (StorageId.isLocalStorage(user)) {
- localStorage().updateConsent(realm, user, consent);
+ public void updateConsent(RealmModel realm, String userId, UserConsentModel consent) {
+ if (StorageId.isLocalStorage(userId)) {
+ localStorage().updateConsent(realm, userId, consent);
} else {
- getFederatedStorage().updateConsent(realm, user, consent);
+ getFederatedStorage().updateConsent(realm, userId, consent);
}
}
@Override
- public boolean revokeConsentForClient(RealmModel realm, UserModel user, String clientInternalId) {
- if (StorageId.isLocalStorage(user)) {
- return localStorage().revokeConsentForClient(realm, user, clientInternalId);
+ public boolean revokeConsentForClient(RealmModel realm, String userId, String clientInternalId) {
+ if (StorageId.isLocalStorage(userId)) {
+ return localStorage().revokeConsentForClient(realm, userId, clientInternalId);
} else {
- return getFederatedStorage().revokeConsentForClient(realm, user, clientInternalId);
+ return getFederatedStorage().revokeConsentForClient(realm, userId, clientInternalId);
}
}
@@ -466,7 +466,7 @@ public class UserStorageManager implements UserProvider, OnUserCache {
if (StorageId.isLocalStorage(user)) {
set.addAll(localStorage().getFederatedIdentities(user, realm));
}
- if (getFederatedStorage() != null) set.addAll(getFederatedStorage().getFederatedIdentities(user, realm));
+ if (getFederatedStorage() != null) set.addAll(getFederatedStorage().getFederatedIdentities(user.getId(), realm));
return set;
}
@@ -477,7 +477,7 @@ public class UserStorageManager implements UserProvider, OnUserCache {
FederatedIdentityModel model = localStorage().getFederatedIdentity(user, socialProvider, realm);
if (model != null) return model;
}
- if (getFederatedStorage() != null) return getFederatedStorage().getFederatedIdentity(user, socialProvider, realm);
+ if (getFederatedStorage() != null) return getFederatedStorage().getFederatedIdentity(user.getId(), socialProvider, realm);
else return null;
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/FederatedStorageExportImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/FederatedStorageExportImportTest.java
new file mode 100644
index 0000000..2591c77
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/storage/FederatedStorageExportImportTest.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2016 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.testsuite.federation.storage;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.keycloak.OAuth2Constants;
+import org.keycloak.common.util.MultivaluedHashMap;
+import org.keycloak.component.ComponentModel;
+import org.keycloak.credential.CredentialModel;
+import org.keycloak.credential.hash.PasswordHashProvider;
+import org.keycloak.exportimport.ExportImportConfig;
+import org.keycloak.exportimport.ExportImportManager;
+import org.keycloak.exportimport.UsersExportStrategy;
+import org.keycloak.exportimport.dir.DirExportProviderFactory;
+import org.keycloak.exportimport.singlefile.SingleFileExportProviderFactory;
+import org.keycloak.models.GroupModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.PasswordPolicy;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.cache.infinispan.UserAdapter;
+import org.keycloak.policy.HashAlgorithmPasswordPolicyProviderFactory;
+import org.keycloak.services.managers.RealmManager;
+import org.keycloak.storage.StorageId;
+import org.keycloak.storage.UserStorageProviderModel;
+import org.keycloak.testsuite.OAuthClient;
+import org.keycloak.testsuite.pages.AppPage;
+import org.keycloak.testsuite.pages.LoginPage;
+import org.keycloak.testsuite.rule.KeycloakRule;
+import org.keycloak.testsuite.rule.WebResource;
+import org.keycloak.testsuite.rule.WebRule;
+import org.openqa.selenium.WebDriver;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class FederatedStorageExportImportTest {
+ public static ComponentModel memoryProvider = null;
+ public static ComponentModel writableProvider = null;
+ @ClassRule
+ public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
+
+ @Override
+ public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
+
+ }
+ });
+
+ public static String basePath = null;
+
+ @BeforeClass
+ public static void setDirs() {
+ basePath = new File(System.getProperty("project.build.directory", "target")).getAbsolutePath();
+
+ }
+
+ protected PasswordHashProvider getHashProvider(KeycloakSession session, PasswordPolicy policy) {
+ PasswordHashProvider hash = session.getProvider(PasswordHashProvider.class, policy.getHashAlgorithm());
+ if (hash == null) {
+ return session.getProvider(PasswordHashProvider.class, HashAlgorithmPasswordPolicyProviderFactory.DEFAULT_VALUE);
+ }
+ return hash;
+ }
+
+
+ @Test
+ public void testSingleFile() throws Exception {
+ clearExportImportProperties();
+ KeycloakSession session = keycloakRule.startSession();
+ RealmModel realm = new RealmManager(session).createRealm("exported");
+ String realmId = realm.getId();
+ RoleModel role = realm.addRole("test-role");
+ GroupModel group = realm.createGroup("test-group");
+ String groupId = group.getId();
+ String userId = "f:1:path";
+ List<String> attrValues = new LinkedList<>();
+ attrValues.add("1");
+ attrValues.add("2");
+ session.userFederatedStorage().setSingleAttribute(realm, userId, "single1", "value1");
+ session.userFederatedStorage().setAttribute(realm, userId, "list1", attrValues);
+ session.userFederatedStorage().addRequiredAction(realm, userId, "UPDATE_PASSWORD");
+ CredentialModel credential = new CredentialModel();
+ getHashProvider(session, realm.getPasswordPolicy()).encode("password", realm.
+ getPasswordPolicy(), credential);
+ session.userFederatedStorage().createCredential(realm, userId, credential);
+ session.userFederatedStorage().grantRole(realm, userId, role);
+ session.userFederatedStorage().joinGroup(realm, userId, group);
+ keycloakRule.stopSession(session, true);
+
+
+
+
+ String targetFilePath = basePath + File.separator + "singleFile-full.json";
+ System.out.println("export file: " + targetFilePath);
+ session = keycloakRule.startSession();
+ ExportImportConfig.setProvider(SingleFileExportProviderFactory.PROVIDER_ID);
+ ExportImportConfig.setFile(targetFilePath);
+ ExportImportConfig.setRealmName("exported");
+ ExportImportConfig.setAction(ExportImportConfig.ACTION_EXPORT);
+ new ExportImportManager(session).runExport();
+ session.realms().removeRealm(realmId);
+ keycloakRule.stopSession(session, true);
+
+ session = keycloakRule.startSession();
+ Assert.assertNull(session.realms().getRealmByName("exported"));
+ ExportImportConfig.setAction(ExportImportConfig.ACTION_IMPORT);
+ new ExportImportManager(session).runImport();
+ realm = session.realms().getRealmByName("exported");
+ Assert.assertNotNull(realm);
+ role = realm.getRole("test-role");
+ group = realm.getGroupById(groupId);
+
+ Assert.assertEquals(1, session.userFederatedStorage().getStoredUsersCount(realm));
+ MultivaluedHashMap<String, String> attributes = session.userFederatedStorage().getAttributes(realm, userId);
+ Assert.assertEquals(2, attributes.size());
+ Assert.assertEquals("value1", attributes.getFirst("single1"));
+ Assert.assertTrue(attributes.getList("list1").contains("1"));
+ Assert.assertTrue(attributes.getList("list1").contains("2"));
+ Assert.assertTrue(session.userFederatedStorage().getRequiredActions(realm, userId).contains("UPDATE_PASSWORD"));
+ Assert.assertTrue(session.userFederatedStorage().getRoleMappings(realm, userId).contains(role));
+ Assert.assertTrue(session.userFederatedStorage().getGroups(realm, userId).contains(group));
+ List<CredentialModel> creds = session.userFederatedStorage().getStoredCredentials(realm, userId);
+ Assert.assertEquals(1, creds.size());
+ Assert.assertTrue(getHashProvider(session, realm.getPasswordPolicy()).verify("password", creds.get(0)));
+ session.realms().removeRealm(realmId);
+ keycloakRule.stopSession(session, true);
+
+ }
+
+ @Test
+ public void testDir() throws Exception {
+ clearExportImportProperties();
+ KeycloakSession session = keycloakRule.startSession();
+ RealmModel realm = new RealmManager(session).createRealm("exported");
+ String realmId = realm.getId();
+ RoleModel role = realm.addRole("test-role");
+ GroupModel group = realm.createGroup("test-group");
+ String groupId = group.getId();
+ String userId = "f:1:path";
+ List<String> attrValues = new LinkedList<>();
+ attrValues.add("1");
+ attrValues.add("2");
+ session.userFederatedStorage().setSingleAttribute(realm, userId, "single1", "value1");
+ session.userFederatedStorage().setAttribute(realm, userId, "list1", attrValues);
+ session.userFederatedStorage().addRequiredAction(realm, userId, "UPDATE_PASSWORD");
+ CredentialModel credential = new CredentialModel();
+ getHashProvider(session, realm.getPasswordPolicy()).encode("password", realm.
+ getPasswordPolicy(), credential);
+ session.userFederatedStorage().createCredential(realm, userId, credential);
+ session.userFederatedStorage().grantRole(realm, userId, role);
+ session.userFederatedStorage().joinGroup(realm, userId, group);
+ keycloakRule.stopSession(session, true);
+
+
+
+
+ String targetFilePath = basePath + File.separator + "dirExport";
+ session = keycloakRule.startSession();
+ ExportImportConfig.setProvider(DirExportProviderFactory.PROVIDER_ID);
+ ExportImportConfig.setDir(targetFilePath);
+ ExportImportConfig.setRealmName("exported");
+ ExportImportConfig.setAction(ExportImportConfig.ACTION_EXPORT);
+ new ExportImportManager(session).runExport();
+ session.realms().removeRealm(realmId);
+ keycloakRule.stopSession(session, true);
+
+ session = keycloakRule.startSession();
+ Assert.assertNull(session.realms().getRealmByName("exported"));
+ ExportImportConfig.setAction(ExportImportConfig.ACTION_IMPORT);
+ new ExportImportManager(session).runImport();
+ realm = session.realms().getRealmByName("exported");
+ Assert.assertNotNull(realm);
+ role = realm.getRole("test-role");
+ group = realm.getGroupById(groupId);
+
+ Assert.assertEquals(1, session.userFederatedStorage().getStoredUsersCount(realm));
+ MultivaluedHashMap<String, String> attributes = session.userFederatedStorage().getAttributes(realm, userId);
+ Assert.assertEquals(2, attributes.size());
+ Assert.assertEquals("value1", attributes.getFirst("single1"));
+ Assert.assertTrue(attributes.getList("list1").contains("1"));
+ Assert.assertTrue(attributes.getList("list1").contains("2"));
+ Assert.assertTrue(session.userFederatedStorage().getRequiredActions(realm, userId).contains("UPDATE_PASSWORD"));
+ Assert.assertTrue(session.userFederatedStorage().getRoleMappings(realm, userId).contains(role));
+ Assert.assertTrue(session.userFederatedStorage().getGroups(realm, userId).contains(group));
+ List<CredentialModel> creds = session.userFederatedStorage().getStoredCredentials(realm, userId);
+ Assert.assertEquals(1, creds.size());
+ Assert.assertTrue(getHashProvider(session, realm.getPasswordPolicy()).verify("password", creds.get(0)));
+ session.realms().removeRealm(realmId);
+ keycloakRule.stopSession(session, true);
+
+ }
+
+ public void clearExportImportProperties() {
+ // Clear export/import properties after test
+ Properties systemProps = System.getProperties();
+ Set<String> propsToRemove = new HashSet<String>();
+
+ for (Object key : systemProps.keySet()) {
+ if (key.toString().startsWith(ExportImportConfig.PREFIX)) {
+ propsToRemove.add(key.toString());
+ }
+ }
+
+ for (String propToRemove : propsToRemove) {
+ systemProps.remove(propToRemove);
+ }
+ }
+
+
+
+
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
index dedc8d1..98c7437 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
@@ -357,15 +357,15 @@ public class ImportTest extends AbstractModelTest {
// Test user consents
admin = session.users().getUserByUsername("admin", realm);
- Assert.assertEquals(2, session.users().getConsents(realm, admin).size());
+ Assert.assertEquals(2, session.users().getConsents(realm, admin.getId()).size());
- UserConsentModel appAdminConsent = session.users().getConsentByClient(realm, admin, application.getId());
+ UserConsentModel appAdminConsent = session.users().getConsentByClient(realm, admin.getId(), application.getId());
Assert.assertEquals(2, appAdminConsent.getGrantedRoles().size());
Assert.assertTrue(appAdminConsent.getGrantedProtocolMappers() == null || appAdminConsent.getGrantedProtocolMappers().isEmpty());
Assert.assertTrue(appAdminConsent.isRoleGranted(realm.getRole("admin")));
Assert.assertTrue(appAdminConsent.isRoleGranted(application.getRole("app-admin")));
- UserConsentModel otherAppAdminConsent = session.users().getConsentByClient(realm, admin, otherApp.getId());
+ UserConsentModel otherAppAdminConsent = session.users().getConsentByClient(realm, admin.getId(), otherApp.getId());
Assert.assertEquals(1, otherAppAdminConsent.getGrantedRoles().size());
Assert.assertEquals(1, otherAppAdminConsent.getGrantedProtocolMappers().size());
Assert.assertTrue(otherAppAdminConsent.isRoleGranted(realm.getRole("admin")));
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserConsentModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserConsentModelTest.java
index c65fee1..9fe49f2 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserConsentModelTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserConsentModelTest.java
@@ -67,7 +67,7 @@ public class UserConsentModelTest extends AbstractModelTest {
johnFooGrant.addGrantedRole(realmRole);
johnFooGrant.addGrantedRole(barClientRole);
johnFooGrant.addGrantedProtocolMapper(fooMapper);
- realmManager.getSession().users().addConsent(realm, john, johnFooGrant);
+ realmManager.getSession().users().addConsent(realm, john.getId(), johnFooGrant);
UserConsentModel johnBarGrant = new UserConsentModel(barClient);
johnBarGrant.addGrantedProtocolMapper(barMapper);
@@ -75,17 +75,17 @@ public class UserConsentModelTest extends AbstractModelTest {
// Update should fail as grant doesn't yet exists
try {
- realmManager.getSession().users().updateConsent(realm, john, johnBarGrant);
+ realmManager.getSession().users().updateConsent(realm, john.getId(), johnBarGrant);
Assert.fail("Not expected to end here");
} catch (ModelException expected) {
}
- realmManager.getSession().users().addConsent(realm, john, johnBarGrant);
+ realmManager.getSession().users().addConsent(realm, john.getId(), johnBarGrant);
UserConsentModel maryFooGrant = new UserConsentModel(fooClient);
maryFooGrant.addGrantedRole(realmRole);
maryFooGrant.addGrantedProtocolMapper(fooMapper);
- realmManager.getSession().users().addConsent(realm, mary, maryFooGrant);
+ realmManager.getSession().users().addConsent(realm, mary.getId(), maryFooGrant);
commit();
}
@@ -99,7 +99,7 @@ public class UserConsentModelTest extends AbstractModelTest {
UserModel john = session.users().getUserByUsername("john", realm);
UserModel mary = session.users().getUserByUsername("mary", realm);
- UserConsentModel johnFooConsent = realmManager.getSession().users().getConsentByClient(realm, john, fooClient.getId());
+ UserConsentModel johnFooConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
Assert.assertEquals(johnFooConsent.getGrantedRoles().size(), 2);
Assert.assertEquals(johnFooConsent.getGrantedProtocolMappers().size(), 1);
Assert.assertTrue(isRoleGranted(realm, "realm-role", johnFooConsent));
@@ -108,7 +108,7 @@ public class UserConsentModelTest extends AbstractModelTest {
Assert.assertNotNull("Created Date should be set", johnFooConsent.getCreatedDate());
Assert.assertNotNull("Last Updated Date should be set", johnFooConsent.getLastUpdatedDate());
- UserConsentModel johnBarConsent = realmManager.getSession().users().getConsentByClient(realm, john, barClient.getId());
+ UserConsentModel johnBarConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), barClient.getId());
Assert.assertEquals(johnBarConsent.getGrantedRoles().size(), 1);
Assert.assertEquals(johnBarConsent.getGrantedProtocolMappers().size(), 1);
Assert.assertTrue(isRoleGranted(realm, "realm-role", johnBarConsent));
@@ -116,7 +116,7 @@ public class UserConsentModelTest extends AbstractModelTest {
Assert.assertNotNull("Created Date should be set", johnBarConsent.getCreatedDate());
Assert.assertNotNull("Last Updated Date should be set", johnBarConsent.getLastUpdatedDate());
- UserConsentModel maryConsent = realmManager.getSession().users().getConsentByClient(realm, mary, fooClient.getId());
+ UserConsentModel maryConsent = realmManager.getSession().users().getConsentByClient(realm, mary.getId(), fooClient.getId());
Assert.assertEquals(maryConsent.getGrantedRoles().size(), 1);
Assert.assertEquals(maryConsent.getGrantedProtocolMappers().size(), 1);
Assert.assertTrue(isRoleGranted(realm, "realm-role", maryConsent));
@@ -125,7 +125,7 @@ public class UserConsentModelTest extends AbstractModelTest {
Assert.assertNotNull("Created Date should be set", maryConsent.getCreatedDate());
Assert.assertNotNull("Last Updated Date should be set", maryConsent.getLastUpdatedDate());
- Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, mary, barClient.getId()));
+ Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, mary.getId(), barClient.getId()));
}
@Test
@@ -136,10 +136,10 @@ public class UserConsentModelTest extends AbstractModelTest {
UserModel john = session.users().getUserByUsername("john", realm);
UserModel mary = session.users().getUserByUsername("mary", realm);
- List<UserConsentModel> johnConsents = realmManager.getSession().users().getConsents(realm, john);
+ List<UserConsentModel> johnConsents = realmManager.getSession().users().getConsents(realm, john.getId());
Assert.assertEquals(2, johnConsents.size());
- List<UserConsentModel> maryConsents = realmManager.getSession().users().getConsents(realm, mary);
+ List<UserConsentModel> maryConsents = realmManager.getSession().users().getConsents(realm, mary.getId());
Assert.assertEquals(1, maryConsents.size());
UserConsentModel maryConsent = maryConsents.get(0);
Assert.assertEquals(maryConsent.getClient().getId(), fooClient.getId());
@@ -155,7 +155,7 @@ public class UserConsentModelTest extends AbstractModelTest {
ClientModel fooClient = realm.getClientByClientId("foo-client");
UserModel john = session.users().getUserByUsername("john", realm);
- UserConsentModel johnConsent = realmManager.getSession().users().getConsentByClient(realm, john, fooClient.getId());
+ UserConsentModel johnConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
// Remove foo protocol mapper from johnConsent
ProtocolMapperModel protMapperModel = fooClient.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "foo");
@@ -168,14 +168,14 @@ public class UserConsentModelTest extends AbstractModelTest {
RoleModel newRealmRole = realm.addRole("new-realm-role");
johnConsent.addGrantedRole(newRealmRole);
- realmManager.getSession().users().updateConsent(realm, john, johnConsent);
+ realmManager.getSession().users().updateConsent(realm, john.getId(), johnConsent);
commit();
realm = realmManager.getRealm("original");
fooClient = realm.getClientByClientId("foo-client");
john = session.users().getUserByUsername("john", realm);
- johnConsent = realmManager.getSession().users().getConsentByClient(realm, john, fooClient.getId());
+ johnConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
Assert.assertEquals(johnConsent.getGrantedRoles().size(), 2);
Assert.assertEquals(johnConsent.getGrantedProtocolMappers().size(), 0);
@@ -191,13 +191,13 @@ public class UserConsentModelTest extends AbstractModelTest {
ClientModel fooClient = realm.getClientByClientId("foo-client");
UserModel john = session.users().getUserByUsername("john", realm);
- realmManager.getSession().users().revokeConsentForClient(realm, john, fooClient.getId());
+ realmManager.getSession().users().revokeConsentForClient(realm, john.getId(), fooClient.getId());
commit();
realm = realmManager.getRealm("original");
john = session.users().getUserByUsername("john", realm);
- Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john, fooClient.getId()));
+ Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId()));
}
@Test
@@ -220,7 +220,7 @@ public class UserConsentModelTest extends AbstractModelTest {
realm = realmManager.getRealm("original");
fooClient = realm.getClientByClientId("foo-client");
UserModel john = session.users().getUserByUsername("john", realm);
- UserConsentModel johnConsent = realmManager.getSession().users().getConsentByClient(realm, john, fooClient.getId());
+ UserConsentModel johnConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
Assert.assertEquals(johnConsent.getGrantedRoles().size(), 2);
Assert.assertEquals(johnConsent.getGrantedProtocolMappers().size(), 0);
@@ -239,7 +239,7 @@ public class UserConsentModelTest extends AbstractModelTest {
ClientModel fooClient = realm.getClientByClientId("foo-client");
ClientModel barClient = realm.getClientByClientId("bar-client");
UserModel john = session.users().getUserByUsername("john", realm);
- UserConsentModel johnConsent = realmManager.getSession().users().getConsentByClient(realm, john, fooClient.getId());
+ UserConsentModel johnConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
Assert.assertEquals(johnConsent.getGrantedRoles().size(), 1);
Assert.assertEquals(johnConsent.getGrantedProtocolMappers().size(), 1);
@@ -261,13 +261,13 @@ public class UserConsentModelTest extends AbstractModelTest {
UserModel john = session.users().getUserByUsername("john", realm);
- UserConsentModel johnFooConsent = realmManager.getSession().users().getConsentByClient(realm, john, fooClient.getId());
+ UserConsentModel johnFooConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
Assert.assertEquals(johnFooConsent.getGrantedRoles().size(), 1);
Assert.assertEquals(johnFooConsent.getGrantedProtocolMappers().size(), 1);
Assert.assertTrue(isRoleGranted(realm, "realm-role", johnFooConsent));
Assert.assertTrue(isMapperGranted(fooClient, "foo", johnFooConsent));
- Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john, barClient.getId()));
+ Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), barClient.getId()));
}
private boolean isRoleGranted(RoleContainerModel roleContainer, String roleName, UserConsentModel consentModel) {