federated import/export

This commit is contained in:
Bill Burke 2016-10-18 10:13:51 -04:00
parent acdc33b2fa
commit 4182e4d92a
35 changed files with 1077 additions and 349 deletions

View file

@ -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;
}
}

View file

@ -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;

View file

@ -193,17 +193,17 @@ 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 + "]");
}
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);
em.persist(consentEntity);
em.flush();
@ -212,15 +212,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>();
@ -232,19 +232,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);
@ -253,13 +253,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 {

View file

@ -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,11 +720,54 @@ 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")

View file

@ -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"),

View file

@ -518,31 +518,31 @@ 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 + "]");
}
MongoUserConsentEntity consentEntity = new MongoUserConsentEntity();
consentEntity.setUserId(user.getId());
consentEntity.setUserId(userId);
consentEntity.setClientId(clientId);
fillEntityFromModel(consent, consentEntity);
getMongoStore().insertEntity(consentEntity, invocationContext);
}
@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);
@ -554,9 +554,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);
@ -599,11 +599,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);
@ -611,8 +611,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;
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);

View file

@ -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) {
@ -2186,4 +2220,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);
}
}
}

View file

@ -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;

View file

@ -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);
}
@ -182,7 +182,7 @@ public abstract class AbstractUserAdapterFederatedStorage implements UserModel {
@Override
public void grantRole(RoleModel role) {
getFederatedStorage().grantRole(realm, this, role);
getFederatedStorage().grantRole(realm, this.getId(), role);
}
@ -211,12 +211,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);
}
@ -306,35 +306,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

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -85,6 +85,13 @@ public class DirExportProvider extends MultipleStepsExportProvider {
ExportUtils.exportUsersToStream(session, realm, users, JsonSerialization.prettyMapper, os);
}
@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() {
}

View file

@ -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());
}
});
}
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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();
}

View file

@ -492,7 +492,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()) {
@ -546,7 +546,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<>();

View file

@ -495,7 +495,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

View file

@ -666,10 +666,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);
@ -679,7 +679,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();

View file

@ -524,7 +524,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) {
@ -573,7 +573,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) {

View file

@ -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;
}

View file

@ -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);
}
}
}

View file

@ -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")));

View file

@ -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,27 +99,27 @@ 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));
Assert.assertTrue(isRoleGranted(barClient, "bar-client-role", johnFooConsent));
Assert.assertTrue(isMapperGranted(fooClient, "foo", johnFooConsent));
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));
Assert.assertTrue(isMapperGranted(barClient, "bar", johnBarConsent));
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));
Assert.assertFalse(isRoleGranted(barClient, "bar-client-role", maryConsent));
Assert.assertTrue(isMapperGranted(fooClient, "foo", maryConsent));
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, mary, barClient.getId()));
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, mary.getId(), barClient.getId()));
}
@Test
@ -130,10 +130,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());
@ -149,7 +149,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");
@ -162,14 +162,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);
@ -184,13 +184,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
@ -213,7 +213,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);
@ -232,7 +232,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);
@ -254,13 +254,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) {