From bb5991239b2add5ba589346667ac3213a2f45018 Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Wed, 29 Jan 2014 20:19:32 -0500 Subject: [PATCH] composite roles --- .../idm/RoleRepresentation.java | 9 + .../org/keycloak/models/ApplicationModel.java | 9 +- .../java/org/keycloak/models/RealmModel.java | 4 + .../org/keycloak/models/RoleMapperModel.java | 9 +- .../java/org/keycloak/models/RoleModel.java | 16 ++ .../org/keycloak/models/ScopeMapperModel.java | 8 +- .../keycloak/models/UserCredentialModel.java | 11 + .../models/jpa/ApplicationAdapter.java | 206 +++++---------- .../org/keycloak/models/jpa/RealmAdapter.java | 245 ++++++++++-------- .../org/keycloak/models/jpa/RoleAdapter.java | 82 +++++- .../entities/AbstractRoleMappingEntity.java | 46 ++++ .../jpa/entities/ApplicationEntity.java | 9 +- ...Entity.java => ApplicationRoleEntity.java} | 10 +- .../ApplicationUserRoleMappingEntity.java | 29 --- .../models/jpa/entities/RealmEntity.java | 13 +- ...appingEntity.java => RealmRoleEntity.java} | 8 +- .../entities/RealmUserRoleMappingEntity.java | 29 --- .../models/jpa/entities/RoleEntity.java | 47 +++- .../jpa/entities/UserRoleMappingEntity.java | 41 +-- .../jpa/entities/UserScopeMappingEntity.java | 18 ++ model/pom.xml | 2 +- services/pom.xml | 2 + .../services/managers/ApplianceBootstrap.java | 4 +- .../services/managers/ApplicationManager.java | 11 +- .../managers/AuthenticationManager.java | 10 +- .../managers/ModelToRepresentation.java | 112 ++++++++ .../services/managers/RealmManager.java | 91 +------ .../services/managers/TokenManager.java | 129 +++++---- .../services/resources/AccountService.java | 8 +- .../resources/admin/AdminService.java | 5 +- .../resources/admin/RealmAdminResource.java | 3 +- .../resources/admin/RealmsAdminResource.java | 3 +- .../admin/RoleContainerResource.java | 70 ++++- .../resources/admin/ScopeMappedResource.java | 30 ++- .../resources/admin/UsersResource.java | 38 +-- .../java/org/keycloak/test/AdapterTest.java | 16 +- .../java/org/keycloak/test/ImportTest.java | 8 +- .../java/org/keycloak/test/ModelTest.java | 3 +- .../test/resources/META-INF/persistence.xml | 10 +- testsuite/integration/pom.xml | 2 + .../main/resources/META-INF/persistence.xml | 10 +- .../org/keycloak/testsuite/OAuthClient.java | 4 + .../testsuite/account/ProfileTest.java | 6 +- .../composites/CompositeRoleTest.java | 157 +++++++++++ .../keycloak/testsuite/forms/AccountTest.java | 2 +- .../testsuite/rule/AbstractKeycloakRule.java | 84 ++++++ .../keycloak/testsuite/rule/KeycloakRule.java | 43 +-- .../test/resources/META-INF/persistence.xml | 10 +- 48 files changed, 1070 insertions(+), 652 deletions(-) create mode 100755 model/jpa/src/main/java/org/keycloak/models/jpa/entities/AbstractRoleMappingEntity.java rename model/jpa/src/main/java/org/keycloak/models/jpa/entities/{ApplicationScopeMappingEntity.java => ApplicationRoleEntity.java} (51%) delete mode 100755 model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationUserRoleMappingEntity.java rename model/jpa/src/main/java/org/keycloak/models/jpa/entities/{RealmScopeMappingEntity.java => RealmRoleEntity.java} (54%) delete mode 100755 model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmUserRoleMappingEntity.java create mode 100755 model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserScopeMappingEntity.java create mode 100755 services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java create mode 100755 testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java create mode 100755 testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java diff --git a/core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java index 4a1610197a..59119a6094 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java @@ -8,6 +8,7 @@ public class RoleRepresentation { protected String id; protected String name; protected String description; + protected boolean composite; public RoleRepresentation() { } @@ -40,4 +41,12 @@ public class RoleRepresentation { public void setDescription(String description) { this.description = description; } + + public boolean isComposite() { + return composite; + } + + public void setComposite(boolean composite) { + this.composite = composite; + } } diff --git a/model/api/src/main/java/org/keycloak/models/ApplicationModel.java b/model/api/src/main/java/org/keycloak/models/ApplicationModel.java index e5374b8280..46576448c9 100755 --- a/model/api/src/main/java/org/keycloak/models/ApplicationModel.java +++ b/model/api/src/main/java/org/keycloak/models/ApplicationModel.java @@ -1,12 +1,13 @@ package org.keycloak.models; import java.util.List; +import java.util.Set; /** * @author Bill Burke * @version $Revision: 1 $ */ -public interface ApplicationModel extends RoleContainerModel, RoleMapperModel, ScopeMapperModel { +public interface ApplicationModel extends RoleContainerModel { void updateApplication(); UserModel getApplicationUser(); @@ -38,4 +39,10 @@ public interface ApplicationModel extends RoleContainerModel, RoleMapperModel, S void addDefaultRole(String name); void updateDefaultRoles(String[] defaultRoles); + + Set getApplicationRoleMappings(UserModel user); + + Set getApplicationScopeMappings(UserModel user); + + void addScope(RoleModel role); } 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 184e6aafa7..ac75c7a542 100755 --- a/model/api/src/main/java/org/keycloak/models/RealmModel.java +++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java @@ -157,4 +157,8 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa Map getSocialConfig(); void setSocialConfig(Map socialConfig); + + Set getRealmRoleMappings(UserModel user); + + Set getRealmScopeMappings(UserModel user); } diff --git a/model/api/src/main/java/org/keycloak/models/RoleMapperModel.java b/model/api/src/main/java/org/keycloak/models/RoleMapperModel.java index a9a9938a88..3c74451158 100755 --- a/model/api/src/main/java/org/keycloak/models/RoleMapperModel.java +++ b/model/api/src/main/java/org/keycloak/models/RoleMapperModel.java @@ -9,14 +9,7 @@ import java.util.Set; */ public interface RoleMapperModel { boolean hasRole(UserModel user, RoleModel role); - void grantRole(UserModel user, RoleModel role); - - Set getRoleMappingValues(UserModel user); - - List getRoleMappings(UserModel user); - + Set getRoleMappings(UserModel user); void deleteRoleMapping(UserModel user, RoleModel role); - - boolean hasRole(UserModel user, String role); } diff --git a/model/api/src/main/java/org/keycloak/models/RoleModel.java b/model/api/src/main/java/org/keycloak/models/RoleModel.java index a8e8ebe195..c2a9507cee 100755 --- a/model/api/src/main/java/org/keycloak/models/RoleModel.java +++ b/model/api/src/main/java/org/keycloak/models/RoleModel.java @@ -1,5 +1,7 @@ package org.keycloak.models; +import java.util.Set; + /** * @author Bill Burke * @version $Revision: 1 $ @@ -14,4 +16,18 @@ public interface RoleModel { String getId(); void setName(String name); + + boolean isComposite(); + + void setComposite(boolean flag); + + void addCompositeRole(RoleModel role); + + void removeCompositeRole(RoleModel role); + + Set getComposites(); + + RoleContainerModel getContainer(); + + } diff --git a/model/api/src/main/java/org/keycloak/models/ScopeMapperModel.java b/model/api/src/main/java/org/keycloak/models/ScopeMapperModel.java index a94ac8d68f..d67529097a 100755 --- a/model/api/src/main/java/org/keycloak/models/ScopeMapperModel.java +++ b/model/api/src/main/java/org/keycloak/models/ScopeMapperModel.java @@ -8,13 +8,7 @@ import java.util.Set; * @version $Revision: 1 $ */ public interface ScopeMapperModel { - void addScopeMapping(UserModel agent, String roleName); - - Set getScopeMappingValues(UserModel agent); - - List getScopeMappings(UserModel agent); - + Set getScopeMappings(UserModel agent); void addScopeMapping(UserModel agent, RoleModel role); - void deleteScopeMapping(UserModel user, RoleModel role); } 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 a20450cf69..410ae877b8 100755 --- a/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java +++ b/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java @@ -13,6 +13,17 @@ public class UserCredentialModel { 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 String getType() { return type; } 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 356fc0c12b..6f46042ee0 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 @@ -1,16 +1,22 @@ package org.keycloak.models.jpa; import org.keycloak.models.ApplicationModel; +import org.keycloak.models.RealmModel; +import org.keycloak.models.RoleContainerModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserModel; import org.keycloak.models.jpa.entities.*; +import org.keycloak.representations.idm.ApplicationMappingsRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -21,8 +27,10 @@ public class ApplicationAdapter implements ApplicationModel { protected EntityManager em; protected ApplicationEntity application; + protected RealmModel realm; - public ApplicationAdapter(EntityManager em, ApplicationEntity application) { + public ApplicationAdapter(RealmModel realm, EntityManager em, ApplicationEntity application) { + this.realm = realm; this.em = em; this.application = application; } @@ -94,31 +102,30 @@ public class ApplicationAdapter implements ApplicationModel { @Override public RoleModel getRole(String name) { - Collection roles = application.getRoles(); - if (roles == null) return null; - for (RoleEntity role : roles) { - if (role.getName().equals(name)) { - return new RoleAdapter(role); - } - } - return null; + TypedQuery query = em.createNamedQuery("getAppRoleByName", ApplicationRoleEntity.class); + query.setParameter("name", name); + query.setParameter("application", application); + List roles = query.getResultList(); + if (roles.size() == 0) return null; + return new RoleAdapter(realm, em, roles.get(0)); } @Override public RoleModel addRole(String name) { RoleModel role = getRole(name); if (role != null) return role; - RoleEntity entity = new RoleEntity(); + ApplicationRoleEntity entity = new ApplicationRoleEntity(); entity.setName(name); + entity.setApplication(application); em.persist(entity); application.getRoles().add(entity); em.flush(); - return new RoleAdapter(entity); + return new RoleAdapter(realm, em, entity); } @Override public boolean removeRoleById(String id) { - RoleEntity role = em.find(RoleEntity.class, id); + ApplicationRoleEntity role = em.find(ApplicationRoleEntity.class, id); if (role == null) { return false; } @@ -126,11 +133,10 @@ public class ApplicationAdapter implements ApplicationModel { application.getRoles().remove(role); application.getDefaultRoles().remove(role); - em.createQuery("delete from " + ApplicationScopeMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate(); - em.createQuery("delete from " + ApplicationUserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate(); - em.createQuery("delete from " + RealmScopeMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate(); - em.createQuery("delete from " + RealmUserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate(); - + em.createQuery("delete from " + UserScopeMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate(); + em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate(); + role.setApplication(null); + em.flush(); em.remove(role); return true; @@ -139,156 +145,59 @@ public class ApplicationAdapter implements ApplicationModel { @Override public List getRoles() { ArrayList list = new ArrayList(); - Collection roles = application.getRoles(); + Collection roles = application.getRoles(); if (roles == null) return list; for (RoleEntity entity : roles) { - list.add(new RoleAdapter(entity)); + list.add(new RoleAdapter(realm, em, entity)); } return list; } @Override public RoleModel getRoleById(String id) { - RoleEntity entity = em.find(RoleEntity.class, id); - if (entity == null) return null; - return new RoleAdapter(entity); + return realm.getRoleById(id); } @Override - public boolean hasRole(UserModel user, RoleModel role) { - TypedQuery query = getApplicationUserRoleMappingEntityTypedQuery((UserAdapter) user, (RoleAdapter) role); - return query.getResultList().size() > 0; - } + public Set getApplicationRoleMappings(UserModel user) { + Set roleMappings = realm.getRoleMappings(user); - protected TypedQuery getApplicationUserRoleMappingEntityTypedQuery(UserAdapter user, RoleAdapter role) { - TypedQuery query = em.createNamedQuery("userHasApplicationRole", ApplicationUserRoleMappingEntity.class); - query.setParameter("user", ((UserAdapter)user).getUser()); - query.setParameter("role", ((RoleAdapter)role).getRole()); - query.setParameter("application", application); - return query; - } - - @Override - public void grantRole(UserModel user, RoleModel role) { - if (hasRole(user, role)) return; - ApplicationUserRoleMappingEntity entity = new ApplicationUserRoleMappingEntity(); - entity.setApplication(application); - entity.setUser(((UserAdapter) user).getUser()); - entity.setRole(((RoleAdapter)role).getRole()); - em.persist(entity); - em.flush(); - } - - @Override - public List getRoleMappings(UserModel user) { - TypedQuery query = em.createNamedQuery("userApplicationMappings", ApplicationUserRoleMappingEntity.class); - query.setParameter("user", ((UserAdapter)user).getUser()); - query.setParameter("application", application); - List entities = query.getResultList(); - List roles = new ArrayList(); - for (ApplicationUserRoleMappingEntity entity : entities) { - roles.add(new RoleAdapter(entity.getRole())); + Set appRoles = new HashSet(); + for (RoleModel role : roleMappings) { + RoleContainerModel container = role.getContainer(); + if (container instanceof RealmModel) { + } else { + ApplicationModel app = (ApplicationModel)container; + if (app.getId().equals(getId())) { + appRoles.add(role); + } + } } - return roles; + + return appRoles; } @Override - public Set getRoleMappingValues(UserModel user) { - TypedQuery query = em.createNamedQuery("userApplicationMappings", ApplicationUserRoleMappingEntity.class); - query.setParameter("user", ((UserAdapter)user).getUser()); - query.setParameter("application", application); - List entities = query.getResultList(); - Set roles = new HashSet(); - for (ApplicationUserRoleMappingEntity entity : entities) { - roles.add(entity.getRole().getName()); + public Set getApplicationScopeMappings(UserModel user) { + Set roleMappings = realm.getScopeMappings(user); + + Set appRoles = new HashSet(); + for (RoleModel role : roleMappings) { + RoleContainerModel container = role.getContainer(); + if (container instanceof RealmModel) { + } else { + ApplicationModel app = (ApplicationModel)container; + if (app.getId().equals(getId())) { + appRoles.add(role); + } + } } - return roles; - } - @Override - public void deleteRoleMapping(UserModel user, RoleModel role) { - TypedQuery query = getApplicationUserRoleMappingEntityTypedQuery((UserAdapter) user, (RoleAdapter) role); - List results = query.getResultList(); - if (results.size() == 0) return; - for (ApplicationUserRoleMappingEntity entity : results) { - em.remove(entity); - } - } - - @Override - public boolean hasRole(UserModel user, String roleName) { - RoleModel role = getRole(roleName); - if (role == null) return false; - return hasRole(user, role); - } - - @Override - public void addScopeMapping(UserModel agent, String roleName) { - RoleModel role = getRole(roleName); - if (role == null) throw new RuntimeException("role does not exist"); - addScopeMapping(agent, role); - } - - @Override - public Set getScopeMappingValues(UserModel agent) { - TypedQuery query = em.createNamedQuery("userApplicationScopeMappings", ApplicationScopeMappingEntity.class); - query.setParameter("user", ((UserAdapter)agent).getUser()); - query.setParameter("application", application); - List entities = query.getResultList(); - Set roles = new HashSet(); - for (ApplicationScopeMappingEntity entity : entities) { - roles.add(entity.getRole().getName()); - } - return roles; - } - - @Override - public List getScopeMappings(UserModel agent) { - TypedQuery query = em.createNamedQuery("userApplicationScopeMappings", ApplicationScopeMappingEntity.class); - query.setParameter("user", ((UserAdapter)agent).getUser()); - query.setParameter("application", application); - List entities = query.getResultList(); - List roles = new ArrayList(); - for (ApplicationScopeMappingEntity entity : entities) { - roles.add(new RoleAdapter(entity.getRole())); - } - return roles; - } - - @Override - public void addScopeMapping(UserModel agent, RoleModel role) { - if (hasScope(agent, role)) return; - ApplicationScopeMappingEntity entity = new ApplicationScopeMappingEntity(); - entity.setApplication(application); - entity.setUser(((UserAdapter) agent).getUser()); - entity.setRole(((RoleAdapter)role).getRole()); - em.persist(entity); - em.flush(); - } - - @Override - public void deleteScopeMapping(UserModel user, RoleModel role) { - TypedQuery query = getApplicationScopeMappingQuery((UserAdapter) user, (RoleAdapter) role); - List results = query.getResultList(); - if (results.size() == 0) return; - for (ApplicationScopeMappingEntity entity : results) { - em.remove(entity); - } - } - - public boolean hasScope(UserModel user, RoleModel role) { - TypedQuery query = getApplicationScopeMappingQuery((UserAdapter) user, (RoleAdapter) role); - return query.getResultList().size() > 0; + return appRoles; } - protected TypedQuery getApplicationScopeMappingQuery(UserAdapter user, RoleAdapter role) { - TypedQuery query = em.createNamedQuery("userHasApplicationScope", ApplicationScopeMappingEntity.class); - query.setParameter("user", ((UserAdapter)user).getUser()); - query.setParameter("role", ((RoleAdapter)role).getRole()); - query.setParameter("application", application); - return query; - } + @Override public List getDefaultRoles() { @@ -347,4 +256,9 @@ public class ApplicationAdapter implements ApplicationModel { } em.flush(); } + + @Override + public void addScope(RoleModel role) { + realm.addScopeMapping(getApplicationUser(), role); + } } 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 25352ca44c..a627a84fee 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 @@ -1,6 +1,18 @@ package org.keycloak.models.jpa; import org.bouncycastle.openssl.PEMWriter; +import org.keycloak.models.RoleContainerModel; +import org.keycloak.models.jpa.entities.ApplicationEntity; +import org.keycloak.models.jpa.entities.CredentialEntity; +import org.keycloak.models.jpa.entities.OAuthClientEntity; +import org.keycloak.models.jpa.entities.RealmEntity; +import org.keycloak.models.jpa.entities.RealmRoleEntity; +import org.keycloak.models.jpa.entities.RequiredCredentialEntity; +import org.keycloak.models.jpa.entities.RoleEntity; +import org.keycloak.models.jpa.entities.SocialLinkEntity; +import org.keycloak.models.jpa.entities.UserEntity; +import org.keycloak.models.jpa.entities.UserRoleMappingEntity; +import org.keycloak.models.jpa.entities.UserScopeMappingEntity; import org.keycloak.models.utils.Pbkdf2PasswordEncoder; import org.keycloak.util.PemUtils; import org.keycloak.models.ApplicationModel; @@ -12,7 +24,6 @@ import org.keycloak.models.RoleModel; import org.keycloak.models.SocialLinkModel; import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserModel; -import org.keycloak.models.jpa.entities.*; import org.keycloak.models.utils.TimeBasedOTP; import javax.persistence.EntityManager; @@ -25,6 +36,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -453,7 +465,7 @@ public class RealmAdapter implements RealmModel { for (ApplicationModel application : getApplications()) { for (String r : application.getDefaultRoles()) { - application.grantRole(userModel, application.getRole(r)); + grantRole(userModel, application.getRole(r)); } } @@ -472,10 +484,8 @@ public class RealmAdapter implements RealmModel { } private void removeUser(UserEntity user) { - em.createQuery("delete from " + ApplicationScopeMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate(); - em.createQuery("delete from " + ApplicationUserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate(); - em.createQuery("delete from " + RealmScopeMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate(); - em.createQuery("delete from " + RealmUserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate(); + em.createQuery("delete from " + UserScopeMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate(); + em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate(); em.createQuery("delete from " + SocialLinkEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate(); em.remove(user); } @@ -552,7 +562,7 @@ public class RealmAdapter implements RealmModel { List list = new ArrayList(); if (realm.getApplications() == null) return list; for (ApplicationEntity entity : realm.getApplications()) { - list.add(new ApplicationAdapter(em, entity)); + list.add(new ApplicationAdapter(this, em, entity)); } return list; } @@ -571,31 +581,41 @@ public class RealmAdapter implements RealmModel { realm.getApplications().add(applicationData); em.persist(applicationData); em.flush(); - ApplicationModel resource = new ApplicationAdapter(em, applicationData); + ApplicationModel resource = new ApplicationAdapter(this, em, applicationData); em.flush(); return resource; } @Override public boolean removeApplication(String id) { - ApplicationEntity application = null; + if (id == null) return false; + ApplicationModel application = getApplicationById(id); + if (application == null) return false; + + for (RoleModel role : application.getRoles()) { + application.removeRoleById(role.getId()); + } + + ApplicationEntity applicationEntity = null; + Iterator it = realm.getApplications().iterator(); + while (it.hasNext()) { + ApplicationEntity ae = it.next(); + if (ae.getId().equals(id)) { + applicationEntity = ae; + it.remove(); + break; + } + } for (ApplicationEntity a : realm.getApplications()) { if (a.getId().equals(id)) { - application = a; + applicationEntity = a; } } if (application == null) { return false; } - realm.getApplications().remove(application); - em.createQuery("delete from " + ApplicationScopeMappingEntity.class.getSimpleName() + " where application = :application").setParameter("application", application).executeUpdate(); - em.createQuery("delete from " + ApplicationUserRoleMappingEntity.class.getSimpleName() + " where application = :application").setParameter("application", application).executeUpdate(); - em.createQuery("delete from " + ApplicationScopeMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", application.getApplicationUser()).executeUpdate(); - em.createQuery("delete from " + RealmScopeMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", application.getApplicationUser()).executeUpdate(); - em.createQuery("delete from " + ApplicationUserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", application.getApplicationUser()).executeUpdate(); - em.createQuery("delete from " + RealmUserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", application.getApplicationUser()).executeUpdate(); - removeUser(application.getApplicationUser()); - em.remove(application); + em.remove(applicationEntity); + removeUser(applicationEntity.getApplicationUser()); return true; } @@ -603,7 +623,7 @@ public class RealmAdapter implements RealmModel { public ApplicationModel getApplicationById(String id) { ApplicationEntity app = em.find(ApplicationEntity.class, id); if (app == null) return null; - return new ApplicationAdapter(em, app); + return new ApplicationAdapter(this, em, app); } @Override @@ -758,10 +778,8 @@ public class RealmAdapter implements RealmModel { @Override public boolean removeOAuthClient(String id) { OAuthClientEntity client = em.find(OAuthClientEntity.class, id); - em.createQuery("delete from " + ApplicationScopeMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", client.getAgent()).executeUpdate(); - em.createQuery("delete from " + RealmScopeMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", client.getAgent()).executeUpdate(); - em.createQuery("delete from " + ApplicationUserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", client.getAgent()).executeUpdate(); - em.createQuery("delete from " + RealmUserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", client.getAgent()).executeUpdate(); + em.createQuery("delete from " + UserScopeMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", client.getAgent()).executeUpdate(); + em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", client.getAgent()).executeUpdate(); removeUser(client.getAgent()); em.remove(client); return true; @@ -820,44 +838,43 @@ public class RealmAdapter implements RealmModel { @Override public RoleModel getRole(String name) { - Collection roles = realm.getRoles(); - if (roles == null) return null; - for (RoleEntity role : roles) { - if (role.getName().equals(name)) { - return new RoleAdapter(role); - } - } - return null; //To change body of implemented methods use File | Settings | File Templates. + TypedQuery query = em.createNamedQuery("getRealmRoleByName", RealmRoleEntity.class); + query.setParameter("name", name); + query.setParameter("realm", realm); + List roles = query.getResultList(); + if (roles.size() == 0) return null; + return new RoleAdapter(this, em, roles.get(0)); } @Override public RoleModel addRole(String name) { RoleModel role = getRole(name); if (role != null) return role; - RoleEntity entity = new RoleEntity(); + RealmRoleEntity entity = new RealmRoleEntity(); entity.setName(name); - em.persist(entity); + entity.setRealm(realm); realm.getRoles().add(entity); + em.persist(entity); em.flush(); - return new RoleAdapter(entity); + return new RoleAdapter(this, em, entity); } @Override public boolean removeRoleById(String id) { - RoleEntity role = em.find(RoleEntity.class, id); + RoleModel role = getRoleById(id); + if (role == null) return false; + if (role == null) { return false; } - + RoleEntity roleEntity = ((RoleAdapter)role).getRole(); realm.getRoles().remove(role); realm.getDefaultRoles().remove(role); - em.createQuery("delete from " + ApplicationScopeMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate(); - em.createQuery("delete from " + ApplicationUserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate(); - em.createQuery("delete from " + RealmScopeMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate(); - em.createQuery("delete from " + RealmUserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate(); + em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", roleEntity).executeUpdate(); + em.createQuery("delete from " + UserScopeMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", roleEntity).executeUpdate(); - em.remove(role); + em.remove(roleEntity); return true; } @@ -865,10 +882,10 @@ public class RealmAdapter implements RealmModel { @Override public List getRoles() { ArrayList list = new ArrayList(); - Collection roles = realm.getRoles(); + Collection roles = realm.getRoles(); if (roles == null) return list; for (RoleEntity entity : roles) { - list.add(new RoleAdapter(entity)); + list.add(new RoleAdapter(this, em, entity)); } return list; } @@ -877,28 +894,46 @@ public class RealmAdapter implements RealmModel { public RoleModel getRoleById(String id) { RoleEntity entity = em.find(RoleEntity.class, id); if (entity == null) return null; - return new RoleAdapter(entity); + return new RoleAdapter(this, em, entity); + } + + protected boolean searchCompositeFor(RoleModel role, RoleModel composite, Set visited) { + if (visited.contains(composite)) return false; + visited.add(composite); + Set composites = composite.getComposites(); + if (composites.contains(role)) return true; + for (RoleModel contained : composites) { + if (!contained.isComposite()) continue; + if (searchCompositeFor(role, contained, visited)) return true; + } + return false; } @Override public boolean hasRole(UserModel user, RoleModel role) { - TypedQuery query = getRealmUserRoleMappingEntityTypedQuery((UserAdapter) user, (RoleAdapter) role); - return query.getResultList().size() > 0; + Set roles = getRoleMappings(user); + if (roles.contains(role)) return true; + + Set visited = new HashSet(); + for (RoleModel mapping : roles) { + if (!mapping.isComposite()) continue; + if (searchCompositeFor(role, mapping, visited)) return true; + + } + return false; } - protected TypedQuery getRealmUserRoleMappingEntityTypedQuery(UserAdapter user, RoleAdapter role) { - TypedQuery query = em.createNamedQuery("userHasRealmRole", RealmUserRoleMappingEntity.class); + protected TypedQuery getUserRoleMappingEntityTypedQuery(UserAdapter user, RoleAdapter role) { + TypedQuery query = em.createNamedQuery("userHasRole", UserRoleMappingEntity.class); query.setParameter("user", ((UserAdapter)user).getUser()); - query.setParameter("role", ((RoleAdapter)role).getRole()); - query.setParameter("realm", realm); + query.setParameter("role", ((RoleAdapter) role).getRole()); return query; } @Override public void grantRole(UserModel user, RoleModel role) { if (hasRole(user, role)) return; - RealmUserRoleMappingEntity entity = new RealmUserRoleMappingEntity(); - entity.setRealm(realm); + UserRoleMappingEntity entity = new UserRoleMappingEntity(); entity.setUser(((UserAdapter) user).getUser()); entity.setRole(((RoleAdapter)role).getRole()); em.persist(entity); @@ -906,79 +941,69 @@ public class RealmAdapter implements RealmModel { } @Override - public List getRoleMappings(UserModel user) { - TypedQuery query = em.createNamedQuery("userRealmMappings", RealmUserRoleMappingEntity.class); - query.setParameter("user", ((UserAdapter)user).getUser()); - query.setParameter("realm", realm); - List entities = query.getResultList(); - List roles = new ArrayList(); - for (RealmUserRoleMappingEntity entity : entities) { - roles.add(new RoleAdapter(entity.getRole())); + public Set getRealmRoleMappings(UserModel user) { + Set roleMappings = getRoleMappings(user); + + Set realmRoles = new HashSet(); + for (RoleModel role : roleMappings) { + RoleContainerModel container = role.getContainer(); + if (container instanceof RealmModel) { + realmRoles.add(role); + } } - return roles; + return realmRoles; } + @Override - public Set getRoleMappingValues(UserModel user) { - TypedQuery query = em.createNamedQuery("userRealmMappings", RealmUserRoleMappingEntity.class); + public Set getRoleMappings(UserModel user) { + TypedQuery query = em.createNamedQuery("userRoleMappings", UserRoleMappingEntity.class); query.setParameter("user", ((UserAdapter)user).getUser()); - query.setParameter("realm", realm); - List entities = query.getResultList(); - Set roles = new HashSet(); - for (RealmUserRoleMappingEntity entity : entities) { - roles.add(entity.getRole().getName()); + List entities = query.getResultList(); + Set roles = new HashSet(); + for (UserRoleMappingEntity entity : entities) { + roles.add(new RoleAdapter(this, em, entity.getRole())); } return roles; } @Override public void deleteRoleMapping(UserModel user, RoleModel role) { - TypedQuery query = getRealmUserRoleMappingEntityTypedQuery((UserAdapter) user, (RoleAdapter) role); - List results = query.getResultList(); + TypedQuery query = getUserRoleMappingEntityTypedQuery((UserAdapter) user, (RoleAdapter) role); + List results = query.getResultList(); if (results.size() == 0) return; - for (RealmUserRoleMappingEntity entity : results) { + for (UserRoleMappingEntity entity : results) { em.remove(entity); } em.flush(); } @Override - public boolean hasRole(UserModel user, String roleName) { - RoleModel role = getRole(roleName); - if (role == null) return false; - return hasRole(user, role); - } + public Set getRealmScopeMappings(UserModel user) { + Set roleMappings = getScopeMappings(user); - @Override - public void addScopeMapping(UserModel agent, String roleName) { - RoleModel role = getRole(roleName); - if (role == null) throw new RuntimeException("role does not exist"); - addScopeMapping(agent, role); - em.flush(); - } - - @Override - public Set getScopeMappingValues(UserModel agent) { - TypedQuery query = em.createNamedQuery("userRealmScopeMappings", RealmScopeMappingEntity.class); - query.setParameter("user", ((UserAdapter)agent).getUser()); - query.setParameter("realm", realm); - List entities = query.getResultList(); - Set roles = new HashSet(); - for (RealmScopeMappingEntity entity : entities) { - roles.add(entity.getRole().getName()); + Set appRoles = new HashSet(); + for (RoleModel role : roleMappings) { + RoleContainerModel container = role.getContainer(); + if (container instanceof RealmModel) { + if (((RealmModel)container).getId().equals(getId())) { + appRoles.add(role); + } + } } - return roles; + + return appRoles; } + @Override - public List getScopeMappings(UserModel agent) { - TypedQuery query = em.createNamedQuery("userRealmScopeMappings", RealmScopeMappingEntity.class); + public Set getScopeMappings(UserModel agent) { + TypedQuery query = em.createNamedQuery("userScopeMappings", UserScopeMappingEntity.class); query.setParameter("user", ((UserAdapter)agent).getUser()); - query.setParameter("realm", realm); - List entities = query.getResultList(); - List roles = new ArrayList(); - for (RealmScopeMappingEntity entity : entities) { - roles.add(new RoleAdapter(entity.getRole())); + List entities = query.getResultList(); + Set roles = new HashSet(); + for (UserScopeMappingEntity entity : entities) { + roles.add(new RoleAdapter(this, em, entity.getRole())); } return roles; } @@ -986,8 +1011,7 @@ public class RealmAdapter implements RealmModel { @Override public void addScopeMapping(UserModel agent, RoleModel role) { if (hasScope(agent, role)) return; - RealmScopeMappingEntity entity = new RealmScopeMappingEntity(); - entity.setRealm(realm); + UserScopeMappingEntity entity = new UserScopeMappingEntity(); entity.setUser(((UserAdapter) agent).getUser()); entity.setRole(((RoleAdapter)role).getRole()); em.persist(entity); @@ -996,25 +1020,24 @@ public class RealmAdapter implements RealmModel { @Override public void deleteScopeMapping(UserModel user, RoleModel role) { - TypedQuery query = getRealmScopeMappingQuery((UserAdapter) user, (RoleAdapter) role); - List results = query.getResultList(); + TypedQuery query = getRealmScopeMappingQuery((UserAdapter) user, (RoleAdapter) role); + List results = query.getResultList(); if (results.size() == 0) return; - for (RealmScopeMappingEntity entity : results) { + for (UserScopeMappingEntity entity : results) { em.remove(entity); } } public boolean hasScope(UserModel user, RoleModel role) { - TypedQuery query = getRealmScopeMappingQuery((UserAdapter) user, (RoleAdapter) role); + TypedQuery query = getRealmScopeMappingQuery((UserAdapter) user, (RoleAdapter) role); return query.getResultList().size() > 0; } - protected TypedQuery getRealmScopeMappingQuery(UserAdapter user, RoleAdapter role) { - TypedQuery query = em.createNamedQuery("userHasRealmScope", RealmScopeMappingEntity.class); + protected TypedQuery getRealmScopeMappingQuery(UserAdapter user, RoleAdapter role) { + TypedQuery query = em.createNamedQuery("userHasScope", UserScopeMappingEntity.class); query.setParameter("user", ((UserAdapter)user).getUser()); query.setParameter("role", ((RoleAdapter)role).getRole()); - query.setParameter("realm", realm); return query; } 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 5785dec672..87c09d0b4c 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 @@ -1,16 +1,28 @@ package org.keycloak.models.jpa; +import org.keycloak.models.RealmModel; +import org.keycloak.models.RoleContainerModel; import org.keycloak.models.RoleModel; +import org.keycloak.models.jpa.entities.ApplicationRoleEntity; +import org.keycloak.models.jpa.entities.RealmRoleEntity; import org.keycloak.models.jpa.entities.RoleEntity; +import javax.persistence.EntityManager; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + /** * @author Bill Burke * @version $Revision: 1 $ */ public class RoleAdapter implements RoleModel { protected RoleEntity role; + protected EntityManager em; + protected RealmModel realm; - public RoleAdapter(RoleEntity role) { + public RoleAdapter(RealmModel realm, EntityManager em, RoleEntity role) { + this.realm = realm; this.role = role; } @@ -46,4 +58,72 @@ public class RoleAdapter implements RoleModel { public void setName(String name) { role.setName(name); } + + @Override + public boolean isComposite() { + return role.isComposite(); + } + + @Override + public void setComposite(boolean flag) { + role.setComposite(flag); + } + + @Override + public void addCompositeRole(RoleModel role) { + RoleEntity entity = ((RoleAdapter)role).getRole(); + for (RoleEntity composite : getRole().getCompositeRoles()) { + if (composite.equals(entity)) return; + } + getRole().getCompositeRoles().add(entity); + } + + @Override + public void removeCompositeRole(RoleModel role) { + RoleEntity entity = ((RoleAdapter)role).getRole(); + Iterator it = getRole().getCompositeRoles().iterator(); + while (it.hasNext()) { + if (it.next().equals(entity)) it.remove(); + } + } + + @Override + public Set getComposites() { + Set set = new HashSet(); + + for (RoleEntity composite : getRole().getCompositeRoles()) { + set.add(new RoleAdapter(realm, em, composite)); + } + return set; + } + + @Override + public RoleContainerModel getContainer() { + if (role instanceof ApplicationRoleEntity) { + ApplicationRoleEntity entity = (ApplicationRoleEntity)role; + return new ApplicationAdapter(realm, em, entity.getApplication()); + } else if (role instanceof RealmRoleEntity) { + RealmRoleEntity entity = (RealmRoleEntity)role; + return new RealmAdapter(em, entity.getRealm()); + + } + throw new IllegalStateException("Unknown role entity type"); + } + + @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.equals(that.role)) return false; + + return true; + } + + @Override + public int hashCode() { + return role.hashCode(); + } } diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AbstractRoleMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AbstractRoleMappingEntity.java new file mode 100755 index 0000000000..c8404531bf --- /dev/null +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AbstractRoleMappingEntity.java @@ -0,0 +1,46 @@ +package org.keycloak.models.jpa.entities; + +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.MappedSuperclass; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +@MappedSuperclass +public class AbstractRoleMappingEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + protected long id; + @ManyToOne + protected UserEntity user; + @ManyToOne + protected RoleEntity role; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public UserEntity getUser() { + return user; + } + + public void setUser(UserEntity user) { + this.user = user; + } + + public RoleEntity getRole() { + return role; + } + + public void setRole(RoleEntity role) { + this.role = role; + } +} diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java index c0e21446a0..667fd483d1 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java @@ -31,9 +31,8 @@ public class ApplicationEntity { @OneToOne(fetch = FetchType.EAGER) private UserEntity applicationUser; - @OneToMany(fetch = FetchType.EAGER, cascade ={CascadeType.REMOVE}, orphanRemoval = true) - @JoinTable(name="APPLICATION_ROLES") - Collection roles = new ArrayList(); + @OneToMany(fetch = FetchType.EAGER, cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "application") + Collection roles = new ArrayList(); @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true) @JoinTable(name="APPLICATION_DEFAULT_ROLES") @@ -83,11 +82,11 @@ public class ApplicationEntity { this.applicationUser = applicationUser; } - public Collection getRoles() { + public Collection getRoles() { return roles; } - public void setRoles(Collection roles) { + public void setRoles(Collection roles) { this.roles = roles; } diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationScopeMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationRoleEntity.java similarity index 51% rename from model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationScopeMappingEntity.java rename to model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationRoleEntity.java index 557c65d012..61a850c316 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationScopeMappingEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationRoleEntity.java @@ -1,6 +1,7 @@ package org.keycloak.models.jpa.entities; import javax.persistence.Entity; +import javax.persistence.JoinTable; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; @@ -10,14 +11,13 @@ import javax.persistence.NamedQuery; * @version $Revision: 1 $ */ @NamedQueries({ - @NamedQuery(name="userHasApplicationScope", query="select m from ApplicationScopeMappingEntity m where m.user = :user and m.role = :role and m.application = :application"), - @NamedQuery(name="userApplicationScopeMappings", query="select m from ApplicationScopeMappingEntity m where m.user = :user and m.application = :application") + @NamedQuery(name="getAppRoleByName", query="select role from ApplicationRoleEntity role where role.name = :name and role.application = :application") }) @Entity -public class ApplicationScopeMappingEntity extends UserRoleMappingEntity { - +public class ApplicationRoleEntity extends RoleEntity { @ManyToOne - protected ApplicationEntity application; + @JoinTable(name = "APPLICATION_ROLE") + private ApplicationEntity application; public ApplicationEntity getApplication() { return application; diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationUserRoleMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationUserRoleMappingEntity.java deleted file mode 100755 index 2b2461d370..0000000000 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationUserRoleMappingEntity.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.keycloak.models.jpa.entities; - -import javax.persistence.Entity; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -@NamedQueries({ - @NamedQuery(name="userHasApplicationRole", query="select m from ApplicationUserRoleMappingEntity m where m.user = :user and m.role = :role and m.application = :application"), - @NamedQuery(name="userApplicationMappings", query="select m from ApplicationUserRoleMappingEntity m where m.user = :user and m.application = :application") -}) -@Entity -public class ApplicationUserRoleMappingEntity extends UserRoleMappingEntity { - - @ManyToOne - protected ApplicationEntity application; - - public ApplicationEntity getApplication() { - return application; - } - - public void setApplication(ApplicationEntity application) { - this.application = application; - } -} diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java index 067b8dcdfd..58c1f17d4c 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java @@ -65,9 +65,8 @@ public class RealmEntity { @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true) Collection applications = new ArrayList(); - @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true) - @JoinTable(name="REALM_ROLES") - Collection roles = new ArrayList(); + @OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm") + Collection roles = new ArrayList(); @ElementCollection @MapKeyColumn(name="name") @@ -229,17 +228,17 @@ public class RealmEntity { this.applications = applications; } - public Collection getRoles() { + public Collection getRoles() { return roles; } - public void setRoles(Collection roles) { + public void setRoles(Collection roles) { this.roles = roles; } - public void addRole(RoleEntity role) { + public void addRole(RealmRoleEntity role) { if (roles == null) { - roles = new ArrayList(); + roles = new ArrayList(); } roles.add(role); } diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmScopeMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmRoleEntity.java similarity index 54% rename from model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmScopeMappingEntity.java rename to model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmRoleEntity.java index 5800e9fffe..6acccbda3d 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmScopeMappingEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmRoleEntity.java @@ -10,14 +10,12 @@ import javax.persistence.NamedQuery; * @version $Revision: 1 $ */ @NamedQueries({ - @NamedQuery(name="userHasRealmScope", query="select m from RealmScopeMappingEntity m where m.user = :user and m.role = :role and m.realm = :realm"), - @NamedQuery(name="userRealmScopeMappings", query="select m from RealmScopeMappingEntity m where m.user = :user and m.realm = :realm") + @NamedQuery(name="getRealmRoleByName", query="select role from RealmRoleEntity role where role.name = :name and role.realm = :realm") }) @Entity -public class RealmScopeMappingEntity extends UserRoleMappingEntity { - +public class RealmRoleEntity extends RoleEntity { @ManyToOne - protected RealmEntity realm; + private RealmEntity realm; public RealmEntity getRealm() { return realm; diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmUserRoleMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmUserRoleMappingEntity.java deleted file mode 100755 index 305ce8d7aa..0000000000 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmUserRoleMappingEntity.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.keycloak.models.jpa.entities; - -import javax.persistence.Entity; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -@NamedQueries({ - @NamedQuery(name="userHasRealmRole", query="select m from RealmUserRoleMappingEntity m where m.user = :user and m.role = :role and m.realm = :realm"), - @NamedQuery(name="userRealmMappings", query="select m from RealmUserRoleMappingEntity m where m.user = :user and m.realm = :realm") -}) -@Entity -public class RealmUserRoleMappingEntity extends UserRoleMappingEntity { - - @ManyToOne - protected RealmEntity realm; - - public RealmEntity getRealm() { - return realm; - } - - public void setRealm(RealmEntity realm) { - this.realm = realm; - } -} diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java index 38beeb35ad..f65a59f5f8 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RoleEntity.java @@ -1,22 +1,34 @@ package org.keycloak.models.jpa.entities; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.JoinTable; +import javax.persistence.OneToMany; +import java.util.ArrayList; +import java.util.Collection; /** * @author Bill Burke * @version $Revision: 1 $ */ @Entity -public class RoleEntity { +public abstract class RoleEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private String id; private String name; private String description; + private boolean composite; + @OneToMany(fetch = FetchType.LAZY, cascade = {}, orphanRemoval = false) + @JoinTable(name = "COMPOSITE_ROLE") + private Collection compositeRoles = new ArrayList(); + public String getId() { return id; @@ -41,4 +53,37 @@ public class RoleEntity { public void setDescription(String description) { this.description = description; } + + public boolean isComposite() { + return composite; + } + + public void setComposite(boolean composite) { + this.composite = composite; + } + + public Collection getCompositeRoles() { + return compositeRoles; + } + + public void setCompositeRoles(Collection compositeRoles) { + this.compositeRoles = compositeRoles; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + RoleEntity that = (RoleEntity) o; + + if (!id.equals(that.id)) return false; + + return true; + } + + @Override + public int hashCode() { + return id.hashCode(); + } } diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java index efb7478d17..6a9aec78bf 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserRoleMappingEntity.java @@ -1,46 +1,23 @@ package org.keycloak.models.jpa.entities; +import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.MappedSuperclass; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; /** * @author Bill Burke * @version $Revision: 1 $ */ -@MappedSuperclass -public abstract class UserRoleMappingEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - protected long id; - @ManyToOne - protected UserEntity user; - @ManyToOne - protected RoleEntity role; +@NamedQueries({ + @NamedQuery(name="userHasRole", query="select m from UserRoleMappingEntity m where m.user = :user and m.role = :role"), + @NamedQuery(name="userRoleMappings", query="select m from UserRoleMappingEntity m where m.user = :user") +}) +@Entity +public class UserRoleMappingEntity extends AbstractRoleMappingEntity { - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public UserEntity getUser() { - return user; - } - - public void setUser(UserEntity user) { - this.user = user; - } - - public RoleEntity getRole() { - return role; - } - - public void setRole(RoleEntity role) { - this.role = role; - } } diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserScopeMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserScopeMappingEntity.java new file mode 100755 index 0000000000..5379608771 --- /dev/null +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserScopeMappingEntity.java @@ -0,0 +1,18 @@ +package org.keycloak.models.jpa.entities; + +import javax.persistence.Entity; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +@NamedQueries({ + @NamedQuery(name="userHasScope", query="select m from UserScopeMappingEntity m where m.user = :user and m.role = :role"), + @NamedQuery(name="userScopeMappings", query="select m from UserScopeMappingEntity m where m.user = :user") +}) +@Entity +public class UserScopeMappingEntity extends AbstractRoleMappingEntity { + +} diff --git a/model/pom.xml b/model/pom.xml index 002c7fc7c9..ab454cad1e 100755 --- a/model/pom.xml +++ b/model/pom.xml @@ -35,7 +35,7 @@ api - picketlink + jpa diff --git a/services/pom.xml b/services/pom.xml index af4945da73..7502bbe8c5 100755 --- a/services/pom.xml +++ b/services/pom.xml @@ -47,12 +47,14 @@ ${project.version} test + org.hibernate.ejb.HibernatePersistence org.keycloak.models.jpa.entities.ApplicationEntity - org.keycloak.models.jpa.entities.ApplicationScopeMappingEntity - org.keycloak.models.jpa.entities.ApplicationUserRoleMappingEntity org.keycloak.models.jpa.entities.CredentialEntity org.keycloak.models.jpa.entities.OAuthClientEntity org.keycloak.models.jpa.entities.RealmEntity - org.keycloak.models.jpa.entities.RealmScopeMappingEntity - org.keycloak.models.jpa.entities.RealmUserRoleMappingEntity org.keycloak.models.jpa.entities.RequiredCredentialEntity - org.keycloak.models.jpa.entities.RoleEntity + 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.UserScopeMappingEntity true diff --git a/testsuite/integration/pom.xml b/testsuite/integration/pom.xml index d0ee3c9c66..e3fffc5ed9 100755 --- a/testsuite/integration/pom.xml +++ b/testsuite/integration/pom.xml @@ -61,11 +61,13 @@ keycloak-model-jpa ${project.version} + org.keycloak keycloak-social-core diff --git a/testsuite/integration/src/main/resources/META-INF/persistence.xml b/testsuite/integration/src/main/resources/META-INF/persistence.xml index 5a4df6c4e3..a020d60d7d 100755 --- a/testsuite/integration/src/main/resources/META-INF/persistence.xml +++ b/testsuite/integration/src/main/resources/META-INF/persistence.xml @@ -6,18 +6,16 @@ org.hibernate.ejb.HibernatePersistence org.keycloak.models.jpa.entities.ApplicationEntity - org.keycloak.models.jpa.entities.ApplicationScopeMappingEntity - org.keycloak.models.jpa.entities.ApplicationUserRoleMappingEntity org.keycloak.models.jpa.entities.CredentialEntity org.keycloak.models.jpa.entities.OAuthClientEntity org.keycloak.models.jpa.entities.RealmEntity - org.keycloak.models.jpa.entities.RealmScopeMappingEntity - org.keycloak.models.jpa.entities.RealmUserRoleMappingEntity org.keycloak.models.jpa.entities.RequiredCredentialEntity - org.keycloak.models.jpa.entities.RoleEntity + 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.UserScopeMappingEntity true @@ -32,6 +30,7 @@ + diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java index 49acb71b19..7dbf997c56 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java @@ -226,6 +226,10 @@ public class OAuthClient { this.realm = realm; return this; } + public OAuthClient realmPublicKey(PublicKey key) { + this.realmPublicKey = key; + return this; + } public OAuthClient clientId(String clientId) { this.clientId = clientId; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java index 7a8f2a24bb..f520c70ad9 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java @@ -58,7 +58,7 @@ public class ProfileTest { UserModel user2 = appRealm.addUser("test-user-no-access@localhost"); user2.setEnabled(true); for (String r : accountApp.getDefaultRoles()) { - accountApp.deleteRoleMapping(user2, accountApp.getRole(r)); + appRealm.deleteRoleMapping(user2, accountApp.getRole(r)); } UserCredentialModel creds = new UserCredentialModel(); creds.setType(CredentialRepresentation.PASSWORD); @@ -66,12 +66,12 @@ public class ProfileTest { appRealm.updateCredential(user2, creds); ApplicationModel app = appRealm.getApplicationNameMap().get("test-app"); - accountApp.addScopeMapping(app.getApplicationUser(), org.keycloak.models.Constants.ACCOUNT_PROFILE_ROLE); + appRealm.addScopeMapping(app.getApplicationUser(), accountApp.getRole(org.keycloak.models.Constants.ACCOUNT_PROFILE_ROLE)); app.getApplicationUser().addWebOrigin("http://localtest.me:8081"); UserModel thirdParty = appRealm.getUser("third-party"); - accountApp.addScopeMapping(thirdParty, org.keycloak.models.Constants.ACCOUNT_PROFILE_ROLE); + appRealm.addScopeMapping(thirdParty, accountApp.getRole(org.keycloak.models.Constants.ACCOUNT_PROFILE_ROLE)); } }); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java new file mode 100755 index 0000000000..ddde357329 --- /dev/null +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java @@ -0,0 +1,157 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.composites; + +import org.junit.Assert; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.keycloak.models.ApplicationModel; +import org.keycloak.models.RealmModel; +import org.keycloak.models.RoleModel; +import org.keycloak.models.UserCredentialModel; +import org.keycloak.models.UserModel; +import org.keycloak.representations.SkeletonKeyToken; +import org.keycloak.services.managers.ApplicationManager; +import org.keycloak.services.managers.RealmManager; +import org.keycloak.testsuite.ApplicationServlet; +import org.keycloak.testsuite.OAuthClient; +import org.keycloak.testsuite.OAuthClient.AccessTokenResponse; +import org.keycloak.testsuite.pages.LoginPage; +import org.keycloak.testsuite.rule.AbstractKeycloakRule; +import org.keycloak.testsuite.rule.WebResource; +import org.keycloak.testsuite.rule.WebRule; +import org.openqa.selenium.WebDriver; + +import java.security.PublicKey; + +/** + * @author Stian Thorgersen + */ +public class CompositeRoleTest { + + public static PublicKey realmPublicKey; + @ClassRule + public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule(){ + @Override + protected void configure(RealmManager manager, RealmModel adminRealm) { + RealmModel realm = manager.createRealm("Test"); + manager.generateRealmKeys(realm); + realmPublicKey = realm.getPublicKey(); + realm.setTokenLifespan(10000); + realm.setSslNotRequired(true); + realm.setEnabled(true); + realm.addRequiredResourceCredential(UserCredentialModel.PASSWORD); + realm.addRequiredOAuthClientCredential(UserCredentialModel.PASSWORD); + realm.addRequiredCredential(UserCredentialModel.PASSWORD); + final RoleModel realmRole1 = realm.addRole("REALM_ROLE_1"); + final RoleModel realmRole2 = realm.addRole("REALM_ROLE_2"); + final RoleModel realmRole3 = realm.addRole("REALM_ROLE_3"); + final RoleModel realmComposite1 = realm.addRole("REALM_COMPOSITE_1"); + realmComposite1.setComposite(true); + realmComposite1.addCompositeRole(realmRole1); + + final UserModel realmComposite1User = realm.addUser("REALM_COMPOSITE_1_USER"); + realmComposite1User.setEnabled(true); + realm.updateCredential(realmComposite1User, UserCredentialModel.password("password")); + realm.grantRole(realmComposite1User, realmComposite1); + + final ApplicationModel realmComposite1Application = new ApplicationManager(manager).createApplication(realm, "REALM_COMPOSITE_1_APPLICATION"); + realmComposite1Application.setEnabled(true); + realmComposite1Application.addScope(realmComposite1); + realmComposite1Application.setBaseUrl("http://localhost:8081/app"); + realmComposite1Application.setManagementUrl("http://localhost:8081/app/logout"); + realm.updateCredential(realmComposite1Application.getApplicationUser(), UserCredentialModel.password("password")); + + final ApplicationModel realmRole1Application = new ApplicationManager(manager).createApplication(realm, "REALM_ROLE_1_APPLICATION"); + realmRole1Application.setEnabled(true); + realmRole1Application.addScope(realmRole1); + realmRole1Application.setBaseUrl("http://localhost:8081/app"); + realmRole1Application.setManagementUrl("http://localhost:8081/app/logout"); + realm.updateCredential(realmRole1Application.getApplicationUser(), UserCredentialModel.password("password")); + + + + deployServlet("app", "/app", ApplicationServlet.class); + + } + }; + + @Rule + public WebRule webRule = new WebRule(this); + + @WebResource + protected WebDriver driver; + + @WebResource + protected OAuthClient oauth; + + @WebResource + protected LoginPage loginPage; + + @Test + public void testRealmOnlyCompositeWithUserCompositeAppComposite() throws Exception { + oauth.realm("Test"); + oauth.realmPublicKey(realmPublicKey); + oauth.clientId("REALM_COMPOSITE_1_APPLICATION"); + oauth.doLogin("REALM_COMPOSITE_1_USER", "password"); + + String code = oauth.getCurrentQuery().get("code"); + AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password"); + + Assert.assertEquals(200, response.getStatusCode()); + + Assert.assertEquals("bearer", response.getTokenType()); + + SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken()); + + Assert.assertEquals("REALM_COMPOSITE_1_USER", token.getSubject()); + + Assert.assertEquals(2, token.getRealmAccess().getRoles().size()); + Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_COMPOSITE_1")); + Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); + } + + @Test + public void testRealmOnlyCompositeWithUserCompositeAppRole() throws Exception { + oauth.realm("Test"); + oauth.realmPublicKey(realmPublicKey); + oauth.clientId("REALM_ROLE_1_APPLICATION"); + oauth.doLogin("REALM_COMPOSITE_1_USER", "password"); + + String code = oauth.getCurrentQuery().get("code"); + AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password"); + + Assert.assertEquals(200, response.getStatusCode()); + + Assert.assertEquals("bearer", response.getTokenType()); + + SkeletonKeyToken token = oauth.verifyToken(response.getAccessToken()); + + Assert.assertEquals("REALM_COMPOSITE_1_USER", token.getSubject()); + + Assert.assertEquals(1, token.getRealmAccess().getRoles().size()); + Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1")); + } + + +} diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java index 3a06d4495f..1d6262f3d8 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java @@ -58,7 +58,7 @@ public class AccountTest { UserModel user2 = appRealm.addUser("test-user-no-access@localhost"); user2.setEnabled(true); for (String r : accountApp.getDefaultRoles()) { - accountApp.deleteRoleMapping(user2, accountApp.getRole(r)); + appRealm.deleteRoleMapping(user2, accountApp.getRole(r)); } UserCredentialModel creds = new UserCredentialModel(); creds.setType(CredentialRepresentation.PASSWORD); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java new file mode 100755 index 0000000000..caf6c58172 --- /dev/null +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/AbstractKeycloakRule.java @@ -0,0 +1,84 @@ +package org.keycloak.testsuite.rule; + +import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.servlet.api.ServletInfo; +import org.junit.rules.ExternalResource; +import org.keycloak.models.Constants; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.services.managers.RealmManager; +import org.keycloak.testutils.KeycloakServer; +import org.keycloak.util.JsonSerialization; + +import javax.servlet.Servlet; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public abstract class AbstractKeycloakRule extends ExternalResource { + protected KeycloakServer server; + + protected void before() throws Throwable { + server = new KeycloakServer(); + server.start(); + + + setupKeycloak(); + } + + protected void setupKeycloak() { + KeycloakSession session = server.getKeycloakSessionFactory().createSession(); + session.getTransaction().begin(); + + try { + RealmManager manager = new RealmManager(session); + + RealmModel adminstrationRealm = manager.getRealm(Constants.ADMIN_REALM); + + configure(manager, adminstrationRealm); + + session.getTransaction().commit(); + } finally { + session.close(); + } + + } + + protected void configure(RealmManager manager, RealmModel adminRealm) { + + } + + public void deployServlet(String name, String contextPath, Class servletClass) { + DeploymentInfo deploymentInfo = new DeploymentInfo(); + deploymentInfo.setClassLoader(getClass().getClassLoader()); + deploymentInfo.setDeploymentName(name); + deploymentInfo.setContextPath(contextPath); + + ServletInfo servlet = new ServletInfo(servletClass.getSimpleName(), servletClass); + servlet.addMapping("/*"); + + deploymentInfo.addServlet(servlet); + server.getServer().deploy(deploymentInfo); + } + + @Override + protected void after() { + server.stop(); + } + + public RealmRepresentation loadJson(String path) throws IOException { + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + int c; + while ((c = is.read()) != -1) { + os.write(c); + } + byte[] bytes = os.toByteArray(); + return JsonSerialization.readValue(bytes, RealmRepresentation.class); + } +} diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java index 466876133b..dd5c033e05 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/rule/KeycloakRule.java @@ -41,9 +41,7 @@ import java.io.InputStream; /** * @author Stian Thorgersen */ -public class KeycloakRule extends ExternalResource { - - private KeycloakServer server; +public class KeycloakRule extends AbstractKeycloakRule { private KeycloakSetup setup; @@ -54,11 +52,9 @@ public class KeycloakRule extends ExternalResource { this.setup = setup; } - protected void before() throws Throwable { - server = new KeycloakServer(); - server.start(); - - server.importRealm(getClass().getResourceAsStream("/testrealm.json")); + @Override + protected void setupKeycloak() { + importRealm(); if (setup != null) { configure(setup); @@ -67,33 +63,8 @@ public class KeycloakRule extends ExternalResource { deployServlet("app", "/app", ApplicationServlet.class); } - public void deployServlet(String name, String contextPath, Class servletClass) { - DeploymentInfo deploymentInfo = new DeploymentInfo(); - deploymentInfo.setClassLoader(getClass().getClassLoader()); - deploymentInfo.setDeploymentName(name); - deploymentInfo.setContextPath(contextPath); - - ServletInfo servlet = new ServletInfo(servletClass.getSimpleName(), servletClass); - servlet.addMapping("/*"); - - deploymentInfo.addServlet(servlet); - server.getServer().deploy(deploymentInfo); - } - - @Override - protected void after() { - server.stop(); - } - - public RealmRepresentation loadJson(String path) throws IOException { - InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - int c; - while ((c = is.read()) != -1) { - os.write(c); - } - byte[] bytes = os.toByteArray(); - return JsonSerialization.readValue(bytes, RealmRepresentation.class); + protected void importRealm() { + server.importRealm(getClass().getResourceAsStream("/testrealm.json")); } public void configure(KeycloakSetup configurer) { @@ -106,7 +77,7 @@ public class KeycloakRule extends ExternalResource { RealmModel adminstrationRealm = manager.getRealm(Constants.ADMIN_REALM); RealmModel appRealm = manager.getRealm("test"); - configurer.config(manager, null, appRealm); + configurer.config(manager, adminstrationRealm, appRealm); session.getTransaction().commit(); } finally { diff --git a/testsuite/performance/src/test/resources/META-INF/persistence.xml b/testsuite/performance/src/test/resources/META-INF/persistence.xml index 8083104f78..2f67fde924 100755 --- a/testsuite/performance/src/test/resources/META-INF/persistence.xml +++ b/testsuite/performance/src/test/resources/META-INF/persistence.xml @@ -2,6 +2,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> + org.hibernate.ejb.HibernatePersistence org.keycloak.models.jpa.entities.ApplicationEntity - org.keycloak.models.jpa.entities.ApplicationScopeMappingEntity - org.keycloak.models.jpa.entities.ApplicationUserRoleMappingEntity org.keycloak.models.jpa.entities.CredentialEntity org.keycloak.models.jpa.entities.OAuthClientEntity org.keycloak.models.jpa.entities.RealmEntity - org.keycloak.models.jpa.entities.RealmScopeMappingEntity - org.keycloak.models.jpa.entities.RealmUserRoleMappingEntity org.keycloak.models.jpa.entities.RequiredCredentialEntity - org.keycloak.models.jpa.entities.RoleEntity + 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.UserScopeMappingEntity true