From f9cb99a1ee41f9d901906407616abedf0b1f737e Mon Sep 17 00:00:00 2001 From: mposolda Date: Tue, 17 Jun 2014 16:57:01 +0200 Subject: [PATCH 1/4] KEYCLOAK-534 Fix MS-SQL --- .../audit/jpa/JpaAuditProviderFactory.java | 3 ++- .../main/java/org/keycloak/util/JpaUtils.java | 22 +++++++++++++++++++ .../models/jpa/JpaKeycloakSessionFactory.java | 17 ++------------ .../models/jpa/entities/RoleEntity.java | 19 +++++++++++++--- .../models/jpa/entities/UserEntity.java | 14 +++++++++++- 5 files changed, 55 insertions(+), 20 deletions(-) create mode 100644 core/src/main/java/org/keycloak/util/JpaUtils.java diff --git a/audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaAuditProviderFactory.java b/audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaAuditProviderFactory.java index 58ff08eae4..546b5e949c 100644 --- a/audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaAuditProviderFactory.java +++ b/audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaAuditProviderFactory.java @@ -5,6 +5,7 @@ import org.keycloak.audit.AuditProvider; import org.keycloak.audit.AuditProviderFactory; import org.keycloak.audit.EventType; import org.keycloak.provider.ProviderSession; +import org.keycloak.util.JpaUtils; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; @@ -28,7 +29,7 @@ public class JpaAuditProviderFactory implements AuditProviderFactory { @Override public void init(Config.Scope config) { - emf = Persistence.createEntityManagerFactory("jpa-keycloak-audit-store"); + emf = Persistence.createEntityManagerFactory("jpa-keycloak-audit-store", JpaUtils.getHibernateProperties()); String[] include = config.getArray("include-events"); if (include != null) { diff --git a/core/src/main/java/org/keycloak/util/JpaUtils.java b/core/src/main/java/org/keycloak/util/JpaUtils.java new file mode 100644 index 0000000000..abb4efe3df --- /dev/null +++ b/core/src/main/java/org/keycloak/util/JpaUtils.java @@ -0,0 +1,22 @@ +package org.keycloak.util; + +import java.util.Properties; + +/** + * @author Marek Posolda + */ +public class JpaUtils { + + // Allows to override some properties in persistence.xml by system properties + public static Properties getHibernateProperties() { + Properties result = new Properties(); + + for (Object property : System.getProperties().keySet()) { + if (property.toString().startsWith("hibernate.")) { + String propValue = System.getProperty(property.toString()); + result.put(property, propValue); + } + } + return result; + } +} diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSessionFactory.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSessionFactory.java index 6efe710f92..2865957841 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSessionFactory.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSessionFactory.java @@ -4,6 +4,7 @@ import org.keycloak.Config; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.provider.ProviderSession; +import org.keycloak.util.JpaUtils; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; @@ -19,7 +20,7 @@ public class JpaKeycloakSessionFactory implements KeycloakSessionFactory { @Override public void init(Config.Scope config) { - emf = Persistence.createEntityManagerFactory("jpa-keycloak-identity-store", getHibernateProperties()); + emf = Persistence.createEntityManagerFactory("jpa-keycloak-identity-store", JpaUtils.getHibernateProperties()); } @Override @@ -36,18 +37,4 @@ public class JpaKeycloakSessionFactory implements KeycloakSessionFactory { public void close() { emf.close(); } - - // Allows to override some properties in persistence.xml by system properties - protected Properties getHibernateProperties() { - Properties result = new Properties(); - - for (Object property : System.getProperties().keySet()) { - if (property.toString().startsWith("hibernate.")) { - String propValue = System.getProperty(property.toString()); - result.put(property, propValue); - } - } - return result; - } - } 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 c6f3eb1b63..5be5fed2e5 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 @@ -26,9 +26,7 @@ import org.hibernate.annotations.GenericGenerator; */ @Entity @Table(uniqueConstraints = { - @UniqueConstraint(columnNames = { "name", "application"}), - @UniqueConstraint(columnNames = { "name", "realm" }) - + @UniqueConstraint(columnNames = { "name", "appRealmConstraint" }) }) @NamedQueries({ @NamedQuery(name="getAppRoleByName", query="select role from RoleEntity role where role.name = :name and role.application = :application"), @@ -57,6 +55,9 @@ public class RoleEntity { @JoinColumn(name = "application") private ApplicationEntity application; + // Hack to ensure that either name+application or name+realm are unique. Needed due to MS-SQL as it don't allow multiple NULL values in the column, which is part of constraint + private String appRealmConstraint; + @ManyToMany(fetch = FetchType.LAZY, cascade = {}) @JoinTable(name = "CompositeRole", joinColumns = @JoinColumn(name = "composite"), inverseJoinColumns = @JoinColumn(name = "role")) private Collection compositeRoles = new ArrayList(); @@ -115,6 +116,7 @@ public class RoleEntity { public void setRealm(RealmEntity realm) { this.realm = realm; + this.appRealmConstraint = realm.getId(); } public ApplicationEntity getApplication() { @@ -123,6 +125,17 @@ public class RoleEntity { public void setApplication(ApplicationEntity application) { this.application = application; + if (application != null) { + this.appRealmConstraint = application.getId(); + } + } + + public String getAppRealmConstraint() { + return appRealmConstraint; + } + + public void setAppRealmConstraint(String appRealmConstraint) { + this.appRealmConstraint = appRealmConstraint; } @Override diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java index d8739017d8..3b765b4443 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java @@ -2,6 +2,7 @@ package org.keycloak.models.jpa.entities; import org.hibernate.annotations.GenericGenerator; import org.keycloak.models.UserModel; +import org.keycloak.models.utils.KeycloakModelUtils; import javax.persistence.CascadeType; import javax.persistence.CollectionTable; @@ -42,7 +43,7 @@ import java.util.Set; @Entity @Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "realm", "loginName" }), - @UniqueConstraint(columnNames = { "realm", "email" }) + @UniqueConstraint(columnNames = { "realm", "emailConstraint" }) }) public class UserEntity { @Id @@ -57,6 +58,8 @@ public class UserEntity { protected boolean emailVerified; protected int notBefore; + // Hack just to workaround the fact that on MS-SQL you can't have unique constraint with multiple NULL values TODO: Find better solution (like unique index with 'where' but that's proprietary) + protected String emailConstraint = KeycloakModelUtils.generateId(); @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "realm") @@ -116,6 +119,7 @@ public class UserEntity { public void setEmail(String email) { this.email = email; + this.emailConstraint = email != null ? email : KeycloakModelUtils.generateId(); } public boolean isEnabled() { @@ -126,6 +130,14 @@ public class UserEntity { this.enabled = enabled; } + public String getEmailConstraint() { + return emailConstraint; + } + + public void setEmailConstraint(String emailConstraint) { + this.emailConstraint = emailConstraint; + } + public boolean isTotp() { return totp; } From 2fd7fdaa7454a362d01a709670d6ac170753fadf Mon Sep 17 00:00:00 2001 From: mposolda Date: Wed, 18 Jun 2014 10:29:57 +0200 Subject: [PATCH 2/4] KEYCLOAK-535 Fix Keycloak with Oracle --- .../models/jpa/entities/AuthenticationProviderEntity.java | 7 ++++++- .../jpa/entities/ClientUserSessionAssociationEntity.java | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationProviderEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationProviderEntity.java index 8517ad28a3..2ce4c127a5 100644 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationProviderEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationProviderEntity.java @@ -8,7 +8,9 @@ import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; +import javax.persistence.JoinColumn; import javax.persistence.MapKeyColumn; +import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; @@ -16,6 +18,7 @@ import org.hibernate.annotations.GenericGenerator; * @author Marek Posolda */ @Entity +@Table(name="AuthProviderEntity") public class AuthenticationProviderEntity { @Id @@ -30,7 +33,9 @@ public class AuthenticationProviderEntity { @ElementCollection @MapKeyColumn(name="name") @Column(name="value") - @CollectionTable + @CollectionTable(name="AuthProviderEntity_cfg", joinColumns = { + @JoinColumn(name = "AuthProviderEntity_id") + }) private Map config; public String getId() { diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientUserSessionAssociationEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientUserSessionAssociationEntity.java index 0cf75aa051..490e75d7c2 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientUserSessionAssociationEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientUserSessionAssociationEntity.java @@ -9,12 +9,14 @@ import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; +import javax.persistence.Table; /** * @author Bill Burke * @version $Revision: 1 $ */ @Entity +@Table(name = "ClientUserSessionAscEntity") @NamedQueries({ @NamedQuery(name = "getAllClientUserSessions", query = "select s from ClientUserSessionAssociationEntity s"), @NamedQuery(name = "getClientUserSessionBySession", query = "select s from ClientUserSessionAssociationEntity s where s.session = :session"), From 5d8c803da6fa15683961f1f08e25ab36fee34603 Mon Sep 17 00:00:00 2001 From: mposolda Date: Wed, 18 Jun 2014 10:31:36 +0200 Subject: [PATCH 3/4] Remove duplicite dependency declarations to remove maven warnings --- examples/demo-template/product-app/pom.xml | 5 ----- server/pom.xml | 17 ----------------- services/pom.xml | 6 ------ 3 files changed, 28 deletions(-) diff --git a/examples/demo-template/product-app/pom.xml b/examples/demo-template/product-app/pom.xml index b8c65c1569..21e9cf0ab1 100755 --- a/examples/demo-template/product-app/pom.xml +++ b/examples/demo-template/product-app/pom.xml @@ -23,11 +23,6 @@ - - org.jboss.spec.javax.servlet - jboss-servlet-api_3.0_spec - provided - org.jboss.spec.javax.servlet jboss-servlet-api_3.0_spec diff --git a/server/pom.xml b/server/pom.xml index 9185e34a3b..ac9c0ff762 100755 --- a/server/pom.xml +++ b/server/pom.xml @@ -260,23 +260,6 @@ org.mongodb mongo-java-driver - - org.picketlink - picketlink-common - - - - org.picketlink - picketlink-idm-api - - - org.picketlink - picketlink-idm-impl - - - org.picketlink - picketlink-idm-simple-schema - diff --git a/services/pom.xml b/services/pom.xml index 9d9a564f2e..4fad80a0ab 100755 --- a/services/pom.xml +++ b/services/pom.xml @@ -97,12 +97,6 @@ ${project.version} provided - - org.keycloak - keycloak-authentication-api - ${project.version} - provided - org.keycloak keycloak-export-import-api From 19a545049b31fbcbd3b8a50f44674b989b7b4716 Mon Sep 17 00:00:00 2001 From: mposolda Date: Wed, 18 Jun 2014 12:31:55 +0200 Subject: [PATCH 4/4] KEYCLOAK-536 Fix Sybase - role can't be used as column name as it's keyword in sybase --- .../main/java/org/keycloak/models/jpa/ApplicationAdapter.java | 2 +- .../src/main/java/org/keycloak/models/jpa/RealmAdapter.java | 2 +- .../models/jpa/entities/AbstractRoleMappingEntity.java | 3 +++ .../main/java/org/keycloak/models/jpa/entities/RoleEntity.java | 2 +- .../org/keycloak/models/jpa/entities/ScopeMappingEntity.java | 3 +++ 5 files changed, 9 insertions(+), 3 deletions(-) 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 36ea18247a..11ee6f07b9 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 @@ -142,7 +142,7 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode applicationEntity.getRoles().remove(role); applicationEntity.getDefaultRoles().remove(role); - em.createNativeQuery("delete from CompositeRole where role = :role").setParameter("role", role).executeUpdate(); + em.createNativeQuery("delete from CompositeRole where childRole = :role").setParameter("role", role).executeUpdate(); em.createQuery("delete from " + ScopeMappingEntity.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); 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 fb92f1432b..18fc1db8ff 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 @@ -928,7 +928,7 @@ public class RealmAdapter implements RealmModel { realm.getRoles().remove(role); realm.getDefaultRoles().remove(role); - em.createNativeQuery("delete from CompositeRole where role = :role").setParameter("role", roleEntity).executeUpdate(); + em.createNativeQuery("delete from CompositeRole where childRole = :role").setParameter("role", roleEntity).executeUpdate(); em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", roleEntity).executeUpdate(); em.createQuery("delete from " + ScopeMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", roleEntity).executeUpdate(); 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 index 685aed752c..2ab0d00cc7 100755 --- 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 @@ -3,6 +3,7 @@ package org.keycloak.models.jpa.entities; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; +import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.MappedSuperclass; @@ -20,7 +21,9 @@ public class AbstractRoleMappingEntity { protected String id; @ManyToOne(fetch= FetchType.LAZY) protected UserEntity user; + @ManyToOne(fetch= FetchType.LAZY) + @JoinColumn(name="roleId") protected RoleEntity role; public String getId() { 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 5be5fed2e5..d3fc6dfb8c 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 @@ -59,7 +59,7 @@ public class RoleEntity { private String appRealmConstraint; @ManyToMany(fetch = FetchType.LAZY, cascade = {}) - @JoinTable(name = "CompositeRole", joinColumns = @JoinColumn(name = "composite"), inverseJoinColumns = @JoinColumn(name = "role")) + @JoinTable(name = "CompositeRole", joinColumns = @JoinColumn(name = "composite"), inverseJoinColumns = @JoinColumn(name = "childRole")) private Collection compositeRoles = new ArrayList(); public String getId() { diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ScopeMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ScopeMappingEntity.java index e1a00f9838..b45b69b8e4 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ScopeMappingEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ScopeMappingEntity.java @@ -6,6 +6,7 @@ import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; +import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; @@ -27,7 +28,9 @@ public class ScopeMappingEntity { protected String id; @ManyToOne(fetch= FetchType.LAZY) protected ClientEntity client; + @ManyToOne(fetch= FetchType.LAZY) + @JoinColumn(name="roleId") protected RoleEntity role; public String getId() {