From 8126110312531a95bcd6c149268200176b2fcd3b Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Sun, 2 Mar 2014 20:28:58 -0500 Subject: [PATCH] refactor getRoleById --- .../admin/js/controllers/applications.js | 4 + .../java/org/keycloak/models/ClientModel.java | 2 + .../java/org/keycloak/models/RealmModel.java | 4 + .../keycloak/models/RoleContainerModel.java | 3 +- .../org/keycloak/models/SocialLinkModel.java | 62 +- .../keycloak/models/UserCredentialModel.java | 138 +- .../models/jpa/ApplicationAdapter.java | 21 +- .../keycloak/models/jpa/ClientAdapter.java | 41 +- .../models/jpa/OAuthClientAdapter.java | 7 +- .../org/keycloak/models/jpa/RealmAdapter.java | 42 +- .../org/keycloak/models/jpa/RoleAdapter.java | 4 +- .../test/resources/META-INF/persistence.xml | 132 +- model/mongo/pom.xml | 274 +-- .../keycloak/models/mongo/api/MongoStore.java | 86 +- .../mongo/api/types/MapperRegistry.java | 222 +- .../models/mongo/impl/EntityInfo.java | 98 +- .../models/mongo/impl/MongoStoreImpl.java | 832 +++---- .../mongo/impl/types/BasicDBListMapper.java | 88 +- .../models/mongo/impl/types/ListMapper.java | 90 +- .../mongo/impl/types/MongoEntityMapper.java | 116 +- .../keycloak/adapters/ApplicationAdapter.java | 622 ++--- .../adapters/MongoKeycloakSession.java | 200 +- .../adapters/MongoKeycloakSessionFactory.java | 140 +- .../keycloak/adapters/OAuthClientAdapter.java | 270 +-- .../mongo/keycloak/adapters/RealmAdapter.java | 2024 +++++++++-------- .../mongo/keycloak/adapters/RoleAdapter.java | 31 +- .../mongo/keycloak/adapters/UserAdapter.java | 332 +-- .../keycloak/entities/ApplicationEntity.java | 314 +-- .../keycloak/entities/OAuthClientEntity.java | 210 +- .../mongo/keycloak/entities/RealmEntity.java | 570 ++--- .../mongo/keycloak/entities/RoleEntity.java | 262 +-- .../mongo/keycloak/entities/UserEntity.java | 306 +-- .../models/mongo/utils/MongoModelUtils.java | 108 +- ...SystemPropertiesConfigurationProvider.java | 110 +- .../keycloak/models/mongo/test/Address.java | 86 +- .../models/mongo/test/MongoStoreTest.java | 292 +-- .../keycloak/models/mongo/test/Person.java | 218 +- .../models/picketlink/ApplicationAdapter.java | 616 ++--- .../relationships/SocialLinkRelationship.java | 146 +- model/tests/pom.xml | 138 +- .../org/keycloak/model/test/AdapterTest.java | 12 +- .../model/test/ApplicationModelTest.java | 172 +- .../model/test/AuthenticationManagerTest.java | 300 +-- .../model/test/CompositeRolesModelTest.java | 226 +- .../org/keycloak/model/test/ModelTest.java | 156 +- .../model/test/MultipleRealmsTest.java | 11 +- .../keycloak/model/test/UserModelTest.java | 242 +- .../src/test/resources/testcomposites.json | 410 ++-- .../resources/admin/RoleByIdResource.java | 4 + .../resources/admin/RoleResource.java | 2 +- .../resources/admin/ScopeMappedResource.java | 4 +- .../resources/admin/UsersResource.java | 16 +- 52 files changed, 5456 insertions(+), 5360 deletions(-) mode change 100644 => 100755 model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java mode change 100644 => 100755 model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/applications.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/applications.js index db064512cb..5bfb651767 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/applications.js +++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/applications.js @@ -3,6 +3,10 @@ module.controller('ApplicationRoleListCtrl', function($scope, $location, realm, $scope.roles = roles; $scope.application = application; + for (var i = 0; i < roles.length; i++) { + console.log("role.id: " + roles[i].id + " role.name: " + roles[i].name); + } + $scope.$watch(function() { return $location.path(); }, function() { diff --git a/model/api/src/main/java/org/keycloak/models/ClientModel.java b/model/api/src/main/java/org/keycloak/models/ClientModel.java index cc7eaff85a..46a71031dd 100755 --- a/model/api/src/main/java/org/keycloak/models/ClientModel.java +++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java @@ -49,4 +49,6 @@ public interface ClientModel { boolean validateSecret(String secret); String getSecret(); public void setSecret(String secret); + + RealmModel getRealm(); } diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java index 43dda29a6d..89592e8b2e 100755 --- a/model/api/src/main/java/org/keycloak/models/RealmModel.java +++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java @@ -101,6 +101,8 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa boolean removeUser(String name); + RoleModel getRoleById(String id); + List getDefaultRoles(); void addDefaultRole(String name); @@ -182,4 +184,6 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa int getNotBefore(); void setNotBefore(int notBefore); + + boolean removeRoleById(String id); } diff --git a/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java b/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java index bd8bfab1e7..62ecfdb7f4 100755 --- a/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java +++ b/model/api/src/main/java/org/keycloak/models/RoleContainerModel.java @@ -12,9 +12,8 @@ public interface RoleContainerModel { RoleModel addRole(String name); - boolean removeRoleById(String id); + boolean removeRole(RoleModel role); Set getRoles(); - RoleModel getRoleById(String id); } diff --git a/model/api/src/main/java/org/keycloak/models/SocialLinkModel.java b/model/api/src/main/java/org/keycloak/models/SocialLinkModel.java index a484477b9d..742da1112e 100755 --- a/model/api/src/main/java/org/keycloak/models/SocialLinkModel.java +++ b/model/api/src/main/java/org/keycloak/models/SocialLinkModel.java @@ -1,31 +1,31 @@ -package org.keycloak.models; - -/** - * @author Marek Posolda - */ -public class SocialLinkModel { - - private String socialUsername; - private String socialProvider; - - public SocialLinkModel(String socialProvider, String socialUsername) { - this.socialUsername = socialUsername; - this.socialProvider = socialProvider; - } - - public String getSocialUsername() { - return socialUsername; - } - - public void setSocialUsername(String socialUsername) { - this.socialUsername = socialUsername; - } - - public String getSocialProvider() { - return socialProvider; - } - - public void setSocialProvider(String socialProvider) { - this.socialProvider = socialProvider; - } -} +package org.keycloak.models; + +/** + * @author Marek Posolda + */ +public class SocialLinkModel { + + private String socialUsername; + private String socialProvider; + + public SocialLinkModel(String socialProvider, String socialUsername) { + this.socialUsername = socialUsername; + this.socialProvider = socialProvider; + } + + public String getSocialUsername() { + return socialUsername; + } + + public void setSocialUsername(String socialUsername) { + this.socialUsername = socialUsername; + } + + public String getSocialProvider() { + return socialProvider; + } + + public void setSocialProvider(String socialProvider) { + this.socialProvider = socialProvider; + } +} diff --git a/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java b/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java index 510f852249..d096b97320 100755 --- a/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java +++ b/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java @@ -1,69 +1,69 @@ -package org.keycloak.models; - -import java.util.UUID; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class UserCredentialModel { - public static final String PASSWORD = "password"; - - // Secret is same as password but it is not hashed - public static final String SECRET = "secret"; - public static final String TOTP = "totp"; - public static final String CLIENT_CERT = "cert"; - - protected String type; - protected String value; - protected String device; - - public UserCredentialModel() { - } - - public static UserCredentialModel password(String password) { - UserCredentialModel model = new UserCredentialModel(); - model.setType(PASSWORD); - model.setValue(password); - return model; - } - - public static UserCredentialModel secret(String password) { - UserCredentialModel model = new UserCredentialModel(); - model.setType(SECRET); - model.setValue(password); - return model; - } - - public static UserCredentialModel generateSecret() { - UserCredentialModel model = new UserCredentialModel(); - model.setType(SECRET); - model.setValue(UUID.randomUUID().toString()); - return model; - } - - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public String getDevice() { - return device; - } - - public void setDevice(String device) { - this.device = device; - } -} +package org.keycloak.models; + +import java.util.UUID; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class UserCredentialModel { + public static final String PASSWORD = "password"; + + // Secret is same as password but it is not hashed + public static final String SECRET = "secret"; + public static final String TOTP = "totp"; + public static final String CLIENT_CERT = "cert"; + + protected String type; + protected String value; + protected String device; + + public UserCredentialModel() { + } + + public static UserCredentialModel password(String password) { + UserCredentialModel model = new UserCredentialModel(); + model.setType(PASSWORD); + model.setValue(password); + return model; + } + + public static UserCredentialModel secret(String password) { + UserCredentialModel model = new UserCredentialModel(); + model.setType(SECRET); + model.setValue(password); + return model; + } + + public static UserCredentialModel generateSecret() { + UserCredentialModel model = new UserCredentialModel(); + model.setType(SECRET); + model.setValue(UUID.randomUUID().toString()); + return model; + } + + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getDevice() { + return device; + } + + public void setDevice(String device) { + this.device = device; + } +} diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java index 69c30ec4eb..371a43a54e 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java @@ -24,10 +24,9 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode protected EntityManager em; protected ApplicationEntity applicationEntity; - protected RealmModel realm; public ApplicationAdapter(RealmModel realm, EntityManager em, ApplicationEntity applicationEntity) { - super(applicationEntity); + super(realm, applicationEntity); this.realm = realm; this.em = em; this.applicationEntity = applicationEntity; @@ -48,7 +47,6 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode entity.setName(name); } - @Override public boolean isSurrogateAuthRequired() { return applicationEntity.isSurrogateAuthRequired(); @@ -103,11 +101,14 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode } @Override - public boolean removeRoleById(String id) { - RoleAdapter roleAdapter = getRoleById(id); + public boolean removeRole(RoleModel roleModel) { + RoleAdapter roleAdapter = (RoleAdapter)roleModel; if (roleAdapter == null) { return false; } + if (!roleAdapter.getContainer().equals(this)) return false; + + if (!(roleAdapter.getRole() instanceof ApplicationRoleEntity)) return false; ApplicationRoleEntity role = (ApplicationRoleEntity)roleAdapter.getRole(); @@ -134,16 +135,6 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode return list; } - @Override - public RoleAdapter getRoleById(String id) { - RoleEntity entity = em.find(RoleEntity.class, id); - - // Check if it's application role and belongs to this application - if (entity == null || !(entity instanceof ApplicationRoleEntity)) return null; - ApplicationRoleEntity appRoleEntity = (ApplicationRoleEntity)entity; - return (appRoleEntity.getApplication().equals(this.entity)) ? new RoleAdapter(this.realm, em, appRoleEntity) : null; - } - @Override public Set getApplicationRoleMappings(UserModel user) { Set roleMappings = realm.getRoleMappings(user); diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java index 2ec95ec59c..7dcd3d9232 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java @@ -1,6 +1,7 @@ package org.keycloak.models.jpa; import org.keycloak.models.ClientModel; +import org.keycloak.models.RealmModel; import org.keycloak.models.jpa.entities.ClientEntity; import org.keycloak.models.jpa.entities.OAuthClientEntity; @@ -13,8 +14,10 @@ import java.util.Set; */ public class ClientAdapter implements ClientModel { protected ClientEntity entity; + protected RealmModel realm; - public ClientAdapter(ClientEntity entity) { + public ClientAdapter(RealmModel realm, ClientEntity entity) { + this.realm = realm; this.entity = entity; } @@ -22,75 +25,111 @@ public class ClientAdapter implements ClientModel { return entity; } + @Override public String getId() { return entity.getId(); } + @Override + public RealmModel getRealm() { + return realm; + } + + @Override public String getClientId() { return entity.getName(); } + @Override public boolean isEnabled() { return entity.isEnabled(); } + @Override public void setEnabled(boolean enabled) { entity.setEnabled(enabled); } + @Override public long getAllowedClaimsMask() { return entity.getAllowedClaimsMask(); } + @Override public void setAllowedClaimsMask(long mask) { entity.setAllowedClaimsMask(mask); } + @Override public Set getWebOrigins() { Set result = new HashSet(); result.addAll(entity.getWebOrigins()); return result; } + @Override public void setWebOrigins(Set webOrigins) { entity.setWebOrigins(webOrigins); } + @Override public void addWebOrigin(String webOrigin) { entity.getWebOrigins().add(webOrigin); } + @Override public void removeWebOrigin(String webOrigin) { entity.getWebOrigins().remove(webOrigin); } + @Override public Set getRedirectUris() { Set result = new HashSet(); result.addAll(entity.getRedirectUris()); return result; } + @Override public void setRedirectUris(Set redirectUris) { entity.setRedirectUris(redirectUris); } + @Override public void addRedirectUri(String redirectUri) { entity.getRedirectUris().add(redirectUri); } + @Override public void removeRedirectUri(String redirectUri) { entity.getRedirectUris().remove(redirectUri); } + @Override public String getSecret() { return entity.getSecret(); } + @Override public void setSecret(String secret) { entity.setSecret(secret); } + @Override public boolean validateSecret(String secret) { return secret.equals(entity.getSecret()); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!this.getClass().equals(o.getClass())) return false; + + ClientAdapter that = (ClientAdapter) o; + return that.getId().equals(getId()); + } + + @Override + public int hashCode() { + return entity.getId().hashCode(); + } } diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java index 692a4e1102..29d643d084 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java @@ -1,6 +1,7 @@ package org.keycloak.models.jpa; import org.keycloak.models.OAuthClientModel; +import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.models.jpa.entities.OAuthClientEntity; @@ -13,7 +14,9 @@ import java.util.Set; */ public class OAuthClientAdapter extends ClientAdapter implements OAuthClientModel { - public OAuthClientAdapter(OAuthClientEntity entity) { - super(entity); + public OAuthClientAdapter(RealmModel realm, OAuthClientEntity entity) { + super(realm, entity); } + + } diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java index d81b2a027b..f7e17ce17b 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java @@ -3,6 +3,7 @@ package org.keycloak.models.jpa; import org.keycloak.models.ClientModel; import org.keycloak.models.RoleContainerModel; import org.keycloak.models.jpa.entities.ApplicationEntity; +import org.keycloak.models.jpa.entities.ApplicationRoleEntity; import org.keycloak.models.jpa.entities.CredentialEntity; import org.keycloak.models.jpa.entities.OAuthClientEntity; import org.keycloak.models.jpa.entities.RealmEntity; @@ -496,7 +497,7 @@ public class RealmAdapter implements RealmModel { if (application == null) return false; for (RoleModel role : application.getRoles()) { - application.removeRoleById(role.getId()); + application.removeRole(role); } ApplicationEntity applicationEntity = null; @@ -673,12 +674,14 @@ public class RealmAdapter implements RealmModel { data.setRealm(realm); em.persist(data); em.flush(); - return new OAuthClientAdapter(data); + return new OAuthClientAdapter(this, data); } @Override public boolean removeOAuthClient(String id) { - OAuthClientEntity client = em.find(OAuthClientEntity.class, id); + OAuthClientModel oauth = getOAuthClientById(id); + if (oauth == null) return false; + OAuthClientEntity client = (OAuthClientEntity)((OAuthClientAdapter)oauth).getEntity(); em.createQuery("delete from " + ScopeMappingEntity.class.getSimpleName() + " where client = :client").setParameter("client", client).executeUpdate(); em.remove(client); return true; @@ -692,7 +695,7 @@ public class RealmAdapter implements RealmModel { query.setParameter("realm", realm); List entities = query.getResultList(); if (entities.size() == 0) return null; - return new OAuthClientAdapter(entities.get(0)); + return new OAuthClientAdapter(this, entities.get(0)); } @Override @@ -700,8 +703,8 @@ public class RealmAdapter implements RealmModel { OAuthClientEntity client = em.find(OAuthClientEntity.class, id); // Check if client belongs to this realm - if (client == null || !this.realm.equals(client.getRealm())) return null; - return new OAuthClientAdapter(client); + if (client == null || !this.realm.getId().equals(client.getRealm().getId())) return null; + return new OAuthClientAdapter(this, client); } @@ -711,7 +714,7 @@ public class RealmAdapter implements RealmModel { query.setParameter("realm", realm); List entities = query.getResultList(); List list = new ArrayList(); - for (OAuthClientEntity entity : entities) list.add(new OAuthClientAdapter(entity)); + for (OAuthClientEntity entity : entities) list.add(new OAuthClientAdapter(this, entity)); return list; } @@ -761,12 +764,12 @@ public class RealmAdapter implements RealmModel { } @Override - public boolean removeRoleById(String id) { - RoleModel role = getRoleById(id); - + public boolean removeRole(RoleModel role) { if (role == null) { return false; } + if (!role.getContainer().equals(this)) return false; + RoleEntity roleEntity = ((RoleAdapter)role).getRole(); realm.getRoles().remove(role); realm.getDefaultRoles().remove(role); @@ -793,11 +796,22 @@ public class RealmAdapter implements RealmModel { @Override public RoleModel getRoleById(String id) { RoleEntity entity = em.find(RoleEntity.class, id); + if (entity == null) return null; + if (entity instanceof RealmRoleEntity) { + RealmRoleEntity roleEntity = (RealmRoleEntity)entity; + if (!roleEntity.getRealm().getId().equals(getId())) return null; + } else { + ApplicationRoleEntity roleEntity = (ApplicationRoleEntity)entity; + if (!roleEntity.getApplication().getRealm().getId().equals(getId())) return null; + } + return new RoleAdapter(this, em, entity); + } - // Check if it's realm role and belongs to this realm - if (entity == null || !(entity instanceof RealmRoleEntity)) return null; - RealmRoleEntity realmRoleEntity = (RealmRoleEntity)entity; - return (realmRoleEntity.getRealm().equals(this.realm)) ? new RoleAdapter(this, em, realmRoleEntity) : null; + @Override + public boolean removeRoleById(String id) { + RoleModel role = getRoleById(id); + if (role == null) return false; + return role.getContainer().removeRole(role); } @Override diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java index e418441de2..421cffad3d 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java @@ -124,13 +124,13 @@ public class RoleAdapter implements RoleModel { RoleAdapter that = (RoleAdapter) o; - if (!role.equals(that.role)) return false; + if (!role.getId().equals(that.role.getId())) return false; return true; } @Override public int hashCode() { - return role.hashCode(); + return role.getId().hashCode(); } } diff --git a/model/jpa/src/test/resources/META-INF/persistence.xml b/model/jpa/src/test/resources/META-INF/persistence.xml index 8fa01f2dfd..b6b99bb4b4 100755 --- a/model/jpa/src/test/resources/META-INF/persistence.xml +++ b/model/jpa/src/test/resources/META-INF/persistence.xml @@ -1,66 +1,66 @@ - - - org.hibernate.ejb.HibernatePersistence - - org.keycloak.models.jpa.entities.ApplicationEntity - org.keycloak.models.jpa.entities.CredentialEntity - org.keycloak.models.jpa.entities.OAuthClientEntity - org.keycloak.models.jpa.entities.RealmEntity - org.keycloak.models.jpa.entities.RequiredCredentialEntity - org.keycloak.models.jpa.entities.ApplicationRoleEntity - org.keycloak.models.jpa.entities.RealmRoleEntity - org.keycloak.models.jpa.entities.SocialLinkEntity - org.keycloak.models.jpa.entities.UserEntity - org.keycloak.models.jpa.entities.UserRoleMappingEntity - org.keycloak.models.jpa.entities.ScopeMappingEntity - - true - - - - - - - - - - - - - - + + + org.hibernate.ejb.HibernatePersistence + + org.keycloak.models.jpa.entities.ApplicationEntity + org.keycloak.models.jpa.entities.CredentialEntity + org.keycloak.models.jpa.entities.OAuthClientEntity + org.keycloak.models.jpa.entities.RealmEntity + org.keycloak.models.jpa.entities.RequiredCredentialEntity + org.keycloak.models.jpa.entities.ApplicationRoleEntity + org.keycloak.models.jpa.entities.RealmRoleEntity + org.keycloak.models.jpa.entities.SocialLinkEntity + org.keycloak.models.jpa.entities.UserEntity + org.keycloak.models.jpa.entities.UserRoleMappingEntity + org.keycloak.models.jpa.entities.ScopeMappingEntity + + true + + + + + + + + + + + + + + diff --git a/model/mongo/pom.xml b/model/mongo/pom.xml index 417249ba39..2ed8d457f5 100755 --- a/model/mongo/pom.xml +++ b/model/mongo/pom.xml @@ -1,138 +1,138 @@ - - - - keycloak-parent - org.keycloak - 1.0-alpha-3-SNAPSHOT - ../../pom.xml - - 4.0.0 - - keycloak-model-mongo - Keycloak Model Mongo - - - - - org.bouncycastle - bcprov-jdk16 - provided - - - org.keycloak - keycloak-core - ${project.version} - provided - - - org.keycloak - keycloak-model-api - ${project.version} - - - org.jboss.logging - jboss-logging - provided - - - org.picketlink - picketlink-common - provided - - - org.mongodb - mongo-java-driver - provided - - - - org.keycloak - keycloak-model-tests - ${project.version} - tests - test - - - - - localhost - 27018 - keycloak - true - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.6 - 1.6 - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - test - integration-test - - test - - - - ${keycloak.mongo.host} - ${keycloak.mongo.port} - ${keycloak.mongo.db} - ${keycloak.mongo.clearOnStartup} - - - org.keycloak:keycloak-model-tests - - - - - default-test - - true - - - - - - - - com.github.joelittlejohn.embedmongo - embedmongo-maven-plugin - - - start-mongodb - pre-integration-test - - start - - - ${keycloak.mongo.port} - file - ${project.build.directory}/mongodb.log - - - - stop-mongodb - post-integration-test - - stop - - - - - - - + + + + keycloak-parent + org.keycloak + 1.0-alpha-3-SNAPSHOT + ../../pom.xml + + 4.0.0 + + keycloak-model-mongo + Keycloak Model Mongo + + + + + org.bouncycastle + bcprov-jdk16 + provided + + + org.keycloak + keycloak-core + ${project.version} + provided + + + org.keycloak + keycloak-model-api + ${project.version} + + + org.jboss.logging + jboss-logging + provided + + + org.picketlink + picketlink-common + provided + + + org.mongodb + mongo-java-driver + provided + + + + org.keycloak + keycloak-model-tests + ${project.version} + tests + test + + + + + localhost + 27018 + keycloak + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + test + integration-test + + test + + + + ${keycloak.mongo.host} + ${keycloak.mongo.port} + ${keycloak.mongo.db} + ${keycloak.mongo.clearOnStartup} + + + org.keycloak:keycloak-model-tests + + + + + default-test + + true + + + + + + + + com.github.joelittlejohn.embedmongo + embedmongo-maven-plugin + + + start-mongodb + pre-integration-test + + start + + + ${keycloak.mongo.port} + file + ${project.build.directory}/mongodb.log + + + + stop-mongodb + post-integration-test + + stop + + + + + + + \ No newline at end of file diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/api/MongoStore.java b/model/mongo/src/main/java/org/keycloak/models/mongo/api/MongoStore.java index 9da25e5b4e..f16400c26d 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/api/MongoStore.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/api/MongoStore.java @@ -1,43 +1,43 @@ -package org.keycloak.models.mongo.api; - -import com.mongodb.DBObject; -import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; - -import java.util.List; - -/** - * @author Marek Posolda - */ -public interface MongoStore { - - /** - * Insert new entity - * - * @param entity to insert - */ - void insertEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context); - - /** - * Update existing entity - * - * @param entity to update - */ - void updateEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context); - - - T loadEntity(Class type, String id, MongoStoreInvocationContext context); - - T loadSingleEntity(Class type, DBObject query, MongoStoreInvocationContext context); - - List loadEntities(Class type, DBObject query, MongoStoreInvocationContext context); - - boolean removeEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context); - - boolean removeEntity(Class type, String id, MongoStoreInvocationContext context); - - boolean removeEntities(Class type, DBObject query, MongoStoreInvocationContext context); - - boolean pushItemToList(MongoIdentifiableEntity entity, String listPropertyName, S itemToPush, boolean skipIfAlreadyPresent, MongoStoreInvocationContext context); - - boolean pullItemFromList(MongoIdentifiableEntity entity, String listPropertyName, S itemToPull, MongoStoreInvocationContext context); -} +package org.keycloak.models.mongo.api; + +import com.mongodb.DBObject; +import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; + +import java.util.List; + +/** + * @author Marek Posolda + */ +public interface MongoStore { + + /** + * Insert new entity + * + * @param entity to insert + */ + void insertEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context); + + /** + * Update existing entity + * + * @param entity to update + */ + void updateEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context); + + + T loadEntity(Class type, String id, MongoStoreInvocationContext context); + + T loadSingleEntity(Class type, DBObject query, MongoStoreInvocationContext context); + + List loadEntities(Class type, DBObject query, MongoStoreInvocationContext context); + + boolean removeEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context); + + boolean removeEntity(Class type, String id, MongoStoreInvocationContext context); + + boolean removeEntities(Class type, DBObject query, MongoStoreInvocationContext context); + + boolean pushItemToList(MongoIdentifiableEntity entity, String listPropertyName, S itemToPush, boolean skipIfAlreadyPresent, MongoStoreInvocationContext context); + + boolean pullItemFromList(MongoIdentifiableEntity entity, String listPropertyName, S itemToPull, MongoStoreInvocationContext context); +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/api/types/MapperRegistry.java b/model/mongo/src/main/java/org/keycloak/models/mongo/api/types/MapperRegistry.java index 6da24b7e2b..d48fa589bc 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/api/types/MapperRegistry.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/api/types/MapperRegistry.java @@ -1,111 +1,111 @@ -package org.keycloak.models.mongo.api.types; - -import java.util.HashMap; -import java.util.Map; - -/** - * Registry of mappers, which allow to convert application object to database objects. MapperRegistry is main entry point to be used by application. - * Application can create instance of MapperRegistry and then register required Mapper objects. - * - * @author Marek Posolda - */ -public class MapperRegistry { - - // TODO: Thread-safety support (maybe...) - // Mappers of Application objects to DB objects - private Map, Mapper> appObjectMappers = new HashMap, Mapper>(); - - // Mappers of DB objects to Application objects - private Map, Map, Mapper>> dbObjectMappers = new HashMap, Map, Mapper>>(); - - - /** - * Add mapper for converting application objects to DB objects - * - * @param mapper - */ - public void addAppObjectMapper(Mapper mapper) { - appObjectMappers.put(mapper.getTypeOfObjectToConvert(), mapper); - } - - - /** - * Add mapper for converting DB objects to application objects - * - * @param mapper - */ - public void addDBObjectMapper(Mapper mapper) { - Class dbObjectType = mapper.getTypeOfObjectToConvert(); - Class appObjectType = mapper.getExpectedReturnType(); - Map, Mapper> appObjects = dbObjectMappers.get(dbObjectType); - if (appObjects == null) { - appObjects = new HashMap, Mapper>(); - dbObjectMappers.put(dbObjectType, appObjects); - } - appObjects.put(appObjectType, mapper); - } - - - public S convertDBObjectToApplicationObject(MapperContext context) { - Object dbObject = context.getObjectToConvert(); - Class expectedApplicationObjectType = context.getExpectedReturnType(); - - Class dbObjectType = dbObject.getClass(); - Mapper mapper; - - Map, Mapper> appObjects = dbObjectMappers.get(dbObjectType); - if (appObjects == null) { - throw new IllegalArgumentException("Not found any mappers for type " + dbObjectType); - } else { - if (appObjects.size() == 1) { - mapper = (Mapper)appObjects.values().iterator().next(); - } else { - // Try to find converter for requested application type - mapper = (Mapper)getAppConverterForType(context.getExpectedReturnType(), appObjects); - } - } - - if (mapper == null) { - throw new IllegalArgumentException("Can't found mapper for type " + dbObjectType + " and expectedApplicationType " + expectedApplicationObjectType); - } - - return mapper.convertObject(context); - } - - - public S convertApplicationObjectToDBObject(Object applicationObject, Class expectedDBObjectType) { - Class appObjectType = applicationObject.getClass(); - Mapper mapper = (Mapper)getAppConverterForType(appObjectType, appObjectMappers); - if (mapper == null) { - throw new IllegalArgumentException("Can't found converter for type " + appObjectType + " in registered appObjectMappers"); - } - if (!expectedDBObjectType.isAssignableFrom(mapper.getExpectedReturnType())) { - throw new IllegalArgumentException("Converter " + mapper + " has return type " + mapper.getExpectedReturnType() + - " but we need type " + expectedDBObjectType); - } - return mapper.convertObject(new MapperContext(applicationObject, expectedDBObjectType, null)); - } - - // Try to find converter for given type or all it's supertypes - private static Mapper getAppConverterForType(Class appObjectType, Map, Mapper> appObjectConverters) { - Mapper mapper = (Mapper)appObjectConverters.get(appObjectType); - if (mapper != null) { - return mapper; - } else { - Class[] interfaces = appObjectType.getInterfaces(); - for (Class interface1 : interfaces) { - mapper = getAppConverterForType(interface1, appObjectConverters); - if (mapper != null) { - return mapper; - } - } - - Class superType = appObjectType.getSuperclass(); - if (superType != null) { - return getAppConverterForType(superType, appObjectConverters); - } else { - return null; - } - } - } -} +package org.keycloak.models.mongo.api.types; + +import java.util.HashMap; +import java.util.Map; + +/** + * Registry of mappers, which allow to convert application object to database objects. MapperRegistry is main entry point to be used by application. + * Application can create instance of MapperRegistry and then register required Mapper objects. + * + * @author Marek Posolda + */ +public class MapperRegistry { + + // TODO: Thread-safety support (maybe...) + // Mappers of Application objects to DB objects + private Map, Mapper> appObjectMappers = new HashMap, Mapper>(); + + // Mappers of DB objects to Application objects + private Map, Map, Mapper>> dbObjectMappers = new HashMap, Map, Mapper>>(); + + + /** + * Add mapper for converting application objects to DB objects + * + * @param mapper + */ + public void addAppObjectMapper(Mapper mapper) { + appObjectMappers.put(mapper.getTypeOfObjectToConvert(), mapper); + } + + + /** + * Add mapper for converting DB objects to application objects + * + * @param mapper + */ + public void addDBObjectMapper(Mapper mapper) { + Class dbObjectType = mapper.getTypeOfObjectToConvert(); + Class appObjectType = mapper.getExpectedReturnType(); + Map, Mapper> appObjects = dbObjectMappers.get(dbObjectType); + if (appObjects == null) { + appObjects = new HashMap, Mapper>(); + dbObjectMappers.put(dbObjectType, appObjects); + } + appObjects.put(appObjectType, mapper); + } + + + public S convertDBObjectToApplicationObject(MapperContext context) { + Object dbObject = context.getObjectToConvert(); + Class expectedApplicationObjectType = context.getExpectedReturnType(); + + Class dbObjectType = dbObject.getClass(); + Mapper mapper; + + Map, Mapper> appObjects = dbObjectMappers.get(dbObjectType); + if (appObjects == null) { + throw new IllegalArgumentException("Not found any mappers for type " + dbObjectType); + } else { + if (appObjects.size() == 1) { + mapper = (Mapper)appObjects.values().iterator().next(); + } else { + // Try to find converter for requested application type + mapper = (Mapper)getAppConverterForType(context.getExpectedReturnType(), appObjects); + } + } + + if (mapper == null) { + throw new IllegalArgumentException("Can't found mapper for type " + dbObjectType + " and expectedApplicationType " + expectedApplicationObjectType); + } + + return mapper.convertObject(context); + } + + + public S convertApplicationObjectToDBObject(Object applicationObject, Class expectedDBObjectType) { + Class appObjectType = applicationObject.getClass(); + Mapper mapper = (Mapper)getAppConverterForType(appObjectType, appObjectMappers); + if (mapper == null) { + throw new IllegalArgumentException("Can't found converter for type " + appObjectType + " in registered appObjectMappers"); + } + if (!expectedDBObjectType.isAssignableFrom(mapper.getExpectedReturnType())) { + throw new IllegalArgumentException("Converter " + mapper + " has return type " + mapper.getExpectedReturnType() + + " but we need type " + expectedDBObjectType); + } + return mapper.convertObject(new MapperContext(applicationObject, expectedDBObjectType, null)); + } + + // Try to find converter for given type or all it's supertypes + private static Mapper getAppConverterForType(Class appObjectType, Map, Mapper> appObjectConverters) { + Mapper mapper = (Mapper)appObjectConverters.get(appObjectType); + if (mapper != null) { + return mapper; + } else { + Class[] interfaces = appObjectType.getInterfaces(); + for (Class interface1 : interfaces) { + mapper = getAppConverterForType(interface1, appObjectConverters); + if (mapper != null) { + return mapper; + } + } + + Class superType = appObjectType.getSuperclass(); + if (superType != null) { + return getAppConverterForType(superType, appObjectConverters); + } else { + return null; + } + } + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/EntityInfo.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/EntityInfo.java index eedb4a73ff..b6ff046bf2 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/EntityInfo.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/EntityInfo.java @@ -1,49 +1,49 @@ -package org.keycloak.models.mongo.impl; - -import org.keycloak.models.mongo.api.MongoEntity; -import org.picketlink.common.properties.Property; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author Marek Posolda - */ -public class EntityInfo { - - private final Class entityClass; - - private final String dbCollectionName; - - private final Map> properties; - - public EntityInfo(Class entityClass, String dbCollectionName, List> properties) { - this.entityClass = entityClass; - this.dbCollectionName = dbCollectionName; - - Map> props= new HashMap>(); - for (Property property : properties) { - props.put(property.getName(), property); - } - this.properties = Collections.unmodifiableMap(props); - } - - public Class getEntityClass() { - return entityClass; - } - - public String getDbCollectionName() { - return dbCollectionName; - } - - public Collection> getProperties() { - return properties.values(); - } - - public Property getPropertyByName(String propertyName) { - return properties.get(propertyName); - } -} +package org.keycloak.models.mongo.impl; + +import org.keycloak.models.mongo.api.MongoEntity; +import org.picketlink.common.properties.Property; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Marek Posolda + */ +public class EntityInfo { + + private final Class entityClass; + + private final String dbCollectionName; + + private final Map> properties; + + public EntityInfo(Class entityClass, String dbCollectionName, List> properties) { + this.entityClass = entityClass; + this.dbCollectionName = dbCollectionName; + + Map> props= new HashMap>(); + for (Property property : properties) { + props.put(property.getName(), property); + } + this.properties = Collections.unmodifiableMap(props); + } + + public Class getEntityClass() { + return entityClass; + } + + public String getDbCollectionName() { + return dbCollectionName; + } + + public Collection> getProperties() { + return properties.values(); + } + + public Property getPropertyByName(String propertyName) { + return properties.get(propertyName); + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoStoreImpl.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoStoreImpl.java index fa41a46937..4d59598fba 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoStoreImpl.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoStoreImpl.java @@ -1,416 +1,416 @@ -package org.keycloak.models.mongo.impl; - -import com.mongodb.BasicDBList; -import com.mongodb.BasicDBObject; -import com.mongodb.DB; -import com.mongodb.DBCollection; -import com.mongodb.DBCursor; -import com.mongodb.DBObject; -import org.jboss.logging.Logger; -import org.keycloak.models.mongo.api.MongoCollection; -import org.keycloak.models.mongo.api.MongoEntity; -import org.keycloak.models.mongo.api.MongoField; -import org.keycloak.models.mongo.api.MongoIdentifiableEntity; -import org.keycloak.models.mongo.api.MongoStore; -import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; -import org.keycloak.models.mongo.api.context.MongoTask; -import org.keycloak.models.mongo.api.types.Mapper; -import org.keycloak.models.mongo.api.types.MapperContext; -import org.keycloak.models.mongo.api.types.MapperRegistry; -import org.keycloak.models.mongo.impl.types.BasicDBListMapper; -import org.keycloak.models.mongo.impl.types.BasicDBObjectMapper; -import org.keycloak.models.mongo.impl.types.BasicDBObjectToMapMapper; -import org.keycloak.models.mongo.impl.types.EnumToStringMapper; -import org.keycloak.models.mongo.impl.types.ListMapper; -import org.keycloak.models.mongo.impl.types.MapMapper; -import org.keycloak.models.mongo.impl.types.MongoEntityMapper; -import org.keycloak.models.mongo.impl.types.SimpleMapper; -import org.keycloak.models.mongo.impl.types.StringToEnumMapper; -import org.keycloak.models.utils.KeycloakModelUtils; -import org.picketlink.common.properties.Property; -import org.picketlink.common.properties.query.AnnotatedPropertyCriteria; -import org.picketlink.common.properties.query.PropertyQueries; - -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * @author Marek Posolda - */ -public class MongoStoreImpl implements MongoStore { - - private static final Class[] SIMPLE_TYPES = { String.class, Integer.class, Boolean.class, Long.class, Double.class, Character.class, Date.class, byte[].class }; - - private final DB database; - private static final Logger logger = Logger.getLogger(MongoStoreImpl.class); - - private final MapperRegistry mapperRegistry; - private ConcurrentMap, EntityInfo> entityInfoCache = - new ConcurrentHashMap, EntityInfo>(); - - - public MongoStoreImpl(DB database, boolean clearCollectionsOnStartup, Class[] managedEntityTypes) { - this.database = database; - - mapperRegistry = new MapperRegistry(); - - for (Class simpleConverterClass : SIMPLE_TYPES) { - SimpleMapper converter = new SimpleMapper(simpleConverterClass); - mapperRegistry.addAppObjectMapper(converter); - mapperRegistry.addDBObjectMapper(converter); - } - - // Specific converter for ArrayList is added just for performance purposes to avoid recursive converter lookup (most of list impl will be ArrayList) - mapperRegistry.addAppObjectMapper(new ListMapper(mapperRegistry, ArrayList.class)); - mapperRegistry.addAppObjectMapper(new ListMapper(mapperRegistry, List.class)); - mapperRegistry.addDBObjectMapper(new BasicDBListMapper(mapperRegistry)); - - mapperRegistry.addAppObjectMapper(new MapMapper(HashMap.class)); - mapperRegistry.addAppObjectMapper(new MapMapper(Map.class)); - mapperRegistry.addDBObjectMapper(new BasicDBObjectToMapMapper()); - - // Enum converters - mapperRegistry.addAppObjectMapper(new EnumToStringMapper()); - mapperRegistry.addDBObjectMapper(new StringToEnumMapper()); - - for (Class type : managedEntityTypes) { - getEntityInfo(type); - mapperRegistry.addAppObjectMapper(new MongoEntityMapper(this, mapperRegistry, type)); - mapperRegistry.addDBObjectMapper(new BasicDBObjectMapper(this, mapperRegistry, type)); - } - - if (clearCollectionsOnStartup) { - // dropDatabase(); - clearManagedCollections(managedEntityTypes); - } - } - - protected void dropDatabase() { - this.database.dropDatabase(); - logger.info("Database " + this.database.getName() + " dropped in MongoDB"); - } - - // Don't drop database, but just clear all data in managed collections (useful for development) - protected void clearManagedCollections(Class[] managedEntityTypes) { - for (Class clazz : managedEntityTypes) { - DBCollection dbCollection = getDBCollectionForType(clazz); - if (dbCollection != null) { - dbCollection.remove(new BasicDBObject()); - logger.debug("Collection " + dbCollection.getName() + " cleared from " + this.database.getName()); - } - } - } - - @Override - public void insertEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context) { - Class clazz = entity.getClass(); - - // Find annotations for ID, for all the properties and for the name of the collection. - EntityInfo entityInfo = getEntityInfo(clazz); - - // Create instance of BasicDBObject and add all declared properties to it (properties with null value probably should be skipped) - BasicDBObject dbObject = mapperRegistry.convertApplicationObjectToDBObject(entity, BasicDBObject.class); - - DBCollection dbCollection = database.getCollection(entityInfo.getDbCollectionName()); - - String currentId = entity.getId(); - - // Generate random ID if not set already - if (currentId == null) { - currentId = KeycloakModelUtils.generateId(); - entity.setId(currentId); - } - - // Adding "_id" - dbObject.put("_id", currentId); - - dbCollection.insert(dbObject); - - // Treat object as created in this transaction (It is already submited to transaction) - context.addCreatedEntity(entity); - } - - @Override - public void updateEntity(final MongoIdentifiableEntity entity, MongoStoreInvocationContext context) { - MongoTask fullUpdateTask = new MongoTask() { - - @Override - public void execute() { - Class clazz = entity.getClass(); - EntityInfo entityInfo = getEntityInfo(clazz); - BasicDBObject dbObject = mapperRegistry.convertApplicationObjectToDBObject(entity, BasicDBObject.class); - DBCollection dbCollection = database.getCollection(entityInfo.getDbCollectionName()); - - String currentId = entity.getId(); - - if (currentId == null) { - throw new IllegalStateException("Can't update entity without id: " + entity); - } else { - BasicDBObject query = new BasicDBObject("_id", currentId); - dbCollection.update(query, dbObject); - } - } - - @Override - public boolean isFullUpdate() { - return true; - } - }; - - // update is just added to context and postponed - context.addUpdateTask(entity, fullUpdateTask); - } - - - @Override - public T loadEntity(Class type, String id, MongoStoreInvocationContext context) { - // First look if we already read the object with this oid and type during this transaction. If yes, use it instead of DB lookup - T cached = context.getLoadedEntity(type, id); - if (cached != null) return cached; - - DBCollection dbCollection = getDBCollectionForType(type); - - BasicDBObject idQuery = new BasicDBObject("_id", id); - DBObject dbObject = dbCollection.findOne(idQuery); - - if (dbObject == null) return null; - - MapperContext mapperContext = new MapperContext(dbObject, type, null); - T converted = mapperRegistry.convertDBObjectToApplicationObject(mapperContext); - - // Now add it to loaded objects - context.addLoadedEntity(converted); - - return converted; - } - - - @Override - public T loadSingleEntity(Class type, DBObject query, MongoStoreInvocationContext context) { - // First we should execute all pending tasks before searching DB - context.beforeDBSearch(type); - - DBCollection dbCollection = getDBCollectionForType(type); - DBObject dbObject = dbCollection.findOne(query); - - if (dbObject == null) { - return null; - } else { - return convertDBObjectToEntity(type, dbObject, context); - } - } - - - @Override - public List loadEntities(Class type, DBObject query, MongoStoreInvocationContext context) { - // First we should execute all pending tasks before searching DB - context.beforeDBSearch(type); - - DBCollection dbCollection = getDBCollectionForType(type); - DBCursor cursor = dbCollection.find(query); - - return convertCursor(type, cursor, context); - } - - - @Override - public boolean removeEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context) { - return removeEntity(entity.getClass(), entity.getId(), context); - } - - - @Override - public boolean removeEntity(Class type, String id, MongoStoreInvocationContext context) { - MongoIdentifiableEntity found = loadEntity(type, id, context); - if (found == null) { - return false; - } else { - DBCollection dbCollection = getDBCollectionForType(type); - BasicDBObject dbQuery = new BasicDBObject("_id", id); - dbCollection.remove(dbQuery); - logger.info("Entity of type: " + type + ", id: " + id + " removed from MongoDB."); - - context.addRemovedEntity(found); - return true; - } - } - - - @Override - public boolean removeEntities(Class type, DBObject query, MongoStoreInvocationContext context) { - List foundObjects = loadEntities(type, query, context); - if (foundObjects.size() == 0) { - return false; - } else { - DBCollection dbCollection = getDBCollectionForType(type); - dbCollection.remove(query); - logger.info("Removed " + foundObjects.size() + " entities of type: " + type + ", query: " + query); - - for (MongoIdentifiableEntity found : foundObjects) { - context.addRemovedEntity(found);; - } - return true; - } - } - - @Override - public boolean pushItemToList(final MongoIdentifiableEntity entity, final String listPropertyName, S itemToPush, boolean skipIfAlreadyPresent, MongoStoreInvocationContext context) { - final Class type = entity.getClass(); - EntityInfo entityInfo = getEntityInfo(type); - - // Add item to list directly in this object - Property listProperty = entityInfo.getPropertyByName(listPropertyName); - if (listProperty == null) { - throw new IllegalArgumentException("Property " + listPropertyName + " doesn't exist on object " + entity); - } - - List list = (List)listProperty.getValue(entity); - if (list == null) { - list = new ArrayList(); - listProperty.setValue(entity, list); - } - - // Skip if item is already in list - if (skipIfAlreadyPresent && list.contains(itemToPush)) { - return false; - } - - // Update java object - list.add(itemToPush); - - // Add update of list to pending tasks - final List listt = list; - context.addUpdateTask(entity, new MongoTask() { - - @Override - public void execute() { - // Now DB update of new list with usage of $set - BasicDBList dbList = mapperRegistry.convertApplicationObjectToDBObject(listt, BasicDBList.class); - - BasicDBObject query = new BasicDBObject("_id", entity.getId()); - BasicDBObject listObject = new BasicDBObject(listPropertyName, dbList); - BasicDBObject setCommand = new BasicDBObject("$set", listObject); - getDBCollectionForType(type).update(query, setCommand); - } - - @Override - public boolean isFullUpdate() { - return false; - } - }); - - return true; - } - - - @Override - public boolean pullItemFromList(final MongoIdentifiableEntity entity, final String listPropertyName, final S itemToPull, MongoStoreInvocationContext context) { - final Class type = entity.getClass(); - EntityInfo entityInfo = getEntityInfo(type); - - // Remove item from list directly in this object - Property listProperty = entityInfo.getPropertyByName(listPropertyName); - if (listProperty == null) { - throw new IllegalArgumentException("Property " + listPropertyName + " doesn't exist on object " + entity); - } - List list = (List)listProperty.getValue(entity); - - // If list is null, we skip both object and DB update - if (list == null || !list.contains(itemToPull)) { - return false; - } else { - - // Update java object - list.remove(itemToPull); - - // Add update of list to pending tasks - context.addUpdateTask(entity, new MongoTask() { - - @Override - public void execute() { - // Pull item from DB - Object dbItemToPull = mapperRegistry.convertApplicationObjectToDBObject(itemToPull, Object.class); - BasicDBObject query = new BasicDBObject("_id", entity.getId()); - BasicDBObject pullObject = new BasicDBObject(listPropertyName, dbItemToPull); - BasicDBObject pullCommand = new BasicDBObject("$pull", pullObject); - getDBCollectionForType(type).update(query, pullCommand); - } - - @Override - public boolean isFullUpdate() { - return false; - } - }); - - return true; - } - } - - // Possibility to add user-defined mappers - public void addAppObjectConverter(Mapper mapper) { - mapperRegistry.addAppObjectMapper(mapper); - } - - public void addDBObjectConverter(Mapper mapper) { - mapperRegistry.addDBObjectMapper(mapper); - } - - public EntityInfo getEntityInfo(Class entityClass) { - EntityInfo entityInfo = entityInfoCache.get(entityClass); - if (entityInfo == null) { - List> properties = PropertyQueries.createQuery(entityClass).addCriteria(new AnnotatedPropertyCriteria(MongoField.class)).getResultList(); - - MongoCollection classAnnotation = entityClass.getAnnotation(MongoCollection.class); - - String dbCollectionName = classAnnotation==null ? null : classAnnotation.collectionName(); - entityInfo = new EntityInfo(entityClass, dbCollectionName, properties); - - EntityInfo existing = entityInfoCache.putIfAbsent(entityClass, entityInfo); - if (existing != null) { - entityInfo = existing; - } - } - - return entityInfo; - } - - protected List convertCursor(Class type, DBCursor cursor, MongoStoreInvocationContext context) { - List result = new ArrayList(); - - try { - for (DBObject dbObject : cursor) { - T entity = convertDBObjectToEntity(type, dbObject, context); - result.add(entity); - } - } finally { - cursor.close(); - } - - return result; - } - - protected T convertDBObjectToEntity(Class type, DBObject dbObject, MongoStoreInvocationContext context) { - // First look if we already have loaded object cached. If yes, we will use cached instance - String id = dbObject.get("_id").toString(); - T object = context.getLoadedEntity(type, id); - - if (object == null) { - // So convert and use fresh instance from DB - MapperContext mapperContext = new MapperContext(dbObject, type, null); - object = mapperRegistry.convertDBObjectToApplicationObject(mapperContext); - context.addLoadedEntity(object); - } - return object; - } - - protected DBCollection getDBCollectionForType(Class type) { - EntityInfo entityInfo = getEntityInfo(type); - String dbCollectionName = entityInfo.getDbCollectionName(); - return dbCollectionName==null ? null : database.getCollection(dbCollectionName); - } -} +package org.keycloak.models.mongo.impl; + +import com.mongodb.BasicDBList; +import com.mongodb.BasicDBObject; +import com.mongodb.DB; +import com.mongodb.DBCollection; +import com.mongodb.DBCursor; +import com.mongodb.DBObject; +import org.jboss.logging.Logger; +import org.keycloak.models.mongo.api.MongoCollection; +import org.keycloak.models.mongo.api.MongoEntity; +import org.keycloak.models.mongo.api.MongoField; +import org.keycloak.models.mongo.api.MongoIdentifiableEntity; +import org.keycloak.models.mongo.api.MongoStore; +import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; +import org.keycloak.models.mongo.api.context.MongoTask; +import org.keycloak.models.mongo.api.types.Mapper; +import org.keycloak.models.mongo.api.types.MapperContext; +import org.keycloak.models.mongo.api.types.MapperRegistry; +import org.keycloak.models.mongo.impl.types.BasicDBListMapper; +import org.keycloak.models.mongo.impl.types.BasicDBObjectMapper; +import org.keycloak.models.mongo.impl.types.BasicDBObjectToMapMapper; +import org.keycloak.models.mongo.impl.types.EnumToStringMapper; +import org.keycloak.models.mongo.impl.types.ListMapper; +import org.keycloak.models.mongo.impl.types.MapMapper; +import org.keycloak.models.mongo.impl.types.MongoEntityMapper; +import org.keycloak.models.mongo.impl.types.SimpleMapper; +import org.keycloak.models.mongo.impl.types.StringToEnumMapper; +import org.keycloak.models.utils.KeycloakModelUtils; +import org.picketlink.common.properties.Property; +import org.picketlink.common.properties.query.AnnotatedPropertyCriteria; +import org.picketlink.common.properties.query.PropertyQueries; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @author Marek Posolda + */ +public class MongoStoreImpl implements MongoStore { + + private static final Class[] SIMPLE_TYPES = { String.class, Integer.class, Boolean.class, Long.class, Double.class, Character.class, Date.class, byte[].class }; + + private final DB database; + private static final Logger logger = Logger.getLogger(MongoStoreImpl.class); + + private final MapperRegistry mapperRegistry; + private ConcurrentMap, EntityInfo> entityInfoCache = + new ConcurrentHashMap, EntityInfo>(); + + + public MongoStoreImpl(DB database, boolean clearCollectionsOnStartup, Class[] managedEntityTypes) { + this.database = database; + + mapperRegistry = new MapperRegistry(); + + for (Class simpleConverterClass : SIMPLE_TYPES) { + SimpleMapper converter = new SimpleMapper(simpleConverterClass); + mapperRegistry.addAppObjectMapper(converter); + mapperRegistry.addDBObjectMapper(converter); + } + + // Specific converter for ArrayList is added just for performance purposes to avoid recursive converter lookup (most of list impl will be ArrayList) + mapperRegistry.addAppObjectMapper(new ListMapper(mapperRegistry, ArrayList.class)); + mapperRegistry.addAppObjectMapper(new ListMapper(mapperRegistry, List.class)); + mapperRegistry.addDBObjectMapper(new BasicDBListMapper(mapperRegistry)); + + mapperRegistry.addAppObjectMapper(new MapMapper(HashMap.class)); + mapperRegistry.addAppObjectMapper(new MapMapper(Map.class)); + mapperRegistry.addDBObjectMapper(new BasicDBObjectToMapMapper()); + + // Enum converters + mapperRegistry.addAppObjectMapper(new EnumToStringMapper()); + mapperRegistry.addDBObjectMapper(new StringToEnumMapper()); + + for (Class type : managedEntityTypes) { + getEntityInfo(type); + mapperRegistry.addAppObjectMapper(new MongoEntityMapper(this, mapperRegistry, type)); + mapperRegistry.addDBObjectMapper(new BasicDBObjectMapper(this, mapperRegistry, type)); + } + + if (clearCollectionsOnStartup) { + // dropDatabase(); + clearManagedCollections(managedEntityTypes); + } + } + + protected void dropDatabase() { + this.database.dropDatabase(); + logger.info("Database " + this.database.getName() + " dropped in MongoDB"); + } + + // Don't drop database, but just clear all data in managed collections (useful for development) + protected void clearManagedCollections(Class[] managedEntityTypes) { + for (Class clazz : managedEntityTypes) { + DBCollection dbCollection = getDBCollectionForType(clazz); + if (dbCollection != null) { + dbCollection.remove(new BasicDBObject()); + logger.debug("Collection " + dbCollection.getName() + " cleared from " + this.database.getName()); + } + } + } + + @Override + public void insertEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context) { + Class clazz = entity.getClass(); + + // Find annotations for ID, for all the properties and for the name of the collection. + EntityInfo entityInfo = getEntityInfo(clazz); + + // Create instance of BasicDBObject and add all declared properties to it (properties with null value probably should be skipped) + BasicDBObject dbObject = mapperRegistry.convertApplicationObjectToDBObject(entity, BasicDBObject.class); + + DBCollection dbCollection = database.getCollection(entityInfo.getDbCollectionName()); + + String currentId = entity.getId(); + + // Generate random ID if not set already + if (currentId == null) { + currentId = KeycloakModelUtils.generateId(); + entity.setId(currentId); + } + + // Adding "_id" + dbObject.put("_id", currentId); + + dbCollection.insert(dbObject); + + // Treat object as created in this transaction (It is already submited to transaction) + context.addCreatedEntity(entity); + } + + @Override + public void updateEntity(final MongoIdentifiableEntity entity, MongoStoreInvocationContext context) { + MongoTask fullUpdateTask = new MongoTask() { + + @Override + public void execute() { + Class clazz = entity.getClass(); + EntityInfo entityInfo = getEntityInfo(clazz); + BasicDBObject dbObject = mapperRegistry.convertApplicationObjectToDBObject(entity, BasicDBObject.class); + DBCollection dbCollection = database.getCollection(entityInfo.getDbCollectionName()); + + String currentId = entity.getId(); + + if (currentId == null) { + throw new IllegalStateException("Can't update entity without id: " + entity); + } else { + BasicDBObject query = new BasicDBObject("_id", currentId); + dbCollection.update(query, dbObject); + } + } + + @Override + public boolean isFullUpdate() { + return true; + } + }; + + // update is just added to context and postponed + context.addUpdateTask(entity, fullUpdateTask); + } + + + @Override + public T loadEntity(Class type, String id, MongoStoreInvocationContext context) { + // First look if we already read the object with this oid and type during this transaction. If yes, use it instead of DB lookup + T cached = context.getLoadedEntity(type, id); + if (cached != null) return cached; + + DBCollection dbCollection = getDBCollectionForType(type); + + BasicDBObject idQuery = new BasicDBObject("_id", id); + DBObject dbObject = dbCollection.findOne(idQuery); + + if (dbObject == null) return null; + + MapperContext mapperContext = new MapperContext(dbObject, type, null); + T converted = mapperRegistry.convertDBObjectToApplicationObject(mapperContext); + + // Now add it to loaded objects + context.addLoadedEntity(converted); + + return converted; + } + + + @Override + public T loadSingleEntity(Class type, DBObject query, MongoStoreInvocationContext context) { + // First we should execute all pending tasks before searching DB + context.beforeDBSearch(type); + + DBCollection dbCollection = getDBCollectionForType(type); + DBObject dbObject = dbCollection.findOne(query); + + if (dbObject == null) { + return null; + } else { + return convertDBObjectToEntity(type, dbObject, context); + } + } + + + @Override + public List loadEntities(Class type, DBObject query, MongoStoreInvocationContext context) { + // First we should execute all pending tasks before searching DB + context.beforeDBSearch(type); + + DBCollection dbCollection = getDBCollectionForType(type); + DBCursor cursor = dbCollection.find(query); + + return convertCursor(type, cursor, context); + } + + + @Override + public boolean removeEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context) { + return removeEntity(entity.getClass(), entity.getId(), context); + } + + + @Override + public boolean removeEntity(Class type, String id, MongoStoreInvocationContext context) { + MongoIdentifiableEntity found = loadEntity(type, id, context); + if (found == null) { + return false; + } else { + DBCollection dbCollection = getDBCollectionForType(type); + BasicDBObject dbQuery = new BasicDBObject("_id", id); + dbCollection.remove(dbQuery); + logger.info("Entity of type: " + type + ", id: " + id + " removed from MongoDB."); + + context.addRemovedEntity(found); + return true; + } + } + + + @Override + public boolean removeEntities(Class type, DBObject query, MongoStoreInvocationContext context) { + List foundObjects = loadEntities(type, query, context); + if (foundObjects.size() == 0) { + return false; + } else { + DBCollection dbCollection = getDBCollectionForType(type); + dbCollection.remove(query); + logger.info("Removed " + foundObjects.size() + " entities of type: " + type + ", query: " + query); + + for (MongoIdentifiableEntity found : foundObjects) { + context.addRemovedEntity(found);; + } + return true; + } + } + + @Override + public boolean pushItemToList(final MongoIdentifiableEntity entity, final String listPropertyName, S itemToPush, boolean skipIfAlreadyPresent, MongoStoreInvocationContext context) { + final Class type = entity.getClass(); + EntityInfo entityInfo = getEntityInfo(type); + + // Add item to list directly in this object + Property listProperty = entityInfo.getPropertyByName(listPropertyName); + if (listProperty == null) { + throw new IllegalArgumentException("Property " + listPropertyName + " doesn't exist on object " + entity); + } + + List list = (List)listProperty.getValue(entity); + if (list == null) { + list = new ArrayList(); + listProperty.setValue(entity, list); + } + + // Skip if item is already in list + if (skipIfAlreadyPresent && list.contains(itemToPush)) { + return false; + } + + // Update java object + list.add(itemToPush); + + // Add update of list to pending tasks + final List listt = list; + context.addUpdateTask(entity, new MongoTask() { + + @Override + public void execute() { + // Now DB update of new list with usage of $set + BasicDBList dbList = mapperRegistry.convertApplicationObjectToDBObject(listt, BasicDBList.class); + + BasicDBObject query = new BasicDBObject("_id", entity.getId()); + BasicDBObject listObject = new BasicDBObject(listPropertyName, dbList); + BasicDBObject setCommand = new BasicDBObject("$set", listObject); + getDBCollectionForType(type).update(query, setCommand); + } + + @Override + public boolean isFullUpdate() { + return false; + } + }); + + return true; + } + + + @Override + public boolean pullItemFromList(final MongoIdentifiableEntity entity, final String listPropertyName, final S itemToPull, MongoStoreInvocationContext context) { + final Class type = entity.getClass(); + EntityInfo entityInfo = getEntityInfo(type); + + // Remove item from list directly in this object + Property listProperty = entityInfo.getPropertyByName(listPropertyName); + if (listProperty == null) { + throw new IllegalArgumentException("Property " + listPropertyName + " doesn't exist on object " + entity); + } + List list = (List)listProperty.getValue(entity); + + // If list is null, we skip both object and DB update + if (list == null || !list.contains(itemToPull)) { + return false; + } else { + + // Update java object + list.remove(itemToPull); + + // Add update of list to pending tasks + context.addUpdateTask(entity, new MongoTask() { + + @Override + public void execute() { + // Pull item from DB + Object dbItemToPull = mapperRegistry.convertApplicationObjectToDBObject(itemToPull, Object.class); + BasicDBObject query = new BasicDBObject("_id", entity.getId()); + BasicDBObject pullObject = new BasicDBObject(listPropertyName, dbItemToPull); + BasicDBObject pullCommand = new BasicDBObject("$pull", pullObject); + getDBCollectionForType(type).update(query, pullCommand); + } + + @Override + public boolean isFullUpdate() { + return false; + } + }); + + return true; + } + } + + // Possibility to add user-defined mappers + public void addAppObjectConverter(Mapper mapper) { + mapperRegistry.addAppObjectMapper(mapper); + } + + public void addDBObjectConverter(Mapper mapper) { + mapperRegistry.addDBObjectMapper(mapper); + } + + public EntityInfo getEntityInfo(Class entityClass) { + EntityInfo entityInfo = entityInfoCache.get(entityClass); + if (entityInfo == null) { + List> properties = PropertyQueries.createQuery(entityClass).addCriteria(new AnnotatedPropertyCriteria(MongoField.class)).getResultList(); + + MongoCollection classAnnotation = entityClass.getAnnotation(MongoCollection.class); + + String dbCollectionName = classAnnotation==null ? null : classAnnotation.collectionName(); + entityInfo = new EntityInfo(entityClass, dbCollectionName, properties); + + EntityInfo existing = entityInfoCache.putIfAbsent(entityClass, entityInfo); + if (existing != null) { + entityInfo = existing; + } + } + + return entityInfo; + } + + protected List convertCursor(Class type, DBCursor cursor, MongoStoreInvocationContext context) { + List result = new ArrayList(); + + try { + for (DBObject dbObject : cursor) { + T entity = convertDBObjectToEntity(type, dbObject, context); + result.add(entity); + } + } finally { + cursor.close(); + } + + return result; + } + + protected T convertDBObjectToEntity(Class type, DBObject dbObject, MongoStoreInvocationContext context) { + // First look if we already have loaded object cached. If yes, we will use cached instance + String id = dbObject.get("_id").toString(); + T object = context.getLoadedEntity(type, id); + + if (object == null) { + // So convert and use fresh instance from DB + MapperContext mapperContext = new MapperContext(dbObject, type, null); + object = mapperRegistry.convertDBObjectToApplicationObject(mapperContext); + context.addLoadedEntity(object); + } + return object; + } + + protected DBCollection getDBCollectionForType(Class type) { + EntityInfo entityInfo = getEntityInfo(type); + String dbCollectionName = entityInfo.getDbCollectionName(); + return dbCollectionName==null ? null : database.getCollection(dbCollectionName); + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/BasicDBListMapper.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/BasicDBListMapper.java index ff81604f60..58d8b9d029 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/BasicDBListMapper.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/BasicDBListMapper.java @@ -1,44 +1,44 @@ -package org.keycloak.models.mongo.impl.types; - -import com.mongodb.BasicDBList; -import org.keycloak.models.mongo.api.types.Mapper; -import org.keycloak.models.mongo.api.types.MapperContext; -import org.keycloak.models.mongo.api.types.MapperRegistry; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Marek Posolda - */ -public class BasicDBListMapper implements Mapper { - - private final MapperRegistry mapperRegistry; - - public BasicDBListMapper(MapperRegistry mapperRegistry) { - this.mapperRegistry = mapperRegistry; - } - - @Override - public List convertObject(MapperContext context) { - BasicDBList dbList = context.getObjectToConvert(); - ArrayList appObjects = new ArrayList(); - Class expectedListElementType = context.getGenericTypes().get(0); - - for (Object dbObject : dbList) { - MapperContext newContext = new MapperContext(dbObject, expectedListElementType, null); - appObjects.add(mapperRegistry.convertDBObjectToApplicationObject(newContext)); - } - return appObjects; - } - - @Override - public Class getTypeOfObjectToConvert() { - return BasicDBList.class; - } - - @Override - public Class getExpectedReturnType() { - return List.class; - } -} +package org.keycloak.models.mongo.impl.types; + +import com.mongodb.BasicDBList; +import org.keycloak.models.mongo.api.types.Mapper; +import org.keycloak.models.mongo.api.types.MapperContext; +import org.keycloak.models.mongo.api.types.MapperRegistry; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Marek Posolda + */ +public class BasicDBListMapper implements Mapper { + + private final MapperRegistry mapperRegistry; + + public BasicDBListMapper(MapperRegistry mapperRegistry) { + this.mapperRegistry = mapperRegistry; + } + + @Override + public List convertObject(MapperContext context) { + BasicDBList dbList = context.getObjectToConvert(); + ArrayList appObjects = new ArrayList(); + Class expectedListElementType = context.getGenericTypes().get(0); + + for (Object dbObject : dbList) { + MapperContext newContext = new MapperContext(dbObject, expectedListElementType, null); + appObjects.add(mapperRegistry.convertDBObjectToApplicationObject(newContext)); + } + return appObjects; + } + + @Override + public Class getTypeOfObjectToConvert() { + return BasicDBList.class; + } + + @Override + public Class getExpectedReturnType() { + return List.class; + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/ListMapper.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/ListMapper.java index 7ac9a593e7..7857e365bf 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/ListMapper.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/ListMapper.java @@ -1,45 +1,45 @@ -package org.keycloak.models.mongo.impl.types; - -import com.mongodb.BasicDBList; -import org.keycloak.models.mongo.api.types.Mapper; -import org.keycloak.models.mongo.api.types.MapperContext; -import org.keycloak.models.mongo.api.types.MapperRegistry; - -import java.util.List; - -/** - * @author Marek Posolda - */ -public class ListMapper implements Mapper { - - private final MapperRegistry mapperRegistry; - private final Class listType; - - public ListMapper(MapperRegistry mapperRegistry, Class listType) { - this.mapperRegistry = mapperRegistry; - this.listType = listType; - } - - @Override - public BasicDBList convertObject(MapperContext context) { - T appObjectsList = context.getObjectToConvert(); - - BasicDBList dbObjects = new BasicDBList(); - for (Object appObject : appObjectsList) { - Object dbObject = mapperRegistry.convertApplicationObjectToDBObject(appObject, Object.class); - - dbObjects.add(dbObject); - } - return dbObjects; - } - - @Override - public Class getTypeOfObjectToConvert() { - return listType; - } - - @Override - public Class getExpectedReturnType() { - return BasicDBList.class; - } -} +package org.keycloak.models.mongo.impl.types; + +import com.mongodb.BasicDBList; +import org.keycloak.models.mongo.api.types.Mapper; +import org.keycloak.models.mongo.api.types.MapperContext; +import org.keycloak.models.mongo.api.types.MapperRegistry; + +import java.util.List; + +/** + * @author Marek Posolda + */ +public class ListMapper implements Mapper { + + private final MapperRegistry mapperRegistry; + private final Class listType; + + public ListMapper(MapperRegistry mapperRegistry, Class listType) { + this.mapperRegistry = mapperRegistry; + this.listType = listType; + } + + @Override + public BasicDBList convertObject(MapperContext context) { + T appObjectsList = context.getObjectToConvert(); + + BasicDBList dbObjects = new BasicDBList(); + for (Object appObject : appObjectsList) { + Object dbObject = mapperRegistry.convertApplicationObjectToDBObject(appObject, Object.class); + + dbObjects.add(dbObject); + } + return dbObjects; + } + + @Override + public Class getTypeOfObjectToConvert() { + return listType; + } + + @Override + public Class getExpectedReturnType() { + return BasicDBList.class; + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/MongoEntityMapper.java b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/MongoEntityMapper.java index 8fb29ebc42..d62deac409 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/MongoEntityMapper.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/MongoEntityMapper.java @@ -1,58 +1,58 @@ -package org.keycloak.models.mongo.impl.types; - -import com.mongodb.BasicDBObject; -import org.keycloak.models.mongo.api.MongoEntity; -import org.keycloak.models.mongo.api.types.Mapper; -import org.keycloak.models.mongo.api.types.MapperContext; -import org.keycloak.models.mongo.api.types.MapperRegistry; -import org.keycloak.models.mongo.impl.MongoStoreImpl; -import org.keycloak.models.mongo.impl.EntityInfo; -import org.picketlink.common.properties.Property; - -import java.util.Collection; - -/** - * @author Marek Posolda - */ -public class MongoEntityMapper implements Mapper { - - private final MongoStoreImpl mongoStoreImpl; - private final MapperRegistry mapperRegistry; - private final Class expectedMongoEntityType; - - public MongoEntityMapper(MongoStoreImpl mongoStoreImpl, MapperRegistry mapperRegistry, Class expectedMongoEntityType) { - this.mongoStoreImpl = mongoStoreImpl; - this.mapperRegistry = mapperRegistry; - this.expectedMongoEntityType = expectedMongoEntityType; - } - - @Override - public BasicDBObject convertObject(MapperContext context) { - T applicationObject = context.getObjectToConvert(); - - EntityInfo entityInfo = mongoStoreImpl.getEntityInfo(applicationObject.getClass()); - - // Create instance of BasicDBObject and add all declared properties to it - BasicDBObject dbObject = new BasicDBObject(); - Collection> props = entityInfo.getProperties(); - for (Property property : props) { - String propName = property.getName(); - Object propValue = property.getValue(applicationObject); - - Object dbValue = propValue == null ? null : mapperRegistry.convertApplicationObjectToDBObject(propValue, Object.class); - dbObject.put(propName, dbValue); - } - - return dbObject; - } - - @Override - public Class getTypeOfObjectToConvert() { - return expectedMongoEntityType; - } - - @Override - public Class getExpectedReturnType() { - return BasicDBObject.class; - } -} +package org.keycloak.models.mongo.impl.types; + +import com.mongodb.BasicDBObject; +import org.keycloak.models.mongo.api.MongoEntity; +import org.keycloak.models.mongo.api.types.Mapper; +import org.keycloak.models.mongo.api.types.MapperContext; +import org.keycloak.models.mongo.api.types.MapperRegistry; +import org.keycloak.models.mongo.impl.MongoStoreImpl; +import org.keycloak.models.mongo.impl.EntityInfo; +import org.picketlink.common.properties.Property; + +import java.util.Collection; + +/** + * @author Marek Posolda + */ +public class MongoEntityMapper implements Mapper { + + private final MongoStoreImpl mongoStoreImpl; + private final MapperRegistry mapperRegistry; + private final Class expectedMongoEntityType; + + public MongoEntityMapper(MongoStoreImpl mongoStoreImpl, MapperRegistry mapperRegistry, Class expectedMongoEntityType) { + this.mongoStoreImpl = mongoStoreImpl; + this.mapperRegistry = mapperRegistry; + this.expectedMongoEntityType = expectedMongoEntityType; + } + + @Override + public BasicDBObject convertObject(MapperContext context) { + T applicationObject = context.getObjectToConvert(); + + EntityInfo entityInfo = mongoStoreImpl.getEntityInfo(applicationObject.getClass()); + + // Create instance of BasicDBObject and add all declared properties to it + BasicDBObject dbObject = new BasicDBObject(); + Collection> props = entityInfo.getProperties(); + for (Property property : props) { + String propName = property.getName(); + Object propValue = property.getValue(applicationObject); + + Object dbValue = propValue == null ? null : mapperRegistry.convertApplicationObjectToDBObject(propValue, Object.class); + dbObject.put(propName, dbValue); + } + + return dbObject; + } + + @Override + public Class getTypeOfObjectToConvert() { + return expectedMongoEntityType; + } + + @Override + public Class getExpectedReturnType() { + return BasicDBObject.class; + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java index 07d8764f4e..07c535f124 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java @@ -1,305 +1,317 @@ -package org.keycloak.models.mongo.keycloak.adapters; - -import com.mongodb.DBObject; -import com.mongodb.QueryBuilder; -import org.keycloak.models.ApplicationModel; -import org.keycloak.models.ClientModel; -import org.keycloak.models.RoleModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; -import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; -import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity; -import org.keycloak.models.mongo.keycloak.entities.RoleEntity; -import org.keycloak.models.mongo.keycloak.entities.UserEntity; -import org.keycloak.models.mongo.utils.MongoModelUtils; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * @author Marek Posolda - */ -public class ApplicationAdapter extends AbstractAdapter implements ApplicationModel { - - private final ApplicationEntity application; - - public ApplicationAdapter(ApplicationEntity applicationEntity, MongoStoreInvocationContext invContext) { - super(invContext); - this.application = applicationEntity; - } - - @Override - public void updateApplication() { - getMongoStore().updateEntity(application, invocationContext); - } - - @Override - public String getId() { - return application.getId(); - } - - @Override - public String getClientId() { - return getName(); - } - - @Override - public String getName() { - return application.getName(); - } - - @Override - public void setName(String name) { - application.setName(name); - } - - @Override - public boolean isEnabled() { - return application.isEnabled(); - } - - @Override - public void setEnabled(boolean enabled) { - application.setEnabled(enabled); - } - - @Override - public boolean isSurrogateAuthRequired() { - return application.isSurrogateAuthRequired(); - } - - @Override - public void setSurrogateAuthRequired(boolean surrogateAuthRequired) { - application.setSurrogateAuthRequired(surrogateAuthRequired); - } - - @Override - public String getManagementUrl() { - return application.getManagementUrl(); - } - - @Override - public void setManagementUrl(String url) { - application.setManagementUrl(url); - } - - @Override - public void setBaseUrl(String url) { - application.setBaseUrl(url); - } - - @Override - public String getBaseUrl() { - return application.getBaseUrl(); - } - - @Override - public long getAllowedClaimsMask() { - return application.getAllowedClaimsMask(); - } - - @Override - public void setAllowedClaimsMask(long mask) { - application.setAllowedClaimsMask(mask); - } - - - @Override - public RoleAdapter getRole(String name) { - DBObject query = new QueryBuilder() - .and("name").is(name) - .and("applicationId").is(getId()) - .get(); - RoleEntity role = getMongoStore().loadSingleEntity(RoleEntity.class, query, invocationContext); - if (role == null) { - return null; - } else { - return new RoleAdapter(role, invocationContext); - } - } - - @Override - public RoleModel getRoleById(String id) { - RoleEntity role = getMongoStore().loadEntity(RoleEntity.class, id, invocationContext); - - // Check that role belongs to this application - if (role == null || !getId().equals(role.getApplicationId())) { - return null; - } else { - return new RoleAdapter(role, this, invocationContext); - } - } - - @Override - public RoleAdapter addRole(String name) { - RoleAdapter existing = getRole(name); - if (existing != null) { - return existing; - } - - RoleEntity roleEntity = new RoleEntity(); - roleEntity.setName(name); - roleEntity.setApplicationId(getId()); - - getMongoStore().insertEntity(roleEntity, invocationContext); - return new RoleAdapter(roleEntity, this, invocationContext); - } - - @Override - public boolean removeRoleById(String id) { - return getMongoStore().removeEntity(RoleEntity.class, id, invocationContext); - } - - @Override - public Set getRoles() { - DBObject query = new QueryBuilder() - .and("applicationId").is(getId()) - .get(); - List roles = getMongoStore().loadEntities(RoleEntity.class, query, invocationContext); - - Set result = new HashSet(); - for (RoleEntity role : roles) { - result.add(new RoleAdapter(role, this, invocationContext)); - } - - return result; - } - - @Override - public Set getApplicationRoleMappings(UserModel user) { - Set result = new HashSet(); - List roles = MongoModelUtils.getAllRolesOfUser(user, invocationContext); - - for (RoleEntity role : roles) { - if (getId().equals(role.getApplicationId())) { - result.add(new RoleAdapter(role, this, invocationContext)); - } - } - return result; - } - - @Override - public void addScope(RoleModel role) { - getMongoStore().pushItemToList(application, "scopeIds", role.getId(), true, invocationContext); - } - - @Override - public Set getApplicationScopeMappings(ClientModel client) { - Set result = new HashSet(); - List roles = MongoModelUtils.getAllScopesOfClient(client, invocationContext); - - for (RoleEntity role : roles) { - if (getId().equals(role.getApplicationId())) { - result.add(new RoleAdapter(role, this, invocationContext)); - } - } - return result; - } - - @Override - public List getDefaultRoles() { - return application.getDefaultRoles(); - } - - @Override - public void addDefaultRole(String name) { - RoleModel role = getRole(name); - if (role == null) { - addRole(name); - } - - getMongoStore().pushItemToList(application, "defaultRoles", name, true, invocationContext); - } - - @Override - public void updateDefaultRoles(String[] defaultRoles) { - List roleNames = new ArrayList(); - for (String roleName : defaultRoles) { - RoleModel role = getRole(roleName); - if (role == null) { - addRole(roleName); - } - - roleNames.add(roleName); - } - - application.setDefaultRoles(roleNames); - } - - @Override - public AbstractMongoIdentifiableEntity getMongoEntity() { - return application; - } - - @Override - public Set getWebOrigins() { - Set result = new HashSet(); - if (application.getWebOrigins() != null) { - result.addAll(application.getWebOrigins()); - } - return result; - } - - @Override - public void setWebOrigins(Set webOrigins) { - List result = new ArrayList(); - result.addAll(webOrigins); - application.setWebOrigins(result); - } - - @Override - public void addWebOrigin(String webOrigin) { - getMongoStore().pushItemToList(application, "webOrigins", webOrigin, true, invocationContext); - } - - @Override - public void removeWebOrigin(String webOrigin) { - getMongoStore().pullItemFromList(application, "webOrigins", webOrigin, invocationContext); - } - - @Override - public Set getRedirectUris() { - Set result = new HashSet(); - if (application.getRedirectUris() != null) { - result.addAll(application.getRedirectUris()); - } - return result; - } - - @Override - public void setRedirectUris(Set redirectUris) { - List result = new ArrayList(); - result.addAll(redirectUris); - application.setRedirectUris(result); - } - - @Override - public void addRedirectUri(String redirectUri) { - getMongoStore().pushItemToList(application, "redirectUris", redirectUri, true, invocationContext); - } - - @Override - public void removeRedirectUri(String redirectUri) { - getMongoStore().pullItemFromList(application, "redirectUris", redirectUri, invocationContext); - } - - @Override - public String getSecret() { - return application.getSecret(); - } - - @Override - public void setSecret(String secret) { - application.setSecret(secret); - } - - - @Override - public boolean validateSecret(String secret) { - return secret.equals(application.getSecret()); - } - - -} +package org.keycloak.models.mongo.keycloak.adapters; + +import com.mongodb.DBObject; +import com.mongodb.QueryBuilder; +import org.keycloak.models.ApplicationModel; +import org.keycloak.models.ClientModel; +import org.keycloak.models.RealmModel; +import org.keycloak.models.RoleModel; +import org.keycloak.models.UserModel; +import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; +import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; +import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity; +import org.keycloak.models.mongo.keycloak.entities.RoleEntity; +import org.keycloak.models.mongo.keycloak.entities.UserEntity; +import org.keycloak.models.mongo.utils.MongoModelUtils; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author Marek Posolda + */ +public class ApplicationAdapter extends AbstractAdapter implements ApplicationModel { + + private final ApplicationEntity application; + private final RealmModel realm; + + public ApplicationAdapter(RealmModel realm, ApplicationEntity applicationEntity, MongoStoreInvocationContext invContext) { + super(invContext); + this.application = applicationEntity; + this.realm = realm; + } + + @Override + public void updateApplication() { + getMongoStore().updateEntity(application, invocationContext); + } + + @Override + public String getId() { + return application.getId(); + } + + @Override + public String getClientId() { + return getName(); + } + + @Override + public String getName() { + return application.getName(); + } + + @Override + public void setName(String name) { + application.setName(name); + } + + @Override + public RealmModel getRealm() { + return realm; + } + + @Override + public boolean isEnabled() { + return application.isEnabled(); + } + + @Override + public void setEnabled(boolean enabled) { + application.setEnabled(enabled); + } + + @Override + public boolean isSurrogateAuthRequired() { + return application.isSurrogateAuthRequired(); + } + + @Override + public void setSurrogateAuthRequired(boolean surrogateAuthRequired) { + application.setSurrogateAuthRequired(surrogateAuthRequired); + } + + @Override + public String getManagementUrl() { + return application.getManagementUrl(); + } + + @Override + public void setManagementUrl(String url) { + application.setManagementUrl(url); + } + + @Override + public void setBaseUrl(String url) { + application.setBaseUrl(url); + } + + @Override + public String getBaseUrl() { + return application.getBaseUrl(); + } + + @Override + public long getAllowedClaimsMask() { + return application.getAllowedClaimsMask(); + } + + @Override + public void setAllowedClaimsMask(long mask) { + application.setAllowedClaimsMask(mask); + } + + + @Override + public RoleAdapter getRole(String name) { + DBObject query = new QueryBuilder() + .and("name").is(name) + .and("applicationId").is(getId()) + .get(); + RoleEntity role = getMongoStore().loadSingleEntity(RoleEntity.class, query, invocationContext); + if (role == null) { + return null; + } else { + return new RoleAdapter(getRealm(), role, invocationContext); + } + } + + @Override + public RoleAdapter addRole(String name) { + RoleAdapter existing = getRole(name); + if (existing != null) { + return existing; + } + + RoleEntity roleEntity = new RoleEntity(); + roleEntity.setName(name); + roleEntity.setApplicationId(getId()); + + getMongoStore().insertEntity(roleEntity, invocationContext); + return new RoleAdapter(getRealm(), roleEntity, this, invocationContext); + } + + @Override + public boolean removeRole(RoleModel role) { + return getMongoStore().removeEntity(RoleEntity.class, role.getId(), invocationContext); + } + + @Override + public Set getRoles() { + DBObject query = new QueryBuilder() + .and("applicationId").is(getId()) + .get(); + List roles = getMongoStore().loadEntities(RoleEntity.class, query, invocationContext); + + Set result = new HashSet(); + for (RoleEntity role : roles) { + result.add(new RoleAdapter(getRealm(), role, this, invocationContext)); + } + + return result; + } + + @Override + public Set getApplicationRoleMappings(UserModel user) { + Set result = new HashSet(); + List roles = MongoModelUtils.getAllRolesOfUser(user, invocationContext); + + for (RoleEntity role : roles) { + if (getId().equals(role.getApplicationId())) { + result.add(new RoleAdapter(getRealm(), role, this, invocationContext)); + } + } + return result; + } + + @Override + public void addScope(RoleModel role) { + getMongoStore().pushItemToList(application, "scopeIds", role.getId(), true, invocationContext); + } + + @Override + public Set getApplicationScopeMappings(ClientModel client) { + Set result = new HashSet(); + List roles = MongoModelUtils.getAllScopesOfClient(client, invocationContext); + + for (RoleEntity role : roles) { + if (getId().equals(role.getApplicationId())) { + result.add(new RoleAdapter(getRealm(), role, this, invocationContext)); + } + } + return result; + } + + @Override + public List getDefaultRoles() { + return application.getDefaultRoles(); + } + + @Override + public void addDefaultRole(String name) { + RoleModel role = getRole(name); + if (role == null) { + addRole(name); + } + + getMongoStore().pushItemToList(application, "defaultRoles", name, true, invocationContext); + } + + @Override + public void updateDefaultRoles(String[] defaultRoles) { + List roleNames = new ArrayList(); + for (String roleName : defaultRoles) { + RoleModel role = getRole(roleName); + if (role == null) { + addRole(roleName); + } + + roleNames.add(roleName); + } + + application.setDefaultRoles(roleNames); + } + + @Override + public AbstractMongoIdentifiableEntity getMongoEntity() { + return application; + } + + @Override + public Set getWebOrigins() { + Set result = new HashSet(); + if (application.getWebOrigins() != null) { + result.addAll(application.getWebOrigins()); + } + return result; + } + + @Override + public void setWebOrigins(Set webOrigins) { + List result = new ArrayList(); + result.addAll(webOrigins); + application.setWebOrigins(result); + } + + @Override + public void addWebOrigin(String webOrigin) { + getMongoStore().pushItemToList(application, "webOrigins", webOrigin, true, invocationContext); + } + + @Override + public void removeWebOrigin(String webOrigin) { + getMongoStore().pullItemFromList(application, "webOrigins", webOrigin, invocationContext); + } + + @Override + public Set getRedirectUris() { + Set result = new HashSet(); + if (application.getRedirectUris() != null) { + result.addAll(application.getRedirectUris()); + } + return result; + } + + @Override + public void setRedirectUris(Set redirectUris) { + List result = new ArrayList(); + result.addAll(redirectUris); + application.setRedirectUris(result); + } + + @Override + public void addRedirectUri(String redirectUri) { + getMongoStore().pushItemToList(application, "redirectUris", redirectUri, true, invocationContext); + } + + @Override + public void removeRedirectUri(String redirectUri) { + getMongoStore().pullItemFromList(application, "redirectUris", redirectUri, invocationContext); + } + + @Override + public String getSecret() { + return application.getSecret(); + } + + @Override + public void setSecret(String secret) { + application.setSecret(secret); + } + + + @Override + public boolean validateSecret(String secret) { + return secret.equals(application.getSecret()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ApplicationAdapter)) return false; + if (!super.equals(o)) return false; + + ApplicationAdapter that = (ApplicationAdapter) o; + + if (!application.getId().equals(that.application.getId())) return false; + + return true; + } + + @Override + public int hashCode() { + return application.getId().hashCode(); + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java index 1420a09653..c90fe01650 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java @@ -1,100 +1,100 @@ -package org.keycloak.models.mongo.keycloak.adapters; - -import com.mongodb.BasicDBObject; -import com.mongodb.DBObject; -import com.mongodb.QueryBuilder; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.KeycloakTransaction; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.mongo.api.MongoStore; -import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; -import org.keycloak.models.mongo.impl.context.TransactionMongoStoreInvocationContext; -import org.keycloak.models.mongo.keycloak.entities.RealmEntity; -import org.keycloak.models.utils.KeycloakModelUtils; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Marek Posolda - */ -public class MongoKeycloakSession implements KeycloakSession { - - private final MongoStoreInvocationContext invocationContext; - private final MongoKeycloakTransaction transaction; - - public MongoKeycloakSession(MongoStore mongoStore) { - // this.invocationContext = new SimpleMongoStoreInvocationContext(mongoStore); - this.invocationContext = new TransactionMongoStoreInvocationContext(mongoStore); - this.transaction = new MongoKeycloakTransaction(invocationContext); - } - - @Override - public KeycloakTransaction getTransaction() { - return transaction; - } - - @Override - public void close() { - // TODO - } - - @Override - public RealmModel createRealm(String name) { - return createRealm(KeycloakModelUtils.generateId(), name); - } - - @Override - public RealmModel createRealm(String id, String name) { - if (getRealm(id) != null) { - throw new IllegalStateException("Realm with id '" + id + "' already exists"); - } - - RealmEntity newRealm = new RealmEntity(); - newRealm.setId(id); - newRealm.setName(name); - - getMongoStore().insertEntity(newRealm, invocationContext); - - return new RealmAdapter(newRealm, invocationContext); - } - - @Override - public RealmModel getRealm(String id) { - RealmEntity realmEntity = getMongoStore().loadEntity(RealmEntity.class, id, invocationContext); - return realmEntity != null ? new RealmAdapter(realmEntity, invocationContext) : null; - } - - @Override - public List getRealms() { - DBObject query = new BasicDBObject(); - List realms = getMongoStore().loadEntities(RealmEntity.class, query, invocationContext); - - List results = new ArrayList(); - for (RealmEntity realmEntity : realms) { - results.add(new RealmAdapter(realmEntity, invocationContext)); - } - return results; - } - - @Override - public RealmModel getRealmByName(String name) { - DBObject query = new QueryBuilder() - .and("name").is(name) - .get(); - RealmEntity realm = getMongoStore().loadSingleEntity(RealmEntity.class, query, invocationContext); - - if (realm == null) return null; - return new RealmAdapter(realm, invocationContext); - } - - @Override - public boolean removeRealm(String id) { - return getMongoStore().removeEntity(RealmEntity.class, id, invocationContext); - } - - protected MongoStore getMongoStore() { - return invocationContext.getMongoStore(); - } -} +package org.keycloak.models.mongo.keycloak.adapters; + +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; +import com.mongodb.QueryBuilder; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.KeycloakTransaction; +import org.keycloak.models.RealmModel; +import org.keycloak.models.UserModel; +import org.keycloak.models.mongo.api.MongoStore; +import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; +import org.keycloak.models.mongo.impl.context.TransactionMongoStoreInvocationContext; +import org.keycloak.models.mongo.keycloak.entities.RealmEntity; +import org.keycloak.models.utils.KeycloakModelUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Marek Posolda + */ +public class MongoKeycloakSession implements KeycloakSession { + + private final MongoStoreInvocationContext invocationContext; + private final MongoKeycloakTransaction transaction; + + public MongoKeycloakSession(MongoStore mongoStore) { + // this.invocationContext = new SimpleMongoStoreInvocationContext(mongoStore); + this.invocationContext = new TransactionMongoStoreInvocationContext(mongoStore); + this.transaction = new MongoKeycloakTransaction(invocationContext); + } + + @Override + public KeycloakTransaction getTransaction() { + return transaction; + } + + @Override + public void close() { + // TODO + } + + @Override + public RealmModel createRealm(String name) { + return createRealm(KeycloakModelUtils.generateId(), name); + } + + @Override + public RealmModel createRealm(String id, String name) { + if (getRealm(id) != null) { + throw new IllegalStateException("Realm with id '" + id + "' already exists"); + } + + RealmEntity newRealm = new RealmEntity(); + newRealm.setId(id); + newRealm.setName(name); + + getMongoStore().insertEntity(newRealm, invocationContext); + + return new RealmAdapter(newRealm, invocationContext); + } + + @Override + public RealmModel getRealm(String id) { + RealmEntity realmEntity = getMongoStore().loadEntity(RealmEntity.class, id, invocationContext); + return realmEntity != null ? new RealmAdapter(realmEntity, invocationContext) : null; + } + + @Override + public List getRealms() { + DBObject query = new BasicDBObject(); + List realms = getMongoStore().loadEntities(RealmEntity.class, query, invocationContext); + + List results = new ArrayList(); + for (RealmEntity realmEntity : realms) { + results.add(new RealmAdapter(realmEntity, invocationContext)); + } + return results; + } + + @Override + public RealmModel getRealmByName(String name) { + DBObject query = new QueryBuilder() + .and("name").is(name) + .get(); + RealmEntity realm = getMongoStore().loadSingleEntity(RealmEntity.class, query, invocationContext); + + if (realm == null) return null; + return new RealmAdapter(realm, invocationContext); + } + + @Override + public boolean removeRealm(String id) { + return getMongoStore().removeEntity(RealmEntity.class, id, invocationContext); + } + + protected MongoStore getMongoStore() { + return invocationContext.getMongoStore(); + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSessionFactory.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSessionFactory.java index 7ff4ead8d2..563dba4e50 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSessionFactory.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSessionFactory.java @@ -1,70 +1,70 @@ -package org.keycloak.models.mongo.keycloak.adapters; - -import com.mongodb.DB; -import com.mongodb.MongoClient; -import org.jboss.logging.Logger; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.KeycloakSessionFactory; -import org.keycloak.models.mongo.api.MongoEntity; -import org.keycloak.models.mongo.api.MongoStore; -import org.keycloak.models.mongo.impl.MongoStoreImpl; -import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity; -import org.keycloak.models.mongo.keycloak.entities.CredentialEntity; -import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity; -import org.keycloak.models.mongo.keycloak.entities.RealmEntity; -import org.keycloak.models.mongo.keycloak.entities.RequiredCredentialEntity; -import org.keycloak.models.mongo.keycloak.entities.RoleEntity; -import org.keycloak.models.mongo.keycloak.entities.SocialLinkEntity; -import org.keycloak.models.mongo.keycloak.entities.UserEntity; -import org.keycloak.models.mongo.utils.MongoConfiguration; - -import java.net.UnknownHostException; - -/** - * KeycloakSessionFactory implementation based on MongoDB - * - * @author Marek Posolda - */ -public class MongoKeycloakSessionFactory implements KeycloakSessionFactory { - protected static final Logger logger = Logger.getLogger(MongoKeycloakSessionFactory.class); - - private static final Class[] MANAGED_ENTITY_TYPES = (Class[])new Class[] { - RealmEntity.class, - UserEntity.class, - RoleEntity.class, - RequiredCredentialEntity.class, - CredentialEntity.class, - SocialLinkEntity.class, - ApplicationEntity.class, - OAuthClientEntity.class - }; - - private final MongoClient mongoClient; - private final MongoStore mongoStore; - - public MongoKeycloakSessionFactory(MongoConfiguration config) { - logger.info(String.format("Configuring MongoStore with: " + config)); - - try { - // TODO: authentication support - mongoClient = new MongoClient(config.getHost(), config.getPort()); - - DB db = mongoClient.getDB(config.getDbName()); - mongoStore = new MongoStoreImpl(db, config.isClearCollectionsOnStartup(), MANAGED_ENTITY_TYPES); - - } catch (UnknownHostException e) { - throw new RuntimeException(e); - } - } - - @Override - public KeycloakSession createSession() { - return new MongoKeycloakSession(mongoStore); - } - - @Override - public void close() { - logger.info("Closing MongoDB client"); - mongoClient.close(); - } -} +package org.keycloak.models.mongo.keycloak.adapters; + +import com.mongodb.DB; +import com.mongodb.MongoClient; +import org.jboss.logging.Logger; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.KeycloakSessionFactory; +import org.keycloak.models.mongo.api.MongoEntity; +import org.keycloak.models.mongo.api.MongoStore; +import org.keycloak.models.mongo.impl.MongoStoreImpl; +import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity; +import org.keycloak.models.mongo.keycloak.entities.CredentialEntity; +import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity; +import org.keycloak.models.mongo.keycloak.entities.RealmEntity; +import org.keycloak.models.mongo.keycloak.entities.RequiredCredentialEntity; +import org.keycloak.models.mongo.keycloak.entities.RoleEntity; +import org.keycloak.models.mongo.keycloak.entities.SocialLinkEntity; +import org.keycloak.models.mongo.keycloak.entities.UserEntity; +import org.keycloak.models.mongo.utils.MongoConfiguration; + +import java.net.UnknownHostException; + +/** + * KeycloakSessionFactory implementation based on MongoDB + * + * @author Marek Posolda + */ +public class MongoKeycloakSessionFactory implements KeycloakSessionFactory { + protected static final Logger logger = Logger.getLogger(MongoKeycloakSessionFactory.class); + + private static final Class[] MANAGED_ENTITY_TYPES = (Class[])new Class[] { + RealmEntity.class, + UserEntity.class, + RoleEntity.class, + RequiredCredentialEntity.class, + CredentialEntity.class, + SocialLinkEntity.class, + ApplicationEntity.class, + OAuthClientEntity.class + }; + + private final MongoClient mongoClient; + private final MongoStore mongoStore; + + public MongoKeycloakSessionFactory(MongoConfiguration config) { + logger.info(String.format("Configuring MongoStore with: " + config)); + + try { + // TODO: authentication support + mongoClient = new MongoClient(config.getHost(), config.getPort()); + + DB db = mongoClient.getDB(config.getDbName()); + mongoStore = new MongoStoreImpl(db, config.isClearCollectionsOnStartup(), MANAGED_ENTITY_TYPES); + + } catch (UnknownHostException e) { + throw new RuntimeException(e); + } + } + + @Override + public KeycloakSession createSession() { + return new MongoKeycloakSession(mongoStore); + } + + @Override + public void close() { + logger.info("Closing MongoDB client"); + mongoClient.close(); + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java index cbdbec62f6..32a877d141 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java @@ -1,131 +1,139 @@ -package org.keycloak.models.mongo.keycloak.adapters; - -import org.keycloak.models.OAuthClientModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; -import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; -import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity; -import org.keycloak.models.mongo.keycloak.entities.UserEntity; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * @author Marek Posolda - */ -public class OAuthClientAdapter extends AbstractAdapter implements OAuthClientModel { - - private final OAuthClientEntity delegate; - - public OAuthClientAdapter(OAuthClientEntity oauthClientEntity, MongoStoreInvocationContext invContext) { - super(invContext); - this.delegate = oauthClientEntity; - } - - @Override - public String getId() { - return delegate.getId(); - } - - @Override - public String getClientId() { - return delegate.getName(); - } - - @Override - public long getAllowedClaimsMask() { - return delegate.getAllowedClaimsMask(); - } - - @Override - public void setAllowedClaimsMask(long mask) { - delegate.setAllowedClaimsMask(mask); - } - - @Override - public boolean isEnabled() { - return delegate.isEnabled(); - } - - @Override - public void setEnabled(boolean enabled) { - delegate.setEnabled(enabled); - } - - @Override - public AbstractMongoIdentifiableEntity getMongoEntity() { - return delegate; - } - - @Override - public Set getWebOrigins() { - Set result = new HashSet(); - if (delegate.getWebOrigins() != null) { - result.addAll(delegate.getWebOrigins()); - } - return result; - } - - @Override - public void setWebOrigins(Set webOrigins) { - List result = new ArrayList(); - result.addAll(webOrigins); - delegate.setWebOrigins(result); - } - - @Override - public void addWebOrigin(String webOrigin) { - getMongoStore().pushItemToList(delegate, "webOrigins", webOrigin, true, invocationContext); - } - - @Override - public void removeWebOrigin(String webOrigin) { - getMongoStore().pullItemFromList(delegate, "webOrigins", webOrigin, invocationContext); - } - - @Override - public Set getRedirectUris() { - Set result = new HashSet(); - if (delegate.getRedirectUris() != null) { - result.addAll(delegate.getRedirectUris()); - } - return result; - } - - @Override - public void setRedirectUris(Set redirectUris) { - List result = new ArrayList(); - result.addAll(redirectUris); - delegate.setRedirectUris(result); - } - - @Override - public void addRedirectUri(String redirectUri) { - getMongoStore().pushItemToList(delegate, "redirectUris", redirectUri, true, invocationContext); - } - - @Override - public void removeRedirectUri(String redirectUri) { - getMongoStore().pullItemFromList(delegate, "redirectUris", redirectUri, invocationContext); - } - - @Override - public String getSecret() { - return delegate.getSecret(); - } - - @Override - public void setSecret(String secret) { - delegate.setSecret(secret); - } - - - @Override - public boolean validateSecret(String secret) { - return secret.equals(delegate.getSecret()); - } - - -} +package org.keycloak.models.mongo.keycloak.adapters; + +import org.keycloak.models.OAuthClientModel; +import org.keycloak.models.RealmModel; +import org.keycloak.models.UserModel; +import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; +import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; +import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity; +import org.keycloak.models.mongo.keycloak.entities.UserEntity; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author Marek Posolda + */ +public class OAuthClientAdapter extends AbstractAdapter implements OAuthClientModel { + + private final OAuthClientEntity delegate; + private final RealmModel realm; + + public OAuthClientAdapter(RealmModel realm, OAuthClientEntity oauthClientEntity, MongoStoreInvocationContext invContext) { + super(invContext); + this.delegate = oauthClientEntity; + this.realm = realm; + } + + @Override + public String getId() { + return delegate.getId(); + } + + @Override + public String getClientId() { + return delegate.getName(); + } + + @Override + public RealmModel getRealm() { + return realm; + } + + @Override + public long getAllowedClaimsMask() { + return delegate.getAllowedClaimsMask(); + } + + @Override + public void setAllowedClaimsMask(long mask) { + delegate.setAllowedClaimsMask(mask); + } + + @Override + public boolean isEnabled() { + return delegate.isEnabled(); + } + + @Override + public void setEnabled(boolean enabled) { + delegate.setEnabled(enabled); + } + + @Override + public AbstractMongoIdentifiableEntity getMongoEntity() { + return delegate; + } + + @Override + public Set getWebOrigins() { + Set result = new HashSet(); + if (delegate.getWebOrigins() != null) { + result.addAll(delegate.getWebOrigins()); + } + return result; + } + + @Override + public void setWebOrigins(Set webOrigins) { + List result = new ArrayList(); + result.addAll(webOrigins); + delegate.setWebOrigins(result); + } + + @Override + public void addWebOrigin(String webOrigin) { + getMongoStore().pushItemToList(delegate, "webOrigins", webOrigin, true, invocationContext); + } + + @Override + public void removeWebOrigin(String webOrigin) { + getMongoStore().pullItemFromList(delegate, "webOrigins", webOrigin, invocationContext); + } + + @Override + public Set getRedirectUris() { + Set result = new HashSet(); + if (delegate.getRedirectUris() != null) { + result.addAll(delegate.getRedirectUris()); + } + return result; + } + + @Override + public void setRedirectUris(Set redirectUris) { + List result = new ArrayList(); + result.addAll(redirectUris); + delegate.setRedirectUris(result); + } + + @Override + public void addRedirectUri(String redirectUri) { + getMongoStore().pushItemToList(delegate, "redirectUris", redirectUri, true, invocationContext); + } + + @Override + public void removeRedirectUri(String redirectUri) { + getMongoStore().pullItemFromList(delegate, "redirectUris", redirectUri, invocationContext); + } + + @Override + public String getSecret() { + return delegate.getSecret(); + } + + @Override + public void setSecret(String secret) { + delegate.setSecret(secret); + } + + + @Override + public boolean validateSecret(String secret) { + return secret.equals(delegate.getSecret()); + } + + +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java index ff941b93f7..22acd3ff8d 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java @@ -1,1008 +1,1016 @@ -package org.keycloak.models.mongo.keycloak.adapters; - -import com.mongodb.DBObject; -import com.mongodb.QueryBuilder; -import org.jboss.logging.Logger; -import org.keycloak.models.ApplicationModel; -import org.keycloak.models.ClientModel; -import org.keycloak.models.OAuthClientModel; -import org.keycloak.models.PasswordPolicy; -import org.keycloak.models.RealmModel; -import org.keycloak.models.RequiredCredentialModel; -import org.keycloak.models.RoleModel; -import org.keycloak.models.SocialLinkModel; -import org.keycloak.models.UserCredentialModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; -import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; -import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity; -import org.keycloak.models.mongo.keycloak.entities.CredentialEntity; -import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity; -import org.keycloak.models.mongo.keycloak.entities.RealmEntity; -import org.keycloak.models.mongo.keycloak.entities.RequiredCredentialEntity; -import org.keycloak.models.mongo.keycloak.entities.RoleEntity; -import org.keycloak.models.mongo.keycloak.entities.SocialLinkEntity; -import org.keycloak.models.mongo.keycloak.entities.UserEntity; -import org.keycloak.models.mongo.utils.MongoModelUtils; -import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.models.utils.Pbkdf2PasswordEncoder; -import org.keycloak.models.utils.TimeBasedOTP; - -import java.security.PrivateKey; -import java.security.PublicKey; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Pattern; - -/** - * @author Marek Posolda - */ -public class RealmAdapter extends AbstractAdapter implements RealmModel { - - private static final Logger logger = Logger.getLogger(RealmAdapter.class); - - private final RealmEntity realm; - - protected volatile transient PublicKey publicKey; - protected volatile transient PrivateKey privateKey; - - private volatile transient PasswordPolicy passwordPolicy; - - public RealmAdapter(RealmEntity realmEntity, MongoStoreInvocationContext invocationContext) { - super(invocationContext); - this.realm = realmEntity; - } - - @Override - public String getId() { - return realm.getId(); - } - - @Override - public String getName() { - return realm.getName(); - } - - @Override - public void setName(String name) { - realm.setName(name); - updateRealm(); - } - - @Override - public boolean isEnabled() { - return realm.isEnabled(); - } - - @Override - public void setEnabled(boolean enabled) { - realm.setEnabled(enabled); - updateRealm(); - } - - @Override - public boolean isSslNotRequired() { - return realm.isSslNotRequired(); - } - - @Override - public void setSslNotRequired(boolean sslNotRequired) { - realm.setSslNotRequired(sslNotRequired); - updateRealm(); - } - - @Override - public boolean isRegistrationAllowed() { - return realm.isRegistrationAllowed(); - } - - @Override - public void setRegistrationAllowed(boolean registrationAllowed) { - realm.setRegistrationAllowed(registrationAllowed); - updateRealm(); - } - - @Override - public boolean isRememberMe() { - return realm.isRememberMe(); - } - - @Override - public void setRememberMe(boolean rememberMe) { - realm.setRememberMe(rememberMe); - updateRealm(); - } - - - @Override - public boolean isVerifyEmail() { - return realm.isVerifyEmail(); - } - - @Override - public void setVerifyEmail(boolean verifyEmail) { - realm.setVerifyEmail(verifyEmail); - updateRealm(); - } - - @Override - public boolean isResetPasswordAllowed() { - return realm.isResetPasswordAllowed(); - } - - @Override - public void setResetPasswordAllowed(boolean resetPassword) { - realm.setResetPasswordAllowed(resetPassword); - updateRealm(); - } - - @Override - public boolean isSocial() { - return realm.isSocial(); - } - - @Override - public void setSocial(boolean social) { - realm.setSocial(social); - updateRealm(); - } - - @Override - public boolean isUpdateProfileOnInitialSocialLogin() { - return realm.isUpdateProfileOnInitialSocialLogin(); - } - - @Override - public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) { - realm.setUpdateProfileOnInitialSocialLogin(updateProfileOnInitialSocialLogin); - updateRealm(); - } - - @Override - public PasswordPolicy getPasswordPolicy() { - if (passwordPolicy == null) { - passwordPolicy = new PasswordPolicy(realm.getPasswordPolicy()); - } - return passwordPolicy; - } - - @Override - public void setPasswordPolicy(PasswordPolicy policy) { - this.passwordPolicy = policy; - realm.setPasswordPolicy(policy.toString()); - updateRealm(); - } - - @Override - public int getNotBefore() { - return realm.getNotBefore(); - } - - @Override - public void setNotBefore(int notBefore) { - realm.setNotBefore(notBefore); - } - - - @Override - public int getAccessTokenLifespan() { - return realm.getAccessTokenLifespan(); - } - - @Override - public void setAccessTokenLifespan(int tokenLifespan) { - realm.setAccessTokenLifespan(tokenLifespan); - updateRealm(); - } - - @Override - public int getCentralLoginLifespan() { - return realm.getCentralLoginLifespan(); - } - - @Override - public void setCentralLoginLifespan(int lifespan) { - realm.setCentralLoginLifespan(lifespan); - updateRealm(); - } - - - @Override - public int getRefreshTokenLifespan() { - return realm.getRefreshTokenLifespan(); - } - - @Override - public void setRefreshTokenLifespan(int tokenLifespan) { - realm.setRefreshTokenLifespan(tokenLifespan); - updateRealm(); - } - - @Override - public int getAccessCodeLifespan() { - return realm.getAccessCodeLifespan(); - } - - @Override - public void setAccessCodeLifespan(int accessCodeLifespan) { - realm.setAccessCodeLifespan(accessCodeLifespan); - updateRealm(); - } - - @Override - public int getAccessCodeLifespanUserAction() { - return realm.getAccessCodeLifespanUserAction(); - } - - @Override - public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) { - realm.setAccessCodeLifespanUserAction(accessCodeLifespanUserAction); - updateRealm(); - } - - @Override - public String getPublicKeyPem() { - return realm.getPublicKeyPem(); - } - - @Override - public void setPublicKeyPem(String publicKeyPem) { - realm.setPublicKeyPem(publicKeyPem); - this.publicKey = null; - updateRealm(); - } - - @Override - public String getPrivateKeyPem() { - return realm.getPrivateKeyPem(); - } - - @Override - public void setPrivateKeyPem(String privateKeyPem) { - realm.setPrivateKeyPem(privateKeyPem); - this.privateKey = null; - updateRealm(); - } - - @Override - public PublicKey getPublicKey() { - if (publicKey != null) return publicKey; - publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem()); - return publicKey; - } - - @Override - public void setPublicKey(PublicKey publicKey) { - this.publicKey = publicKey; - String publicKeyPem = KeycloakModelUtils.getPemFromKey(publicKey); - setPublicKeyPem(publicKeyPem); - } - - @Override - public PrivateKey getPrivateKey() { - if (privateKey != null) return privateKey; - privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem()); - return privateKey; - } - - @Override - public void setPrivateKey(PrivateKey privateKey) { - this.privateKey = privateKey; - String privateKeyPem = KeycloakModelUtils.getPemFromKey(privateKey); - setPrivateKeyPem(privateKeyPem); - } - - @Override - public String getLoginTheme() { - return realm.getLoginTheme(); - } - - @Override - public void setLoginTheme(String name) { - realm.setLoginTheme(name); - updateRealm(); - } - - @Override - public String getAccountTheme() { - return realm.getAccountTheme(); - } - - @Override - public void setAccountTheme(String name) { - realm.setAccountTheme(name); - updateRealm(); - } - - @Override - public UserAdapter getUser(String name) { - DBObject query = new QueryBuilder() - .and("loginName").is(name) - .and("realmId").is(getId()) - .get(); - UserEntity user = getMongoStore().loadSingleEntity(UserEntity.class, query, invocationContext); - - if (user == null) { - return null; - } else { - return new UserAdapter(user, invocationContext); - } - } - - @Override - public UserModel getUserByEmail(String email) { - DBObject query = new QueryBuilder() - .and("email").is(email) - .and("realmId").is(getId()) - .get(); - UserEntity user = getMongoStore().loadSingleEntity(UserEntity.class, query, invocationContext); - - if (user == null) { - return null; - } else { - return new UserAdapter(user, invocationContext); - } - } - - @Override - public UserModel getUserById(String id) { - UserEntity user = getMongoStore().loadEntity(UserEntity.class, id, invocationContext); - - // Check that it's user from this realm - if (user == null || !getId().equals(user.getRealmId())) { - return null; - } else { - return new UserAdapter(user, invocationContext); - } - } - - @Override - public UserAdapter addUser(String username) { - UserAdapter userModel = addUserEntity(username); - - for (String r : getDefaultRoles()) { - grantRole(userModel, getRole(r)); - } - - for (ApplicationModel application : getApplications()) { - for (String r : application.getDefaultRoles()) { - grantRole(userModel, application.getRole(r)); - } - } - - return userModel; - } - - // Add just user entity without defaultRoles - protected UserAdapter addUserEntity(String username) { - if (getUser(username) != null) { - throw new IllegalArgumentException("User " + username + " already exists"); - } - - UserEntity userEntity = new UserEntity(); - userEntity.setLoginName(username); - userEntity.setEnabled(true); - userEntity.setRealmId(getId()); - - getMongoStore().insertEntity(userEntity, invocationContext); - return new UserAdapter(userEntity, invocationContext); - } - - @Override - public boolean removeUser(String name) { - DBObject query = new QueryBuilder() - .and("loginName").is(name) - .and("realmId").is(getId()) - .get(); - return getMongoStore().removeEntities(UserEntity.class, query, invocationContext); - } - - @Override - public RoleAdapter getRole(String name) { - DBObject query = new QueryBuilder() - .and("name").is(name) - .and("realmId").is(getId()) - .get(); - RoleEntity role = getMongoStore().loadSingleEntity(RoleEntity.class, query, invocationContext); - if (role == null) { - return null; - } else { - return new RoleAdapter(role, this, invocationContext); - } - } - - @Override - public RoleModel addRole(String name) { - RoleAdapter role = getRole(name); - if (role != null) { - // Compatibility with JPA model - return role; - // throw new IllegalArgumentException("Role " + name + " already exists"); - } - - RoleEntity roleEntity = new RoleEntity(); - roleEntity.setName(name); - roleEntity.setRealmId(getId()); - - getMongoStore().insertEntity(roleEntity, invocationContext); - return new RoleAdapter(roleEntity, this, invocationContext); - } - - @Override - public boolean removeRoleById(String id) { - return getMongoStore().removeEntity(RoleEntity.class, id, invocationContext); - } - - @Override - public Set getRoles() { - DBObject query = new QueryBuilder() - .and("realmId").is(getId()) - .get(); - List roles = getMongoStore().loadEntities(RoleEntity.class, query, invocationContext); - - Set result = new HashSet(); - - if (roles == null) return result; - for (RoleEntity role : roles) { - result.add(new RoleAdapter(role, this, invocationContext)); - } - - return result; - } - - @Override - public RoleModel getRoleById(String id) { - RoleEntity role = getMongoStore().loadEntity(RoleEntity.class, id, invocationContext); - if (role == null || !getId().equals(role.getRealmId())) { - return null; - } else { - return new RoleAdapter(role, this, invocationContext); - } - } - - @Override - public List getDefaultRoles() { - return realm.getDefaultRoles(); - } - - @Override - public void addDefaultRole(String name) { - RoleModel role = getRole(name); - if (role == null) { - addRole(name); - } - - getMongoStore().pushItemToList(realm, "defaultRoles", name, true, invocationContext); - } - - @Override - public void updateDefaultRoles(String[] defaultRoles) { - List roleNames = new ArrayList(); - for (String roleName : defaultRoles) { - RoleModel role = getRole(roleName); - if (role == null) { - addRole(roleName); - } - - roleNames.add(roleName); - } - - realm.setDefaultRoles(roleNames); - updateRealm(); - } - - @Override - public ClientModel findClient(String clientId) { - ClientModel model = getApplicationByName(clientId); - if (model != null) return model; - return getOAuthClient(clientId); - } - - - @Override - public ApplicationModel getApplicationById(String id) { - ApplicationEntity appData = getMongoStore().loadEntity(ApplicationEntity.class, id, invocationContext); - - // Check if application belongs to this realm - if (appData == null || !getId().equals(appData.getRealmId())) { - return null; - } - - return new ApplicationAdapter(appData, invocationContext); - } - - @Override - public ApplicationModel getApplicationByName(String name) { - DBObject query = new QueryBuilder() - .and("realmId").is(getId()) - .and("name").is(name) - .get(); - ApplicationEntity appEntity = getMongoStore().loadSingleEntity(ApplicationEntity.class, query, invocationContext); - return appEntity==null ? null : new ApplicationAdapter(appEntity, invocationContext); - } - - @Override - public Map getApplicationNameMap() { - Map resourceMap = new HashMap(); - for (ApplicationModel resource : getApplications()) { - resourceMap.put(resource.getName(), resource); - } - return resourceMap; - } - - @Override - public List getApplications() { - DBObject query = new QueryBuilder() - .and("realmId").is(getId()) - .get(); - List appDatas = getMongoStore().loadEntities(ApplicationEntity.class, query, invocationContext); - - List result = new ArrayList(); - for (ApplicationEntity appData : appDatas) { - result.add(new ApplicationAdapter(appData, invocationContext)); - } - return result; - } - - @Override - public ApplicationModel addApplication(String name) { - ApplicationEntity appData = new ApplicationEntity(); - appData.setName(name); - appData.setRealmId(getId()); - appData.setEnabled(true); - getMongoStore().insertEntity(appData, invocationContext); - - return new ApplicationAdapter(appData, invocationContext); - } - - @Override - public boolean removeApplication(String id) { - return getMongoStore().removeEntity(ApplicationEntity.class, id, invocationContext); - } - - @Override - public boolean hasRole(UserModel user, RoleModel role) { - Set roles = getRoleMappings(user); - if (roles.contains(role)) return true; - - for (RoleModel mapping : roles) { - if (mapping.hasRole(role)) return true; - } - return false; - } - - @Override - public void grantRole(UserModel user, RoleModel role) { - UserEntity userEntity = ((UserAdapter)user).getUser(); - getMongoStore().pushItemToList(userEntity, "roleIds", role.getId(), true, invocationContext); - } - - @Override - public Set getRoleMappings(UserModel user) { - Set result = new HashSet(); - List roles = MongoModelUtils.getAllRolesOfUser(user, invocationContext); - - for (RoleEntity role : roles) { - if (getId().equals(role.getRealmId())) { - result.add(new RoleAdapter(role, this, invocationContext)); - } else { - // Likely applicationRole, but we don't have this application yet - result.add(new RoleAdapter(role, invocationContext)); - } - } - return result; - } - - @Override - public Set getRealmRoleMappings(UserModel user) { - Set allRoles = getRoleMappings(user); - - // Filter to retrieve just realm roles TODO: Maybe improve to avoid filter programmatically... Maybe have separate fields for realmRoles and appRoles on user? - Set realmRoles = new HashSet(); - for (RoleModel role : allRoles) { - RoleEntity roleEntity = ((RoleAdapter)role).getRole(); - - if (getId().equals(roleEntity.getRealmId())) { - realmRoles.add(role); - } - } - return realmRoles; - } - - @Override - public void deleteRoleMapping(UserModel user, RoleModel role) { - if (user == null || role == null) return; - - UserEntity userEntity = ((UserAdapter)user).getUser(); - getMongoStore().pullItemFromList(userEntity, "roleIds", role.getId(), invocationContext); - } - - @Override - public Set getScopeMappings(ClientModel client) { - Set result = new HashSet(); - List roles = MongoModelUtils.getAllScopesOfClient(client, invocationContext); - - for (RoleEntity role : roles) { - if (getId().equals(role.getRealmId())) { - result.add(new RoleAdapter(role, this, invocationContext)); - } else { - // Likely applicationRole, but we don't have this application yet - result.add(new RoleAdapter(role, invocationContext)); - } - } - return result; - } - - @Override - public Set getRealmScopeMappings(ClientModel client) { - Set allScopes = getScopeMappings(client); - - // Filter to retrieve just realm roles TODO: Maybe improve to avoid filter programmatically... Maybe have separate fields for realmRoles and appRoles on user? - Set realmRoles = new HashSet(); - for (RoleModel role : allScopes) { - RoleEntity roleEntity = ((RoleAdapter)role).getRole(); - - if (getId().equals(roleEntity.getRealmId())) { - realmRoles.add(role); - } - } - return realmRoles; - } - - @Override - public boolean hasScope(ClientModel client, RoleModel role) { - Set roles = getScopeMappings(client); - if (roles.contains(role)) return true; - - for (RoleModel mapping : roles) { - if (mapping.hasRole(role)) return true; - } - return false; - } - - - @Override - public void addScopeMapping(ClientModel client, RoleModel role) { - getMongoStore().pushItemToList(((AbstractAdapter)client).getMongoEntity(), "scopeIds", role.getId(), true, invocationContext); - } - - @Override - public void deleteScopeMapping(ClientModel client, RoleModel role) { - getMongoStore().pullItemFromList(((AbstractAdapter)client).getMongoEntity(), "scopeIds", role.getId(), invocationContext); - } - - @Override - public OAuthClientModel addOAuthClient(String name) { - OAuthClientEntity oauthClient = new OAuthClientEntity(); - oauthClient.setRealmId(getId()); - oauthClient.setName(name); - getMongoStore().insertEntity(oauthClient, invocationContext); - - return new OAuthClientAdapter(oauthClient, invocationContext); - } - - @Override - public boolean removeOAuthClient(String id) { - return getMongoStore().removeEntity(OAuthClientEntity.class, id, invocationContext); - } - - @Override - public OAuthClientModel getOAuthClient(String name) { - DBObject query = new QueryBuilder() - .and("realmId").is(getId()) - .and("name").is(name) - .get(); - OAuthClientEntity oauthClient = getMongoStore().loadSingleEntity(OAuthClientEntity.class, query, invocationContext); - return oauthClient == null ? null : new OAuthClientAdapter(oauthClient, invocationContext); - } - - @Override - public OAuthClientModel getOAuthClientById(String id) { - OAuthClientEntity clientEntity = getMongoStore().loadEntity(OAuthClientEntity.class, id, invocationContext); - - // Check if client belongs to this realm - if (clientEntity == null || !getId().equals(clientEntity.getRealmId())) return null; - - return new OAuthClientAdapter(clientEntity, invocationContext); - } - - @Override - public List getOAuthClients() { - DBObject query = new QueryBuilder() - .and("realmId").is(getId()) - .get(); - List results = getMongoStore().loadEntities(OAuthClientEntity.class, query, invocationContext); - List list = new ArrayList(); - for (OAuthClientEntity data : results) { - list.add(new OAuthClientAdapter(data, invocationContext)); - } - return list; - } - - @Override - public void addRequiredCredential(String type) { - RequiredCredentialModel credentialModel = initRequiredCredentialModel(type); - addRequiredCredential(credentialModel, realm.getRequiredCredentials()); - } - - protected void addRequiredCredential(RequiredCredentialModel credentialModel, List persistentCollection) { - RequiredCredentialEntity credEntity = new RequiredCredentialEntity(); - credEntity.setType(credentialModel.getType()); - credEntity.setFormLabel(credentialModel.getFormLabel()); - credEntity.setInput(credentialModel.isInput()); - credEntity.setSecret(credentialModel.isSecret()); - - persistentCollection.add(credEntity); - - updateRealm(); - } - - @Override - public void updateRequiredCredentials(Set creds) { - updateRequiredCredentials(creds, realm.getRequiredCredentials()); - } - - protected void updateRequiredCredentials(Set creds, List credsEntities) { - Set already = new HashSet(); - Set toRemove = new HashSet(); - for (RequiredCredentialEntity entity : credsEntities) { - if (!creds.contains(entity.getType())) { - toRemove.add(entity); - } else { - already.add(entity.getType()); - } - } - for (RequiredCredentialEntity entity : toRemove) { - credsEntities.remove(entity); - } - for (String cred : creds) { - logger.info("updating cred: " + cred); - if (!already.contains(cred)) { - RequiredCredentialModel credentialModel = initRequiredCredentialModel(cred); - addRequiredCredential(credentialModel, credsEntities); - } - } - } - - @Override - public List getRequiredCredentials() { - return convertRequiredCredentialEntities(realm.getRequiredCredentials()); - } - - protected List convertRequiredCredentialEntities(Collection credEntities) { - - List result = new ArrayList(); - for (RequiredCredentialEntity entity : credEntities) { - RequiredCredentialModel model = new RequiredCredentialModel(); - model.setFormLabel(entity.getFormLabel()); - model.setInput(entity.isInput()); - model.setSecret(entity.isSecret()); - model.setType(entity.getType()); - - result.add(model); - } - return result; - } - - @Override - public boolean validatePassword(UserModel user, String password) { - for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) { - if (cred.getType().equals(UserCredentialModel.PASSWORD)) { - return new Pbkdf2PasswordEncoder(cred.getSalt()).verify(password, cred.getValue()); - } - } - return false; - } - - @Override - public boolean validateTOTP(UserModel user, String password, String token) { - if (!validatePassword(user, password)) return false; - for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) { - if (cred.getType().equals(UserCredentialModel.TOTP)) { - return new TimeBasedOTP().validate(token, cred.getValue().getBytes()); - } - } - return false; - } - - - @Override - public void updateCredential(UserModel user, UserCredentialModel cred) { - CredentialEntity credentialEntity = null; - UserEntity userEntity = ((UserAdapter) user).getUser(); - for (CredentialEntity entity : userEntity.getCredentials()) { - if (entity.getType().equals(cred.getType())) { - credentialEntity = entity; - } - } - - if (credentialEntity == null) { - credentialEntity = new CredentialEntity(); - credentialEntity.setType(cred.getType()); - credentialEntity.setDevice(cred.getDevice()); - userEntity.getCredentials().add(credentialEntity); - } - if (cred.getType().equals(UserCredentialModel.PASSWORD)) { - byte[] salt = Pbkdf2PasswordEncoder.getSalt(); - credentialEntity.setValue(new Pbkdf2PasswordEncoder(salt).encode(cred.getValue())); - credentialEntity.setSalt(salt); - } else { - credentialEntity.setValue(cred.getValue()); - } - credentialEntity.setDevice(cred.getDevice()); - - getMongoStore().updateEntity(userEntity, invocationContext); - } - - @Override - public UserModel getUserBySocialLink(SocialLinkModel socialLink) { - DBObject query = new QueryBuilder() - .and("socialLinks.socialProvider").is(socialLink.getSocialProvider()) - .and("socialLinks.socialUsername").is(socialLink.getSocialUsername()) - .and("realmId").is(getId()) - .get(); - UserEntity userEntity = getMongoStore().loadSingleEntity(UserEntity.class, query, invocationContext); - return userEntity==null ? null : new UserAdapter(userEntity, invocationContext); - } - - @Override - public Set getSocialLinks(UserModel user) { - UserEntity userEntity = ((UserAdapter)user).getUser(); - List linkEntities = userEntity.getSocialLinks(); - - if (linkEntities == null) { - return Collections.EMPTY_SET; - } - - Set result = new HashSet(); - for (SocialLinkEntity socialLinkEntity : linkEntities) { - SocialLinkModel model = new SocialLinkModel(socialLinkEntity.getSocialProvider(), socialLinkEntity.getSocialUsername()); - result.add(model); - } - return result; - } - - @Override - public void addSocialLink(UserModel user, SocialLinkModel socialLink) { - UserEntity userEntity = ((UserAdapter)user).getUser(); - SocialLinkEntity socialLinkEntity = new SocialLinkEntity(); - socialLinkEntity.setSocialProvider(socialLink.getSocialProvider()); - socialLinkEntity.setSocialUsername(socialLink.getSocialUsername()); - - getMongoStore().pushItemToList(userEntity, "socialLinks", socialLinkEntity, true, invocationContext); - } - - @Override - public void removeSocialLink(UserModel user, SocialLinkModel socialLink) { - SocialLinkEntity socialLinkEntity = new SocialLinkEntity(); - socialLinkEntity.setSocialProvider(socialLink.getSocialProvider()); - socialLinkEntity.setSocialUsername(socialLink.getSocialUsername()); - - UserEntity userEntity = ((UserAdapter)user).getUser(); - getMongoStore().pullItemFromList(userEntity, "socialLinks", socialLinkEntity, invocationContext); - } - - protected void updateRealm() { - getMongoStore().updateEntity(realm, invocationContext); - } - - protected RequiredCredentialModel initRequiredCredentialModel(String type) { - RequiredCredentialModel model = RequiredCredentialModel.BUILT_IN.get(type); - if (model == null) { - throw new RuntimeException("Unknown credential type " + type); - } - return model; - } - - @Override - public List getUsers() { - DBObject query = new QueryBuilder() - .and("realmId").is(getId()) - .get(); - List users = getMongoStore().loadEntities(UserEntity.class, query, invocationContext); - return convertUserEntities(users); - } - - @Override - public List searchForUser(String search) { - search = search.trim(); - Pattern caseInsensitivePattern = Pattern.compile("(?i:" + search + ")"); - - QueryBuilder nameBuilder; - int spaceInd = search.lastIndexOf(" "); - - // Case when we have search string like "ohn Bow". Then firstName must end with "ohn" AND lastName must start with "bow" (everything case-insensitive) - if (spaceInd != -1) { - String firstName = search.substring(0, spaceInd); - String lastName = search.substring(spaceInd + 1); - Pattern firstNamePattern = Pattern.compile("(?i:" + firstName + "$)"); - Pattern lastNamePattern = Pattern.compile("(?i:^" + lastName + ")"); - nameBuilder = new QueryBuilder().and( - new QueryBuilder().put("firstName").regex(firstNamePattern).get(), - new QueryBuilder().put("lastName").regex(lastNamePattern).get() - ); - } else { - // Case when we have search without spaces like "foo". The firstName OR lastName could be "foo" (everything case-insensitive) - nameBuilder = new QueryBuilder().or( - new QueryBuilder().put("firstName").regex(caseInsensitivePattern).get(), - new QueryBuilder().put("lastName").regex(caseInsensitivePattern).get() - ); - } - - QueryBuilder builder = new QueryBuilder().and( - new QueryBuilder().and("realmId").is(getId()).get(), - new QueryBuilder().or( - new QueryBuilder().put("loginName").regex(caseInsensitivePattern).get(), - new QueryBuilder().put("email").regex(caseInsensitivePattern).get(), - nameBuilder.get() - - ).get() - ); - - List users = getMongoStore().loadEntities(UserEntity.class, builder.get(), invocationContext); - return convertUserEntities(users); - } - - @Override - public List searchForUserByAttributes(Map attributes) { - QueryBuilder queryBuilder = new QueryBuilder() - .and("realmId").is(getId()); - - for (Map.Entry entry : attributes.entrySet()) { - if (entry.getKey().equals(UserModel.LOGIN_NAME)) { - queryBuilder.and("loginName").regex(Pattern.compile("(?i:" + entry.getValue() + "$)")); - } else if (entry.getKey().equalsIgnoreCase(UserModel.FIRST_NAME)) { - queryBuilder.and(UserModel.FIRST_NAME).regex(Pattern.compile("(?i:" + entry.getValue() + "$)")); - - } else if (entry.getKey().equalsIgnoreCase(UserModel.LAST_NAME)) { - queryBuilder.and(UserModel.LAST_NAME).regex(Pattern.compile("(?i:" + entry.getValue() + "$)")); - - } else if (entry.getKey().equalsIgnoreCase(UserModel.EMAIL)) { - queryBuilder.and(UserModel.EMAIL).regex(Pattern.compile("(?i:" + entry.getValue() + "$)")); - } - } - List users = getMongoStore().loadEntities(UserEntity.class, queryBuilder.get(), invocationContext); - return convertUserEntities(users); - } - - protected List convertUserEntities(List userEntities) { - List userModels = new ArrayList(); - for (UserEntity user : userEntities) { - userModels.add(new UserAdapter(user, invocationContext)); - } - return userModels; - } - - @Override - public Map getSmtpConfig() { - return realm.getSmtpConfig(); - } - - @Override - public void setSmtpConfig(Map smtpConfig) { - realm.setSmtpConfig(smtpConfig); - updateRealm(); - } - - @Override - public Map getSocialConfig() { - return realm.getSocialConfig(); - } - - @Override - public void setSocialConfig(Map socialConfig) { - realm.setSocialConfig(socialConfig); - updateRealm(); - } - - @Override - public AbstractMongoIdentifiableEntity getMongoEntity() { - return realm; - } -} +package org.keycloak.models.mongo.keycloak.adapters; + +import com.mongodb.DBObject; +import com.mongodb.QueryBuilder; +import org.jboss.logging.Logger; +import org.keycloak.models.ApplicationModel; +import org.keycloak.models.ClientModel; +import org.keycloak.models.OAuthClientModel; +import org.keycloak.models.PasswordPolicy; +import org.keycloak.models.RealmModel; +import org.keycloak.models.RequiredCredentialModel; +import org.keycloak.models.RoleModel; +import org.keycloak.models.SocialLinkModel; +import org.keycloak.models.UserCredentialModel; +import org.keycloak.models.UserModel; +import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; +import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; +import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity; +import org.keycloak.models.mongo.keycloak.entities.CredentialEntity; +import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity; +import org.keycloak.models.mongo.keycloak.entities.RealmEntity; +import org.keycloak.models.mongo.keycloak.entities.RequiredCredentialEntity; +import org.keycloak.models.mongo.keycloak.entities.RoleEntity; +import org.keycloak.models.mongo.keycloak.entities.SocialLinkEntity; +import org.keycloak.models.mongo.keycloak.entities.UserEntity; +import org.keycloak.models.mongo.utils.MongoModelUtils; +import org.keycloak.models.utils.KeycloakModelUtils; +import org.keycloak.models.utils.Pbkdf2PasswordEncoder; +import org.keycloak.models.utils.TimeBasedOTP; + +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +/** + * @author Marek Posolda + */ +public class RealmAdapter extends AbstractAdapter implements RealmModel { + + private static final Logger logger = Logger.getLogger(RealmAdapter.class); + + private final RealmEntity realm; + + protected volatile transient PublicKey publicKey; + protected volatile transient PrivateKey privateKey; + + private volatile transient PasswordPolicy passwordPolicy; + + public RealmAdapter(RealmEntity realmEntity, MongoStoreInvocationContext invocationContext) { + super(invocationContext); + this.realm = realmEntity; + } + + @Override + public String getId() { + return realm.getId(); + } + + @Override + public String getName() { + return realm.getName(); + } + + @Override + public void setName(String name) { + realm.setName(name); + updateRealm(); + } + + @Override + public boolean isEnabled() { + return realm.isEnabled(); + } + + @Override + public void setEnabled(boolean enabled) { + realm.setEnabled(enabled); + updateRealm(); + } + + @Override + public boolean isSslNotRequired() { + return realm.isSslNotRequired(); + } + + @Override + public void setSslNotRequired(boolean sslNotRequired) { + realm.setSslNotRequired(sslNotRequired); + updateRealm(); + } + + @Override + public boolean isRegistrationAllowed() { + return realm.isRegistrationAllowed(); + } + + @Override + public void setRegistrationAllowed(boolean registrationAllowed) { + realm.setRegistrationAllowed(registrationAllowed); + updateRealm(); + } + + @Override + public boolean isRememberMe() { + return realm.isRememberMe(); + } + + @Override + public void setRememberMe(boolean rememberMe) { + realm.setRememberMe(rememberMe); + updateRealm(); + } + + + @Override + public boolean isVerifyEmail() { + return realm.isVerifyEmail(); + } + + @Override + public void setVerifyEmail(boolean verifyEmail) { + realm.setVerifyEmail(verifyEmail); + updateRealm(); + } + + @Override + public boolean isResetPasswordAllowed() { + return realm.isResetPasswordAllowed(); + } + + @Override + public void setResetPasswordAllowed(boolean resetPassword) { + realm.setResetPasswordAllowed(resetPassword); + updateRealm(); + } + + @Override + public boolean isSocial() { + return realm.isSocial(); + } + + @Override + public void setSocial(boolean social) { + realm.setSocial(social); + updateRealm(); + } + + @Override + public boolean isUpdateProfileOnInitialSocialLogin() { + return realm.isUpdateProfileOnInitialSocialLogin(); + } + + @Override + public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) { + realm.setUpdateProfileOnInitialSocialLogin(updateProfileOnInitialSocialLogin); + updateRealm(); + } + + @Override + public PasswordPolicy getPasswordPolicy() { + if (passwordPolicy == null) { + passwordPolicy = new PasswordPolicy(realm.getPasswordPolicy()); + } + return passwordPolicy; + } + + @Override + public void setPasswordPolicy(PasswordPolicy policy) { + this.passwordPolicy = policy; + realm.setPasswordPolicy(policy.toString()); + updateRealm(); + } + + @Override + public int getNotBefore() { + return realm.getNotBefore(); + } + + @Override + public void setNotBefore(int notBefore) { + realm.setNotBefore(notBefore); + } + + + @Override + public int getAccessTokenLifespan() { + return realm.getAccessTokenLifespan(); + } + + @Override + public void setAccessTokenLifespan(int tokenLifespan) { + realm.setAccessTokenLifespan(tokenLifespan); + updateRealm(); + } + + @Override + public int getCentralLoginLifespan() { + return realm.getCentralLoginLifespan(); + } + + @Override + public void setCentralLoginLifespan(int lifespan) { + realm.setCentralLoginLifespan(lifespan); + updateRealm(); + } + + + @Override + public int getRefreshTokenLifespan() { + return realm.getRefreshTokenLifespan(); + } + + @Override + public void setRefreshTokenLifespan(int tokenLifespan) { + realm.setRefreshTokenLifespan(tokenLifespan); + updateRealm(); + } + + @Override + public int getAccessCodeLifespan() { + return realm.getAccessCodeLifespan(); + } + + @Override + public void setAccessCodeLifespan(int accessCodeLifespan) { + realm.setAccessCodeLifespan(accessCodeLifespan); + updateRealm(); + } + + @Override + public int getAccessCodeLifespanUserAction() { + return realm.getAccessCodeLifespanUserAction(); + } + + @Override + public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) { + realm.setAccessCodeLifespanUserAction(accessCodeLifespanUserAction); + updateRealm(); + } + + @Override + public String getPublicKeyPem() { + return realm.getPublicKeyPem(); + } + + @Override + public void setPublicKeyPem(String publicKeyPem) { + realm.setPublicKeyPem(publicKeyPem); + this.publicKey = null; + updateRealm(); + } + + @Override + public String getPrivateKeyPem() { + return realm.getPrivateKeyPem(); + } + + @Override + public void setPrivateKeyPem(String privateKeyPem) { + realm.setPrivateKeyPem(privateKeyPem); + this.privateKey = null; + updateRealm(); + } + + @Override + public PublicKey getPublicKey() { + if (publicKey != null) return publicKey; + publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem()); + return publicKey; + } + + @Override + public void setPublicKey(PublicKey publicKey) { + this.publicKey = publicKey; + String publicKeyPem = KeycloakModelUtils.getPemFromKey(publicKey); + setPublicKeyPem(publicKeyPem); + } + + @Override + public PrivateKey getPrivateKey() { + if (privateKey != null) return privateKey; + privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem()); + return privateKey; + } + + @Override + public void setPrivateKey(PrivateKey privateKey) { + this.privateKey = privateKey; + String privateKeyPem = KeycloakModelUtils.getPemFromKey(privateKey); + setPrivateKeyPem(privateKeyPem); + } + + @Override + public String getLoginTheme() { + return realm.getLoginTheme(); + } + + @Override + public void setLoginTheme(String name) { + realm.setLoginTheme(name); + updateRealm(); + } + + @Override + public String getAccountTheme() { + return realm.getAccountTheme(); + } + + @Override + public void setAccountTheme(String name) { + realm.setAccountTheme(name); + updateRealm(); + } + + @Override + public UserAdapter getUser(String name) { + DBObject query = new QueryBuilder() + .and("loginName").is(name) + .and("realmId").is(getId()) + .get(); + UserEntity user = getMongoStore().loadSingleEntity(UserEntity.class, query, invocationContext); + + if (user == null) { + return null; + } else { + return new UserAdapter(user, invocationContext); + } + } + + @Override + public UserModel getUserByEmail(String email) { + DBObject query = new QueryBuilder() + .and("email").is(email) + .and("realmId").is(getId()) + .get(); + UserEntity user = getMongoStore().loadSingleEntity(UserEntity.class, query, invocationContext); + + if (user == null) { + return null; + } else { + return new UserAdapter(user, invocationContext); + } + } + + @Override + public UserModel getUserById(String id) { + UserEntity user = getMongoStore().loadEntity(UserEntity.class, id, invocationContext); + + // Check that it's user from this realm + if (user == null || !getId().equals(user.getRealmId())) { + return null; + } else { + return new UserAdapter(user, invocationContext); + } + } + + @Override + public UserAdapter addUser(String username) { + UserAdapter userModel = addUserEntity(username); + + for (String r : getDefaultRoles()) { + grantRole(userModel, getRole(r)); + } + + for (ApplicationModel application : getApplications()) { + for (String r : application.getDefaultRoles()) { + grantRole(userModel, application.getRole(r)); + } + } + + return userModel; + } + + // Add just user entity without defaultRoles + protected UserAdapter addUserEntity(String username) { + if (getUser(username) != null) { + throw new IllegalArgumentException("User " + username + " already exists"); + } + + UserEntity userEntity = new UserEntity(); + userEntity.setLoginName(username); + userEntity.setEnabled(true); + userEntity.setRealmId(getId()); + + getMongoStore().insertEntity(userEntity, invocationContext); + return new UserAdapter(userEntity, invocationContext); + } + + @Override + public boolean removeUser(String name) { + DBObject query = new QueryBuilder() + .and("loginName").is(name) + .and("realmId").is(getId()) + .get(); + return getMongoStore().removeEntities(UserEntity.class, query, invocationContext); + } + + @Override + public RoleAdapter getRole(String name) { + DBObject query = new QueryBuilder() + .and("name").is(name) + .and("realmId").is(getId()) + .get(); + RoleEntity role = getMongoStore().loadSingleEntity(RoleEntity.class, query, invocationContext); + if (role == null) { + return null; + } else { + return new RoleAdapter(this, role, this, invocationContext); + } + } + + @Override + public RoleModel addRole(String name) { + RoleAdapter role = getRole(name); + if (role != null) { + // Compatibility with JPA model + return role; + // throw new IllegalArgumentException("Role " + name + " already exists"); + } + + RoleEntity roleEntity = new RoleEntity(); + roleEntity.setName(name); + roleEntity.setRealmId(getId()); + + getMongoStore().insertEntity(roleEntity, invocationContext); + return new RoleAdapter(this, roleEntity, this, invocationContext); + } + + @Override + public boolean removeRole(RoleModel role) { + return removeRoleById(role.getId()); + } + + @Override + public boolean removeRoleById(String id) { + return getMongoStore().removeEntity(RoleEntity.class, id, invocationContext); + } + + @Override + public Set getRoles() { + DBObject query = new QueryBuilder() + .and("realmId").is(getId()) + .get(); + List roles = getMongoStore().loadEntities(RoleEntity.class, query, invocationContext); + + Set result = new HashSet(); + + if (roles == null) return result; + for (RoleEntity role : roles) { + result.add(new RoleAdapter(this, role, this, invocationContext)); + } + + return result; + } + + @Override + public RoleModel getRoleById(String id) { + RoleEntity role = getMongoStore().loadEntity(RoleEntity.class, id, invocationContext); + if (role == null) return null; + if (role.getRealmId() != null) { + if (!role.getRealmId().equals(this.getId())) return null; + } else { + ApplicationModel app = getApplicationById(role.getApplicationId()); + if (app == null) return null; + } + return new RoleAdapter(this, role, null, invocationContext); + } + + @Override + public List getDefaultRoles() { + return realm.getDefaultRoles(); + } + + @Override + public void addDefaultRole(String name) { + RoleModel role = getRole(name); + if (role == null) { + addRole(name); + } + + getMongoStore().pushItemToList(realm, "defaultRoles", name, true, invocationContext); + } + + @Override + public void updateDefaultRoles(String[] defaultRoles) { + List roleNames = new ArrayList(); + for (String roleName : defaultRoles) { + RoleModel role = getRole(roleName); + if (role == null) { + addRole(roleName); + } + + roleNames.add(roleName); + } + + realm.setDefaultRoles(roleNames); + updateRealm(); + } + + @Override + public ClientModel findClient(String clientId) { + ClientModel model = getApplicationByName(clientId); + if (model != null) return model; + return getOAuthClient(clientId); + } + + + @Override + public ApplicationModel getApplicationById(String id) { + ApplicationEntity appData = getMongoStore().loadEntity(ApplicationEntity.class, id, invocationContext); + + // Check if application belongs to this realm + if (appData == null || !getId().equals(appData.getRealmId())) { + return null; + } + + return new ApplicationAdapter(this, appData, invocationContext); + } + + @Override + public ApplicationModel getApplicationByName(String name) { + DBObject query = new QueryBuilder() + .and("realmId").is(getId()) + .and("name").is(name) + .get(); + ApplicationEntity appEntity = getMongoStore().loadSingleEntity(ApplicationEntity.class, query, invocationContext); + return appEntity==null ? null : new ApplicationAdapter(this, appEntity, invocationContext); + } + + @Override + public Map getApplicationNameMap() { + Map resourceMap = new HashMap(); + for (ApplicationModel resource : getApplications()) { + resourceMap.put(resource.getName(), resource); + } + return resourceMap; + } + + @Override + public List getApplications() { + DBObject query = new QueryBuilder() + .and("realmId").is(getId()) + .get(); + List appDatas = getMongoStore().loadEntities(ApplicationEntity.class, query, invocationContext); + + List result = new ArrayList(); + for (ApplicationEntity appData : appDatas) { + result.add(new ApplicationAdapter(this, appData, invocationContext)); + } + return result; + } + + @Override + public ApplicationModel addApplication(String name) { + ApplicationEntity appData = new ApplicationEntity(); + appData.setName(name); + appData.setRealmId(getId()); + appData.setEnabled(true); + getMongoStore().insertEntity(appData, invocationContext); + + return new ApplicationAdapter(this, appData, invocationContext); + } + + @Override + public boolean removeApplication(String id) { + return getMongoStore().removeEntity(ApplicationEntity.class, id, invocationContext); + } + + @Override + public boolean hasRole(UserModel user, RoleModel role) { + Set roles = getRoleMappings(user); + if (roles.contains(role)) return true; + + for (RoleModel mapping : roles) { + if (mapping.hasRole(role)) return true; + } + return false; + } + + @Override + public void grantRole(UserModel user, RoleModel role) { + UserEntity userEntity = ((UserAdapter)user).getUser(); + getMongoStore().pushItemToList(userEntity, "roleIds", role.getId(), true, invocationContext); + } + + @Override + public Set getRoleMappings(UserModel user) { + Set result = new HashSet(); + List roles = MongoModelUtils.getAllRolesOfUser(user, invocationContext); + + for (RoleEntity role : roles) { + if (getId().equals(role.getRealmId())) { + result.add(new RoleAdapter(this, role, this, invocationContext)); + } else { + // Likely applicationRole, but we don't have this application yet + result.add(new RoleAdapter(this, role, invocationContext)); + } + } + return result; + } + + @Override + public Set getRealmRoleMappings(UserModel user) { + Set allRoles = getRoleMappings(user); + + // Filter to retrieve just realm roles TODO: Maybe improve to avoid filter programmatically... Maybe have separate fields for realmRoles and appRoles on user? + Set realmRoles = new HashSet(); + for (RoleModel role : allRoles) { + RoleEntity roleEntity = ((RoleAdapter)role).getRole(); + + if (getId().equals(roleEntity.getRealmId())) { + realmRoles.add(role); + } + } + return realmRoles; + } + + @Override + public void deleteRoleMapping(UserModel user, RoleModel role) { + if (user == null || role == null) return; + + UserEntity userEntity = ((UserAdapter)user).getUser(); + getMongoStore().pullItemFromList(userEntity, "roleIds", role.getId(), invocationContext); + } + + @Override + public Set getScopeMappings(ClientModel client) { + Set result = new HashSet(); + List roles = MongoModelUtils.getAllScopesOfClient(client, invocationContext); + + for (RoleEntity role : roles) { + if (getId().equals(role.getRealmId())) { + result.add(new RoleAdapter(this, role, this, invocationContext)); + } else { + // Likely applicationRole, but we don't have this application yet + result.add(new RoleAdapter(this, role, invocationContext)); + } + } + return result; + } + + @Override + public Set getRealmScopeMappings(ClientModel client) { + Set allScopes = getScopeMappings(client); + + // Filter to retrieve just realm roles TODO: Maybe improve to avoid filter programmatically... Maybe have separate fields for realmRoles and appRoles on user? + Set realmRoles = new HashSet(); + for (RoleModel role : allScopes) { + RoleEntity roleEntity = ((RoleAdapter)role).getRole(); + + if (getId().equals(roleEntity.getRealmId())) { + realmRoles.add(role); + } + } + return realmRoles; + } + + @Override + public boolean hasScope(ClientModel client, RoleModel role) { + Set roles = getScopeMappings(client); + if (roles.contains(role)) return true; + + for (RoleModel mapping : roles) { + if (mapping.hasRole(role)) return true; + } + return false; + } + + + @Override + public void addScopeMapping(ClientModel client, RoleModel role) { + getMongoStore().pushItemToList(((AbstractAdapter)client).getMongoEntity(), "scopeIds", role.getId(), true, invocationContext); + } + + @Override + public void deleteScopeMapping(ClientModel client, RoleModel role) { + getMongoStore().pullItemFromList(((AbstractAdapter)client).getMongoEntity(), "scopeIds", role.getId(), invocationContext); + } + + @Override + public OAuthClientModel addOAuthClient(String name) { + OAuthClientEntity oauthClient = new OAuthClientEntity(); + oauthClient.setRealmId(getId()); + oauthClient.setName(name); + getMongoStore().insertEntity(oauthClient, invocationContext); + + return new OAuthClientAdapter(this, oauthClient, invocationContext); + } + + @Override + public boolean removeOAuthClient(String id) { + return getMongoStore().removeEntity(OAuthClientEntity.class, id, invocationContext); + } + + @Override + public OAuthClientModel getOAuthClient(String name) { + DBObject query = new QueryBuilder() + .and("realmId").is(getId()) + .and("name").is(name) + .get(); + OAuthClientEntity oauthClient = getMongoStore().loadSingleEntity(OAuthClientEntity.class, query, invocationContext); + return oauthClient == null ? null : new OAuthClientAdapter(this, oauthClient, invocationContext); + } + + @Override + public OAuthClientModel getOAuthClientById(String id) { + OAuthClientEntity clientEntity = getMongoStore().loadEntity(OAuthClientEntity.class, id, invocationContext); + + // Check if client belongs to this realm + if (clientEntity == null || !getId().equals(clientEntity.getRealmId())) return null; + + return new OAuthClientAdapter(this, clientEntity, invocationContext); + } + + @Override + public List getOAuthClients() { + DBObject query = new QueryBuilder() + .and("realmId").is(getId()) + .get(); + List results = getMongoStore().loadEntities(OAuthClientEntity.class, query, invocationContext); + List list = new ArrayList(); + for (OAuthClientEntity data : results) { + list.add(new OAuthClientAdapter(this, data, invocationContext)); + } + return list; + } + + @Override + public void addRequiredCredential(String type) { + RequiredCredentialModel credentialModel = initRequiredCredentialModel(type); + addRequiredCredential(credentialModel, realm.getRequiredCredentials()); + } + + protected void addRequiredCredential(RequiredCredentialModel credentialModel, List persistentCollection) { + RequiredCredentialEntity credEntity = new RequiredCredentialEntity(); + credEntity.setType(credentialModel.getType()); + credEntity.setFormLabel(credentialModel.getFormLabel()); + credEntity.setInput(credentialModel.isInput()); + credEntity.setSecret(credentialModel.isSecret()); + + persistentCollection.add(credEntity); + + updateRealm(); + } + + @Override + public void updateRequiredCredentials(Set creds) { + updateRequiredCredentials(creds, realm.getRequiredCredentials()); + } + + protected void updateRequiredCredentials(Set creds, List credsEntities) { + Set already = new HashSet(); + Set toRemove = new HashSet(); + for (RequiredCredentialEntity entity : credsEntities) { + if (!creds.contains(entity.getType())) { + toRemove.add(entity); + } else { + already.add(entity.getType()); + } + } + for (RequiredCredentialEntity entity : toRemove) { + credsEntities.remove(entity); + } + for (String cred : creds) { + logger.info("updating cred: " + cred); + if (!already.contains(cred)) { + RequiredCredentialModel credentialModel = initRequiredCredentialModel(cred); + addRequiredCredential(credentialModel, credsEntities); + } + } + } + + @Override + public List getRequiredCredentials() { + return convertRequiredCredentialEntities(realm.getRequiredCredentials()); + } + + protected List convertRequiredCredentialEntities(Collection credEntities) { + + List result = new ArrayList(); + for (RequiredCredentialEntity entity : credEntities) { + RequiredCredentialModel model = new RequiredCredentialModel(); + model.setFormLabel(entity.getFormLabel()); + model.setInput(entity.isInput()); + model.setSecret(entity.isSecret()); + model.setType(entity.getType()); + + result.add(model); + } + return result; + } + + @Override + public boolean validatePassword(UserModel user, String password) { + for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) { + if (cred.getType().equals(UserCredentialModel.PASSWORD)) { + return new Pbkdf2PasswordEncoder(cred.getSalt()).verify(password, cred.getValue()); + } + } + return false; + } + + @Override + public boolean validateTOTP(UserModel user, String password, String token) { + if (!validatePassword(user, password)) return false; + for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) { + if (cred.getType().equals(UserCredentialModel.TOTP)) { + return new TimeBasedOTP().validate(token, cred.getValue().getBytes()); + } + } + return false; + } + + + @Override + public void updateCredential(UserModel user, UserCredentialModel cred) { + CredentialEntity credentialEntity = null; + UserEntity userEntity = ((UserAdapter) user).getUser(); + for (CredentialEntity entity : userEntity.getCredentials()) { + if (entity.getType().equals(cred.getType())) { + credentialEntity = entity; + } + } + + if (credentialEntity == null) { + credentialEntity = new CredentialEntity(); + credentialEntity.setType(cred.getType()); + credentialEntity.setDevice(cred.getDevice()); + userEntity.getCredentials().add(credentialEntity); + } + if (cred.getType().equals(UserCredentialModel.PASSWORD)) { + byte[] salt = Pbkdf2PasswordEncoder.getSalt(); + credentialEntity.setValue(new Pbkdf2PasswordEncoder(salt).encode(cred.getValue())); + credentialEntity.setSalt(salt); + } else { + credentialEntity.setValue(cred.getValue()); + } + credentialEntity.setDevice(cred.getDevice()); + + getMongoStore().updateEntity(userEntity, invocationContext); + } + + @Override + public UserModel getUserBySocialLink(SocialLinkModel socialLink) { + DBObject query = new QueryBuilder() + .and("socialLinks.socialProvider").is(socialLink.getSocialProvider()) + .and("socialLinks.socialUsername").is(socialLink.getSocialUsername()) + .and("realmId").is(getId()) + .get(); + UserEntity userEntity = getMongoStore().loadSingleEntity(UserEntity.class, query, invocationContext); + return userEntity==null ? null : new UserAdapter(userEntity, invocationContext); + } + + @Override + public Set getSocialLinks(UserModel user) { + UserEntity userEntity = ((UserAdapter)user).getUser(); + List linkEntities = userEntity.getSocialLinks(); + + if (linkEntities == null) { + return Collections.EMPTY_SET; + } + + Set result = new HashSet(); + for (SocialLinkEntity socialLinkEntity : linkEntities) { + SocialLinkModel model = new SocialLinkModel(socialLinkEntity.getSocialProvider(), socialLinkEntity.getSocialUsername()); + result.add(model); + } + return result; + } + + @Override + public void addSocialLink(UserModel user, SocialLinkModel socialLink) { + UserEntity userEntity = ((UserAdapter)user).getUser(); + SocialLinkEntity socialLinkEntity = new SocialLinkEntity(); + socialLinkEntity.setSocialProvider(socialLink.getSocialProvider()); + socialLinkEntity.setSocialUsername(socialLink.getSocialUsername()); + + getMongoStore().pushItemToList(userEntity, "socialLinks", socialLinkEntity, true, invocationContext); + } + + @Override + public void removeSocialLink(UserModel user, SocialLinkModel socialLink) { + SocialLinkEntity socialLinkEntity = new SocialLinkEntity(); + socialLinkEntity.setSocialProvider(socialLink.getSocialProvider()); + socialLinkEntity.setSocialUsername(socialLink.getSocialUsername()); + + UserEntity userEntity = ((UserAdapter)user).getUser(); + getMongoStore().pullItemFromList(userEntity, "socialLinks", socialLinkEntity, invocationContext); + } + + protected void updateRealm() { + getMongoStore().updateEntity(realm, invocationContext); + } + + protected RequiredCredentialModel initRequiredCredentialModel(String type) { + RequiredCredentialModel model = RequiredCredentialModel.BUILT_IN.get(type); + if (model == null) { + throw new RuntimeException("Unknown credential type " + type); + } + return model; + } + + @Override + public List getUsers() { + DBObject query = new QueryBuilder() + .and("realmId").is(getId()) + .get(); + List users = getMongoStore().loadEntities(UserEntity.class, query, invocationContext); + return convertUserEntities(users); + } + + @Override + public List searchForUser(String search) { + search = search.trim(); + Pattern caseInsensitivePattern = Pattern.compile("(?i:" + search + ")"); + + QueryBuilder nameBuilder; + int spaceInd = search.lastIndexOf(" "); + + // Case when we have search string like "ohn Bow". Then firstName must end with "ohn" AND lastName must start with "bow" (everything case-insensitive) + if (spaceInd != -1) { + String firstName = search.substring(0, spaceInd); + String lastName = search.substring(spaceInd + 1); + Pattern firstNamePattern = Pattern.compile("(?i:" + firstName + "$)"); + Pattern lastNamePattern = Pattern.compile("(?i:^" + lastName + ")"); + nameBuilder = new QueryBuilder().and( + new QueryBuilder().put("firstName").regex(firstNamePattern).get(), + new QueryBuilder().put("lastName").regex(lastNamePattern).get() + ); + } else { + // Case when we have search without spaces like "foo". The firstName OR lastName could be "foo" (everything case-insensitive) + nameBuilder = new QueryBuilder().or( + new QueryBuilder().put("firstName").regex(caseInsensitivePattern).get(), + new QueryBuilder().put("lastName").regex(caseInsensitivePattern).get() + ); + } + + QueryBuilder builder = new QueryBuilder().and( + new QueryBuilder().and("realmId").is(getId()).get(), + new QueryBuilder().or( + new QueryBuilder().put("loginName").regex(caseInsensitivePattern).get(), + new QueryBuilder().put("email").regex(caseInsensitivePattern).get(), + nameBuilder.get() + + ).get() + ); + + List users = getMongoStore().loadEntities(UserEntity.class, builder.get(), invocationContext); + return convertUserEntities(users); + } + + @Override + public List searchForUserByAttributes(Map attributes) { + QueryBuilder queryBuilder = new QueryBuilder() + .and("realmId").is(getId()); + + for (Map.Entry entry : attributes.entrySet()) { + if (entry.getKey().equals(UserModel.LOGIN_NAME)) { + queryBuilder.and("loginName").regex(Pattern.compile("(?i:" + entry.getValue() + "$)")); + } else if (entry.getKey().equalsIgnoreCase(UserModel.FIRST_NAME)) { + queryBuilder.and(UserModel.FIRST_NAME).regex(Pattern.compile("(?i:" + entry.getValue() + "$)")); + + } else if (entry.getKey().equalsIgnoreCase(UserModel.LAST_NAME)) { + queryBuilder.and(UserModel.LAST_NAME).regex(Pattern.compile("(?i:" + entry.getValue() + "$)")); + + } else if (entry.getKey().equalsIgnoreCase(UserModel.EMAIL)) { + queryBuilder.and(UserModel.EMAIL).regex(Pattern.compile("(?i:" + entry.getValue() + "$)")); + } + } + List users = getMongoStore().loadEntities(UserEntity.class, queryBuilder.get(), invocationContext); + return convertUserEntities(users); + } + + protected List convertUserEntities(List userEntities) { + List userModels = new ArrayList(); + for (UserEntity user : userEntities) { + userModels.add(new UserAdapter(user, invocationContext)); + } + return userModels; + } + + @Override + public Map getSmtpConfig() { + return realm.getSmtpConfig(); + } + + @Override + public void setSmtpConfig(Map smtpConfig) { + realm.setSmtpConfig(smtpConfig); + updateRealm(); + } + + @Override + public Map getSocialConfig() { + return realm.getSocialConfig(); + } + + @Override + public void setSocialConfig(Map socialConfig) { + realm.setSocialConfig(socialConfig); + updateRealm(); + } + + @Override + public AbstractMongoIdentifiableEntity getMongoEntity() { + return realm; + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java old mode 100644 new mode 100755 index 0436569e90..1165da3452 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RoleAdapter.java @@ -7,6 +7,7 @@ import java.util.Set; import com.mongodb.DBObject; import com.mongodb.QueryBuilder; +import org.keycloak.models.RealmModel; import org.keycloak.models.RoleContainerModel; import org.keycloak.models.RoleModel; import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; @@ -26,15 +27,17 @@ public class RoleAdapter extends AbstractAdapter implements RoleModel { private final RoleEntity role; private RoleContainerModel roleContainer; + private RealmModel realm; - public RoleAdapter(RoleEntity roleEntity, MongoStoreInvocationContext invContext) { - this(roleEntity, null, invContext); + public RoleAdapter(RealmModel realm, RoleEntity roleEntity, MongoStoreInvocationContext invContext) { + this(realm, roleEntity, null, invContext); } - public RoleAdapter(RoleEntity roleEntity, RoleContainerModel roleContainer, MongoStoreInvocationContext invContext) { + public RoleAdapter(RealmModel realm, RoleEntity roleEntity, RoleContainerModel roleContainer, MongoStoreInvocationContext invContext) { super(invContext); this.role = roleEntity; this.roleContainer = roleContainer; + this.realm = realm; } @Override @@ -96,7 +99,7 @@ public class RoleAdapter extends AbstractAdapter implements RoleModel { Set set = new HashSet(); for (RoleEntity childRole : childRoles) { - set.add(new RoleAdapter(childRole, invocationContext)); + set.add(new RoleAdapter(realm, childRole, invocationContext)); } return set; } @@ -116,7 +119,7 @@ public class RoleAdapter extends AbstractAdapter implements RoleModel { if (appEntity == null) { throw new IllegalStateException("Application with id: " + role.getApplicationId() + " doesn't exists"); } - roleContainer = new ApplicationAdapter(appEntity, invocationContext); + roleContainer = new ApplicationAdapter(realm, appEntity, invocationContext); } else { throw new IllegalStateException("Both realmId and applicationId are null for role: " + this); } @@ -141,4 +144,22 @@ public class RoleAdapter extends AbstractAdapter implements RoleModel { public AbstractMongoIdentifiableEntity getMongoEntity() { return role; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + RoleAdapter that = (RoleAdapter) o; + + if (!role.getId().equals(that.role.getId())) return false; + + return true; + } + + @Override + public int hashCode() { + return role.getId().hashCode(); + } + } diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java index 8f22a7bffd..d3d4d6a1b1 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java @@ -1,166 +1,166 @@ -package org.keycloak.models.mongo.keycloak.adapters; - -import org.keycloak.models.UserModel; -import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; -import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; -import org.keycloak.models.mongo.keycloak.entities.UserEntity; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Wrapper around UserData object, which will persist wrapped object after each set operation (compatibility with picketlink based impl) - * - * @author Marek Posolda - */ -public class UserAdapter extends AbstractAdapter implements UserModel { - - private final UserEntity user; - - public UserAdapter(UserEntity userEntity, MongoStoreInvocationContext invContext) { - super(invContext); - this.user = userEntity; - } - - @Override - public String getId() { - return user.getId(); - } - - @Override - public String getLoginName() { - return user.getLoginName(); - } - - @Override - public boolean isEnabled() { - return user.isEnabled(); - } - - @Override - public void setEnabled(boolean enabled) { - user.setEnabled(enabled); - updateUser(); - } - - @Override - public String getFirstName() { - return user.getFirstName(); - } - - @Override - public void setFirstName(String firstName) { - user.setFirstName(firstName); - updateUser(); - } - - @Override - public String getLastName() { - return user.getLastName(); - } - - @Override - public void setLastName(String lastName) { - user.setLastName(lastName); - updateUser(); - } - - @Override - public String getEmail() { - return user.getEmail(); - } - - @Override - public void setEmail(String email) { - user.setEmail(email); - updateUser(); - } - - @Override - public boolean isEmailVerified() { - return user.isEmailVerified(); - } - - @Override - public void setEmailVerified(boolean verified) { - user.setEmailVerified(verified); - updateUser(); - } - - @Override - public void setAttribute(String name, String value) { - if (user.getAttributes() == null) { - user.setAttributes(new HashMap()); - } - - user.getAttributes().put(name, value); - updateUser(); - } - - @Override - public void removeAttribute(String name) { - if (user.getAttributes() == null) return; - - user.getAttributes().remove(name); - updateUser(); - } - - @Override - public String getAttribute(String name) { - return user.getAttributes()==null ? null : user.getAttributes().get(name); - } - - @Override - public Map getAttributes() { - return user.getAttributes()==null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(user.getAttributes()); - } - - public UserEntity getUser() { - return user; - } - - - @Override - public Set getRequiredActions() { - Set result = new HashSet(); - if (user.getRequiredActions() != null) { - result.addAll(user.getRequiredActions()); - } - return result; - } - - @Override - public void addRequiredAction(RequiredAction action) { - getMongoStore().pushItemToList(user, "requiredActions", action, true, invocationContext); - } - - @Override - public void removeRequiredAction(RequiredAction action) { - getMongoStore().pullItemFromList(user, "requiredActions", action, invocationContext); - } - - @Override - public boolean isTotp() { - return user.isTotp(); - } - - @Override - public void setTotp(boolean totp) { - user.setTotp(totp); - updateUser(); - } - - protected void updateUser() { - getMongoStore().updateEntity(user, invocationContext); - } - - @Override - public AbstractMongoIdentifiableEntity getMongoEntity() { - return user; - } -} +package org.keycloak.models.mongo.keycloak.adapters; + +import org.keycloak.models.UserModel; +import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; +import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; +import org.keycloak.models.mongo.keycloak.entities.UserEntity; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Wrapper around UserData object, which will persist wrapped object after each set operation (compatibility with picketlink based impl) + * + * @author Marek Posolda + */ +public class UserAdapter extends AbstractAdapter implements UserModel { + + private final UserEntity user; + + public UserAdapter(UserEntity userEntity, MongoStoreInvocationContext invContext) { + super(invContext); + this.user = userEntity; + } + + @Override + public String getId() { + return user.getId(); + } + + @Override + public String getLoginName() { + return user.getLoginName(); + } + + @Override + public boolean isEnabled() { + return user.isEnabled(); + } + + @Override + public void setEnabled(boolean enabled) { + user.setEnabled(enabled); + updateUser(); + } + + @Override + public String getFirstName() { + return user.getFirstName(); + } + + @Override + public void setFirstName(String firstName) { + user.setFirstName(firstName); + updateUser(); + } + + @Override + public String getLastName() { + return user.getLastName(); + } + + @Override + public void setLastName(String lastName) { + user.setLastName(lastName); + updateUser(); + } + + @Override + public String getEmail() { + return user.getEmail(); + } + + @Override + public void setEmail(String email) { + user.setEmail(email); + updateUser(); + } + + @Override + public boolean isEmailVerified() { + return user.isEmailVerified(); + } + + @Override + public void setEmailVerified(boolean verified) { + user.setEmailVerified(verified); + updateUser(); + } + + @Override + public void setAttribute(String name, String value) { + if (user.getAttributes() == null) { + user.setAttributes(new HashMap()); + } + + user.getAttributes().put(name, value); + updateUser(); + } + + @Override + public void removeAttribute(String name) { + if (user.getAttributes() == null) return; + + user.getAttributes().remove(name); + updateUser(); + } + + @Override + public String getAttribute(String name) { + return user.getAttributes()==null ? null : user.getAttributes().get(name); + } + + @Override + public Map getAttributes() { + return user.getAttributes()==null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(user.getAttributes()); + } + + public UserEntity getUser() { + return user; + } + + + @Override + public Set getRequiredActions() { + Set result = new HashSet(); + if (user.getRequiredActions() != null) { + result.addAll(user.getRequiredActions()); + } + return result; + } + + @Override + public void addRequiredAction(RequiredAction action) { + getMongoStore().pushItemToList(user, "requiredActions", action, true, invocationContext); + } + + @Override + public void removeRequiredAction(RequiredAction action) { + getMongoStore().pullItemFromList(user, "requiredActions", action, invocationContext); + } + + @Override + public boolean isTotp() { + return user.isTotp(); + } + + @Override + public void setTotp(boolean totp) { + user.setTotp(totp); + updateUser(); + } + + protected void updateUser() { + getMongoStore().updateEntity(user, invocationContext); + } + + @Override + public AbstractMongoIdentifiableEntity getMongoEntity() { + return user; + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java index f77b6a884a..60f166745c 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java @@ -1,157 +1,157 @@ -package org.keycloak.models.mongo.keycloak.entities; - -import java.util.ArrayList; -import java.util.List; - -import com.mongodb.DBObject; -import com.mongodb.QueryBuilder; -import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; -import org.keycloak.models.mongo.api.MongoCollection; -import org.keycloak.models.mongo.api.MongoEntity; -import org.keycloak.models.mongo.api.MongoField; -import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; - -/** - * @author Marek Posolda - */ -@MongoCollection(collectionName = "applications") -public class ApplicationEntity extends AbstractMongoIdentifiableEntity implements MongoEntity, ScopedEntity { - - private String name; - private boolean enabled; - private boolean surrogateAuthRequired; - private String managementUrl; - private String baseUrl; - private String secret; - - private String realmId; - private long allowedClaimsMask; - private List scopeIds; - private List webOrigins; - private List redirectUris; - - - // We are using names of defaultRoles (not ids) - private List defaultRoles = new ArrayList(); - - @MongoField - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @MongoField - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @MongoField - public boolean isSurrogateAuthRequired() { - return surrogateAuthRequired; - } - - public void setSurrogateAuthRequired(boolean surrogateAuthRequired) { - this.surrogateAuthRequired = surrogateAuthRequired; - } - - @MongoField - public String getManagementUrl() { - return managementUrl; - } - - public void setManagementUrl(String managementUrl) { - this.managementUrl = managementUrl; - } - - @MongoField - public String getBaseUrl() { - return baseUrl; - } - - public void setBaseUrl(String baseUrl) { - this.baseUrl = baseUrl; - } - - @Override - @MongoField - public List getScopeIds() { - return scopeIds; - } - - @Override - public void setScopeIds(List scopeIds) { - this.scopeIds = scopeIds; - } - - @MongoField - public List getWebOrigins() { - return webOrigins; - } - - public void setWebOrigins(List webOrigins) { - this.webOrigins = webOrigins; - } - - @MongoField - public List getRedirectUris() { - return redirectUris; - } - - public void setRedirectUris(List redirectUris) { - this.redirectUris = redirectUris; - } - - - - @MongoField - public long getAllowedClaimsMask() { - return allowedClaimsMask; - } - - public void setAllowedClaimsMask(long allowedClaimsMask) { - this.allowedClaimsMask = allowedClaimsMask; - } - - @MongoField - public String getRealmId() { - return realmId; - } - - public void setRealmId(String realmId) { - this.realmId = realmId; - } - - @MongoField - public String getSecret() { - return secret; - } - - public void setSecret(String secret) { - this.secret = secret; - } - - @MongoField - public List getDefaultRoles() { - return defaultRoles; - } - - public void setDefaultRoles(List defaultRoles) { - this.defaultRoles = defaultRoles; - } - - @Override - public void afterRemove(MongoStoreInvocationContext context) { - // Remove all roles, which belongs to this application - DBObject query = new QueryBuilder() - .and("applicationId").is(getId()) - .get(); - context.getMongoStore().removeEntities(RoleEntity.class, query, context); - } -} +package org.keycloak.models.mongo.keycloak.entities; + +import java.util.ArrayList; +import java.util.List; + +import com.mongodb.DBObject; +import com.mongodb.QueryBuilder; +import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; +import org.keycloak.models.mongo.api.MongoCollection; +import org.keycloak.models.mongo.api.MongoEntity; +import org.keycloak.models.mongo.api.MongoField; +import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; + +/** + * @author Marek Posolda + */ +@MongoCollection(collectionName = "applications") +public class ApplicationEntity extends AbstractMongoIdentifiableEntity implements MongoEntity, ScopedEntity { + + private String name; + private boolean enabled; + private boolean surrogateAuthRequired; + private String managementUrl; + private String baseUrl; + private String secret; + + private String realmId; + private long allowedClaimsMask; + private List scopeIds; + private List webOrigins; + private List redirectUris; + + + // We are using names of defaultRoles (not ids) + private List defaultRoles = new ArrayList(); + + @MongoField + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @MongoField + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + @MongoField + public boolean isSurrogateAuthRequired() { + return surrogateAuthRequired; + } + + public void setSurrogateAuthRequired(boolean surrogateAuthRequired) { + this.surrogateAuthRequired = surrogateAuthRequired; + } + + @MongoField + public String getManagementUrl() { + return managementUrl; + } + + public void setManagementUrl(String managementUrl) { + this.managementUrl = managementUrl; + } + + @MongoField + public String getBaseUrl() { + return baseUrl; + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + @Override + @MongoField + public List getScopeIds() { + return scopeIds; + } + + @Override + public void setScopeIds(List scopeIds) { + this.scopeIds = scopeIds; + } + + @MongoField + public List getWebOrigins() { + return webOrigins; + } + + public void setWebOrigins(List webOrigins) { + this.webOrigins = webOrigins; + } + + @MongoField + public List getRedirectUris() { + return redirectUris; + } + + public void setRedirectUris(List redirectUris) { + this.redirectUris = redirectUris; + } + + + + @MongoField + public long getAllowedClaimsMask() { + return allowedClaimsMask; + } + + public void setAllowedClaimsMask(long allowedClaimsMask) { + this.allowedClaimsMask = allowedClaimsMask; + } + + @MongoField + public String getRealmId() { + return realmId; + } + + public void setRealmId(String realmId) { + this.realmId = realmId; + } + + @MongoField + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } + + @MongoField + public List getDefaultRoles() { + return defaultRoles; + } + + public void setDefaultRoles(List defaultRoles) { + this.defaultRoles = defaultRoles; + } + + @Override + public void afterRemove(MongoStoreInvocationContext context) { + // Remove all roles, which belongs to this application + DBObject query = new QueryBuilder() + .and("applicationId").is(getId()) + .get(); + context.getMongoStore().removeEntities(RoleEntity.class, query, context); + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java index c59443f3fd..9ef85a324c 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java @@ -1,105 +1,105 @@ -package org.keycloak.models.mongo.keycloak.entities; - -import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; -import org.keycloak.models.mongo.api.MongoCollection; -import org.keycloak.models.mongo.api.MongoEntity; -import org.keycloak.models.mongo.api.MongoField; -import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; - -import java.util.List; - -/** - * @author Marek Posolda - */ -@MongoCollection(collectionName = "oauthClients") -public class OAuthClientEntity extends AbstractMongoIdentifiableEntity implements MongoEntity, ScopedEntity { - - private String name; - private boolean enabled; - private String realmId; - private String secret; - private long allowedClaimsMask; - private List scopeIds; - private List webOrigins; - private List redirectUris; - - @MongoField - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @MongoField - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @MongoField - public String getRealmId() { - return realmId; - } - - public void setRealmId(String realmId) { - this.realmId = realmId; - } - - @MongoField - public String getSecret() { - return secret; - } - - public void setSecret(String secret) { - this.secret = secret; - } - - - @MongoField - public long getAllowedClaimsMask() { - return allowedClaimsMask; - } - - public void setAllowedClaimsMask(long allowedClaimsMask) { - this.allowedClaimsMask = allowedClaimsMask; - } - - @MongoField - public List getWebOrigins() { - return webOrigins; - } - - public void setWebOrigins(List webOrigins) { - this.webOrigins = webOrigins; - } - - @MongoField - public List getRedirectUris() { - return redirectUris; - } - - public void setRedirectUris(List redirectUris) { - this.redirectUris = redirectUris; - } - - @MongoField - public List getScopeIds() { - return scopeIds; - } - - public void setScopeIds(List scopeIds) { - this.scopeIds = scopeIds; - } - - - - - @Override - public void afterRemove(MongoStoreInvocationContext context) { - } -} +package org.keycloak.models.mongo.keycloak.entities; + +import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; +import org.keycloak.models.mongo.api.MongoCollection; +import org.keycloak.models.mongo.api.MongoEntity; +import org.keycloak.models.mongo.api.MongoField; +import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; + +import java.util.List; + +/** + * @author Marek Posolda + */ +@MongoCollection(collectionName = "oauthClients") +public class OAuthClientEntity extends AbstractMongoIdentifiableEntity implements MongoEntity, ScopedEntity { + + private String name; + private boolean enabled; + private String realmId; + private String secret; + private long allowedClaimsMask; + private List scopeIds; + private List webOrigins; + private List redirectUris; + + @MongoField + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @MongoField + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + @MongoField + public String getRealmId() { + return realmId; + } + + public void setRealmId(String realmId) { + this.realmId = realmId; + } + + @MongoField + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } + + + @MongoField + public long getAllowedClaimsMask() { + return allowedClaimsMask; + } + + public void setAllowedClaimsMask(long allowedClaimsMask) { + this.allowedClaimsMask = allowedClaimsMask; + } + + @MongoField + public List getWebOrigins() { + return webOrigins; + } + + public void setWebOrigins(List webOrigins) { + this.webOrigins = webOrigins; + } + + @MongoField + public List getRedirectUris() { + return redirectUris; + } + + public void setRedirectUris(List redirectUris) { + this.redirectUris = redirectUris; + } + + @MongoField + public List getScopeIds() { + return scopeIds; + } + + public void setScopeIds(List scopeIds) { + this.scopeIds = scopeIds; + } + + + + + @Override + public void afterRemove(MongoStoreInvocationContext context) { + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RealmEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RealmEntity.java index b8b2ef2e29..90f39a87ce 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RealmEntity.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RealmEntity.java @@ -1,285 +1,285 @@ -package org.keycloak.models.mongo.keycloak.entities; - -import com.mongodb.DBObject; -import com.mongodb.QueryBuilder; -import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; -import org.keycloak.models.mongo.api.MongoCollection; -import org.keycloak.models.mongo.api.MongoEntity; -import org.keycloak.models.mongo.api.MongoField; -import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author Marek Posolda - */ -@MongoCollection(collectionName = "realms") -public class RealmEntity extends AbstractMongoIdentifiableEntity implements MongoEntity { - - private String name; - private boolean enabled; - private boolean sslNotRequired; - private boolean registrationAllowed; - private boolean rememberMe; - private boolean verifyEmail; - private boolean resetPasswordAllowed; - private boolean social; - private boolean updateProfileOnInitialSocialLogin; - private String passwordPolicy; - - private int centralLoginLifespan; - private int accessTokenLifespan; - private int accessCodeLifespan; - private int accessCodeLifespanUserAction; - private int refreshTokenLifespan; - private int notBefore; - - private String publicKeyPem; - private String privateKeyPem; - - private String loginTheme; - private String accountTheme; - - // We are using names of defaultRoles (not ids) - private List defaultRoles = new ArrayList(); - - private List requiredCredentials = new ArrayList(); - - private Map smtpConfig = new HashMap(); - private Map socialConfig = new HashMap(); - - @MongoField - public String getName() { - return name; - } - - public void setName(String realmName) { - this.name = realmName; - } - - @MongoField - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @MongoField - public boolean isSslNotRequired() { - return sslNotRequired; - } - - public void setSslNotRequired(boolean sslNotRequired) { - this.sslNotRequired = sslNotRequired; - } - - @MongoField - public boolean isRegistrationAllowed() { - return registrationAllowed; - } - - public void setRegistrationAllowed(boolean registrationAllowed) { - this.registrationAllowed = registrationAllowed; - } - - @MongoField - public boolean isRememberMe() { - return rememberMe; - } - - public void setRememberMe(boolean rememberMe) { - this.rememberMe = rememberMe; - } - - @MongoField - public boolean isVerifyEmail() { - return verifyEmail; - } - - public void setVerifyEmail(boolean verifyEmail) { - this.verifyEmail = verifyEmail; - } - - @MongoField - public boolean isResetPasswordAllowed() { - return resetPasswordAllowed; - } - - public void setResetPasswordAllowed(boolean resetPasswordAllowed) { - this.resetPasswordAllowed = resetPasswordAllowed; - } - - @MongoField - public boolean isSocial() { - return social; - } - - public void setSocial(boolean social) { - this.social = social; - } - - @MongoField - public boolean isUpdateProfileOnInitialSocialLogin() { - return updateProfileOnInitialSocialLogin; - } - - public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) { - this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin; - } - - @MongoField - public String getPasswordPolicy() { - return passwordPolicy; - } - - public void setPasswordPolicy(String passwordPolicy) { - this.passwordPolicy = passwordPolicy; - } - - @MongoField - public int getNotBefore() { - return notBefore; - } - - public void setNotBefore(int notBefore) { - this.notBefore = notBefore; - } - - @MongoField - public int getCentralLoginLifespan() { - return centralLoginLifespan; - } - - public void setCentralLoginLifespan(int centralLoginLifespan) { - this.centralLoginLifespan = centralLoginLifespan; - } - - @MongoField - public int getAccessTokenLifespan() { - return accessTokenLifespan; - } - - public void setAccessTokenLifespan(int accessTokenLifespan) { - this.accessTokenLifespan = accessTokenLifespan; - } - - @MongoField - public int getRefreshTokenLifespan() { - return refreshTokenLifespan; - } - - public void setRefreshTokenLifespan(int refreshTokenLifespan) { - this.refreshTokenLifespan = refreshTokenLifespan; - } - - @MongoField - public int getAccessCodeLifespan() { - return accessCodeLifespan; - } - - public void setAccessCodeLifespan(int accessCodeLifespan) { - this.accessCodeLifespan = accessCodeLifespan; - } - - @MongoField - public int getAccessCodeLifespanUserAction() { - return accessCodeLifespanUserAction; - } - - public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) { - this.accessCodeLifespanUserAction = accessCodeLifespanUserAction; - } - - @MongoField - public String getPublicKeyPem() { - return publicKeyPem; - } - - public void setPublicKeyPem(String publicKeyPem) { - this.publicKeyPem = publicKeyPem; - } - - @MongoField - public String getPrivateKeyPem() { - return privateKeyPem; - } - - public void setPrivateKeyPem(String privateKeyPem) { - this.privateKeyPem = privateKeyPem; - } - - @MongoField - public String getLoginTheme() { - return loginTheme; - } - - public void setLoginTheme(String loginTheme) { - this.loginTheme = loginTheme; - } - - @MongoField - public String getAccountTheme() { - return accountTheme; - } - - public void setAccountTheme(String accountTheme) { - this.accountTheme = accountTheme; - } - - @MongoField - public List getDefaultRoles() { - return defaultRoles; - } - - public void setDefaultRoles(List defaultRoles) { - this.defaultRoles = defaultRoles; - } - - @MongoField - public List getRequiredCredentials() { - return requiredCredentials; - } - - public void setRequiredCredentials(List requiredCredentials) { - this.requiredCredentials = requiredCredentials; - } - - @MongoField - public Map getSmtpConfig() { - return smtpConfig; - } - - public void setSmtpConfig(Map smptConfig) { - this.smtpConfig = smptConfig; - } - - @MongoField - public Map getSocialConfig() { - return socialConfig; - } - - public void setSocialConfig(Map socialConfig) { - this.socialConfig = socialConfig; - } - - @Override - public void afterRemove(MongoStoreInvocationContext context) { - DBObject query = new QueryBuilder() - .and("realmId").is(getId()) - .get(); - - // Remove all users of this realm - context.getMongoStore().removeEntities(UserEntity.class, query, context); - - // Remove all roles of this realm - context.getMongoStore().removeEntities(RoleEntity.class, query, context); - - // Remove all applications of this realm - context.getMongoStore().removeEntities(ApplicationEntity.class, query, context); - } -} +package org.keycloak.models.mongo.keycloak.entities; + +import com.mongodb.DBObject; +import com.mongodb.QueryBuilder; +import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; +import org.keycloak.models.mongo.api.MongoCollection; +import org.keycloak.models.mongo.api.MongoEntity; +import org.keycloak.models.mongo.api.MongoField; +import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Marek Posolda + */ +@MongoCollection(collectionName = "realms") +public class RealmEntity extends AbstractMongoIdentifiableEntity implements MongoEntity { + + private String name; + private boolean enabled; + private boolean sslNotRequired; + private boolean registrationAllowed; + private boolean rememberMe; + private boolean verifyEmail; + private boolean resetPasswordAllowed; + private boolean social; + private boolean updateProfileOnInitialSocialLogin; + private String passwordPolicy; + + private int centralLoginLifespan; + private int accessTokenLifespan; + private int accessCodeLifespan; + private int accessCodeLifespanUserAction; + private int refreshTokenLifespan; + private int notBefore; + + private String publicKeyPem; + private String privateKeyPem; + + private String loginTheme; + private String accountTheme; + + // We are using names of defaultRoles (not ids) + private List defaultRoles = new ArrayList(); + + private List requiredCredentials = new ArrayList(); + + private Map smtpConfig = new HashMap(); + private Map socialConfig = new HashMap(); + + @MongoField + public String getName() { + return name; + } + + public void setName(String realmName) { + this.name = realmName; + } + + @MongoField + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + @MongoField + public boolean isSslNotRequired() { + return sslNotRequired; + } + + public void setSslNotRequired(boolean sslNotRequired) { + this.sslNotRequired = sslNotRequired; + } + + @MongoField + public boolean isRegistrationAllowed() { + return registrationAllowed; + } + + public void setRegistrationAllowed(boolean registrationAllowed) { + this.registrationAllowed = registrationAllowed; + } + + @MongoField + public boolean isRememberMe() { + return rememberMe; + } + + public void setRememberMe(boolean rememberMe) { + this.rememberMe = rememberMe; + } + + @MongoField + public boolean isVerifyEmail() { + return verifyEmail; + } + + public void setVerifyEmail(boolean verifyEmail) { + this.verifyEmail = verifyEmail; + } + + @MongoField + public boolean isResetPasswordAllowed() { + return resetPasswordAllowed; + } + + public void setResetPasswordAllowed(boolean resetPasswordAllowed) { + this.resetPasswordAllowed = resetPasswordAllowed; + } + + @MongoField + public boolean isSocial() { + return social; + } + + public void setSocial(boolean social) { + this.social = social; + } + + @MongoField + public boolean isUpdateProfileOnInitialSocialLogin() { + return updateProfileOnInitialSocialLogin; + } + + public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) { + this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin; + } + + @MongoField + public String getPasswordPolicy() { + return passwordPolicy; + } + + public void setPasswordPolicy(String passwordPolicy) { + this.passwordPolicy = passwordPolicy; + } + + @MongoField + public int getNotBefore() { + return notBefore; + } + + public void setNotBefore(int notBefore) { + this.notBefore = notBefore; + } + + @MongoField + public int getCentralLoginLifespan() { + return centralLoginLifespan; + } + + public void setCentralLoginLifespan(int centralLoginLifespan) { + this.centralLoginLifespan = centralLoginLifespan; + } + + @MongoField + public int getAccessTokenLifespan() { + return accessTokenLifespan; + } + + public void setAccessTokenLifespan(int accessTokenLifespan) { + this.accessTokenLifespan = accessTokenLifespan; + } + + @MongoField + public int getRefreshTokenLifespan() { + return refreshTokenLifespan; + } + + public void setRefreshTokenLifespan(int refreshTokenLifespan) { + this.refreshTokenLifespan = refreshTokenLifespan; + } + + @MongoField + public int getAccessCodeLifespan() { + return accessCodeLifespan; + } + + public void setAccessCodeLifespan(int accessCodeLifespan) { + this.accessCodeLifespan = accessCodeLifespan; + } + + @MongoField + public int getAccessCodeLifespanUserAction() { + return accessCodeLifespanUserAction; + } + + public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) { + this.accessCodeLifespanUserAction = accessCodeLifespanUserAction; + } + + @MongoField + public String getPublicKeyPem() { + return publicKeyPem; + } + + public void setPublicKeyPem(String publicKeyPem) { + this.publicKeyPem = publicKeyPem; + } + + @MongoField + public String getPrivateKeyPem() { + return privateKeyPem; + } + + public void setPrivateKeyPem(String privateKeyPem) { + this.privateKeyPem = privateKeyPem; + } + + @MongoField + public String getLoginTheme() { + return loginTheme; + } + + public void setLoginTheme(String loginTheme) { + this.loginTheme = loginTheme; + } + + @MongoField + public String getAccountTheme() { + return accountTheme; + } + + public void setAccountTheme(String accountTheme) { + this.accountTheme = accountTheme; + } + + @MongoField + public List getDefaultRoles() { + return defaultRoles; + } + + public void setDefaultRoles(List defaultRoles) { + this.defaultRoles = defaultRoles; + } + + @MongoField + public List getRequiredCredentials() { + return requiredCredentials; + } + + public void setRequiredCredentials(List requiredCredentials) { + this.requiredCredentials = requiredCredentials; + } + + @MongoField + public Map getSmtpConfig() { + return smtpConfig; + } + + public void setSmtpConfig(Map smptConfig) { + this.smtpConfig = smptConfig; + } + + @MongoField + public Map getSocialConfig() { + return socialConfig; + } + + public void setSocialConfig(Map socialConfig) { + this.socialConfig = socialConfig; + } + + @Override + public void afterRemove(MongoStoreInvocationContext context) { + DBObject query = new QueryBuilder() + .and("realmId").is(getId()) + .get(); + + // Remove all users of this realm + context.getMongoStore().removeEntities(UserEntity.class, query, context); + + // Remove all roles of this realm + context.getMongoStore().removeEntities(RoleEntity.class, query, context); + + // Remove all applications of this realm + context.getMongoStore().removeEntities(ApplicationEntity.class, query, context); + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RoleEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RoleEntity.java index e2e97279dc..ee8b72fae6 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RoleEntity.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/RoleEntity.java @@ -1,131 +1,131 @@ -package org.keycloak.models.mongo.keycloak.entities; - -import com.mongodb.DBObject; -import com.mongodb.QueryBuilder; -import org.jboss.logging.Logger; -import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; -import org.keycloak.models.mongo.api.MongoCollection; -import org.keycloak.models.mongo.api.MongoEntity; -import org.keycloak.models.mongo.api.MongoField; -import org.keycloak.models.mongo.api.MongoStore; -import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; - -import java.util.List; - -/** - * @author Marek Posolda - */ -@MongoCollection(collectionName = "roles") -public class RoleEntity extends AbstractMongoIdentifiableEntity implements MongoEntity { - - private static final Logger logger = Logger.getLogger(RoleEntity.class); - - private String name; - private String description; - - private List compositeRoleIds; - - private String realmId; - private String applicationId; - - @MongoField - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @MongoField - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - @MongoField - public List getCompositeRoleIds() { - return compositeRoleIds; - } - - public void setCompositeRoleIds(List compositeRoleIds) { - this.compositeRoleIds = compositeRoleIds; - } - - @MongoField - public String getRealmId() { - return realmId; - } - - public void setRealmId(String realmId) { - this.realmId = realmId; - } - - @MongoField - public String getApplicationId() { - return applicationId; - } - - public void setApplicationId(String applicationId) { - this.applicationId = applicationId; - } - - @Override - public void afterRemove(MongoStoreInvocationContext invContext) { - MongoStore mongoStore = invContext.getMongoStore(); - - // Remove this role from all users, which has it - DBObject query = new QueryBuilder() - .and("roleIds").is(getId()) - .get(); - - List users = mongoStore.loadEntities(UserEntity.class, query, invContext); - for (UserEntity user : users) { - logger.info("Removing role " + getName() + " from user " + user.getLoginName()); - mongoStore.pullItemFromList(user, "roleIds", getId(), invContext); - } - - // Remove this scope from all users, which has it - query = new QueryBuilder() - .and("scopeIds").is(getId()) - .get(); - - users = mongoStore.loadEntities(UserEntity.class, query, invContext); - for (UserEntity user : users) { - logger.info("Removing scope " + getName() + " from user " + user.getLoginName()); - mongoStore.pullItemFromList(user, "scopeIds", getId(), invContext); - } - - // Remove defaultRoles from realm - if (realmId != null) { - RealmEntity realmEntity = mongoStore.loadEntity(RealmEntity.class, realmId, invContext); - - // Realm might be already removed at this point - if (realmEntity != null) { - mongoStore.pullItemFromList(realmEntity, "defaultRoles", getId(), invContext); - } - } - - // Remove defaultRoles from application - if (applicationId != null) { - ApplicationEntity appEntity = mongoStore.loadEntity(ApplicationEntity.class, applicationId, invContext); - - // Application might be already removed at this point - if (appEntity != null) { - mongoStore.pullItemFromList(appEntity, "defaultRoles", getId(), invContext); - } - } - - // Remove this role from others who has it as composite - query = new QueryBuilder() - .and("compositeRoleIds").is(getId()) - .get(); - List parentRoles = mongoStore.loadEntities(RoleEntity.class, query, invContext); - for (RoleEntity role : parentRoles) { - mongoStore.pullItemFromList(role, "compositeRoleIds", getId(), invContext); - } - } -} +package org.keycloak.models.mongo.keycloak.entities; + +import com.mongodb.DBObject; +import com.mongodb.QueryBuilder; +import org.jboss.logging.Logger; +import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; +import org.keycloak.models.mongo.api.MongoCollection; +import org.keycloak.models.mongo.api.MongoEntity; +import org.keycloak.models.mongo.api.MongoField; +import org.keycloak.models.mongo.api.MongoStore; +import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; + +import java.util.List; + +/** + * @author Marek Posolda + */ +@MongoCollection(collectionName = "roles") +public class RoleEntity extends AbstractMongoIdentifiableEntity implements MongoEntity { + + private static final Logger logger = Logger.getLogger(RoleEntity.class); + + private String name; + private String description; + + private List compositeRoleIds; + + private String realmId; + private String applicationId; + + @MongoField + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @MongoField + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @MongoField + public List getCompositeRoleIds() { + return compositeRoleIds; + } + + public void setCompositeRoleIds(List compositeRoleIds) { + this.compositeRoleIds = compositeRoleIds; + } + + @MongoField + public String getRealmId() { + return realmId; + } + + public void setRealmId(String realmId) { + this.realmId = realmId; + } + + @MongoField + public String getApplicationId() { + return applicationId; + } + + public void setApplicationId(String applicationId) { + this.applicationId = applicationId; + } + + @Override + public void afterRemove(MongoStoreInvocationContext invContext) { + MongoStore mongoStore = invContext.getMongoStore(); + + // Remove this role from all users, which has it + DBObject query = new QueryBuilder() + .and("roleIds").is(getId()) + .get(); + + List users = mongoStore.loadEntities(UserEntity.class, query, invContext); + for (UserEntity user : users) { + logger.info("Removing role " + getName() + " from user " + user.getLoginName()); + mongoStore.pullItemFromList(user, "roleIds", getId(), invContext); + } + + // Remove this scope from all users, which has it + query = new QueryBuilder() + .and("scopeIds").is(getId()) + .get(); + + users = mongoStore.loadEntities(UserEntity.class, query, invContext); + for (UserEntity user : users) { + logger.info("Removing scope " + getName() + " from user " + user.getLoginName()); + mongoStore.pullItemFromList(user, "scopeIds", getId(), invContext); + } + + // Remove defaultRoles from realm + if (realmId != null) { + RealmEntity realmEntity = mongoStore.loadEntity(RealmEntity.class, realmId, invContext); + + // Realm might be already removed at this point + if (realmEntity != null) { + mongoStore.pullItemFromList(realmEntity, "defaultRoles", getId(), invContext); + } + } + + // Remove defaultRoles from application + if (applicationId != null) { + ApplicationEntity appEntity = mongoStore.loadEntity(ApplicationEntity.class, applicationId, invContext); + + // Application might be already removed at this point + if (appEntity != null) { + mongoStore.pullItemFromList(appEntity, "defaultRoles", getId(), invContext); + } + } + + // Remove this role from others who has it as composite + query = new QueryBuilder() + .and("compositeRoleIds").is(getId()) + .get(); + List parentRoles = mongoStore.loadEntities(RoleEntity.class, query, invContext); + for (RoleEntity role : parentRoles) { + mongoStore.pullItemFromList(role, "compositeRoleIds", getId(), invContext); + } + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/UserEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/UserEntity.java index c21a726dbd..753ab8b408 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/UserEntity.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/UserEntity.java @@ -1,153 +1,153 @@ -package org.keycloak.models.mongo.keycloak.entities; - -import org.keycloak.models.UserModel; -import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; -import org.keycloak.models.mongo.api.MongoCollection; -import org.keycloak.models.mongo.api.MongoEntity; -import org.keycloak.models.mongo.api.MongoField; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * @author Marek Posolda - */ -@MongoCollection(collectionName = "users") -public class UserEntity extends AbstractMongoIdentifiableEntity implements MongoEntity { - - private String loginName; - private String firstName; - private String lastName; - private String email; - private boolean emailVerified; - private boolean totp; - private boolean enabled; - - private String realmId; - - private List roleIds; - - private Map attributes; - private List requiredActions; - private List credentials = new ArrayList(); - private List socialLinks; - - @MongoField - public String getLoginName() { - return loginName; - } - - public void setLoginName(String loginName) { - this.loginName = loginName; - } - - @MongoField - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - @MongoField - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - @MongoField - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - @MongoField - public boolean isEmailVerified() { - return emailVerified; - } - - public void setEmailVerified(boolean emailVerified) { - this.emailVerified = emailVerified; - } - - @MongoField - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @MongoField - public boolean isTotp() { - return totp; - } - - public void setTotp(boolean totp) { - this.totp = totp; - } - - @MongoField - public String getRealmId() { - return realmId; - } - - public void setRealmId(String realmId) { - this.realmId = realmId; - } - - @MongoField - public List getRoleIds() { - return roleIds; - } - - public void setRoleIds(List roleIds) { - this.roleIds = roleIds; - } - - - @MongoField - public Map getAttributes() { - return attributes; - } - - public void setAttributes(Map attributes) { - this.attributes = attributes; - } - - @MongoField - public List getRequiredActions() { - return requiredActions; - } - - public void setRequiredActions(List requiredActions) { - this.requiredActions = requiredActions; - } - - @MongoField - public List getCredentials() { - return credentials; - } - - public void setCredentials(List credentials) { - this.credentials = credentials; - } - - @MongoField - public List getSocialLinks() { - return socialLinks; - } - - public void setSocialLinks(List socialLinks) { - this.socialLinks = socialLinks; - } -} +package org.keycloak.models.mongo.keycloak.entities; + +import org.keycloak.models.UserModel; +import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; +import org.keycloak.models.mongo.api.MongoCollection; +import org.keycloak.models.mongo.api.MongoEntity; +import org.keycloak.models.mongo.api.MongoField; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author Marek Posolda + */ +@MongoCollection(collectionName = "users") +public class UserEntity extends AbstractMongoIdentifiableEntity implements MongoEntity { + + private String loginName; + private String firstName; + private String lastName; + private String email; + private boolean emailVerified; + private boolean totp; + private boolean enabled; + + private String realmId; + + private List roleIds; + + private Map attributes; + private List requiredActions; + private List credentials = new ArrayList(); + private List socialLinks; + + @MongoField + public String getLoginName() { + return loginName; + } + + public void setLoginName(String loginName) { + this.loginName = loginName; + } + + @MongoField + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + @MongoField + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + @MongoField + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + @MongoField + public boolean isEmailVerified() { + return emailVerified; + } + + public void setEmailVerified(boolean emailVerified) { + this.emailVerified = emailVerified; + } + + @MongoField + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + @MongoField + public boolean isTotp() { + return totp; + } + + public void setTotp(boolean totp) { + this.totp = totp; + } + + @MongoField + public String getRealmId() { + return realmId; + } + + public void setRealmId(String realmId) { + this.realmId = realmId; + } + + @MongoField + public List getRoleIds() { + return roleIds; + } + + public void setRoleIds(List roleIds) { + this.roleIds = roleIds; + } + + + @MongoField + public Map getAttributes() { + return attributes; + } + + public void setAttributes(Map attributes) { + this.attributes = attributes; + } + + @MongoField + public List getRequiredActions() { + return requiredActions; + } + + public void setRequiredActions(List requiredActions) { + this.requiredActions = requiredActions; + } + + @MongoField + public List getCredentials() { + return credentials; + } + + public void setCredentials(List credentials) { + this.credentials = credentials; + } + + @MongoField + public List getSocialLinks() { + return socialLinks; + } + + public void setSocialLinks(List socialLinks) { + this.socialLinks = socialLinks; + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java b/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java index 050e9367a4..8b1a26e51e 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/utils/MongoModelUtils.java @@ -1,54 +1,54 @@ -package org.keycloak.models.mongo.utils; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import com.mongodb.DBObject; -import com.mongodb.QueryBuilder; -import org.bson.types.ObjectId; -import org.keycloak.models.ClientModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; -import org.keycloak.models.mongo.keycloak.adapters.AbstractAdapter; -import org.keycloak.models.mongo.keycloak.adapters.UserAdapter; -import org.keycloak.models.mongo.keycloak.entities.RoleEntity; -import org.keycloak.models.mongo.keycloak.entities.ScopedEntity; -import org.keycloak.models.mongo.keycloak.entities.UserEntity; - -/** - * @author Marek Posolda - */ -public class MongoModelUtils { - - // Get everything including both application and realm roles - public static List getAllRolesOfUser(UserModel user, MongoStoreInvocationContext invContext) { - UserEntity userEntity = ((UserAdapter)user).getUser(); - List roleIds = userEntity.getRoleIds(); - - if (roleIds == null || roleIds.isEmpty()) { - return Collections.EMPTY_LIST; - } - - DBObject query = new QueryBuilder() - .and("_id").in(roleIds) - .get(); - return invContext.getMongoStore().loadEntities(RoleEntity.class, query, invContext); - } - - // Get everything including both application and realm scopes - public static List getAllScopesOfClient(ClientModel client, MongoStoreInvocationContext invContext) { - ScopedEntity scopedEntity = (ScopedEntity)((AbstractAdapter)client).getMongoEntity(); - List scopeIds = scopedEntity.getScopeIds(); - - if (scopeIds == null || scopeIds.isEmpty()) { - return Collections.EMPTY_LIST; - } - - DBObject query = new QueryBuilder() - .and("_id").in(scopeIds) - .get(); - return invContext.getMongoStore().loadEntities(RoleEntity.class, query, invContext); - } -} +package org.keycloak.models.mongo.utils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import com.mongodb.DBObject; +import com.mongodb.QueryBuilder; +import org.bson.types.ObjectId; +import org.keycloak.models.ClientModel; +import org.keycloak.models.UserModel; +import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; +import org.keycloak.models.mongo.keycloak.adapters.AbstractAdapter; +import org.keycloak.models.mongo.keycloak.adapters.UserAdapter; +import org.keycloak.models.mongo.keycloak.entities.RoleEntity; +import org.keycloak.models.mongo.keycloak.entities.ScopedEntity; +import org.keycloak.models.mongo.keycloak.entities.UserEntity; + +/** + * @author Marek Posolda + */ +public class MongoModelUtils { + + // Get everything including both application and realm roles + public static List getAllRolesOfUser(UserModel user, MongoStoreInvocationContext invContext) { + UserEntity userEntity = ((UserAdapter)user).getUser(); + List roleIds = userEntity.getRoleIds(); + + if (roleIds == null || roleIds.isEmpty()) { + return Collections.EMPTY_LIST; + } + + DBObject query = new QueryBuilder() + .and("_id").in(roleIds) + .get(); + return invContext.getMongoStore().loadEntities(RoleEntity.class, query, invContext); + } + + // Get everything including both application and realm scopes + public static List getAllScopesOfClient(ClientModel client, MongoStoreInvocationContext invContext) { + ScopedEntity scopedEntity = (ScopedEntity)((AbstractAdapter)client).getMongoEntity(); + List scopeIds = scopedEntity.getScopeIds(); + + if (scopeIds == null || scopeIds.isEmpty()) { + return Collections.EMPTY_LIST; + } + + DBObject query = new QueryBuilder() + .and("_id").in(scopeIds) + .get(); + return invContext.getMongoStore().loadEntities(RoleEntity.class, query, invContext); + } +} diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/utils/SystemPropertiesConfigurationProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/utils/SystemPropertiesConfigurationProvider.java index ce24c63795..1b0c075758 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/utils/SystemPropertiesConfigurationProvider.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/utils/SystemPropertiesConfigurationProvider.java @@ -1,55 +1,55 @@ -package org.keycloak.models.mongo.utils; - -/** - * @author Marek Posolda - */ -public class SystemPropertiesConfigurationProvider { - - private static final String MONGO_HOST = "keycloak.mongo.host"; - private static final String MONGO_PORT = "keycloak.mongo.port"; - private static final String MONGO_DB_NAME = "keycloak.mongo.db"; - private static final String MONGO_CLEAR_ON_STARTUP = "keycloak.mongo.clearOnStartup"; - - // Property names from Liveoak . Those are used as fallback in case that original value is not available - private static final String MONGO_HOST_2 = "mongo.host"; - private static final String MONGO_PORT_2 = "mongo.port"; - private static final String MONGO_DB_NAME_2 = "mongo.db"; - private static final String MONGO_CLEAR_ON_STARTUP_2 = "mongo.clearCollectionsOnStartup"; - - // Port where MongoDB instance is normally started on linux. This port should be used if we're not starting embedded instance - private static final String MONGO_DEFAULT_PORT = "27017"; - - public static String getMongoHost() { - return getSystemPropertyWithFallback(MONGO_HOST, MONGO_HOST_2, "localhost"); - } - - public static int getMongoPort() { - String portProp = getSystemPropertyWithFallback(MONGO_PORT, MONGO_PORT_2, MONGO_DEFAULT_PORT); - return Integer.parseInt(portProp); - } - - public static String getMongoDbName() { - return getSystemPropertyWithFallback(MONGO_DB_NAME, MONGO_DB_NAME_2, "keycloak"); - } - - public static boolean isClearCollectionsOnStartup() { - String property = getSystemPropertyWithFallback(MONGO_CLEAR_ON_STARTUP, MONGO_CLEAR_ON_STARTUP_2, "false"); - return "true".equalsIgnoreCase(property); - } - - // Check if property propName1 (like "keycloak.mongo.host" is available and if not, then fallback to property "mongo.host" ) - private static String getSystemPropertyWithFallback(String propName1, String propName2, String defaultValue) { - String propValue1 = System.getProperty(propName1); - return propValue1!=null ? propValue1 : System.getProperty(propName2, defaultValue); - } - - // Create configuration based on system properties - public static MongoConfiguration createConfiguration() { - return new MongoConfiguration( - getMongoHost(), - getMongoPort(), - getMongoDbName(), - isClearCollectionsOnStartup() - ); - } -} +package org.keycloak.models.mongo.utils; + +/** + * @author Marek Posolda + */ +public class SystemPropertiesConfigurationProvider { + + private static final String MONGO_HOST = "keycloak.mongo.host"; + private static final String MONGO_PORT = "keycloak.mongo.port"; + private static final String MONGO_DB_NAME = "keycloak.mongo.db"; + private static final String MONGO_CLEAR_ON_STARTUP = "keycloak.mongo.clearOnStartup"; + + // Property names from Liveoak . Those are used as fallback in case that original value is not available + private static final String MONGO_HOST_2 = "mongo.host"; + private static final String MONGO_PORT_2 = "mongo.port"; + private static final String MONGO_DB_NAME_2 = "mongo.db"; + private static final String MONGO_CLEAR_ON_STARTUP_2 = "mongo.clearCollectionsOnStartup"; + + // Port where MongoDB instance is normally started on linux. This port should be used if we're not starting embedded instance + private static final String MONGO_DEFAULT_PORT = "27017"; + + public static String getMongoHost() { + return getSystemPropertyWithFallback(MONGO_HOST, MONGO_HOST_2, "localhost"); + } + + public static int getMongoPort() { + String portProp = getSystemPropertyWithFallback(MONGO_PORT, MONGO_PORT_2, MONGO_DEFAULT_PORT); + return Integer.parseInt(portProp); + } + + public static String getMongoDbName() { + return getSystemPropertyWithFallback(MONGO_DB_NAME, MONGO_DB_NAME_2, "keycloak"); + } + + public static boolean isClearCollectionsOnStartup() { + String property = getSystemPropertyWithFallback(MONGO_CLEAR_ON_STARTUP, MONGO_CLEAR_ON_STARTUP_2, "false"); + return "true".equalsIgnoreCase(property); + } + + // Check if property propName1 (like "keycloak.mongo.host" is available and if not, then fallback to property "mongo.host" ) + private static String getSystemPropertyWithFallback(String propName1, String propName2, String defaultValue) { + String propValue1 = System.getProperty(propName1); + return propValue1!=null ? propValue1 : System.getProperty(propName2, defaultValue); + } + + // Create configuration based on system properties + public static MongoConfiguration createConfiguration() { + return new MongoConfiguration( + getMongoHost(), + getMongoPort(), + getMongoDbName(), + isClearCollectionsOnStartup() + ); + } +} diff --git a/model/mongo/src/test/java/org/keycloak/models/mongo/test/Address.java b/model/mongo/src/test/java/org/keycloak/models/mongo/test/Address.java index 81bd7d8dce..30aaa27b00 100755 --- a/model/mongo/src/test/java/org/keycloak/models/mongo/test/Address.java +++ b/model/mongo/src/test/java/org/keycloak/models/mongo/test/Address.java @@ -1,43 +1,43 @@ -package org.keycloak.models.mongo.test; - -import org.keycloak.models.mongo.api.MongoEntity; -import org.keycloak.models.mongo.api.MongoField; - -import java.util.List; - -/** - * @author Marek Posolda - */ -public class Address implements MongoEntity { - - private String street; - private int number; - private List flatNumbers; - - @MongoField - public String getStreet() { - return street; - } - - public void setStreet(String street) { - this.street = street; - } - - @MongoField - public int getNumber() { - return number; - } - - public void setNumber(int number) { - this.number = number; - } - - @MongoField - public List getFlatNumbers() { - return flatNumbers; - } - - public void setFlatNumbers(List flatNumbers) { - this.flatNumbers = flatNumbers; - } -} +package org.keycloak.models.mongo.test; + +import org.keycloak.models.mongo.api.MongoEntity; +import org.keycloak.models.mongo.api.MongoField; + +import java.util.List; + +/** + * @author Marek Posolda + */ +public class Address implements MongoEntity { + + private String street; + private int number; + private List flatNumbers; + + @MongoField + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + @MongoField + public int getNumber() { + return number; + } + + public void setNumber(int number) { + this.number = number; + } + + @MongoField + public List getFlatNumbers() { + return flatNumbers; + } + + public void setFlatNumbers(List flatNumbers) { + this.flatNumbers = flatNumbers; + } +} diff --git a/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoStoreTest.java b/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoStoreTest.java index fba9489afe..219293b5e7 100755 --- a/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoStoreTest.java +++ b/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoStoreTest.java @@ -1,146 +1,146 @@ -package org.keycloak.models.mongo.test; - -import com.mongodb.DB; -import com.mongodb.DBObject; -import com.mongodb.MongoClient; -import com.mongodb.QueryBuilder; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.keycloak.models.mongo.api.MongoEntity; -import org.keycloak.models.mongo.api.MongoStore; -import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; -import org.keycloak.models.mongo.impl.MongoStoreImpl; -import org.keycloak.models.mongo.impl.context.TransactionMongoStoreInvocationContext; -import org.keycloak.models.mongo.utils.SystemPropertiesConfigurationProvider; - -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * @author Marek Posolda - */ -public class MongoStoreTest { - - private static final Class[] MANAGED_DATA_TYPES = (Class[])new Class[] { - Person.class, - Address.class, - }; - - private MongoClient mongoClient; - private MongoStore mongoStore; - - @Before - public void before() throws Exception { - try { - // TODO: authentication support - mongoClient = new MongoClient("localhost", SystemPropertiesConfigurationProvider.getMongoPort()); - - DB db = mongoClient.getDB("keycloakTest"); - mongoStore = new MongoStoreImpl(db, true, MANAGED_DATA_TYPES); - - } catch (UnknownHostException e) { - throw new RuntimeException(e); - } - } - - @After - public void after() throws Exception { - mongoClient.close(); - } - - @Test - public void mongoModelTest() throws Exception { - MongoStoreInvocationContext context = new TransactionMongoStoreInvocationContext(mongoStore); - - // Add some user - Person john = new Person(); - john.setFirstName("john"); - john.setAge(25); - john.setGender(Person.Gender.MALE); - - mongoStore.insertEntity(john, context); - - // Add another user - Person mary = new Person(); - mary.setFirstName("mary"); - mary.setKids(asList("Peter", "Paul", "Wendy")); - - Address addr1 = new Address(); - addr1.setStreet("Elm"); - addr1.setNumber(5); - addr1.setFlatNumbers(asList("flat1", "flat2")); - Address addr2 = new Address(); - List
addresses = new ArrayList
(); - addresses.add(addr1); - addresses.add(addr2); - - mary.setAddresses(addresses); - mary.setMainAddress(addr1); - mary.setGender(Person.Gender.FEMALE); - mary.setGenders(asList(Person.Gender.FEMALE)); - - mongoStore.insertEntity(mary, context); - - Assert.assertEquals(2, mongoStore.loadEntities(Person.class, new QueryBuilder().get(), context).size()); - - DBObject query = new QueryBuilder().and("addresses.flatNumbers").is("flat1").get(); - List persons = mongoStore.loadEntities(Person.class, query, context); - Assert.assertEquals(1, persons.size()); - mary = persons.get(0); - Assert.assertEquals(mary.getFirstName(), "mary"); - Assert.assertTrue(mary.getKids().contains("Paul")); - Assert.assertEquals(2, mary.getAddresses().size()); - Assert.assertEquals(Address.class, mary.getAddresses().get(0).getClass()); - - // Test push/pull - mongoStore.pushItemToList(mary, "kids", "Pauline", true, context); - mongoStore.pullItemFromList(mary, "kids", "Paul", context); - - Address addr3 = new Address(); - addr3.setNumber(6); - addr3.setStreet("Broadway"); - mongoStore.pushItemToList(mary, "addresses", addr3, true, context); - - mary = mongoStore.loadEntity(Person.class, mary.getId(), context); - Assert.assertEquals(3, mary.getKids().size()); - Assert.assertTrue(mary.getKids().contains("Pauline")); - Assert.assertFalse(mary.getKids().contains("Paul")); - Assert.assertEquals(3, mary.getAddresses().size()); - Address mainAddress = mary.getMainAddress(); - Assert.assertEquals("Elm", mainAddress.getStreet()); - Assert.assertEquals(5, mainAddress.getNumber()); - Assert.assertEquals(Person.Gender.FEMALE, mary.getGender()); - Assert.assertTrue(mary.getGenders().contains(Person.Gender.FEMALE)); - - - // Some test of Map (attributes) - mary.addAttribute("attr1", "value1"); - mary.addAttribute("attr2", "value2"); - mary.addAttribute("attr.some3", "value3"); - mongoStore.updateEntity(mary, context); - - mary = mongoStore.loadEntity(Person.class, mary.getId(), context); - Assert.assertEquals(3, mary.getAttributes().size()); - - mary.removeAttribute("attr2"); - mary.removeAttribute("nonExisting"); - mongoStore.updateEntity(mary, context); - - mary = mongoStore.loadEntity(Person.class, mary.getId(), context); - Assert.assertEquals(2, mary.getAttributes().size()); - Assert.assertEquals("value1", mary.getAttributes().get("attr1")); - Assert.assertEquals("value3", mary.getAttributes().get("attr.some3")); - - context.commit(); - } - - private List asList(T... objects) { - List list = new ArrayList(); - list.addAll(Arrays.asList(objects)); - return list; - } -} +package org.keycloak.models.mongo.test; + +import com.mongodb.DB; +import com.mongodb.DBObject; +import com.mongodb.MongoClient; +import com.mongodb.QueryBuilder; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.keycloak.models.mongo.api.MongoEntity; +import org.keycloak.models.mongo.api.MongoStore; +import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext; +import org.keycloak.models.mongo.impl.MongoStoreImpl; +import org.keycloak.models.mongo.impl.context.TransactionMongoStoreInvocationContext; +import org.keycloak.models.mongo.utils.SystemPropertiesConfigurationProvider; + +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author Marek Posolda + */ +public class MongoStoreTest { + + private static final Class[] MANAGED_DATA_TYPES = (Class[])new Class[] { + Person.class, + Address.class, + }; + + private MongoClient mongoClient; + private MongoStore mongoStore; + + @Before + public void before() throws Exception { + try { + // TODO: authentication support + mongoClient = new MongoClient("localhost", SystemPropertiesConfigurationProvider.getMongoPort()); + + DB db = mongoClient.getDB("keycloakTest"); + mongoStore = new MongoStoreImpl(db, true, MANAGED_DATA_TYPES); + + } catch (UnknownHostException e) { + throw new RuntimeException(e); + } + } + + @After + public void after() throws Exception { + mongoClient.close(); + } + + @Test + public void mongoModelTest() throws Exception { + MongoStoreInvocationContext context = new TransactionMongoStoreInvocationContext(mongoStore); + + // Add some user + Person john = new Person(); + john.setFirstName("john"); + john.setAge(25); + john.setGender(Person.Gender.MALE); + + mongoStore.insertEntity(john, context); + + // Add another user + Person mary = new Person(); + mary.setFirstName("mary"); + mary.setKids(asList("Peter", "Paul", "Wendy")); + + Address addr1 = new Address(); + addr1.setStreet("Elm"); + addr1.setNumber(5); + addr1.setFlatNumbers(asList("flat1", "flat2")); + Address addr2 = new Address(); + List
addresses = new ArrayList
(); + addresses.add(addr1); + addresses.add(addr2); + + mary.setAddresses(addresses); + mary.setMainAddress(addr1); + mary.setGender(Person.Gender.FEMALE); + mary.setGenders(asList(Person.Gender.FEMALE)); + + mongoStore.insertEntity(mary, context); + + Assert.assertEquals(2, mongoStore.loadEntities(Person.class, new QueryBuilder().get(), context).size()); + + DBObject query = new QueryBuilder().and("addresses.flatNumbers").is("flat1").get(); + List persons = mongoStore.loadEntities(Person.class, query, context); + Assert.assertEquals(1, persons.size()); + mary = persons.get(0); + Assert.assertEquals(mary.getFirstName(), "mary"); + Assert.assertTrue(mary.getKids().contains("Paul")); + Assert.assertEquals(2, mary.getAddresses().size()); + Assert.assertEquals(Address.class, mary.getAddresses().get(0).getClass()); + + // Test push/pull + mongoStore.pushItemToList(mary, "kids", "Pauline", true, context); + mongoStore.pullItemFromList(mary, "kids", "Paul", context); + + Address addr3 = new Address(); + addr3.setNumber(6); + addr3.setStreet("Broadway"); + mongoStore.pushItemToList(mary, "addresses", addr3, true, context); + + mary = mongoStore.loadEntity(Person.class, mary.getId(), context); + Assert.assertEquals(3, mary.getKids().size()); + Assert.assertTrue(mary.getKids().contains("Pauline")); + Assert.assertFalse(mary.getKids().contains("Paul")); + Assert.assertEquals(3, mary.getAddresses().size()); + Address mainAddress = mary.getMainAddress(); + Assert.assertEquals("Elm", mainAddress.getStreet()); + Assert.assertEquals(5, mainAddress.getNumber()); + Assert.assertEquals(Person.Gender.FEMALE, mary.getGender()); + Assert.assertTrue(mary.getGenders().contains(Person.Gender.FEMALE)); + + + // Some test of Map (attributes) + mary.addAttribute("attr1", "value1"); + mary.addAttribute("attr2", "value2"); + mary.addAttribute("attr.some3", "value3"); + mongoStore.updateEntity(mary, context); + + mary = mongoStore.loadEntity(Person.class, mary.getId(), context); + Assert.assertEquals(3, mary.getAttributes().size()); + + mary.removeAttribute("attr2"); + mary.removeAttribute("nonExisting"); + mongoStore.updateEntity(mary, context); + + mary = mongoStore.loadEntity(Person.class, mary.getId(), context); + Assert.assertEquals(2, mary.getAttributes().size()); + Assert.assertEquals("value1", mary.getAttributes().get("attr1")); + Assert.assertEquals("value3", mary.getAttributes().get("attr.some3")); + + context.commit(); + } + + private List asList(T... objects) { + List list = new ArrayList(); + list.addAll(Arrays.asList(objects)); + return list; + } +} diff --git a/model/mongo/src/test/java/org/keycloak/models/mongo/test/Person.java b/model/mongo/src/test/java/org/keycloak/models/mongo/test/Person.java index 47ac69bdd9..88811269a4 100755 --- a/model/mongo/src/test/java/org/keycloak/models/mongo/test/Person.java +++ b/model/mongo/src/test/java/org/keycloak/models/mongo/test/Person.java @@ -1,109 +1,109 @@ -package org.keycloak.models.mongo.test; - -import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; -import org.keycloak.models.mongo.api.MongoCollection; -import org.keycloak.models.mongo.api.MongoField; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author Marek Posolda - */ -@MongoCollection(collectionName = "persons") -public class Person extends AbstractMongoIdentifiableEntity { - - private String firstName; - private int age; - private List kids; - private List
addresses; - private Address mainAddress; - private Gender gender; - private List genders; - private Map attributes = new HashMap(); - - @MongoField - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - @MongoField - public int getAge() { - return age; - } - - public void setAge(int age) { - this.age = age; - } - - @MongoField - public Gender getGender() { - return gender; - } - - public void setGender(Gender gender) { - this.gender = gender; - } - - @MongoField - public List getGenders() { - return genders; - } - - public void setGenders(List genders) { - this.genders = genders; - } - - @MongoField - public List getKids() { - return kids; - } - - public void setKids(List kids) { - this.kids = kids; - } - - @MongoField - public List
getAddresses() { - return addresses; - } - - public void setAddresses(List
addresses) { - this.addresses = addresses; - } - - @MongoField - public Address getMainAddress() { - return mainAddress; - } - - public void setMainAddress(Address mainAddress) { - this.mainAddress = mainAddress; - } - - @MongoField - public Map getAttributes() { - return attributes; - } - - public void setAttributes(Map attributes) { - this.attributes = attributes; - } - - public void addAttribute(String key, String value) { - attributes.put(key, value); - } - - public void removeAttribute(String key) { - attributes.remove(key); - } - - public static enum Gender { - MALE, FEMALE - } -} +package org.keycloak.models.mongo.test; + +import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity; +import org.keycloak.models.mongo.api.MongoCollection; +import org.keycloak.models.mongo.api.MongoField; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Marek Posolda + */ +@MongoCollection(collectionName = "persons") +public class Person extends AbstractMongoIdentifiableEntity { + + private String firstName; + private int age; + private List kids; + private List
addresses; + private Address mainAddress; + private Gender gender; + private List genders; + private Map attributes = new HashMap(); + + @MongoField + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + @MongoField + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + @MongoField + public Gender getGender() { + return gender; + } + + public void setGender(Gender gender) { + this.gender = gender; + } + + @MongoField + public List getGenders() { + return genders; + } + + public void setGenders(List genders) { + this.genders = genders; + } + + @MongoField + public List getKids() { + return kids; + } + + public void setKids(List kids) { + this.kids = kids; + } + + @MongoField + public List
getAddresses() { + return addresses; + } + + public void setAddresses(List
addresses) { + this.addresses = addresses; + } + + @MongoField + public Address getMainAddress() { + return mainAddress; + } + + public void setMainAddress(Address mainAddress) { + this.mainAddress = mainAddress; + } + + @MongoField + public Map getAttributes() { + return attributes; + } + + public void setAttributes(Map attributes) { + this.attributes = attributes; + } + + public void addAttribute(String key, String value) { + attributes.put(key, value); + } + + public void removeAttribute(String key) { + attributes.remove(key); + } + + public static enum Gender { + MALE, FEMALE + } +} diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java index 2dc9d63872..9fa72d0894 100755 --- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java +++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/ApplicationAdapter.java @@ -1,308 +1,308 @@ -package org.keycloak.models.picketlink; - -import org.keycloak.models.ApplicationModel; -import org.keycloak.models.RoleModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.picketlink.mappings.ApplicationData; -import org.keycloak.models.picketlink.relationships.ScopeRelationship; -import org.picketlink.idm.IdentityManagementException; -import org.picketlink.idm.IdentityManager; -import org.picketlink.idm.PartitionManager; -import org.picketlink.idm.RelationshipManager; -import org.picketlink.idm.model.IdentityType; -import org.picketlink.idm.model.sample.Grant; -import org.picketlink.idm.model.sample.Role; -import org.picketlink.idm.model.sample.SampleModel; -import org.picketlink.idm.query.IdentityQuery; -import org.picketlink.idm.query.RelationshipQuery; - -import java.util.*; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class ApplicationAdapter implements ApplicationModel { - protected ApplicationData applicationData; - protected RealmAdapter realm; - protected IdentityManager idm; - protected PartitionManager partitionManager; - protected RelationshipManager relationshipManager; - - public ApplicationAdapter(ApplicationData applicationData, RealmAdapter realm, PartitionManager partitionManager) { - this.applicationData = applicationData; - this.realm = realm; - this.partitionManager = partitionManager; - } - - protected IdentityManager getIdm() { - if (idm == null) idm = partitionManager.createIdentityManager(applicationData); - return idm; - } - - protected RelationshipManager getRelationshipManager() { - if (relationshipManager == null) relationshipManager = partitionManager.createRelationshipManager(); - return relationshipManager; - } - - @Override - public void updateApplication() { - partitionManager.update(applicationData); - } - - @Override - public UserAdapter getApplicationUser() { - return new UserAdapter(applicationData.getResourceUser(), realm.getIdm()); - } - - @Override - public String getId() { - // for some reason picketlink queries by name when finding partition, don't know what ID is used for now - return applicationData.getName(); - } - - @Override - public String getName() { - return applicationData.getResourceName(); - } - - @Override - public void setName(String name) { - applicationData.setResourceName(name); - updateApplication(); - } - - @Override - public boolean isEnabled() { - return applicationData.isEnabled(); - } - - @Override - public void setEnabled(boolean enabled) { - applicationData.setEnabled(enabled); - updateApplication(); - } - - @Override - public boolean isSurrogateAuthRequired() { - return applicationData.isSurrogateAuthRequired(); - } - - @Override - public void setSurrogateAuthRequired(boolean surrogateAuthRequired) { - applicationData.setSurrogateAuthRequired(surrogateAuthRequired); - updateApplication(); - } - - @Override - public String getManagementUrl() { - return applicationData.getManagementUrl(); - } - - @Override - public void setManagementUrl(String url) { - applicationData.setManagementUrl(url); - updateApplication(); - } - - @Override - public String getBaseUrl() { - return applicationData.getBaseUrl(); - } - - @Override - public void setBaseUrl(String url) { - applicationData.setBaseUrl(url); - updateApplication(); - } - - @Override - public RoleAdapter getRole(String name) { - Role role = SampleModel.getRole(getIdm(), name); - if (role == null) return null; - return new RoleAdapter(role, getIdm()); - } - - @Override - public RoleModel getRoleById(String id) { - IdentityQuery query = getIdm().createIdentityQuery(Role.class); - query.setParameter(IdentityType.ID, id); - List roles = query.getResultList(); - if (roles.size() == 0) return null; - return new RoleAdapter(roles.get(0), getIdm()); - } - - @Override - public void grantRole(UserModel user, RoleModel role) { - SampleModel.grantRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole()); - } - - @Override - public boolean hasRole(UserModel user, RoleModel role) { - return SampleModel.hasRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole()); - } - - @Override - public boolean hasRole(UserModel user, String role) { - RoleModel roleModel = getRole(role); - return hasRole(user, roleModel); - } - - @Override - public RoleAdapter addRole(String name) { - Role role = new Role(name); - getIdm().add(role); - return new RoleAdapter(role, getIdm()); - } - - @Override - public boolean removeRoleById(String id) { - try { - getIdm().remove(getIdm().lookupIdentityById(Role.class, id)); - return true; - } catch (IdentityManagementException e) { - return false; - } - } - - @Override - public List getRoles() { - IdentityQuery query = getIdm().createIdentityQuery(Role.class); - query.setParameter(Role.PARTITION, applicationData); - List roles = query.getResultList(); - List roleModels = new ArrayList(); - for (Role role : roles) { - roleModels.add(new RoleAdapter(role, idm)); - } - return roleModels; - } - - @Override - public Set getRoleMappingValues(UserModel user) { - RelationshipQuery query = getRelationshipManager().createRelationshipQuery(Grant.class); - query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser()); - List grants = query.getResultList(); - HashSet set = new HashSet(); - for (Grant grant : grants) { - if (grant.getRole().getPartition().getId().equals(applicationData.getId())) set.add(grant.getRole().getName()); - } - return set; - } - - @Override - public List getRoleMappings(UserModel user) { - RelationshipQuery query = getRelationshipManager().createRelationshipQuery(Grant.class); - query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser()); - List grants = query.getResultList(); - List set = new ArrayList(); - for (Grant grant : grants) { - if (grant.getRole().getPartition().getId().equals(applicationData.getId())) set.add(new RoleAdapter(grant.getRole(), getIdm())); - } - return set; - } - - @Override - public void deleteRoleMapping(UserModel user, RoleModel role) { - RelationshipQuery query = getRelationshipManager().createRelationshipQuery(Grant.class); - query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser()); - query.setParameter(Grant.ROLE, ((RoleAdapter)role).getRole()); - List grants = query.getResultList(); - for (Grant grant : grants) { - getRelationshipManager().remove(grant); - } - } - - @Override - public void addScopeMapping(UserModel agent, String roleName) { - IdentityManager idm = getIdm(); - Role role = SampleModel.getRole(idm,roleName); - if (role == null) throw new RuntimeException("role not found"); - addScopeMapping(agent, new RoleAdapter(role, idm)); - - } - - @Override - public void addScopeMapping(UserModel agent, RoleModel role) { - ScopeRelationship scope = new ScopeRelationship(); - scope.setClient(((UserAdapter)agent).getUser()); - scope.setScope(((RoleAdapter)role).getRole()); - getRelationshipManager().add(scope); - } - - @Override - public void deleteScopeMapping(UserModel user, RoleModel role) { - RelationshipQuery query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class); - query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)user).getUser()); - query.setParameter(ScopeRelationship.SCOPE, ((RoleAdapter)role).getRole()); - List grants = query.getResultList(); - for (ScopeRelationship grant : grants) { - getRelationshipManager().remove(grant); - } - } - - - @Override - public Set getScopeMappingValues(UserModel agent) { - RelationshipQuery query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class); - query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser()); - List scope = query.getResultList(); - HashSet set = new HashSet(); - for (ScopeRelationship rel : scope) { - if (rel.getScope().getPartition().getId().equals(applicationData.getId())) set.add(rel.getScope().getName()); - } - return set; - } - - @Override - public List getScopeMappings(UserModel agent) { - RelationshipQuery query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class); - query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser()); - List scope = query.getResultList(); - List roles = new ArrayList(); - for (ScopeRelationship rel : scope) { - if (rel.getScope().getPartition().getId().equals(applicationData.getId())) roles.add(new RoleAdapter(rel.getScope(), getIdm())); - } - return roles; - } - - @Override - public List getDefaultRoles() { - if ( applicationData.getDefaultRoles() != null) { - return Arrays.asList(applicationData.getDefaultRoles()); - } - else { - return Collections.emptyList(); - } - } - - @Override - public void addDefaultRole(String name) { - if (getRole(name) == null) { - addRole(name); - } - - String[] defaultRoles = applicationData.getDefaultRoles(); - if (defaultRoles == null) { - defaultRoles = new String[1]; - } else { - defaultRoles = Arrays.copyOf(defaultRoles, defaultRoles.length + 1); - } - defaultRoles[defaultRoles.length - 1] = name; - - applicationData.setDefaultRoles(defaultRoles); - updateApplication(); - } - - @Override - public void updateDefaultRoles(String[] defaultRoles) { - for (String name : defaultRoles) { - if (getRole(name) == null) { - addRole(name); - } - } - - applicationData.setDefaultRoles(defaultRoles); - updateApplication(); - } - -} +package org.keycloak.models.picketlink; + +import org.keycloak.models.ApplicationModel; +import org.keycloak.models.RoleModel; +import org.keycloak.models.UserModel; +import org.keycloak.models.picketlink.mappings.ApplicationData; +import org.keycloak.models.picketlink.relationships.ScopeRelationship; +import org.picketlink.idm.IdentityManagementException; +import org.picketlink.idm.IdentityManager; +import org.picketlink.idm.PartitionManager; +import org.picketlink.idm.RelationshipManager; +import org.picketlink.idm.model.IdentityType; +import org.picketlink.idm.model.sample.Grant; +import org.picketlink.idm.model.sample.Role; +import org.picketlink.idm.model.sample.SampleModel; +import org.picketlink.idm.query.IdentityQuery; +import org.picketlink.idm.query.RelationshipQuery; + +import java.util.*; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class ApplicationAdapter implements ApplicationModel { + protected ApplicationData applicationData; + protected RealmAdapter realm; + protected IdentityManager idm; + protected PartitionManager partitionManager; + protected RelationshipManager relationshipManager; + + public ApplicationAdapter(ApplicationData applicationData, RealmAdapter realm, PartitionManager partitionManager) { + this.applicationData = applicationData; + this.realm = realm; + this.partitionManager = partitionManager; + } + + protected IdentityManager getIdm() { + if (idm == null) idm = partitionManager.createIdentityManager(applicationData); + return idm; + } + + protected RelationshipManager getRelationshipManager() { + if (relationshipManager == null) relationshipManager = partitionManager.createRelationshipManager(); + return relationshipManager; + } + + @Override + public void updateApplication() { + partitionManager.update(applicationData); + } + + @Override + public UserAdapter getApplicationUser() { + return new UserAdapter(applicationData.getResourceUser(), realm.getIdm()); + } + + @Override + public String getId() { + // for some reason picketlink queries by name when finding partition, don't know what ID is used for now + return applicationData.getName(); + } + + @Override + public String getName() { + return applicationData.getResourceName(); + } + + @Override + public void setName(String name) { + applicationData.setResourceName(name); + updateApplication(); + } + + @Override + public boolean isEnabled() { + return applicationData.isEnabled(); + } + + @Override + public void setEnabled(boolean enabled) { + applicationData.setEnabled(enabled); + updateApplication(); + } + + @Override + public boolean isSurrogateAuthRequired() { + return applicationData.isSurrogateAuthRequired(); + } + + @Override + public void setSurrogateAuthRequired(boolean surrogateAuthRequired) { + applicationData.setSurrogateAuthRequired(surrogateAuthRequired); + updateApplication(); + } + + @Override + public String getManagementUrl() { + return applicationData.getManagementUrl(); + } + + @Override + public void setManagementUrl(String url) { + applicationData.setManagementUrl(url); + updateApplication(); + } + + @Override + public String getBaseUrl() { + return applicationData.getBaseUrl(); + } + + @Override + public void setBaseUrl(String url) { + applicationData.setBaseUrl(url); + updateApplication(); + } + + @Override + public RoleAdapter getRole(String name) { + Role role = SampleModel.getRole(getIdm(), name); + if (role == null) return null; + return new RoleAdapter(role, getIdm()); + } + + @Override + public RoleModel getRoleById(String id) { + IdentityQuery query = getIdm().createIdentityQuery(Role.class); + query.setParameter(IdentityType.ID, id); + List roles = query.getResultList(); + if (roles.size() == 0) return null; + return new RoleAdapter(roles.get(0), getIdm()); + } + + @Override + public void grantRole(UserModel user, RoleModel role) { + SampleModel.grantRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole()); + } + + @Override + public boolean hasRole(UserModel user, RoleModel role) { + return SampleModel.hasRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole()); + } + + @Override + public boolean hasRole(UserModel user, String role) { + RoleModel roleModel = getRole(role); + return hasRole(user, roleModel); + } + + @Override + public RoleAdapter addRole(String name) { + Role role = new Role(name); + getIdm().add(role); + return new RoleAdapter(role, getIdm()); + } + + @Override + public boolean removeRoleById(String id) { + try { + getIdm().remove(getIdm().lookupIdentityById(Role.class, id)); + return true; + } catch (IdentityManagementException e) { + return false; + } + } + + @Override + public List getRoles() { + IdentityQuery query = getIdm().createIdentityQuery(Role.class); + query.setParameter(Role.PARTITION, applicationData); + List roles = query.getResultList(); + List roleModels = new ArrayList(); + for (Role role : roles) { + roleModels.add(new RoleAdapter(role, idm)); + } + return roleModels; + } + + @Override + public Set getRoleMappingValues(UserModel user) { + RelationshipQuery query = getRelationshipManager().createRelationshipQuery(Grant.class); + query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser()); + List grants = query.getResultList(); + HashSet set = new HashSet(); + for (Grant grant : grants) { + if (grant.getRole().getPartition().getId().equals(applicationData.getId())) set.add(grant.getRole().getName()); + } + return set; + } + + @Override + public List getRoleMappings(UserModel user) { + RelationshipQuery query = getRelationshipManager().createRelationshipQuery(Grant.class); + query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser()); + List grants = query.getResultList(); + List set = new ArrayList(); + for (Grant grant : grants) { + if (grant.getRole().getPartition().getId().equals(applicationData.getId())) set.add(new RoleAdapter(grant.getRole(), getIdm())); + } + return set; + } + + @Override + public void deleteRoleMapping(UserModel user, RoleModel role) { + RelationshipQuery query = getRelationshipManager().createRelationshipQuery(Grant.class); + query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser()); + query.setParameter(Grant.ROLE, ((RoleAdapter)role).getRole()); + List grants = query.getResultList(); + for (Grant grant : grants) { + getRelationshipManager().remove(grant); + } + } + + @Override + public void addScopeMapping(UserModel agent, String roleName) { + IdentityManager idm = getIdm(); + Role role = SampleModel.getRole(idm,roleName); + if (role == null) throw new RuntimeException("role not found"); + addScopeMapping(agent, new RoleAdapter(role, idm)); + + } + + @Override + public void addScopeMapping(UserModel agent, RoleModel role) { + ScopeRelationship scope = new ScopeRelationship(); + scope.setClient(((UserAdapter)agent).getUser()); + scope.setScope(((RoleAdapter)role).getRole()); + getRelationshipManager().add(scope); + } + + @Override + public void deleteScopeMapping(UserModel user, RoleModel role) { + RelationshipQuery query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class); + query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)user).getUser()); + query.setParameter(ScopeRelationship.SCOPE, ((RoleAdapter)role).getRole()); + List grants = query.getResultList(); + for (ScopeRelationship grant : grants) { + getRelationshipManager().remove(grant); + } + } + + + @Override + public Set getScopeMappingValues(UserModel agent) { + RelationshipQuery query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class); + query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser()); + List scope = query.getResultList(); + HashSet set = new HashSet(); + for (ScopeRelationship rel : scope) { + if (rel.getScope().getPartition().getId().equals(applicationData.getId())) set.add(rel.getScope().getName()); + } + return set; + } + + @Override + public List getScopeMappings(UserModel agent) { + RelationshipQuery query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class); + query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser()); + List scope = query.getResultList(); + List roles = new ArrayList(); + for (ScopeRelationship rel : scope) { + if (rel.getScope().getPartition().getId().equals(applicationData.getId())) roles.add(new RoleAdapter(rel.getScope(), getIdm())); + } + return roles; + } + + @Override + public List getDefaultRoles() { + if ( applicationData.getDefaultRoles() != null) { + return Arrays.asList(applicationData.getDefaultRoles()); + } + else { + return Collections.emptyList(); + } + } + + @Override + public void addDefaultRole(String name) { + if (getRole(name) == null) { + addRole(name); + } + + String[] defaultRoles = applicationData.getDefaultRoles(); + if (defaultRoles == null) { + defaultRoles = new String[1]; + } else { + defaultRoles = Arrays.copyOf(defaultRoles, defaultRoles.length + 1); + } + defaultRoles[defaultRoles.length - 1] = name; + + applicationData.setDefaultRoles(defaultRoles); + updateApplication(); + } + + @Override + public void updateDefaultRoles(String[] defaultRoles) { + for (String name : defaultRoles) { + if (getRole(name) == null) { + addRole(name); + } + } + + applicationData.setDefaultRoles(defaultRoles); + updateApplication(); + } + +} diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/SocialLinkRelationship.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/SocialLinkRelationship.java index da8f04f01c..62ec7e343e 100755 --- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/SocialLinkRelationship.java +++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/SocialLinkRelationship.java @@ -1,73 +1,73 @@ -package org.keycloak.models.picketlink.relationships; - -import org.picketlink.idm.model.AbstractAttributedType; -import org.picketlink.idm.model.Attribute; -import org.picketlink.idm.model.Relationship; -import org.picketlink.idm.model.annotation.AttributeProperty; -import org.picketlink.idm.model.sample.User; -import org.picketlink.idm.query.AttributeParameter; -import org.picketlink.idm.query.RelationshipQueryParameter; - -/** - * Binding between user and his social username for particular Social provider - * - * Example: Keycloak user "john" has username "john123" in social provider "facebook" - * - * @author Marek Posolda - */ -public class SocialLinkRelationship extends AbstractAttributedType implements Relationship { - - private static final long serialVersionUID = 154879L; - - public static final AttributeParameter SOCIAL_PROVIDER = new AttributeParameter("socialProvider"); - public static final AttributeParameter SOCIAL_USERNAME = new AttributeParameter("socialUsername"); - - // realm is needed to allow searching as combination socialUsername+socialProvider may not be unique - // (Same user could have mapped same facebook account to username "foo" in "realm1" and to username "bar" in "realm2") - public static final AttributeParameter REALM = new AttributeParameter("realm"); - - public static final RelationshipQueryParameter USER = new RelationshipQueryParameter() { - - @Override - public String getName() { - return "user"; - } - }; - - private User user; - - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - - @AttributeProperty - public String getSocialProvider() { - return (String)getAttribute("socialProvider").getValue(); - } - - public void setSocialProvider(String socialProvider) { - setAttribute(new Attribute("socialProvider", socialProvider)); - } - - @AttributeProperty - public String getSocialUsername() { - return (String)getAttribute("socialUsername").getValue(); - } - - public void setSocialUsername(String socialProviderUserId) { - setAttribute(new Attribute("socialUsername", socialProviderUserId)); - } - - @AttributeProperty - public String getRealm() { - return (String)getAttribute("realm").getValue(); - } - - public void setRealm(String realm) { - setAttribute(new Attribute("realm", realm)); - } -} +package org.keycloak.models.picketlink.relationships; + +import org.picketlink.idm.model.AbstractAttributedType; +import org.picketlink.idm.model.Attribute; +import org.picketlink.idm.model.Relationship; +import org.picketlink.idm.model.annotation.AttributeProperty; +import org.picketlink.idm.model.sample.User; +import org.picketlink.idm.query.AttributeParameter; +import org.picketlink.idm.query.RelationshipQueryParameter; + +/** + * Binding between user and his social username for particular Social provider + * + * Example: Keycloak user "john" has username "john123" in social provider "facebook" + * + * @author Marek Posolda + */ +public class SocialLinkRelationship extends AbstractAttributedType implements Relationship { + + private static final long serialVersionUID = 154879L; + + public static final AttributeParameter SOCIAL_PROVIDER = new AttributeParameter("socialProvider"); + public static final AttributeParameter SOCIAL_USERNAME = new AttributeParameter("socialUsername"); + + // realm is needed to allow searching as combination socialUsername+socialProvider may not be unique + // (Same user could have mapped same facebook account to username "foo" in "realm1" and to username "bar" in "realm2") + public static final AttributeParameter REALM = new AttributeParameter("realm"); + + public static final RelationshipQueryParameter USER = new RelationshipQueryParameter() { + + @Override + public String getName() { + return "user"; + } + }; + + private User user; + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + @AttributeProperty + public String getSocialProvider() { + return (String)getAttribute("socialProvider").getValue(); + } + + public void setSocialProvider(String socialProvider) { + setAttribute(new Attribute("socialProvider", socialProvider)); + } + + @AttributeProperty + public String getSocialUsername() { + return (String)getAttribute("socialUsername").getValue(); + } + + public void setSocialUsername(String socialProviderUserId) { + setAttribute(new Attribute("socialUsername", socialProviderUserId)); + } + + @AttributeProperty + public String getRealm() { + return (String)getAttribute("realm").getValue(); + } + + public void setRealm(String realm) { + setAttribute(new Attribute("realm", realm)); + } +} diff --git a/model/tests/pom.xml b/model/tests/pom.xml index 8357eaa378..c56a0751f6 100755 --- a/model/tests/pom.xml +++ b/model/tests/pom.xml @@ -1,69 +1,69 @@ - - - - keycloak-parent - org.keycloak - 1.0-alpha-3-SNAPSHOT - ../../pom.xml - - 4.0.0 - - keycloak-model-tests - Keycloak Model Tests - - - - - org.keycloak - keycloak-services - ${project.version} - compile - - - junit - junit - compile - - - org.codehaus.jackson - jackson-core-asl - compile - - - org.codehaus.jackson - jackson-mapper-asl - compile - - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - package-tests-jar - package - - test-jar - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - true - - - - - - - + + + + keycloak-parent + org.keycloak + 1.0-alpha-3-SNAPSHOT + ../../pom.xml + + 4.0.0 + + keycloak-model-tests + Keycloak Model Tests + + + + + org.keycloak + keycloak-services + ${project.version} + compile + + + junit + junit + compile + + + org.codehaus.jackson + jackson-core-asl + compile + + + org.codehaus.jackson + jackson-mapper-asl + compile + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + package-tests-jar + package + + test-jar + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + + diff --git a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java index c73f3b0b53..7a2994543b 100755 --- a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java +++ b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java @@ -241,8 +241,8 @@ public class AdapterTest extends AbstractModelTest { Assert.assertFalse(realmModel.removeRoleById(realmRole.getId())); Assert.assertNull(realmModel.getRole(realmRole.getName())); - Assert.assertTrue(app.removeRoleById(appRole.getId())); - Assert.assertFalse(app.removeRoleById(appRole.getId())); + Assert.assertTrue(realmModel.removeRoleById(appRole.getId())); + Assert.assertFalse(realmModel.removeRoleById(appRole.getId())); Assert.assertNull(app.getRole(appRole.getName())); } @@ -431,13 +431,9 @@ public class AdapterTest extends AbstractModelTest { Set appRoles = application.getRoles(); Assert.assertEquals(2, appRoles.size()); RoleModel appBarRole = application.getRole("bar"); + Assert.assertNotNull(appBarRole); - // This should return null because it's realmRole - Assert.assertNull(application.getRoleById(realmUserRole.getId())); - - // This should return null because appBarRole is application role - Assert.assertNull(realmModel.getRoleById(appBarRole.getId())); - found = application.getRoleById(appBarRole.getId()); + found = realmModel.getRoleById(appBarRole.getId()); Assert.assertNotNull(found); assertRolesEquals(found, appBarRole); diff --git a/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java index c314619948..ba7a03b395 100755 --- a/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java +++ b/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java @@ -1,86 +1,86 @@ -package org.keycloak.model.test; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.keycloak.models.ApplicationModel; -import org.keycloak.models.RealmModel; -import org.keycloak.models.RoleModel; -import org.keycloak.models.UserModel; -import org.keycloak.representations.idm.ApplicationRepresentation; -import org.keycloak.services.managers.ApplicationManager; - -import java.util.Iterator; -import java.util.List; - -/** - * @author Stian Thorgersen - */ -public class ApplicationModelTest extends AbstractModelTest { - private ApplicationModel application; - private RealmModel realm; - private ApplicationManager appManager; - - @Before - public void before() throws Exception { - super.before(); - appManager = new ApplicationManager(realmManager); - - realm = realmManager.createRealm("original"); - application = realm.addApplication("application"); - application.setBaseUrl("http://base"); - application.setManagementUrl("http://management"); - application.setName("app-name"); - application.addRole("role-1"); - application.addRole("role-2"); - application.addRole("role-3"); - application.addDefaultRole("role-1"); - application.addDefaultRole("role-2"); - - application.addRedirectUri("redirect-1"); - application.addRedirectUri("redirect-2"); - - application.addWebOrigin("origin-1"); - application.addWebOrigin("origin-2"); - - application.updateApplication(); - } - - @Test - public void persist() { - RealmModel persisted = realmManager.getRealm(realm.getId()); - - assertEquals(application, persisted.getApplicationNameMap().get("app-name")); - } - - @Test - public void json() { - ApplicationRepresentation representation = appManager.toRepresentation(application); - - RealmModel realm = realmManager.createRealm("copy"); - ApplicationModel copy = appManager.createApplication(realm, representation); - - assertEquals(application, copy); - } - - public static void assertEquals(ApplicationModel expected, ApplicationModel actual) { - Assert.assertEquals(expected.getName(), actual.getName()); - Assert.assertEquals(expected.getBaseUrl(), actual.getBaseUrl()); - Assert.assertEquals(expected.getManagementUrl(), actual.getManagementUrl()); - Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles()); - - Assert.assertTrue(expected.getRedirectUris().containsAll(actual.getRedirectUris())); - Assert.assertTrue(expected.getWebOrigins().containsAll(actual.getWebOrigins())); - } - - public static void assertEquals(List expected, List actual) { - Assert.assertEquals(expected.size(), actual.size()); - Iterator exp = expected.iterator(); - Iterator act = actual.iterator(); - while (exp.hasNext()) { - Assert.assertEquals(exp.next().getName(), act.next().getName()); - } - } - -} - +package org.keycloak.model.test; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.keycloak.models.ApplicationModel; +import org.keycloak.models.RealmModel; +import org.keycloak.models.RoleModel; +import org.keycloak.models.UserModel; +import org.keycloak.representations.idm.ApplicationRepresentation; +import org.keycloak.services.managers.ApplicationManager; + +import java.util.Iterator; +import java.util.List; + +/** + * @author Stian Thorgersen + */ +public class ApplicationModelTest extends AbstractModelTest { + private ApplicationModel application; + private RealmModel realm; + private ApplicationManager appManager; + + @Before + public void before() throws Exception { + super.before(); + appManager = new ApplicationManager(realmManager); + + realm = realmManager.createRealm("original"); + application = realm.addApplication("application"); + application.setBaseUrl("http://base"); + application.setManagementUrl("http://management"); + application.setName("app-name"); + application.addRole("role-1"); + application.addRole("role-2"); + application.addRole("role-3"); + application.addDefaultRole("role-1"); + application.addDefaultRole("role-2"); + + application.addRedirectUri("redirect-1"); + application.addRedirectUri("redirect-2"); + + application.addWebOrigin("origin-1"); + application.addWebOrigin("origin-2"); + + application.updateApplication(); + } + + @Test + public void persist() { + RealmModel persisted = realmManager.getRealm(realm.getId()); + + assertEquals(application, persisted.getApplicationNameMap().get("app-name")); + } + + @Test + public void json() { + ApplicationRepresentation representation = appManager.toRepresentation(application); + + RealmModel realm = realmManager.createRealm("copy"); + ApplicationModel copy = appManager.createApplication(realm, representation); + + assertEquals(application, copy); + } + + public static void assertEquals(ApplicationModel expected, ApplicationModel actual) { + Assert.assertEquals(expected.getName(), actual.getName()); + Assert.assertEquals(expected.getBaseUrl(), actual.getBaseUrl()); + Assert.assertEquals(expected.getManagementUrl(), actual.getManagementUrl()); + Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles()); + + Assert.assertTrue(expected.getRedirectUris().containsAll(actual.getRedirectUris())); + Assert.assertTrue(expected.getWebOrigins().containsAll(actual.getWebOrigins())); + } + + public static void assertEquals(List expected, List actual) { + Assert.assertEquals(expected.size(), actual.size()); + Iterator exp = expected.iterator(); + Iterator act = actual.iterator(); + while (exp.hasNext()) { + Assert.assertEquals(exp.next().getName(), act.next().getName()); + } + } + +} + diff --git a/model/tests/src/test/java/org/keycloak/model/test/AuthenticationManagerTest.java b/model/tests/src/test/java/org/keycloak/model/test/AuthenticationManagerTest.java index c4d316c993..3faddc9525 100755 --- a/model/tests/src/test/java/org/keycloak/model/test/AuthenticationManagerTest.java +++ b/model/tests/src/test/java/org/keycloak/model/test/AuthenticationManagerTest.java @@ -1,150 +1,150 @@ -package org.keycloak.model.test; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserCredentialModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.UserModel.RequiredAction; -import org.keycloak.models.utils.TimeBasedOTP; -import org.keycloak.representations.idm.CredentialRepresentation; -import org.keycloak.services.managers.AuthenticationManager; -import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus; - -import javax.ws.rs.core.MultivaluedHashMap; -import javax.ws.rs.core.MultivaluedMap; -import java.util.UUID; - -public class AuthenticationManagerTest extends AbstractModelTest { - - private AuthenticationManager am; - private MultivaluedMap formData; - private TimeBasedOTP otp; - private RealmModel realm; - private UserModel user; - - @Test - public void authForm() { - AuthenticationStatus status = am.authenticateForm(realm, user, formData); - Assert.assertEquals(AuthenticationStatus.SUCCESS, status); - } - - @Test - public void authFormInvalidPassword() { - formData.remove(CredentialRepresentation.PASSWORD); - formData.add(CredentialRepresentation.PASSWORD, "invalid"); - - AuthenticationStatus status = am.authenticateForm(realm, user, formData); - Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status); - } - - @Test - public void authFormMissingPassword() { - formData.remove(CredentialRepresentation.PASSWORD); - - AuthenticationStatus status = am.authenticateForm(realm, user, formData); - Assert.assertEquals(AuthenticationStatus.MISSING_PASSWORD, status); - } - - @Test - public void authFormRequiredAction() { - realm.addRequiredCredential(CredentialRepresentation.TOTP); - user.addRequiredAction(RequiredAction.CONFIGURE_TOTP); - - AuthenticationStatus status = am.authenticateForm(realm, user, formData); - Assert.assertEquals(AuthenticationStatus.ACTIONS_REQUIRED, status); - } - - @Test - public void authFormUserDisabled() { - user.setEnabled(false); - - AuthenticationStatus status = am.authenticateForm(realm, user, formData); - Assert.assertEquals(AuthenticationStatus.ACCOUNT_DISABLED, status); - } - - @Test - public void authFormWithTotp() { - realm.addRequiredCredential(CredentialRepresentation.TOTP); - - String totpSecret = UUID.randomUUID().toString(); - - UserCredentialModel credential = new UserCredentialModel(); - credential.setType(CredentialRepresentation.TOTP); - credential.setValue(totpSecret); - - realm.updateCredential(user, credential); - - user.setTotp(true); - - String token = otp.generate(totpSecret); - - formData.add(CredentialRepresentation.TOTP, token); - - AuthenticationStatus status = am.authenticateForm(realm, user, formData); - Assert.assertEquals(AuthenticationStatus.SUCCESS, status); - } - - @Test - public void authFormWithTotpInvalidPassword() { - authFormWithTotp(); - - formData.remove(CredentialRepresentation.PASSWORD); - formData.add(CredentialRepresentation.PASSWORD, "invalid"); - - AuthenticationStatus status = am.authenticateForm(realm, user, formData); - Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status); - } - - @Test - public void authFormWithTotpInvalidTotp() { - authFormWithTotp(); - - formData.remove(CredentialRepresentation.TOTP); - formData.add(CredentialRepresentation.TOTP, "invalid"); - - AuthenticationStatus status = am.authenticateForm(realm, user, formData); - Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status); - } - - @Test - public void authFormWithTotpMissingTotp() { - authFormWithTotp(); - - formData.remove(CredentialRepresentation.TOTP); - - AuthenticationStatus status = am.authenticateForm(realm, user, formData); - Assert.assertEquals(AuthenticationStatus.MISSING_TOTP, status); - } - - @Before - public void before() throws Exception { - super.before(); - realm = realmManager.createRealm("Test"); - realm.setAccessCodeLifespan(100); - realm.setEnabled(true); - realm.setName("Test"); - realm.setPrivateKeyPem("0234234"); - realm.setPublicKeyPem("0234234"); - realm.setAccessTokenLifespan(1000); - realm.addRequiredCredential(CredentialRepresentation.PASSWORD); - - am = new AuthenticationManager(); - - user = realm.addUser("test"); - user.setEnabled(true); - - UserCredentialModel credential = new UserCredentialModel(); - credential.setType(CredentialRepresentation.PASSWORD); - credential.setValue("password"); - - realm.updateCredential(user, credential); - - formData = new MultivaluedHashMap(); - formData.add(CredentialRepresentation.PASSWORD, "password"); - - otp = new TimeBasedOTP(); - } - -} +package org.keycloak.model.test; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.keycloak.models.RealmModel; +import org.keycloak.models.UserCredentialModel; +import org.keycloak.models.UserModel; +import org.keycloak.models.UserModel.RequiredAction; +import org.keycloak.models.utils.TimeBasedOTP; +import org.keycloak.representations.idm.CredentialRepresentation; +import org.keycloak.services.managers.AuthenticationManager; +import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus; + +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; +import java.util.UUID; + +public class AuthenticationManagerTest extends AbstractModelTest { + + private AuthenticationManager am; + private MultivaluedMap formData; + private TimeBasedOTP otp; + private RealmModel realm; + private UserModel user; + + @Test + public void authForm() { + AuthenticationStatus status = am.authenticateForm(realm, user, formData); + Assert.assertEquals(AuthenticationStatus.SUCCESS, status); + } + + @Test + public void authFormInvalidPassword() { + formData.remove(CredentialRepresentation.PASSWORD); + formData.add(CredentialRepresentation.PASSWORD, "invalid"); + + AuthenticationStatus status = am.authenticateForm(realm, user, formData); + Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status); + } + + @Test + public void authFormMissingPassword() { + formData.remove(CredentialRepresentation.PASSWORD); + + AuthenticationStatus status = am.authenticateForm(realm, user, formData); + Assert.assertEquals(AuthenticationStatus.MISSING_PASSWORD, status); + } + + @Test + public void authFormRequiredAction() { + realm.addRequiredCredential(CredentialRepresentation.TOTP); + user.addRequiredAction(RequiredAction.CONFIGURE_TOTP); + + AuthenticationStatus status = am.authenticateForm(realm, user, formData); + Assert.assertEquals(AuthenticationStatus.ACTIONS_REQUIRED, status); + } + + @Test + public void authFormUserDisabled() { + user.setEnabled(false); + + AuthenticationStatus status = am.authenticateForm(realm, user, formData); + Assert.assertEquals(AuthenticationStatus.ACCOUNT_DISABLED, status); + } + + @Test + public void authFormWithTotp() { + realm.addRequiredCredential(CredentialRepresentation.TOTP); + + String totpSecret = UUID.randomUUID().toString(); + + UserCredentialModel credential = new UserCredentialModel(); + credential.setType(CredentialRepresentation.TOTP); + credential.setValue(totpSecret); + + realm.updateCredential(user, credential); + + user.setTotp(true); + + String token = otp.generate(totpSecret); + + formData.add(CredentialRepresentation.TOTP, token); + + AuthenticationStatus status = am.authenticateForm(realm, user, formData); + Assert.assertEquals(AuthenticationStatus.SUCCESS, status); + } + + @Test + public void authFormWithTotpInvalidPassword() { + authFormWithTotp(); + + formData.remove(CredentialRepresentation.PASSWORD); + formData.add(CredentialRepresentation.PASSWORD, "invalid"); + + AuthenticationStatus status = am.authenticateForm(realm, user, formData); + Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status); + } + + @Test + public void authFormWithTotpInvalidTotp() { + authFormWithTotp(); + + formData.remove(CredentialRepresentation.TOTP); + formData.add(CredentialRepresentation.TOTP, "invalid"); + + AuthenticationStatus status = am.authenticateForm(realm, user, formData); + Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status); + } + + @Test + public void authFormWithTotpMissingTotp() { + authFormWithTotp(); + + formData.remove(CredentialRepresentation.TOTP); + + AuthenticationStatus status = am.authenticateForm(realm, user, formData); + Assert.assertEquals(AuthenticationStatus.MISSING_TOTP, status); + } + + @Before + public void before() throws Exception { + super.before(); + realm = realmManager.createRealm("Test"); + realm.setAccessCodeLifespan(100); + realm.setEnabled(true); + realm.setName("Test"); + realm.setPrivateKeyPem("0234234"); + realm.setPublicKeyPem("0234234"); + realm.setAccessTokenLifespan(1000); + realm.addRequiredCredential(CredentialRepresentation.PASSWORD); + + am = new AuthenticationManager(); + + user = realm.addUser("test"); + user.setEnabled(true); + + UserCredentialModel credential = new UserCredentialModel(); + credential.setType(CredentialRepresentation.PASSWORD); + credential.setValue("password"); + + realm.updateCredential(user, credential); + + formData = new MultivaluedHashMap(); + formData.add(CredentialRepresentation.PASSWORD, "password"); + + otp = new TimeBasedOTP(); + } + +} diff --git a/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java index 2472ed0700..61d5621da8 100755 --- a/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java +++ b/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java @@ -1,113 +1,113 @@ -package org.keycloak.model.test; - -import java.util.HashSet; -import java.util.Set; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.keycloak.models.ApplicationModel; -import org.keycloak.models.RealmModel; -import org.keycloak.models.RoleModel; -import org.keycloak.models.UserModel; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.services.managers.RealmManager; - -/** - * @author Marek Posolda - */ -public class CompositeRolesModelTest extends AbstractModelTest { - - @Before - public void before() throws Exception { - super.before(); - RealmManager manager = realmManager; - RealmRepresentation rep = AbstractModelTest.loadJson("testcomposites.json"); - RealmModel realm = manager.createRealm("Test", rep.getRealm()); - manager.importRealm(rep, realm); - } - - @Test - public void testComposites() { - Set requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "APP_COMPOSITE_USER"); - Assert.assertEquals(2, requestedRoles.size()); - assertContains("APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles); - assertContains("realm", "REALM_ROLE_1", requestedRoles); - - requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "REALM_APP_COMPOSITE_USER"); - Assert.assertEquals(1, requestedRoles.size()); - assertContains("APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles); - - requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_COMPOSITE_1_USER"); - Assert.assertEquals(1, requestedRoles.size()); - assertContains("realm", "REALM_COMPOSITE_1", requestedRoles); - - requestedRoles = getRequestedRoles("REALM_ROLE_1_APPLICATION", "REALM_COMPOSITE_1_USER"); - Assert.assertEquals(1, requestedRoles.size()); - assertContains("realm", "REALM_ROLE_1", requestedRoles); - - requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_ROLE_1_USER"); - Assert.assertEquals(1, requestedRoles.size()); - assertContains("realm", "REALM_ROLE_1", requestedRoles); - } - - // Same algorithm as in TokenManager.createAccessCode - private Set getRequestedRoles(String applicationName, String username) { - Set requestedRoles = new HashSet(); - - RealmModel realm = realmManager.getRealm("Test"); - UserModel user = realm.getUser(username); - ApplicationModel application = realm.getApplicationByName(applicationName); - - Set roleMappings = realm.getRoleMappings(user); - Set scopeMappings = realm.getScopeMappings(application); - Set appRoles = application.getRoles(); - if (appRoles != null) scopeMappings.addAll(appRoles); - - for (RoleModel role : roleMappings) { - if (role.getContainer().equals(application)) requestedRoles.add(role); - for (RoleModel desiredRole : scopeMappings) { - Set visited = new HashSet(); - applyScope(role, desiredRole, visited, requestedRoles); - } - } - - return requestedRoles; - } - - private static void applyScope(RoleModel role, RoleModel scope, Set visited, Set requested) { - if (visited.contains(scope)) return; - visited.add(scope); - if (role.hasRole(scope)) { - requested.add(scope); - return; - } - if (!scope.isComposite()) return; - - for (RoleModel contained : scope.getComposites()) { - applyScope(role, contained, visited, requested); - } - } - - private RoleModel getRole(String appName, String roleName) { - RealmModel realm = realmManager.getRealm("Test"); - if ("realm".equals(appName)) { - return realm.getRole(roleName); - } else { - return realm.getApplicationByName(appName).getRole(roleName); - } - } - - private void assertContains(String appName, String roleName, Set requestedRoles) { - RoleModel expectedRole = getRole(appName, roleName); - - Assert.assertTrue(requestedRoles.contains(expectedRole)); - - // Check if requestedRole has correct role container - for (RoleModel role : requestedRoles) { - if (role.equals(expectedRole)) { - Assert.assertEquals(role.getContainer(), expectedRole.getContainer()); - } - } - } -} +package org.keycloak.model.test; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.keycloak.models.ApplicationModel; +import org.keycloak.models.RealmModel; +import org.keycloak.models.RoleModel; +import org.keycloak.models.UserModel; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.services.managers.RealmManager; + +/** + * @author Marek Posolda + */ +public class CompositeRolesModelTest extends AbstractModelTest { + + @Before + public void before() throws Exception { + super.before(); + RealmManager manager = realmManager; + RealmRepresentation rep = AbstractModelTest.loadJson("testcomposites.json"); + RealmModel realm = manager.createRealm("Test", rep.getRealm()); + manager.importRealm(rep, realm); + } + + @Test + public void testComposites() { + Set requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "APP_COMPOSITE_USER"); + Assert.assertEquals(2, requestedRoles.size()); + assertContains("APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles); + assertContains("realm", "REALM_ROLE_1", requestedRoles); + + requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "REALM_APP_COMPOSITE_USER"); + Assert.assertEquals(1, requestedRoles.size()); + assertContains("APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles); + + requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_COMPOSITE_1_USER"); + Assert.assertEquals(1, requestedRoles.size()); + assertContains("realm", "REALM_COMPOSITE_1", requestedRoles); + + requestedRoles = getRequestedRoles("REALM_ROLE_1_APPLICATION", "REALM_COMPOSITE_1_USER"); + Assert.assertEquals(1, requestedRoles.size()); + assertContains("realm", "REALM_ROLE_1", requestedRoles); + + requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_ROLE_1_USER"); + Assert.assertEquals(1, requestedRoles.size()); + assertContains("realm", "REALM_ROLE_1", requestedRoles); + } + + // Same algorithm as in TokenManager.createAccessCode + private Set getRequestedRoles(String applicationName, String username) { + Set requestedRoles = new HashSet(); + + RealmModel realm = realmManager.getRealm("Test"); + UserModel user = realm.getUser(username); + ApplicationModel application = realm.getApplicationByName(applicationName); + + Set roleMappings = realm.getRoleMappings(user); + Set scopeMappings = realm.getScopeMappings(application); + Set appRoles = application.getRoles(); + if (appRoles != null) scopeMappings.addAll(appRoles); + + for (RoleModel role : roleMappings) { + if (role.getContainer().equals(application)) requestedRoles.add(role); + for (RoleModel desiredRole : scopeMappings) { + Set visited = new HashSet(); + applyScope(role, desiredRole, visited, requestedRoles); + } + } + + return requestedRoles; + } + + private static void applyScope(RoleModel role, RoleModel scope, Set visited, Set requested) { + if (visited.contains(scope)) return; + visited.add(scope); + if (role.hasRole(scope)) { + requested.add(scope); + return; + } + if (!scope.isComposite()) return; + + for (RoleModel contained : scope.getComposites()) { + applyScope(role, contained, visited, requested); + } + } + + private RoleModel getRole(String appName, String roleName) { + RealmModel realm = realmManager.getRealm("Test"); + if ("realm".equals(appName)) { + return realm.getRole(roleName); + } else { + return realm.getApplicationByName(appName).getRole(roleName); + } + } + + private void assertContains(String appName, String roleName, Set requestedRoles) { + RoleModel expectedRole = getRole(appName, roleName); + + Assert.assertTrue(requestedRoles.contains(expectedRole)); + + // Check if requestedRole has correct role container + for (RoleModel role : requestedRoles) { + if (role.equals(expectedRole)) { + Assert.assertEquals(role.getContainer(), expectedRole.getContainer()); + } + } + } +} diff --git a/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java index b15e888898..c2bafc454a 100755 --- a/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java +++ b/model/tests/src/test/java/org/keycloak/model/test/ModelTest.java @@ -1,78 +1,78 @@ -package org.keycloak.model.test; - -import org.junit.Assert; -import org.junit.Test; -import org.keycloak.models.PasswordPolicy; -import org.keycloak.models.RealmModel; -import org.keycloak.models.RoleModel; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.services.managers.ModelToRepresentation; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; - -public class ModelTest extends AbstractModelTest { - - @Test - public void importExportRealm() { - RealmModel realm = realmManager.createRealm("original"); - realm.setRegistrationAllowed(true); - realm.setResetPasswordAllowed(true); - realm.setSocial(true); - realm.setSslNotRequired(true); - realm.setVerifyEmail(true); - realm.setAccessTokenLifespan(1000); - realm.setPasswordPolicy(new PasswordPolicy("length")); - realm.setAccessCodeLifespan(1001); - realm.setAccessCodeLifespanUserAction(1002); - realm.setPublicKeyPem("0234234"); - realm.setPrivateKeyPem("1234234"); - realm.addDefaultRole("default-role"); - - HashMap smtp = new HashMap(); - smtp.put("from", "auto@keycloak"); - smtp.put("hostname", "localhost"); - realm.setSmtpConfig(smtp); - - HashMap social = new HashMap(); - social.put("google.key", "1234"); - social.put("google.secret", "5678"); - realm.setSocialConfig(social); - - RealmModel persisted = realmManager.getRealm(realm.getId()); - assertEquals(realm, persisted); - - RealmModel copy = importExport(realm, "copy"); - assertEquals(realm, copy); - } - - public static void assertEquals(RealmModel expected, RealmModel actual) { - Assert.assertEquals(expected.isUpdateProfileOnInitialSocialLogin(), - actual.isUpdateProfileOnInitialSocialLogin()); - Assert.assertEquals(expected.isRegistrationAllowed(), actual.isRegistrationAllowed()); - Assert.assertEquals(expected.isResetPasswordAllowed(), actual.isResetPasswordAllowed()); - Assert.assertEquals(expected.isSocial(), actual.isSocial()); - Assert.assertEquals(expected.isSslNotRequired(), actual.isSslNotRequired()); - Assert.assertEquals(expected.isVerifyEmail(), actual.isVerifyEmail()); - Assert.assertEquals(expected.getAccessTokenLifespan(), actual.getAccessTokenLifespan()); - - Assert.assertEquals(expected.getAccessCodeLifespan(), actual.getAccessCodeLifespan()); - Assert.assertEquals(expected.getAccessCodeLifespanUserAction(), actual.getAccessCodeLifespanUserAction()); - Assert.assertEquals(expected.getPublicKeyPem(), actual.getPublicKeyPem()); - Assert.assertEquals(expected.getPrivateKeyPem(), actual.getPrivateKeyPem()); - - Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles()); - - Assert.assertEquals(expected.getSmtpConfig(), actual.getSmtpConfig()); - Assert.assertEquals(expected.getSocialConfig(), actual.getSocialConfig()); - } - - private RealmModel importExport(RealmModel src, String copyName) { - RealmRepresentation representation = ModelToRepresentation.toRepresentation(src); - RealmModel copy = realmManager.createRealm(copyName); - realmManager.importRealm(representation, copy); - return realmManager.getRealm(copy.getId()); - } - -} +package org.keycloak.model.test; + +import org.junit.Assert; +import org.junit.Test; +import org.keycloak.models.PasswordPolicy; +import org.keycloak.models.RealmModel; +import org.keycloak.models.RoleModel; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.services.managers.ModelToRepresentation; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +public class ModelTest extends AbstractModelTest { + + @Test + public void importExportRealm() { + RealmModel realm = realmManager.createRealm("original"); + realm.setRegistrationAllowed(true); + realm.setResetPasswordAllowed(true); + realm.setSocial(true); + realm.setSslNotRequired(true); + realm.setVerifyEmail(true); + realm.setAccessTokenLifespan(1000); + realm.setPasswordPolicy(new PasswordPolicy("length")); + realm.setAccessCodeLifespan(1001); + realm.setAccessCodeLifespanUserAction(1002); + realm.setPublicKeyPem("0234234"); + realm.setPrivateKeyPem("1234234"); + realm.addDefaultRole("default-role"); + + HashMap smtp = new HashMap(); + smtp.put("from", "auto@keycloak"); + smtp.put("hostname", "localhost"); + realm.setSmtpConfig(smtp); + + HashMap social = new HashMap(); + social.put("google.key", "1234"); + social.put("google.secret", "5678"); + realm.setSocialConfig(social); + + RealmModel persisted = realmManager.getRealm(realm.getId()); + assertEquals(realm, persisted); + + RealmModel copy = importExport(realm, "copy"); + assertEquals(realm, copy); + } + + public static void assertEquals(RealmModel expected, RealmModel actual) { + Assert.assertEquals(expected.isUpdateProfileOnInitialSocialLogin(), + actual.isUpdateProfileOnInitialSocialLogin()); + Assert.assertEquals(expected.isRegistrationAllowed(), actual.isRegistrationAllowed()); + Assert.assertEquals(expected.isResetPasswordAllowed(), actual.isResetPasswordAllowed()); + Assert.assertEquals(expected.isSocial(), actual.isSocial()); + Assert.assertEquals(expected.isSslNotRequired(), actual.isSslNotRequired()); + Assert.assertEquals(expected.isVerifyEmail(), actual.isVerifyEmail()); + Assert.assertEquals(expected.getAccessTokenLifespan(), actual.getAccessTokenLifespan()); + + Assert.assertEquals(expected.getAccessCodeLifespan(), actual.getAccessCodeLifespan()); + Assert.assertEquals(expected.getAccessCodeLifespanUserAction(), actual.getAccessCodeLifespanUserAction()); + Assert.assertEquals(expected.getPublicKeyPem(), actual.getPublicKeyPem()); + Assert.assertEquals(expected.getPrivateKeyPem(), actual.getPrivateKeyPem()); + + Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles()); + + Assert.assertEquals(expected.getSmtpConfig(), actual.getSmtpConfig()); + Assert.assertEquals(expected.getSocialConfig(), actual.getSocialConfig()); + } + + private RealmModel importExport(RealmModel src, String copyName) { + RealmRepresentation representation = ModelToRepresentation.toRepresentation(src); + RealmModel copy = realmManager.createRealm(copyName); + realmManager.importRealm(representation, copy); + return realmManager.getRealm(copy.getId()); + } + +} diff --git a/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java b/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java old mode 100644 new mode 100755 index 25808e3519..8b33c3feb2 --- a/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java +++ b/model/tests/src/test/java/org/keycloak/model/test/MultipleRealmsTest.java @@ -75,20 +75,11 @@ public class MultipleRealmsTest extends AbstractModelTest { Assert.assertEquals(r2cl1.getId(), realm2.getOAuthClientById(r2cl1.getId()).getId()); RoleModel r1App1Role = r1app1.getRole("app1Role1"); - Assert.assertNull(realm1.getRoleById(r1App1Role.getId())); - Assert.assertNull(realm2.getRoleById(r1App1Role.getId())); - Assert.assertEquals(r1App1Role, r1app1.getRoleById(r1App1Role.getId())); - Assert.assertNull(r1app2.getRoleById(r1App1Role.getId())); - Assert.assertNull(r2app1.getRoleById(r1App1Role.getId())); - Assert.assertNull(r2app2.getRoleById(r1App1Role.getId())); + Assert.assertEquals(r1App1Role, realm1.getRoleById(r1App1Role.getId())); RoleModel r2Role1 = realm2.getRole("role2"); Assert.assertNull(realm1.getRoleById(r2Role1.getId())); Assert.assertEquals(r2Role1, realm2.getRoleById(r2Role1.getId())); - Assert.assertNull(r1app1.getRoleById(r2Role1.getId())); - Assert.assertNull(r1app2.getRoleById(r2Role1.getId())); - Assert.assertNull(r2app1.getRoleById(r2Role1.getId())); - Assert.assertNull(r2app2.getRoleById(r2Role1.getId())); } private void createObjects(RealmModel realm) { diff --git a/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java index 5bc94d2035..132e39ce5a 100755 --- a/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java +++ b/model/tests/src/test/java/org/keycloak/model/test/UserModelTest.java @@ -1,121 +1,121 @@ -package org.keycloak.model.test; - -import org.junit.Assert; -import org.junit.Test; -import org.keycloak.models.ApplicationModel; -import org.keycloak.models.ClientModel; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.UserModel.RequiredAction; - -/** - * @author Stian Thorgersen - */ -public class UserModelTest extends AbstractModelTest { - - @Test - public void persistUser() { - RealmModel realm = realmManager.createRealm("original"); - UserModel user = realm.addUser("user"); - user.setFirstName("first-name"); - user.setLastName("last-name"); - user.setEmail("email"); - - user.addRequiredAction(RequiredAction.CONFIGURE_TOTP); - user.addRequiredAction(RequiredAction.UPDATE_PASSWORD); - - UserModel persisted = realmManager.getRealm(realm.getId()).getUser("user"); - - assertEquals(user, persisted); - - UserModel persisted2 = realmManager.getRealm(realm.getId()).getUserById(user.getId()); - assertEquals(user, persisted2); - } - - @Test - public void webOriginSetTest() { - RealmModel realm = realmManager.createRealm("original"); - ClientModel client = realm.addApplication("user"); - - Assert.assertTrue(client.getWebOrigins().isEmpty()); - - client.addWebOrigin("origin-1"); - Assert.assertEquals(1, client.getWebOrigins().size()); - - client.addWebOrigin("origin-2"); - Assert.assertEquals(2, client.getWebOrigins().size()); - - client.removeWebOrigin("origin-2"); - Assert.assertEquals(1, client.getWebOrigins().size()); - - client.removeWebOrigin("origin-1"); - Assert.assertTrue(client.getWebOrigins().isEmpty()); - - client = realm.addOAuthClient("oauthclient2"); - - Assert.assertTrue(client.getWebOrigins().isEmpty()); - - client.addWebOrigin("origin-1"); - Assert.assertEquals(1, client.getWebOrigins().size()); - - client.addWebOrigin("origin-2"); - Assert.assertEquals(2, client.getWebOrigins().size()); - - client.removeWebOrigin("origin-2"); - Assert.assertEquals(1, client.getWebOrigins().size()); - - client.removeWebOrigin("origin-1"); - Assert.assertTrue(client.getWebOrigins().isEmpty()); - - } - - @Test - public void testUserRequiredActions() throws Exception { - RealmModel realm = realmManager.createRealm("original"); - UserModel user = realm.addUser("user"); - - Assert.assertTrue(user.getRequiredActions().isEmpty()); - - user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP); - String id = realm.getId(); - commit(); - realm = realmManager.getRealm(id); - user = realm.getUser("user"); - - Assert.assertEquals(1, user.getRequiredActions().size()); - Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP)); - - user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP); - user = realm.getUser("user"); - - Assert.assertEquals(1, user.getRequiredActions().size()); - Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP)); - - user.addRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL); - user = realm.getUser("user"); - - Assert.assertEquals(2, user.getRequiredActions().size()); - Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP)); - Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL)); - - user.removeRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP); - user = realm.getUser("user"); - - Assert.assertEquals(1, user.getRequiredActions().size()); - Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL)); - - user.removeRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL); - user = realm.getUser("user"); - - Assert.assertTrue(user.getRequiredActions().isEmpty()); - } - - public static void assertEquals(UserModel expected, UserModel actual) { - Assert.assertEquals(expected.getLoginName(), actual.getLoginName()); - Assert.assertEquals(expected.getFirstName(), actual.getFirstName()); - Assert.assertEquals(expected.getLastName(), actual.getLastName()); - Assert.assertArrayEquals(expected.getRequiredActions().toArray(), actual.getRequiredActions().toArray()); - } - -} - +package org.keycloak.model.test; + +import org.junit.Assert; +import org.junit.Test; +import org.keycloak.models.ApplicationModel; +import org.keycloak.models.ClientModel; +import org.keycloak.models.RealmModel; +import org.keycloak.models.UserModel; +import org.keycloak.models.UserModel.RequiredAction; + +/** + * @author Stian Thorgersen + */ +public class UserModelTest extends AbstractModelTest { + + @Test + public void persistUser() { + RealmModel realm = realmManager.createRealm("original"); + UserModel user = realm.addUser("user"); + user.setFirstName("first-name"); + user.setLastName("last-name"); + user.setEmail("email"); + + user.addRequiredAction(RequiredAction.CONFIGURE_TOTP); + user.addRequiredAction(RequiredAction.UPDATE_PASSWORD); + + UserModel persisted = realmManager.getRealm(realm.getId()).getUser("user"); + + assertEquals(user, persisted); + + UserModel persisted2 = realmManager.getRealm(realm.getId()).getUserById(user.getId()); + assertEquals(user, persisted2); + } + + @Test + public void webOriginSetTest() { + RealmModel realm = realmManager.createRealm("original"); + ClientModel client = realm.addApplication("user"); + + Assert.assertTrue(client.getWebOrigins().isEmpty()); + + client.addWebOrigin("origin-1"); + Assert.assertEquals(1, client.getWebOrigins().size()); + + client.addWebOrigin("origin-2"); + Assert.assertEquals(2, client.getWebOrigins().size()); + + client.removeWebOrigin("origin-2"); + Assert.assertEquals(1, client.getWebOrigins().size()); + + client.removeWebOrigin("origin-1"); + Assert.assertTrue(client.getWebOrigins().isEmpty()); + + client = realm.addOAuthClient("oauthclient2"); + + Assert.assertTrue(client.getWebOrigins().isEmpty()); + + client.addWebOrigin("origin-1"); + Assert.assertEquals(1, client.getWebOrigins().size()); + + client.addWebOrigin("origin-2"); + Assert.assertEquals(2, client.getWebOrigins().size()); + + client.removeWebOrigin("origin-2"); + Assert.assertEquals(1, client.getWebOrigins().size()); + + client.removeWebOrigin("origin-1"); + Assert.assertTrue(client.getWebOrigins().isEmpty()); + + } + + @Test + public void testUserRequiredActions() throws Exception { + RealmModel realm = realmManager.createRealm("original"); + UserModel user = realm.addUser("user"); + + Assert.assertTrue(user.getRequiredActions().isEmpty()); + + user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP); + String id = realm.getId(); + commit(); + realm = realmManager.getRealm(id); + user = realm.getUser("user"); + + Assert.assertEquals(1, user.getRequiredActions().size()); + Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP)); + + user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP); + user = realm.getUser("user"); + + Assert.assertEquals(1, user.getRequiredActions().size()); + Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP)); + + user.addRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL); + user = realm.getUser("user"); + + Assert.assertEquals(2, user.getRequiredActions().size()); + Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP)); + Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL)); + + user.removeRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP); + user = realm.getUser("user"); + + Assert.assertEquals(1, user.getRequiredActions().size()); + Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL)); + + user.removeRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL); + user = realm.getUser("user"); + + Assert.assertTrue(user.getRequiredActions().isEmpty()); + } + + public static void assertEquals(UserModel expected, UserModel actual) { + Assert.assertEquals(expected.getLoginName(), actual.getLoginName()); + Assert.assertEquals(expected.getFirstName(), actual.getFirstName()); + Assert.assertEquals(expected.getLastName(), actual.getLastName()); + Assert.assertArrayEquals(expected.getRequiredActions().toArray(), actual.getRequiredActions().toArray()); + } + +} + diff --git a/model/tests/src/test/resources/testcomposites.json b/model/tests/src/test/resources/testcomposites.json index d035fd5c1c..61038ea65b 100755 --- a/model/tests/src/test/resources/testcomposites.json +++ b/model/tests/src/test/resources/testcomposites.json @@ -1,206 +1,206 @@ -{ - "id": "Test", - "realm": "Test", - "enabled": true, - "accessTokenLifespan": 600, - "accessCodeLifespan": 600, - "accessCodeLifespanUserAction": 600, - "sslNotRequired": true, - "registrationAllowed": true, - "resetPasswordAllowed": true, - "requiredCredentials": [ "password" ], - "smtpServer": { - "from": "auto@keycloak.org", - "host": "localhost", - "port":"3025" - }, - "users" : [ - { - "username" : "REALM_COMPOSITE_1_USER", - "enabled": true, - "email" : "test-user@localhost", - "credentials" : [ - { "type" : "password", - "value" : "password" } - ] - }, - { - "username" : "REALM_ROLE_1_USER", - "enabled": true, - "email" : "test-user@localhost", - "credentials" : [ - { "type" : "password", - "value" : "password" } - ] - }, - { - "username" : "REALM_APP_COMPOSITE_USER", - "enabled": true, - "email" : "test-user@localhost", - "credentials" : [ - { "type" : "password", - "value" : "password" } - ] - }, - { - "username" : "REALM_APP_ROLE_USER", - "enabled": true, - "email" : "test-user@localhost", - "credentials" : [ - { "type" : "password", - "value" : "password" } - ] - }, - { - "username" : "APP_COMPOSITE_USER", - "enabled": true, - "email" : "test-user@localhost", - "credentials" : [ - { "type" : "password", - "value" : "password" } - ] - } - ], - "oauthClients" : [ - { - "name" : "third-party", - "enabled": true, - "secret": "password" - } - ], - "roleMappings": [ - { - "username": "REALM_COMPOSITE_1_USER", - "roles": ["REALM_COMPOSITE_1"] - }, - { - "username": "REALM_ROLE_1_USER", - "roles": ["REALM_ROLE_1"] - }, - { - "username": "REALM_APP_COMPOSITE_USER", - "roles": ["REALM_APP_COMPOSITE_ROLE"] - }, - { - "username": "APP_COMPOSITE_USER", - "roles": ["REALM_APP_COMPOSITE_ROLE", "REALM_COMPOSITE_1"] - } - ], - "scopeMappings": [ - { - "client": "REALM_COMPOSITE_1_APPLICATION", - "roles": ["REALM_COMPOSITE_1"] - }, - { - "client": "REALM_ROLE_1_APPLICATION", - "roles": ["REALM_ROLE_1"] - } - ], - "applications": [ - { - "name": "REALM_COMPOSITE_1_APPLICATION", - "enabled": true, - "baseUrl": "http://localhost:8081/app", - "adminUrl": "http://localhost:8081/app/logout", - "secret": "password" - }, - { - "name": "REALM_ROLE_1_APPLICATION", - "enabled": true, - "baseUrl": "http://localhost:8081/app", - "adminUrl": "http://localhost:8081/app/logout", - "secret": "password" - }, - { - "name": "APP_ROLE_APPLICATION", - "enabled": true, - "baseUrl": "http://localhost:8081/app", - "adminUrl": "http://localhost:8081/app/logout", - "secret": "password" - }, - { - "name": "APP_COMPOSITE_APPLICATION", - "enabled": true, - "baseUrl": "http://localhost:8081/app", - "adminUrl": "http://localhost:8081/app/logout", - "secret": "password" - } - ], - "roles" : { - "realm" : [ - { - "name": "REALM_ROLE_1" - }, - { - "name": "REALM_ROLE_2" - }, - { - "name": "REALM_ROLE_3" - }, - { - "name": "REALM_COMPOSITE_1", - "composites": { - "realm": ["REALM_ROLE_1"] - } - }, - { - "name": "REALM_APP_COMPOSITE_ROLE", - "composites": { - "application": { - "APP_ROLE_APPLICATION" :[ - "APP_ROLE_1" - ] - } - } - } - ], - "application" : { - "APP_ROLE_APPLICATION" : [ - { - "name": "APP_ROLE_1" - }, - { - "name": "APP_ROLE_2" - } - ], - "APP_COMPOSITE_APPLICATION" : [ - { - "name": "APP_COMPOSITE_ROLE", - "composites": { - "realm" : [ - "REALM_ROLE_1", - "REALM_ROLE_2", - "REALM_ROLE_3" - ], - "application": { - "APP_ROLE_APPLICATION" :[ - "APP_ROLE_1" - ] - } - } - }, - { - "name": "APP_ROLE_2" - } - ] - } - - }, - - "applicationRoleMappings": { - "APP_ROLE_APPLICATION": [ - { - "username": "REALM_APP_ROLE_USER", - "roles": ["APP_ROLE_2"] - } - ] - }, - "applicationScopeMappings": { - "APP_ROLE_APPLICATION": [ - { - "client": "APP_COMPOSITE_APPLICATION", - "roles": ["APP_ROLE_2"] - } - ] - } +{ + "id": "Test", + "realm": "Test", + "enabled": true, + "accessTokenLifespan": 600, + "accessCodeLifespan": 600, + "accessCodeLifespanUserAction": 600, + "sslNotRequired": true, + "registrationAllowed": true, + "resetPasswordAllowed": true, + "requiredCredentials": [ "password" ], + "smtpServer": { + "from": "auto@keycloak.org", + "host": "localhost", + "port":"3025" + }, + "users" : [ + { + "username" : "REALM_COMPOSITE_1_USER", + "enabled": true, + "email" : "test-user@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ] + }, + { + "username" : "REALM_ROLE_1_USER", + "enabled": true, + "email" : "test-user@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ] + }, + { + "username" : "REALM_APP_COMPOSITE_USER", + "enabled": true, + "email" : "test-user@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ] + }, + { + "username" : "REALM_APP_ROLE_USER", + "enabled": true, + "email" : "test-user@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ] + }, + { + "username" : "APP_COMPOSITE_USER", + "enabled": true, + "email" : "test-user@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ] + } + ], + "oauthClients" : [ + { + "name" : "third-party", + "enabled": true, + "secret": "password" + } + ], + "roleMappings": [ + { + "username": "REALM_COMPOSITE_1_USER", + "roles": ["REALM_COMPOSITE_1"] + }, + { + "username": "REALM_ROLE_1_USER", + "roles": ["REALM_ROLE_1"] + }, + { + "username": "REALM_APP_COMPOSITE_USER", + "roles": ["REALM_APP_COMPOSITE_ROLE"] + }, + { + "username": "APP_COMPOSITE_USER", + "roles": ["REALM_APP_COMPOSITE_ROLE", "REALM_COMPOSITE_1"] + } + ], + "scopeMappings": [ + { + "client": "REALM_COMPOSITE_1_APPLICATION", + "roles": ["REALM_COMPOSITE_1"] + }, + { + "client": "REALM_ROLE_1_APPLICATION", + "roles": ["REALM_ROLE_1"] + } + ], + "applications": [ + { + "name": "REALM_COMPOSITE_1_APPLICATION", + "enabled": true, + "baseUrl": "http://localhost:8081/app", + "adminUrl": "http://localhost:8081/app/logout", + "secret": "password" + }, + { + "name": "REALM_ROLE_1_APPLICATION", + "enabled": true, + "baseUrl": "http://localhost:8081/app", + "adminUrl": "http://localhost:8081/app/logout", + "secret": "password" + }, + { + "name": "APP_ROLE_APPLICATION", + "enabled": true, + "baseUrl": "http://localhost:8081/app", + "adminUrl": "http://localhost:8081/app/logout", + "secret": "password" + }, + { + "name": "APP_COMPOSITE_APPLICATION", + "enabled": true, + "baseUrl": "http://localhost:8081/app", + "adminUrl": "http://localhost:8081/app/logout", + "secret": "password" + } + ], + "roles" : { + "realm" : [ + { + "name": "REALM_ROLE_1" + }, + { + "name": "REALM_ROLE_2" + }, + { + "name": "REALM_ROLE_3" + }, + { + "name": "REALM_COMPOSITE_1", + "composites": { + "realm": ["REALM_ROLE_1"] + } + }, + { + "name": "REALM_APP_COMPOSITE_ROLE", + "composites": { + "application": { + "APP_ROLE_APPLICATION" :[ + "APP_ROLE_1" + ] + } + } + } + ], + "application" : { + "APP_ROLE_APPLICATION" : [ + { + "name": "APP_ROLE_1" + }, + { + "name": "APP_ROLE_2" + } + ], + "APP_COMPOSITE_APPLICATION" : [ + { + "name": "APP_COMPOSITE_ROLE", + "composites": { + "realm" : [ + "REALM_ROLE_1", + "REALM_ROLE_2", + "REALM_ROLE_3" + ], + "application": { + "APP_ROLE_APPLICATION" :[ + "APP_ROLE_1" + ] + } + } + }, + { + "name": "APP_ROLE_2" + } + ] + } + + }, + + "applicationRoleMappings": { + "APP_ROLE_APPLICATION": [ + { + "username": "REALM_APP_ROLE_USER", + "roles": ["APP_ROLE_2"] + } + ] + }, + "applicationScopeMappings": { + "APP_ROLE_APPLICATION": [ + { + "client": "APP_COMPOSITE_APPLICATION", + "roles": ["APP_ROLE_2"] + } + ] + } } \ No newline at end of file diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java index f5b7cb0bc0..501a725c13 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java @@ -1,6 +1,7 @@ package org.keycloak.services.resources.admin; import org.jboss.resteasy.annotations.cache.NoCache; +import org.jboss.resteasy.logging.Logger; import org.keycloak.models.ApplicationModel; import org.keycloak.models.Constants; import org.keycloak.models.OAuthClientModel; @@ -28,6 +29,7 @@ import java.util.Set; * @version $Revision: 1 $ */ public class RoleByIdResource extends RoleResource { + protected static final Logger logger = Logger.getLogger(RoleByIdResource.class); private final RealmModel realm; private final RealmAuth auth; @@ -101,6 +103,8 @@ public class RoleByIdResource extends RoleResource { @NoCache @Produces("application/json") public Set getRoleComposites(final @PathParam("role-id") String id) { + + logger.info("*** getRoleComposites: '" + id + "'"); RoleModel role = getRoleModel(id); auth.requireView(); return getRoleComposites(role); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java index 94d95af59b..5eb952fc2e 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleResource.java @@ -28,7 +28,7 @@ public abstract class RoleResource { } protected void deleteRole(RoleModel role) { - if (!role.getContainer().removeRoleById(role.getId())) { + if (!role.getContainer().removeRole(role)) { throw new NotFoundException(); } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java index c6f9b03ff9..6e7dbe4b65 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java @@ -173,7 +173,7 @@ public class ScopeMappedResource { } for (RoleRepresentation role : roles) { - RoleModel roleModel = app.getRoleById(role.getId()); + RoleModel roleModel = app.getRole(role.getName()); if (roleModel == null) { throw new NotFoundException(); } @@ -202,7 +202,7 @@ public class ScopeMappedResource { } else { for (RoleRepresentation role : roles) { - RoleModel roleModel = app.getRoleById(role.getId()); + RoleModel roleModel = app.getRole(role.getName()); if (roleModel == null) { throw new NotFoundException(); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java index 6b07988c0d..29b73748cc 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java @@ -281,8 +281,8 @@ public class UsersResource { } for (RoleRepresentation role : roles) { - RoleModel roleModel = realm.getRoleById(role.getId()); - if (roleModel == null) { + RoleModel roleModel = realm.getRole(role.getName()); + if (roleModel == null || !roleModel.getId().equals(role.getId())) { throw new NotFoundException(); } realm.grantRole(user, roleModel); @@ -311,8 +311,8 @@ public class UsersResource { } else { for (RoleRepresentation role : roles) { - RoleModel roleModel = realm.getRoleById(role.getId()); - if (roleModel == null) { + RoleModel roleModel = realm.getRole(role.getName()); + if (roleModel == null || !roleModel.getId().equals(role.getId())) { throw new NotFoundException(); } realm.deleteRoleMapping(user, roleModel); @@ -368,8 +368,8 @@ public class UsersResource { } for (RoleRepresentation role : roles) { - RoleModel roleModel = application.getRoleById(role.getId()); - if (roleModel == null) { + RoleModel roleModel = application.getRole(role.getName()); + if (roleModel == null || !roleModel.getId().equals(role.getId())) { throw new NotFoundException(); } realm.grantRole(user, roleModel); @@ -406,8 +406,8 @@ public class UsersResource { } else { for (RoleRepresentation role : roles) { - RoleModel roleModel = application.getRoleById(role.getId()); - if (roleModel == null) { + RoleModel roleModel = application.getRole(role.getName()); + if (roleModel == null || !roleModel.getId().equals(role.getId())) { throw new NotFoundException(); } realm.deleteRoleMapping(user, roleModel);