diff --git a/docbook/reference/en/en-US/modules/Overview.xml b/docbook/reference/en/en-US/modules/Overview.xml index 8e970c7699..bdd3b2b9e9 100755 --- a/docbook/reference/en/en-US/modules/Overview.xml +++ b/docbook/reference/en/en-US/modules/Overview.xml @@ -78,7 +78,7 @@ Once a user is logged in, they can visit any other application managed by the realm and not have to re-enter credentials. This also hold true for logging out. Roles can also be defined at the application level and assigned to specific users. Depending on the application type, you may also be able to view and manage - user sessions from the adminstration console. + user sessions from the administration console. An oauth client is similar to an application in that it can request something like a login diff --git a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java index 4582a03274..b814d7fe82 100644 --- a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java +++ b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java @@ -6,6 +6,7 @@ import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.util.Set; +import java.util.UUID; import java.util.concurrent.atomic.AtomicLong; import org.bouncycastle.openssl.PEMWriter; @@ -25,7 +26,7 @@ public final class KeycloakModelUtils { private static AtomicLong counter = new AtomicLong(1); public static String generateId() { - return counter.getAndIncrement() + "-" + System.currentTimeMillis(); + return UUID.randomUUID().toString(); } public static PublicKey getPublicKey(String publicKeyPem) { diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java index a072c75cc6..1a24530d77 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java @@ -83,12 +83,12 @@ public class JpaKeycloakSession implements KeycloakSession { adapter.removeApplication(a.getId()); } + em.createQuery("delete from " + OAuthClientEntity.class.getSimpleName() + " where realm = :realm").setParameter("realm", realm).executeUpdate(); + for (UserEntity u : em.createQuery("from UserEntity", UserEntity.class).getResultList()) { adapter.removeUser(u.getLoginName()); } - em.createQuery("delete from " + OAuthClientEntity.class.getSimpleName() + " where realm = :realm").setParameter("realm", realm).executeUpdate(); - em.remove(realm); return true; diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java index 629f7959c9..03473e5d41 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java @@ -1,5 +1,9 @@ package org.keycloak.models.jpa; +import java.util.Map; +import java.util.Properties; + +import org.jboss.resteasy.logging.Logger; import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.ModelProvider; @@ -19,8 +23,21 @@ public class JpaModelProvider implements ModelProvider { @Override public KeycloakSessionFactory createFactory() { - EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa-keycloak-identity-store"); + EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa-keycloak-identity-store", getHibernateProperties()); return new JpaKeycloakSessionFactory(emf); } + + // 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/AbstractRoleMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/AbstractRoleMappingEntity.java index c8404531bf..101d558fc9 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 @@ -1,11 +1,12 @@ 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; +import org.hibernate.annotations.GenericGenerator; + /** * @author Bill Burke * @version $Revision: 1 $ @@ -13,18 +14,19 @@ import javax.persistence.MappedSuperclass; @MappedSuperclass public class AbstractRoleMappingEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - protected long id; + @GenericGenerator(name="keycloak_generator", strategy="org.keycloak.models.jpa.utils.JpaIdGenerator") + @GeneratedValue(generator = "keycloak_generator") + protected String id; @ManyToOne protected UserEntity user; @ManyToOne protected RoleEntity role; - public long getId() { + public String getId() { return id; } - public void setId(long id) { + public void setId(String id) { this.id = id; } 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 667fd483d1..5da99fceff 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 @@ -4,7 +4,6 @@ import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinTable; import javax.persistence.OneToMany; @@ -12,6 +11,8 @@ import javax.persistence.OneToOne; import java.util.ArrayList; import java.util.Collection; +import org.hibernate.annotations.GenericGenerator; + /** * @author Bill Burke * @version $Revision: 1 $ @@ -19,7 +20,8 @@ import java.util.Collection; @Entity public class ApplicationEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GenericGenerator(name="keycloak_generator", strategy="org.keycloak.models.jpa.utils.JpaIdGenerator") + @GeneratedValue(generator = "keycloak_generator") private String id; private String name; diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java index ec110b8d7c..e42eefe7f7 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/CredentialEntity.java @@ -2,12 +2,13 @@ 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.NamedQueries; import javax.persistence.NamedQuery; +import org.hibernate.annotations.GenericGenerator; + /** * @author Bill Burke * @version $Revision: 1 $ @@ -18,7 +19,8 @@ import javax.persistence.NamedQuery; @Entity public class CredentialEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GenericGenerator(name="keycloak_generator", strategy="org.keycloak.models.jpa.utils.JpaIdGenerator") + @GeneratedValue(generator = "keycloak_generator") protected String id; protected String type; diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java index 9d440c309e..d266ed7502 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java @@ -3,13 +3,14 @@ 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.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.OneToOne; +import org.hibernate.annotations.GenericGenerator; + /** * @author Bill Burke * @version $Revision: 1 $ @@ -22,7 +23,8 @@ import javax.persistence.OneToOne; @Entity public class OAuthClientEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GenericGenerator(name="keycloak_generator", strategy="org.keycloak.models.jpa.utils.JpaIdGenerator") + @GeneratedValue(generator = "keycloak_generator") private String id; private String name; diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java index 8a35808169..94870224a5 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RequiredCredentialEntity.java @@ -2,9 +2,10 @@ package org.keycloak.models.jpa.entities; import javax.persistence.Entity; import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; import javax.persistence.Id; +import org.hibernate.annotations.GenericGenerator; + /** * @author Bill Burke * @version $Revision: 1 $ @@ -12,7 +13,8 @@ import javax.persistence.Id; @Entity public class RequiredCredentialEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GenericGenerator(name="keycloak_generator", strategy="org.keycloak.models.jpa.utils.JpaIdGenerator") + @GeneratedValue(generator = "keycloak_generator") protected String id; protected String type; 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 1c21d125cc..acb40c9d23 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 @@ -3,7 +3,6 @@ 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; @@ -13,6 +12,8 @@ import javax.persistence.OneToMany; import java.util.ArrayList; import java.util.Collection; +import org.hibernate.annotations.GenericGenerator; + /** * @author Bill Burke * @version $Revision: 1 $ @@ -21,7 +22,8 @@ import java.util.Collection; @Inheritance(strategy = InheritanceType.SINGLE_TABLE) public abstract class RoleEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GenericGenerator(name="keycloak_generator", strategy="org.keycloak.models.jpa.utils.JpaIdGenerator") + @GeneratedValue(generator = "keycloak_generator") private String id; private String name; diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java index ccc0a592bc..9063948673 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java @@ -8,6 +8,9 @@ import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; +import org.hibernate.annotations.GenericGenerator; +import org.keycloak.models.jpa.utils.JpaIdGenerator; + /** * @author Bill Burke * @version $Revision: 1 $ @@ -20,8 +23,11 @@ import javax.persistence.NamedQuery; @Entity public class SocialLinkEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private long id; + @GenericGenerator(name="keycloak_generator", strategy="org.keycloak.models.jpa.utils.JpaIdGenerator") + @GeneratedValue(generator = "keycloak_generator") + private String id; + + private String str = JpaIdGenerator.class.getName(); @ManyToOne private UserEntity user; @@ -32,11 +38,11 @@ public class SocialLinkEntity { protected String socialProvider; protected String socialUsername; - public long getId() { + public String getId() { return id; } - public void setId(long id) { + public void setId(String id) { this.id = id; } 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 bcddabd47c..04af485bf8 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 @@ -1,5 +1,6 @@ package org.keycloak.models.jpa.entities; +import org.hibernate.annotations.GenericGenerator; import org.keycloak.models.UserModel; import javax.persistence.CascadeType; @@ -35,7 +36,8 @@ import java.util.Set; @Entity public class UserEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GenericGenerator(name="uuid_generator", strategy="org.keycloak.models.jpa.utils.JpaIdGenerator") + @GeneratedValue(generator = "uuid_generator") protected String id; protected String loginName; diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/utils/JpaIdGenerator.java b/model/jpa/src/main/java/org/keycloak/models/jpa/utils/JpaIdGenerator.java new file mode 100644 index 0000000000..6fc10e854b --- /dev/null +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/utils/JpaIdGenerator.java @@ -0,0 +1,19 @@ +package org.keycloak.models.jpa.utils; + +import java.io.Serializable; + +import org.hibernate.HibernateException; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.id.IdentifierGenerator; +import org.keycloak.models.utils.KeycloakModelUtils; + +/** + * @author Marek Posolda + */ +public class JpaIdGenerator implements IdentifierGenerator { + + @Override + public Serializable generate(SessionImplementor session, Object object) throws HibernateException { + return KeycloakModelUtils.generateId(); + } +} 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 f0e135e5c3..fa41a46937 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 @@ -6,7 +6,6 @@ import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBObject; -import org.bson.types.ObjectId; import org.jboss.logging.Logger; import org.keycloak.models.mongo.api.MongoCollection; import org.keycloak.models.mongo.api.MongoEntity; @@ -27,6 +26,7 @@ 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; @@ -120,18 +120,17 @@ public class MongoStoreImpl implements MongoStore { String currentId = entity.getId(); - // Inserting object, which already has oid property set. So we need to set "_id" - if (currentId != null) { - dbObject.put("_id", getObjectId(currentId)); + // 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); - // Add id to value of given object - if (currentId == null) { - entity.setId(dbObject.getString("_id")); - } - // Treat object as created in this transaction (It is already submited to transaction) context.addCreatedEntity(entity); } @@ -152,7 +151,7 @@ public class MongoStoreImpl implements MongoStore { if (currentId == null) { throw new IllegalStateException("Can't update entity without id: " + entity); } else { - BasicDBObject query = new BasicDBObject("_id", getObjectId(currentId)); + BasicDBObject query = new BasicDBObject("_id", currentId); dbCollection.update(query, dbObject); } } @@ -176,7 +175,7 @@ public class MongoStoreImpl implements MongoStore { DBCollection dbCollection = getDBCollectionForType(type); - BasicDBObject idQuery = new BasicDBObject("_id", getObjectId(id)); + BasicDBObject idQuery = new BasicDBObject("_id", id); DBObject dbObject = dbCollection.findOne(idQuery); if (dbObject == null) return null; @@ -193,14 +192,16 @@ public class MongoStoreImpl implements MongoStore { @Override public T loadSingleEntity(Class type, DBObject query, MongoStoreInvocationContext context) { - List result = loadEntities(type, query, context); - if (result.size() > 1) { - throw new IllegalStateException("There are " + result.size() + " results for type=" + type + ", query=" + query + ". We expect just one"); - } else if (result.size() == 1) { - return result.get(0); - } else { - // 0 results + // 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); } } @@ -230,7 +231,7 @@ public class MongoStoreImpl implements MongoStore { return false; } else { DBCollection dbCollection = getDBCollectionForType(type); - BasicDBObject dbQuery = new BasicDBObject("_id", getObjectId(id)); + BasicDBObject dbQuery = new BasicDBObject("_id", id); dbCollection.remove(dbQuery); logger.info("Entity of type: " + type + ", id: " + id + " removed from MongoDB."); @@ -291,7 +292,7 @@ public class MongoStoreImpl implements MongoStore { // Now DB update of new list with usage of $set BasicDBList dbList = mapperRegistry.convertApplicationObjectToDBObject(listt, BasicDBList.class); - BasicDBObject query = new BasicDBObject("_id", getObjectId(entity.getId())); + BasicDBObject query = new BasicDBObject("_id", entity.getId()); BasicDBObject listObject = new BasicDBObject(listPropertyName, dbList); BasicDBObject setCommand = new BasicDBObject("$set", listObject); getDBCollectionForType(type).update(query, setCommand); @@ -334,7 +335,7 @@ public class MongoStoreImpl implements MongoStore { public void execute() { // Pull item from DB Object dbItemToPull = mapperRegistry.convertApplicationObjectToDBObject(itemToPull, Object.class); - BasicDBObject query = new BasicDBObject("_id", getObjectId(entity.getId())); + BasicDBObject query = new BasicDBObject("_id", entity.getId()); BasicDBObject pullObject = new BasicDBObject(listPropertyName, dbItemToPull); BasicDBObject pullCommand = new BasicDBObject("$pull", pullObject); getDBCollectionForType(type).update(query, pullCommand); @@ -350,7 +351,7 @@ public class MongoStoreImpl implements MongoStore { } } - // Possibility to add user-defined converters + // Possibility to add user-defined mappers public void addAppObjectConverter(Mapper mapper) { mapperRegistry.addAppObjectMapper(mapper); } @@ -383,17 +384,7 @@ public class MongoStoreImpl implements MongoStore { try { for (DBObject dbObject : cursor) { - // First look if we already have loaded object cached. If yes, we will use cached instance - String id = dbObject.get("_id").toString(); - T entity = context.getLoadedEntity(type, id); - - if (entity == null) { - // So convert and use fresh instance from DB - MapperContext mapperContext = new MapperContext(dbObject, type, null); - entity = mapperRegistry.convertDBObjectToApplicationObject(mapperContext); - context.addLoadedEntity(entity); - } - + T entity = convertDBObjectToEntity(type, dbObject, context); result.add(entity); } } finally { @@ -403,18 +394,23 @@ public class MongoStoreImpl implements MongoStore { 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(entityInfo.getDbCollectionName()); - } - - // We allow ObjectId to be both "ObjectId" or "String". - protected Object getObjectId(String idAsString) { - if (ObjectId.isValid(idAsString)) { - return new ObjectId(idAsString); - } else { - return idAsString; - } + return dbCollectionName==null ? null : database.getCollection(dbCollectionName); } } 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 index a3ed40b16a..0436569e90 100644 --- 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 @@ -90,7 +90,7 @@ public class RoleAdapter extends AbstractAdapter implements RoleModel { } DBObject query = new QueryBuilder() - .and("_id").in(MongoModelUtils.convertStringsToObjectIds(role.getCompositeRoleIds())) + .and("_id").in(role.getCompositeRoleIds()) .get(); List childRoles = getMongoStore().loadEntities(RoleEntity.class, query, invocationContext); 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 4be29ecb34..b7a9a21392 100644 --- 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 @@ -19,14 +19,6 @@ import org.keycloak.models.mongo.keycloak.entities.UserEntity; */ public class MongoModelUtils { - public static List convertStringsToObjectIds(Collection strings) { - List result = new ArrayList(); - for (String id : strings) { - result.add(new ObjectId(id)); - } - return result; - } - // Get everything including both application and realm roles public static List getAllRolesOfUser(UserModel user, MongoStoreInvocationContext invContext) { UserEntity userEntity = ((UserAdapter)user).getUser(); @@ -37,7 +29,7 @@ public class MongoModelUtils { } DBObject query = new QueryBuilder() - .and("_id").in(convertStringsToObjectIds(roleIds)) + .and("_id").in(roleIds) .get(); return invContext.getMongoStore().loadEntities(RoleEntity.class, query, invContext); } @@ -52,7 +44,7 @@ public class MongoModelUtils { } DBObject query = new QueryBuilder() - .and("_id").in(convertStringsToObjectIds(scopeIds)) + .and("_id").in(scopeIds) .get(); return invContext.getMongoStore().loadEntities(RoleEntity.class, query, invContext); } diff --git a/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoDBModelTest.java b/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoStoreTest.java similarity index 99% rename from model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoDBModelTest.java rename to model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoStoreTest.java index 7ee814131c..fba9489afe 100755 --- a/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoDBModelTest.java +++ b/model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoStoreTest.java @@ -23,7 +23,7 @@ import java.util.List; /** * @author Marek Posolda */ -public class MongoDBModelTest { +public class MongoStoreTest { private static final Class[] MANAGED_DATA_TYPES = (Class[])new Class[] { Person.class, diff --git a/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java index 1f2fda1be3..f334236650 100644 --- a/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java +++ b/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java @@ -40,6 +40,14 @@ public class AbstractModelTest { factory.close(); } + protected void commit() { + identitySession.getTransaction().commit(); + identitySession.close(); + identitySession = factory.createSession(); + identitySession.getTransaction().begin(); + realmManager = new RealmManager(identitySession); + } + public static RealmRepresentation loadJson(String path) throws IOException { InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path); ByteArrayOutputStream os = new ByteArrayOutputStream(); 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 6bd1f07bd1..cd18852239 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 @@ -96,11 +96,7 @@ public class AdapterTest extends AbstractModelTest { String id = realmModel.getId(); System.out.println("id: " + id); - identitySession.getTransaction().commit(); - identitySession.close(); - identitySession = factory.createSession(); - identitySession.getTransaction().begin(); - realmManager = new RealmManager(identitySession); + commit(); List realms = identitySession.getRealms(null); System.out.println("num realms: " + realms.size()); Assert.assertEquals(realms.size(), 1); 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 1baf83e0a9..ec14411199 100644 --- a/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java +++ b/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java @@ -28,48 +28,29 @@ public class CompositeRolesModelTest extends AbstractModelTest { } @Test - public void testAppComposites() { + 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); - } - - @Test - public void testRealmAppComposites() { - Set requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "REALM_APP_COMPOSITE_USER"); + requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "REALM_APP_COMPOSITE_USER"); Assert.assertEquals(1, requestedRoles.size()); assertContains("APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles); - } - - @Test - public void testRealmOnlyWithUserCompositeAppComposite() throws Exception { - Set requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_COMPOSITE_1_USER"); + requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_COMPOSITE_1_USER"); Assert.assertEquals(1, requestedRoles.size()); assertContains("realm", "REALM_COMPOSITE_1", requestedRoles); - } - @Test - public void testRealmOnlyWithUserCompositeAppRole() throws Exception { - Set requestedRoles = getRequestedRoles("REALM_ROLE_1_APPLICATION", "REALM_COMPOSITE_1_USER"); + 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); } - @Test - public void testRealmOnlyWithUserRoleAppComposite() throws Exception { - Set requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_ROLE_1_USER"); - - Assert.assertEquals(1, requestedRoles.size()); - assertContains("realm", "REALM_ROLE_1", requestedRoles); - } - - // TODO: more tests... - // Same algorithm as in TokenManager.createAccessCode private Set getRequestedRoles(String applicationName, String username) { Set requestedRoles = new HashSet(); 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 6567e19971..89bc061cd5 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 @@ -99,14 +99,6 @@ public class UserModelTest extends AbstractModelTest { Assert.assertTrue(user.getRequiredActions().isEmpty()); } - protected void commit() { - identitySession.getTransaction().commit(); - identitySession.close(); - identitySession = factory.createSession(); - identitySession.getTransaction().begin(); - realmManager = new RealmManager(identitySession); - } - public static void assertEquals(UserModel expected, UserModel actual) { Assert.assertEquals(expected.getLoginName(), actual.getLoginName()); Assert.assertEquals(expected.getFirstName(), actual.getFirstName()); diff --git a/pom.xml b/pom.xml index 2f4bab5b35..8e5632ef9e 100755 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,10 @@ 1.0.1.Final 4.0.1.Final 1.3.161 + 5.1.29 + 9.3-1100-jdbc41 1.6.1 + 1.4.01 5.1.25 1.6.1 7.1.1.Final @@ -323,6 +326,11 @@ dom4j ${dom4j.version} + + xml-apis + xml-apis + ${xml-apis.version} + org.slf4j slf4j-api @@ -544,5 +552,42 @@ distribution + + + + + + hibernate.connection.driver_class + com.mysql.jdbc.Driver + + + mysql + + + mysql + mysql-connector-java + ${mysql.version} + + + + + + + + + hibernate.connection.driver_class + org.postgresql.Driver + + + postgresql + + + org.postgresql + postgresql + ${postgresql.version} + + + + diff --git a/server/src/main/java/org/keycloak/server/KeycloakServerApplication.java b/server/src/main/java/org/keycloak/server/KeycloakServerApplication.java index fdcdaa4e57..fc9331a1de 100755 --- a/server/src/main/java/org/keycloak/server/KeycloakServerApplication.java +++ b/server/src/main/java/org/keycloak/server/KeycloakServerApplication.java @@ -29,7 +29,6 @@ public class KeycloakServerApplication extends KeycloakApplication { session.getTransaction().begin(); RealmRepresentation rep = loadJson(new FileInputStream(importRealm), RealmRepresentation.class); importRealm(session, rep); - session.getTransaction().commit(); } String themeDir = System.getProperty("keycloak.theme.dir"); diff --git a/testsuite/integration/pom.xml b/testsuite/integration/pom.xml index d668ee8389..d1d1d5ad20 100755 --- a/testsuite/integration/pom.xml +++ b/testsuite/integration/pom.xml @@ -232,12 +232,10 @@ com.h2database h2 - 1.3.161 org.hibernate hibernate-entitymanager - 3.6.6.Final com.icegreen @@ -247,6 +245,10 @@ org.seleniumhq.selenium selenium-java + + xml-apis + xml-apis + org.seleniumhq.selenium selenium-chrome-driver diff --git a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java index ebd181b93e..6fbb6fde19 100755 --- a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java +++ b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java @@ -96,7 +96,7 @@ public class KeycloakServer { } } - private static T loadJson(InputStream is, Class type) { + public static T loadJson(InputStream is, Class type) { try { return JsonSerialization.readValue(is, type); } catch (IOException e) { diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java index ddd15ed166..dfb2fc9253 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeImportRoleTest.java @@ -41,6 +41,7 @@ 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.keycloak.testutils.KeycloakServer; import org.openqa.selenium.WebDriver; import java.security.PublicKey; @@ -55,12 +56,12 @@ public class CompositeImportRoleTest { public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule(){ @Override protected void configure(RealmManager manager, RealmModel adminRealm) { - server.importRealm(getClass().getResourceAsStream("/testcomposite.json")); - RealmModel realm = manager.getRealmByName("Test"); + RealmModel realm = manager.createRealm("Test"); + RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/testcomposite.json"), RealmRepresentation.class); + manager.importRealm(representation, realm); + realmPublicKey = realm.getPublicKey(); - - deployServlet("app", "/app", ApplicationServlet.class); }