refactor getRoleById

This commit is contained in:
Bill Burke 2014-03-02 20:28:58 -05:00
parent f8eb56d6b7
commit 8126110312
52 changed files with 5456 additions and 5360 deletions

View file

@ -3,6 +3,10 @@ module.controller('ApplicationRoleListCtrl', function($scope, $location, realm,
$scope.roles = roles;
$scope.application = application;
for (var i = 0; i < roles.length; i++) {
console.log("role.id: " + roles[i].id + " role.name: " + roles[i].name);
}
$scope.$watch(function() {
return $location.path();
}, function() {

View file

@ -49,4 +49,6 @@ public interface ClientModel {
boolean validateSecret(String secret);
String getSecret();
public void setSecret(String secret);
RealmModel getRealm();
}

View file

@ -101,6 +101,8 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
boolean removeUser(String name);
RoleModel getRoleById(String id);
List<String> getDefaultRoles();
void addDefaultRole(String name);
@ -182,4 +184,6 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
int getNotBefore();
void setNotBefore(int notBefore);
boolean removeRoleById(String id);
}

View file

@ -12,9 +12,8 @@ public interface RoleContainerModel {
RoleModel addRole(String name);
boolean removeRoleById(String id);
boolean removeRole(RoleModel role);
Set<RoleModel> getRoles();
RoleModel getRoleById(String id);
}

View file

@ -1,31 +1,31 @@
package org.keycloak.models;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class SocialLinkModel {
private String socialUsername;
private String socialProvider;
public SocialLinkModel(String socialProvider, String socialUsername) {
this.socialUsername = socialUsername;
this.socialProvider = socialProvider;
}
public String getSocialUsername() {
return socialUsername;
}
public void setSocialUsername(String socialUsername) {
this.socialUsername = socialUsername;
}
public String getSocialProvider() {
return socialProvider;
}
public void setSocialProvider(String socialProvider) {
this.socialProvider = socialProvider;
}
}
package org.keycloak.models;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class SocialLinkModel {
private String socialUsername;
private String socialProvider;
public SocialLinkModel(String socialProvider, String socialUsername) {
this.socialUsername = socialUsername;
this.socialProvider = socialProvider;
}
public String getSocialUsername() {
return socialUsername;
}
public void setSocialUsername(String socialUsername) {
this.socialUsername = socialUsername;
}
public String getSocialProvider() {
return socialProvider;
}
public void setSocialProvider(String socialProvider) {
this.socialProvider = socialProvider;
}
}

View file

@ -1,69 +1,69 @@
package org.keycloak.models;
import java.util.UUID;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class UserCredentialModel {
public static final String PASSWORD = "password";
// Secret is same as password but it is not hashed
public static final String SECRET = "secret";
public static final String TOTP = "totp";
public static final String CLIENT_CERT = "cert";
protected String type;
protected String value;
protected String device;
public UserCredentialModel() {
}
public static UserCredentialModel password(String password) {
UserCredentialModel model = new UserCredentialModel();
model.setType(PASSWORD);
model.setValue(password);
return model;
}
public static UserCredentialModel secret(String password) {
UserCredentialModel model = new UserCredentialModel();
model.setType(SECRET);
model.setValue(password);
return model;
}
public static UserCredentialModel generateSecret() {
UserCredentialModel model = new UserCredentialModel();
model.setType(SECRET);
model.setValue(UUID.randomUUID().toString());
return model;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDevice() {
return device;
}
public void setDevice(String device) {
this.device = device;
}
}
package org.keycloak.models;
import java.util.UUID;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class UserCredentialModel {
public static final String PASSWORD = "password";
// Secret is same as password but it is not hashed
public static final String SECRET = "secret";
public static final String TOTP = "totp";
public static final String CLIENT_CERT = "cert";
protected String type;
protected String value;
protected String device;
public UserCredentialModel() {
}
public static UserCredentialModel password(String password) {
UserCredentialModel model = new UserCredentialModel();
model.setType(PASSWORD);
model.setValue(password);
return model;
}
public static UserCredentialModel secret(String password) {
UserCredentialModel model = new UserCredentialModel();
model.setType(SECRET);
model.setValue(password);
return model;
}
public static UserCredentialModel generateSecret() {
UserCredentialModel model = new UserCredentialModel();
model.setType(SECRET);
model.setValue(UUID.randomUUID().toString());
return model;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDevice() {
return device;
}
public void setDevice(String device) {
this.device = device;
}
}

View file

@ -24,10 +24,9 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode
protected EntityManager em;
protected ApplicationEntity applicationEntity;
protected RealmModel realm;
public ApplicationAdapter(RealmModel realm, EntityManager em, ApplicationEntity applicationEntity) {
super(applicationEntity);
super(realm, applicationEntity);
this.realm = realm;
this.em = em;
this.applicationEntity = applicationEntity;
@ -48,7 +47,6 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode
entity.setName(name);
}
@Override
public boolean isSurrogateAuthRequired() {
return applicationEntity.isSurrogateAuthRequired();
@ -103,11 +101,14 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode
}
@Override
public boolean removeRoleById(String id) {
RoleAdapter roleAdapter = getRoleById(id);
public boolean removeRole(RoleModel roleModel) {
RoleAdapter roleAdapter = (RoleAdapter)roleModel;
if (roleAdapter == null) {
return false;
}
if (!roleAdapter.getContainer().equals(this)) return false;
if (!(roleAdapter.getRole() instanceof ApplicationRoleEntity)) return false;
ApplicationRoleEntity role = (ApplicationRoleEntity)roleAdapter.getRole();
@ -134,16 +135,6 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode
return list;
}
@Override
public RoleAdapter getRoleById(String id) {
RoleEntity entity = em.find(RoleEntity.class, id);
// Check if it's application role and belongs to this application
if (entity == null || !(entity instanceof ApplicationRoleEntity)) return null;
ApplicationRoleEntity appRoleEntity = (ApplicationRoleEntity)entity;
return (appRoleEntity.getApplication().equals(this.entity)) ? new RoleAdapter(this.realm, em, appRoleEntity) : null;
}
@Override
public Set<RoleModel> getApplicationRoleMappings(UserModel user) {
Set<RoleModel> roleMappings = realm.getRoleMappings(user);

View file

@ -1,6 +1,7 @@
package org.keycloak.models.jpa;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.jpa.entities.ClientEntity;
import org.keycloak.models.jpa.entities.OAuthClientEntity;
@ -13,8 +14,10 @@ import java.util.Set;
*/
public class ClientAdapter implements ClientModel {
protected ClientEntity entity;
protected RealmModel realm;
public ClientAdapter(ClientEntity entity) {
public ClientAdapter(RealmModel realm, ClientEntity entity) {
this.realm = realm;
this.entity = entity;
}
@ -22,75 +25,111 @@ public class ClientAdapter implements ClientModel {
return entity;
}
@Override
public String getId() {
return entity.getId();
}
@Override
public RealmModel getRealm() {
return realm;
}
@Override
public String getClientId() {
return entity.getName();
}
@Override
public boolean isEnabled() {
return entity.isEnabled();
}
@Override
public void setEnabled(boolean enabled) {
entity.setEnabled(enabled);
}
@Override
public long getAllowedClaimsMask() {
return entity.getAllowedClaimsMask();
}
@Override
public void setAllowedClaimsMask(long mask) {
entity.setAllowedClaimsMask(mask);
}
@Override
public Set<String> getWebOrigins() {
Set<String> result = new HashSet<String>();
result.addAll(entity.getWebOrigins());
return result;
}
@Override
public void setWebOrigins(Set<String> webOrigins) {
entity.setWebOrigins(webOrigins);
}
@Override
public void addWebOrigin(String webOrigin) {
entity.getWebOrigins().add(webOrigin);
}
@Override
public void removeWebOrigin(String webOrigin) {
entity.getWebOrigins().remove(webOrigin);
}
@Override
public Set<String> getRedirectUris() {
Set<String> result = new HashSet<String>();
result.addAll(entity.getRedirectUris());
return result;
}
@Override
public void setRedirectUris(Set<String> redirectUris) {
entity.setRedirectUris(redirectUris);
}
@Override
public void addRedirectUri(String redirectUri) {
entity.getRedirectUris().add(redirectUri);
}
@Override
public void removeRedirectUri(String redirectUri) {
entity.getRedirectUris().remove(redirectUri);
}
@Override
public String getSecret() {
return entity.getSecret();
}
@Override
public void setSecret(String secret) {
entity.setSecret(secret);
}
@Override
public boolean validateSecret(String secret) {
return secret.equals(entity.getSecret());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!this.getClass().equals(o.getClass())) return false;
ClientAdapter that = (ClientAdapter) o;
return that.getId().equals(getId());
}
@Override
public int hashCode() {
return entity.getId().hashCode();
}
}

View file

@ -1,6 +1,7 @@
package org.keycloak.models.jpa;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.jpa.entities.OAuthClientEntity;
@ -13,7 +14,9 @@ import java.util.Set;
*/
public class OAuthClientAdapter extends ClientAdapter implements OAuthClientModel {
public OAuthClientAdapter(OAuthClientEntity entity) {
super(entity);
public OAuthClientAdapter(RealmModel realm, OAuthClientEntity entity) {
super(realm, entity);
}
}

View file

@ -3,6 +3,7 @@ package org.keycloak.models.jpa;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.jpa.entities.ApplicationEntity;
import org.keycloak.models.jpa.entities.ApplicationRoleEntity;
import org.keycloak.models.jpa.entities.CredentialEntity;
import org.keycloak.models.jpa.entities.OAuthClientEntity;
import org.keycloak.models.jpa.entities.RealmEntity;
@ -496,7 +497,7 @@ public class RealmAdapter implements RealmModel {
if (application == null) return false;
for (RoleModel role : application.getRoles()) {
application.removeRoleById(role.getId());
application.removeRole(role);
}
ApplicationEntity applicationEntity = null;
@ -673,12 +674,14 @@ public class RealmAdapter implements RealmModel {
data.setRealm(realm);
em.persist(data);
em.flush();
return new OAuthClientAdapter(data);
return new OAuthClientAdapter(this, data);
}
@Override
public boolean removeOAuthClient(String id) {
OAuthClientEntity client = em.find(OAuthClientEntity.class, id);
OAuthClientModel oauth = getOAuthClientById(id);
if (oauth == null) return false;
OAuthClientEntity client = (OAuthClientEntity)((OAuthClientAdapter)oauth).getEntity();
em.createQuery("delete from " + ScopeMappingEntity.class.getSimpleName() + " where client = :client").setParameter("client", client).executeUpdate();
em.remove(client);
return true;
@ -692,7 +695,7 @@ public class RealmAdapter implements RealmModel {
query.setParameter("realm", realm);
List<OAuthClientEntity> entities = query.getResultList();
if (entities.size() == 0) return null;
return new OAuthClientAdapter(entities.get(0));
return new OAuthClientAdapter(this, entities.get(0));
}
@Override
@ -700,8 +703,8 @@ public class RealmAdapter implements RealmModel {
OAuthClientEntity client = em.find(OAuthClientEntity.class, id);
// Check if client belongs to this realm
if (client == null || !this.realm.equals(client.getRealm())) return null;
return new OAuthClientAdapter(client);
if (client == null || !this.realm.getId().equals(client.getRealm().getId())) return null;
return new OAuthClientAdapter(this, client);
}
@ -711,7 +714,7 @@ public class RealmAdapter implements RealmModel {
query.setParameter("realm", realm);
List<OAuthClientEntity> entities = query.getResultList();
List<OAuthClientModel> list = new ArrayList<OAuthClientModel>();
for (OAuthClientEntity entity : entities) list.add(new OAuthClientAdapter(entity));
for (OAuthClientEntity entity : entities) list.add(new OAuthClientAdapter(this, entity));
return list;
}
@ -761,12 +764,12 @@ public class RealmAdapter implements RealmModel {
}
@Override
public boolean removeRoleById(String id) {
RoleModel role = getRoleById(id);
public boolean removeRole(RoleModel role) {
if (role == null) {
return false;
}
if (!role.getContainer().equals(this)) return false;
RoleEntity roleEntity = ((RoleAdapter)role).getRole();
realm.getRoles().remove(role);
realm.getDefaultRoles().remove(role);
@ -793,11 +796,22 @@ public class RealmAdapter implements RealmModel {
@Override
public RoleModel getRoleById(String id) {
RoleEntity entity = em.find(RoleEntity.class, id);
if (entity == null) return null;
if (entity instanceof RealmRoleEntity) {
RealmRoleEntity roleEntity = (RealmRoleEntity)entity;
if (!roleEntity.getRealm().getId().equals(getId())) return null;
} else {
ApplicationRoleEntity roleEntity = (ApplicationRoleEntity)entity;
if (!roleEntity.getApplication().getRealm().getId().equals(getId())) return null;
}
return new RoleAdapter(this, em, entity);
}
// Check if it's realm role and belongs to this realm
if (entity == null || !(entity instanceof RealmRoleEntity)) return null;
RealmRoleEntity realmRoleEntity = (RealmRoleEntity)entity;
return (realmRoleEntity.getRealm().equals(this.realm)) ? new RoleAdapter(this, em, realmRoleEntity) : null;
@Override
public boolean removeRoleById(String id) {
RoleModel role = getRoleById(id);
if (role == null) return false;
return role.getContainer().removeRole(role);
}
@Override

View file

@ -124,13 +124,13 @@ public class RoleAdapter implements RoleModel {
RoleAdapter that = (RoleAdapter) o;
if (!role.equals(that.role)) return false;
if (!role.getId().equals(that.role.getId())) return false;
return true;
}
@Override
public int hashCode() {
return role.hashCode();
return role.getId().hashCode();
}
}

View file

@ -1,66 +1,66 @@
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
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">
<persistence-unit name="jpa-keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.keycloak.models.jpa.entities.ApplicationEntity</class>
<class>org.keycloak.models.jpa.entities.CredentialEntity</class>
<class>org.keycloak.models.jpa.entities.OAuthClientEntity</class>
<class>org.keycloak.models.jpa.entities.RealmEntity</class>
<class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
<class>org.keycloak.models.jpa.entities.ApplicationRoleEntity</class>
<class>org.keycloak.models.jpa.entities.RealmRoleEntity</class>
<class>org.keycloak.models.jpa.entities.SocialLinkEntity</class>
<class>org.keycloak.models.jpa.entities.UserEntity</class>
<class>org.keycloak.models.jpa.entities.UserRoleMappingEntity</class>
<class>org.keycloak.models.jpa.entities.ScopeMappingEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.connection.url" value="jdbc:h2:mem:test"/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
<!--
<persistence-unit name="picketlink-keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.picketlink.idm.jpa.model.sample.simple.AttributedTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.AccountTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.RoleTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.GroupTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.IdentityTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.RelationshipTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.RelationshipIdentityTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.PartitionTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.PasswordCredentialTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.DigestCredentialTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.X509CredentialTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.OTPCredentialTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.AttributeTypeEntity</class>
<class>org.keycloak.models.picketlink.mappings.RealmEntity</class>
<class>org.keycloak.models.picketlink.mappings.ApplicationEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.connection.url" value="jdbc:h2:mem:test"/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
-->
</persistence>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
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">
<persistence-unit name="jpa-keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.keycloak.models.jpa.entities.ApplicationEntity</class>
<class>org.keycloak.models.jpa.entities.CredentialEntity</class>
<class>org.keycloak.models.jpa.entities.OAuthClientEntity</class>
<class>org.keycloak.models.jpa.entities.RealmEntity</class>
<class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
<class>org.keycloak.models.jpa.entities.ApplicationRoleEntity</class>
<class>org.keycloak.models.jpa.entities.RealmRoleEntity</class>
<class>org.keycloak.models.jpa.entities.SocialLinkEntity</class>
<class>org.keycloak.models.jpa.entities.UserEntity</class>
<class>org.keycloak.models.jpa.entities.UserRoleMappingEntity</class>
<class>org.keycloak.models.jpa.entities.ScopeMappingEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.connection.url" value="jdbc:h2:mem:test"/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
<!--
<persistence-unit name="picketlink-keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.picketlink.idm.jpa.model.sample.simple.AttributedTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.AccountTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.RoleTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.GroupTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.IdentityTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.RelationshipTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.RelationshipIdentityTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.PartitionTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.PasswordCredentialTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.DigestCredentialTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.X509CredentialTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.OTPCredentialTypeEntity</class>
<class>org.picketlink.idm.jpa.model.sample.simple.AttributeTypeEntity</class>
<class>org.keycloak.models.picketlink.mappings.RealmEntity</class>
<class>org.keycloak.models.picketlink.mappings.ApplicationEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.connection.url" value="jdbc:h2:mem:test"/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
-->
</persistence>

View file

@ -1,138 +1,138 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-alpha-3-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-model-mongo</artifactId>
<name>Keycloak Model Mongo</name>
<description/>
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.picketlink</groupId>
<artifactId>picketlink-common</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-tests</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<keycloak.mongo.host>localhost</keycloak.mongo.host>
<keycloak.mongo.port>27018</keycloak.mongo.port>
<keycloak.mongo.db>keycloak</keycloak.mongo.db>
<keycloak.mongo.clearOnStartup>true</keycloak.mongo.clearOnStartup>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<!-- Postpone tests to "integration-test" phase, so that we can bootstrap embedded mongo on 27018 before running tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>test</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<systemPropertyVariables>
<keycloak.mongo.host>${keycloak.mongo.host}</keycloak.mongo.host>
<keycloak.mongo.port>${keycloak.mongo.port}</keycloak.mongo.port>
<keycloak.mongo.db>${keycloak.mongo.db}</keycloak.mongo.db>
<keycloak.mongo.clearOnStartup>${keycloak.mongo.clearOnStartup}</keycloak.mongo.clearOnStartup>
</systemPropertyVariables>
<dependenciesToScan>
<dependency>org.keycloak:keycloak-model-tests</dependency>
</dependenciesToScan>
</configuration>
</execution>
<execution>
<id>default-test</id>
<configuration>
<skip>true</skip>
</configuration>
</execution>
</executions>
</plugin>
<!-- Embedded mongo -->
<plugin>
<groupId>com.github.joelittlejohn.embedmongo</groupId>
<artifactId>embedmongo-maven-plugin</artifactId>
<executions>
<execution>
<id>start-mongodb</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
<configuration>
<port>${keycloak.mongo.port}</port>
<logging>file</logging>
<logFile>${project.build.directory}/mongodb.log</logFile>
</configuration>
</execution>
<execution>
<id>stop-mongodb</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-alpha-3-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-model-mongo</artifactId>
<name>Keycloak Model Mongo</name>
<description/>
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.picketlink</groupId>
<artifactId>picketlink-common</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-tests</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<keycloak.mongo.host>localhost</keycloak.mongo.host>
<keycloak.mongo.port>27018</keycloak.mongo.port>
<keycloak.mongo.db>keycloak</keycloak.mongo.db>
<keycloak.mongo.clearOnStartup>true</keycloak.mongo.clearOnStartup>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<!-- Postpone tests to "integration-test" phase, so that we can bootstrap embedded mongo on 27018 before running tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>test</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<systemPropertyVariables>
<keycloak.mongo.host>${keycloak.mongo.host}</keycloak.mongo.host>
<keycloak.mongo.port>${keycloak.mongo.port}</keycloak.mongo.port>
<keycloak.mongo.db>${keycloak.mongo.db}</keycloak.mongo.db>
<keycloak.mongo.clearOnStartup>${keycloak.mongo.clearOnStartup}</keycloak.mongo.clearOnStartup>
</systemPropertyVariables>
<dependenciesToScan>
<dependency>org.keycloak:keycloak-model-tests</dependency>
</dependenciesToScan>
</configuration>
</execution>
<execution>
<id>default-test</id>
<configuration>
<skip>true</skip>
</configuration>
</execution>
</executions>
</plugin>
<!-- Embedded mongo -->
<plugin>
<groupId>com.github.joelittlejohn.embedmongo</groupId>
<artifactId>embedmongo-maven-plugin</artifactId>
<executions>
<execution>
<id>start-mongodb</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
<configuration>
<port>${keycloak.mongo.port}</port>
<logging>file</logging>
<logFile>${project.build.directory}/mongodb.log</logFile>
</configuration>
</execution>
<execution>
<id>stop-mongodb</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View file

@ -1,43 +1,43 @@
package org.keycloak.models.mongo.api;
import com.mongodb.DBObject;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public interface MongoStore {
/**
* Insert new entity
*
* @param entity to insert
*/
void insertEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context);
/**
* Update existing entity
*
* @param entity to update
*/
void updateEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context);
<T extends MongoIdentifiableEntity> T loadEntity(Class<T> type, String id, MongoStoreInvocationContext context);
<T extends MongoIdentifiableEntity> T loadSingleEntity(Class<T> type, DBObject query, MongoStoreInvocationContext context);
<T extends MongoIdentifiableEntity> List<T> loadEntities(Class<T> type, DBObject query, MongoStoreInvocationContext context);
boolean removeEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context);
boolean removeEntity(Class<? extends MongoIdentifiableEntity> type, String id, MongoStoreInvocationContext context);
boolean removeEntities(Class<? extends MongoIdentifiableEntity> type, DBObject query, MongoStoreInvocationContext context);
<S> boolean pushItemToList(MongoIdentifiableEntity entity, String listPropertyName, S itemToPush, boolean skipIfAlreadyPresent, MongoStoreInvocationContext context);
<S> boolean pullItemFromList(MongoIdentifiableEntity entity, String listPropertyName, S itemToPull, MongoStoreInvocationContext context);
}
package org.keycloak.models.mongo.api;
import com.mongodb.DBObject;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public interface MongoStore {
/**
* Insert new entity
*
* @param entity to insert
*/
void insertEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context);
/**
* Update existing entity
*
* @param entity to update
*/
void updateEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context);
<T extends MongoIdentifiableEntity> T loadEntity(Class<T> type, String id, MongoStoreInvocationContext context);
<T extends MongoIdentifiableEntity> T loadSingleEntity(Class<T> type, DBObject query, MongoStoreInvocationContext context);
<T extends MongoIdentifiableEntity> List<T> loadEntities(Class<T> type, DBObject query, MongoStoreInvocationContext context);
boolean removeEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context);
boolean removeEntity(Class<? extends MongoIdentifiableEntity> type, String id, MongoStoreInvocationContext context);
boolean removeEntities(Class<? extends MongoIdentifiableEntity> type, DBObject query, MongoStoreInvocationContext context);
<S> boolean pushItemToList(MongoIdentifiableEntity entity, String listPropertyName, S itemToPush, boolean skipIfAlreadyPresent, MongoStoreInvocationContext context);
<S> boolean pullItemFromList(MongoIdentifiableEntity entity, String listPropertyName, S itemToPull, MongoStoreInvocationContext context);
}

View file

@ -1,111 +1,111 @@
package org.keycloak.models.mongo.api.types;
import java.util.HashMap;
import java.util.Map;
/**
* Registry of mappers, which allow to convert application object to database objects. MapperRegistry is main entry point to be used by application.
* Application can create instance of MapperRegistry and then register required Mapper objects.
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class MapperRegistry {
// TODO: Thread-safety support (maybe...)
// Mappers of Application objects to DB objects
private Map<Class<?>, Mapper<?, ?>> appObjectMappers = new HashMap<Class<?>, Mapper<?, ?>>();
// Mappers of DB objects to Application objects
private Map<Class<?>, Map<Class<?>, Mapper<?, ?>>> dbObjectMappers = new HashMap<Class<?>, Map<Class<?>, Mapper<?,?>>>();
/**
* Add mapper for converting application objects to DB objects
*
* @param mapper
*/
public void addAppObjectMapper(Mapper<?, ?> mapper) {
appObjectMappers.put(mapper.getTypeOfObjectToConvert(), mapper);
}
/**
* Add mapper for converting DB objects to application objects
*
* @param mapper
*/
public void addDBObjectMapper(Mapper<?, ?> mapper) {
Class<?> dbObjectType = mapper.getTypeOfObjectToConvert();
Class<?> appObjectType = mapper.getExpectedReturnType();
Map<Class<?>, Mapper<?, ?>> appObjects = dbObjectMappers.get(dbObjectType);
if (appObjects == null) {
appObjects = new HashMap<Class<?>, Mapper<?, ?>>();
dbObjectMappers.put(dbObjectType, appObjects);
}
appObjects.put(appObjectType, mapper);
}
public <S> S convertDBObjectToApplicationObject(MapperContext<Object, S> context) {
Object dbObject = context.getObjectToConvert();
Class<?> expectedApplicationObjectType = context.getExpectedReturnType();
Class<?> dbObjectType = dbObject.getClass();
Mapper<Object, S> mapper;
Map<Class<?>, Mapper<?, ?>> appObjects = dbObjectMappers.get(dbObjectType);
if (appObjects == null) {
throw new IllegalArgumentException("Not found any mappers for type " + dbObjectType);
} else {
if (appObjects.size() == 1) {
mapper = (Mapper<Object, S>)appObjects.values().iterator().next();
} else {
// Try to find converter for requested application type
mapper = (Mapper<Object, S>)getAppConverterForType(context.getExpectedReturnType(), appObjects);
}
}
if (mapper == null) {
throw new IllegalArgumentException("Can't found mapper for type " + dbObjectType + " and expectedApplicationType " + expectedApplicationObjectType);
}
return mapper.convertObject(context);
}
public <S> S convertApplicationObjectToDBObject(Object applicationObject, Class<S> expectedDBObjectType) {
Class<?> appObjectType = applicationObject.getClass();
Mapper<Object, S> mapper = (Mapper<Object, S>)getAppConverterForType(appObjectType, appObjectMappers);
if (mapper == null) {
throw new IllegalArgumentException("Can't found converter for type " + appObjectType + " in registered appObjectMappers");
}
if (!expectedDBObjectType.isAssignableFrom(mapper.getExpectedReturnType())) {
throw new IllegalArgumentException("Converter " + mapper + " has return type " + mapper.getExpectedReturnType() +
" but we need type " + expectedDBObjectType);
}
return mapper.convertObject(new MapperContext<Object, S>(applicationObject, expectedDBObjectType, null));
}
// Try to find converter for given type or all it's supertypes
private static Mapper<Object, ?> getAppConverterForType(Class<?> appObjectType, Map<Class<?>, Mapper<?, ?>> appObjectConverters) {
Mapper<Object, ?> mapper = (Mapper<Object, ?>)appObjectConverters.get(appObjectType);
if (mapper != null) {
return mapper;
} else {
Class<?>[] interfaces = appObjectType.getInterfaces();
for (Class<?> interface1 : interfaces) {
mapper = getAppConverterForType(interface1, appObjectConverters);
if (mapper != null) {
return mapper;
}
}
Class<?> superType = appObjectType.getSuperclass();
if (superType != null) {
return getAppConverterForType(superType, appObjectConverters);
} else {
return null;
}
}
}
}
package org.keycloak.models.mongo.api.types;
import java.util.HashMap;
import java.util.Map;
/**
* Registry of mappers, which allow to convert application object to database objects. MapperRegistry is main entry point to be used by application.
* Application can create instance of MapperRegistry and then register required Mapper objects.
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class MapperRegistry {
// TODO: Thread-safety support (maybe...)
// Mappers of Application objects to DB objects
private Map<Class<?>, Mapper<?, ?>> appObjectMappers = new HashMap<Class<?>, Mapper<?, ?>>();
// Mappers of DB objects to Application objects
private Map<Class<?>, Map<Class<?>, Mapper<?, ?>>> dbObjectMappers = new HashMap<Class<?>, Map<Class<?>, Mapper<?,?>>>();
/**
* Add mapper for converting application objects to DB objects
*
* @param mapper
*/
public void addAppObjectMapper(Mapper<?, ?> mapper) {
appObjectMappers.put(mapper.getTypeOfObjectToConvert(), mapper);
}
/**
* Add mapper for converting DB objects to application objects
*
* @param mapper
*/
public void addDBObjectMapper(Mapper<?, ?> mapper) {
Class<?> dbObjectType = mapper.getTypeOfObjectToConvert();
Class<?> appObjectType = mapper.getExpectedReturnType();
Map<Class<?>, Mapper<?, ?>> appObjects = dbObjectMappers.get(dbObjectType);
if (appObjects == null) {
appObjects = new HashMap<Class<?>, Mapper<?, ?>>();
dbObjectMappers.put(dbObjectType, appObjects);
}
appObjects.put(appObjectType, mapper);
}
public <S> S convertDBObjectToApplicationObject(MapperContext<Object, S> context) {
Object dbObject = context.getObjectToConvert();
Class<?> expectedApplicationObjectType = context.getExpectedReturnType();
Class<?> dbObjectType = dbObject.getClass();
Mapper<Object, S> mapper;
Map<Class<?>, Mapper<?, ?>> appObjects = dbObjectMappers.get(dbObjectType);
if (appObjects == null) {
throw new IllegalArgumentException("Not found any mappers for type " + dbObjectType);
} else {
if (appObjects.size() == 1) {
mapper = (Mapper<Object, S>)appObjects.values().iterator().next();
} else {
// Try to find converter for requested application type
mapper = (Mapper<Object, S>)getAppConverterForType(context.getExpectedReturnType(), appObjects);
}
}
if (mapper == null) {
throw new IllegalArgumentException("Can't found mapper for type " + dbObjectType + " and expectedApplicationType " + expectedApplicationObjectType);
}
return mapper.convertObject(context);
}
public <S> S convertApplicationObjectToDBObject(Object applicationObject, Class<S> expectedDBObjectType) {
Class<?> appObjectType = applicationObject.getClass();
Mapper<Object, S> mapper = (Mapper<Object, S>)getAppConverterForType(appObjectType, appObjectMappers);
if (mapper == null) {
throw new IllegalArgumentException("Can't found converter for type " + appObjectType + " in registered appObjectMappers");
}
if (!expectedDBObjectType.isAssignableFrom(mapper.getExpectedReturnType())) {
throw new IllegalArgumentException("Converter " + mapper + " has return type " + mapper.getExpectedReturnType() +
" but we need type " + expectedDBObjectType);
}
return mapper.convertObject(new MapperContext<Object, S>(applicationObject, expectedDBObjectType, null));
}
// Try to find converter for given type or all it's supertypes
private static Mapper<Object, ?> getAppConverterForType(Class<?> appObjectType, Map<Class<?>, Mapper<?, ?>> appObjectConverters) {
Mapper<Object, ?> mapper = (Mapper<Object, ?>)appObjectConverters.get(appObjectType);
if (mapper != null) {
return mapper;
} else {
Class<?>[] interfaces = appObjectType.getInterfaces();
for (Class<?> interface1 : interfaces) {
mapper = getAppConverterForType(interface1, appObjectConverters);
if (mapper != null) {
return mapper;
}
}
Class<?> superType = appObjectType.getSuperclass();
if (superType != null) {
return getAppConverterForType(superType, appObjectConverters);
} else {
return null;
}
}
}
}

View file

@ -1,49 +1,49 @@
package org.keycloak.models.mongo.impl;
import org.keycloak.models.mongo.api.MongoEntity;
import org.picketlink.common.properties.Property;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class EntityInfo {
private final Class<? extends MongoEntity> entityClass;
private final String dbCollectionName;
private final Map<String, Property<Object>> properties;
public EntityInfo(Class<? extends MongoEntity> entityClass, String dbCollectionName, List<Property<Object>> properties) {
this.entityClass = entityClass;
this.dbCollectionName = dbCollectionName;
Map<String, Property<Object>> props= new HashMap<String, Property<Object>>();
for (Property<Object> property : properties) {
props.put(property.getName(), property);
}
this.properties = Collections.unmodifiableMap(props);
}
public Class<? extends MongoEntity> getEntityClass() {
return entityClass;
}
public String getDbCollectionName() {
return dbCollectionName;
}
public Collection<Property<Object>> getProperties() {
return properties.values();
}
public Property<Object> getPropertyByName(String propertyName) {
return properties.get(propertyName);
}
}
package org.keycloak.models.mongo.impl;
import org.keycloak.models.mongo.api.MongoEntity;
import org.picketlink.common.properties.Property;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class EntityInfo {
private final Class<? extends MongoEntity> entityClass;
private final String dbCollectionName;
private final Map<String, Property<Object>> properties;
public EntityInfo(Class<? extends MongoEntity> entityClass, String dbCollectionName, List<Property<Object>> properties) {
this.entityClass = entityClass;
this.dbCollectionName = dbCollectionName;
Map<String, Property<Object>> props= new HashMap<String, Property<Object>>();
for (Property<Object> property : properties) {
props.put(property.getName(), property);
}
this.properties = Collections.unmodifiableMap(props);
}
public Class<? extends MongoEntity> getEntityClass() {
return entityClass;
}
public String getDbCollectionName() {
return dbCollectionName;
}
public Collection<Property<Object>> getProperties() {
return properties.values();
}
public Property<Object> getPropertyByName(String propertyName) {
return properties.get(propertyName);
}
}

View file

@ -1,416 +1,416 @@
package org.keycloak.models.mongo.impl;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import org.jboss.logging.Logger;
import org.keycloak.models.mongo.api.MongoCollection;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoField;
import org.keycloak.models.mongo.api.MongoIdentifiableEntity;
import org.keycloak.models.mongo.api.MongoStore;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.mongo.api.context.MongoTask;
import org.keycloak.models.mongo.api.types.Mapper;
import org.keycloak.models.mongo.api.types.MapperContext;
import org.keycloak.models.mongo.api.types.MapperRegistry;
import org.keycloak.models.mongo.impl.types.BasicDBListMapper;
import org.keycloak.models.mongo.impl.types.BasicDBObjectMapper;
import org.keycloak.models.mongo.impl.types.BasicDBObjectToMapMapper;
import org.keycloak.models.mongo.impl.types.EnumToStringMapper;
import org.keycloak.models.mongo.impl.types.ListMapper;
import org.keycloak.models.mongo.impl.types.MapMapper;
import org.keycloak.models.mongo.impl.types.MongoEntityMapper;
import org.keycloak.models.mongo.impl.types.SimpleMapper;
import org.keycloak.models.mongo.impl.types.StringToEnumMapper;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.picketlink.common.properties.Property;
import org.picketlink.common.properties.query.AnnotatedPropertyCriteria;
import org.picketlink.common.properties.query.PropertyQueries;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class MongoStoreImpl implements MongoStore {
private static final Class<?>[] SIMPLE_TYPES = { String.class, Integer.class, Boolean.class, Long.class, Double.class, Character.class, Date.class, byte[].class };
private final DB database;
private static final Logger logger = Logger.getLogger(MongoStoreImpl.class);
private final MapperRegistry mapperRegistry;
private ConcurrentMap<Class<? extends MongoEntity>, EntityInfo> entityInfoCache =
new ConcurrentHashMap<Class<? extends MongoEntity>, EntityInfo>();
public MongoStoreImpl(DB database, boolean clearCollectionsOnStartup, Class<? extends MongoEntity>[] managedEntityTypes) {
this.database = database;
mapperRegistry = new MapperRegistry();
for (Class<?> simpleConverterClass : SIMPLE_TYPES) {
SimpleMapper converter = new SimpleMapper(simpleConverterClass);
mapperRegistry.addAppObjectMapper(converter);
mapperRegistry.addDBObjectMapper(converter);
}
// Specific converter for ArrayList is added just for performance purposes to avoid recursive converter lookup (most of list impl will be ArrayList)
mapperRegistry.addAppObjectMapper(new ListMapper(mapperRegistry, ArrayList.class));
mapperRegistry.addAppObjectMapper(new ListMapper(mapperRegistry, List.class));
mapperRegistry.addDBObjectMapper(new BasicDBListMapper(mapperRegistry));
mapperRegistry.addAppObjectMapper(new MapMapper(HashMap.class));
mapperRegistry.addAppObjectMapper(new MapMapper(Map.class));
mapperRegistry.addDBObjectMapper(new BasicDBObjectToMapMapper());
// Enum converters
mapperRegistry.addAppObjectMapper(new EnumToStringMapper());
mapperRegistry.addDBObjectMapper(new StringToEnumMapper());
for (Class<? extends MongoEntity> type : managedEntityTypes) {
getEntityInfo(type);
mapperRegistry.addAppObjectMapper(new MongoEntityMapper(this, mapperRegistry, type));
mapperRegistry.addDBObjectMapper(new BasicDBObjectMapper(this, mapperRegistry, type));
}
if (clearCollectionsOnStartup) {
// dropDatabase();
clearManagedCollections(managedEntityTypes);
}
}
protected void dropDatabase() {
this.database.dropDatabase();
logger.info("Database " + this.database.getName() + " dropped in MongoDB");
}
// Don't drop database, but just clear all data in managed collections (useful for development)
protected void clearManagedCollections(Class<? extends MongoEntity>[] managedEntityTypes) {
for (Class<? extends MongoEntity> clazz : managedEntityTypes) {
DBCollection dbCollection = getDBCollectionForType(clazz);
if (dbCollection != null) {
dbCollection.remove(new BasicDBObject());
logger.debug("Collection " + dbCollection.getName() + " cleared from " + this.database.getName());
}
}
}
@Override
public void insertEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context) {
Class<? extends MongoEntity> clazz = entity.getClass();
// Find annotations for ID, for all the properties and for the name of the collection.
EntityInfo entityInfo = getEntityInfo(clazz);
// Create instance of BasicDBObject and add all declared properties to it (properties with null value probably should be skipped)
BasicDBObject dbObject = mapperRegistry.convertApplicationObjectToDBObject(entity, BasicDBObject.class);
DBCollection dbCollection = database.getCollection(entityInfo.getDbCollectionName());
String currentId = entity.getId();
// Generate random ID if not set already
if (currentId == null) {
currentId = KeycloakModelUtils.generateId();
entity.setId(currentId);
}
// Adding "_id"
dbObject.put("_id", currentId);
dbCollection.insert(dbObject);
// Treat object as created in this transaction (It is already submited to transaction)
context.addCreatedEntity(entity);
}
@Override
public void updateEntity(final MongoIdentifiableEntity entity, MongoStoreInvocationContext context) {
MongoTask fullUpdateTask = new MongoTask() {
@Override
public void execute() {
Class<? extends MongoEntity> clazz = entity.getClass();
EntityInfo entityInfo = getEntityInfo(clazz);
BasicDBObject dbObject = mapperRegistry.convertApplicationObjectToDBObject(entity, BasicDBObject.class);
DBCollection dbCollection = database.getCollection(entityInfo.getDbCollectionName());
String currentId = entity.getId();
if (currentId == null) {
throw new IllegalStateException("Can't update entity without id: " + entity);
} else {
BasicDBObject query = new BasicDBObject("_id", currentId);
dbCollection.update(query, dbObject);
}
}
@Override
public boolean isFullUpdate() {
return true;
}
};
// update is just added to context and postponed
context.addUpdateTask(entity, fullUpdateTask);
}
@Override
public <T extends MongoIdentifiableEntity> T loadEntity(Class<T> type, String id, MongoStoreInvocationContext context) {
// First look if we already read the object with this oid and type during this transaction. If yes, use it instead of DB lookup
T cached = context.getLoadedEntity(type, id);
if (cached != null) return cached;
DBCollection dbCollection = getDBCollectionForType(type);
BasicDBObject idQuery = new BasicDBObject("_id", id);
DBObject dbObject = dbCollection.findOne(idQuery);
if (dbObject == null) return null;
MapperContext<Object, T> mapperContext = new MapperContext<Object, T>(dbObject, type, null);
T converted = mapperRegistry.convertDBObjectToApplicationObject(mapperContext);
// Now add it to loaded objects
context.addLoadedEntity(converted);
return converted;
}
@Override
public <T extends MongoIdentifiableEntity> T loadSingleEntity(Class<T> type, DBObject query, MongoStoreInvocationContext context) {
// First we should execute all pending tasks before searching DB
context.beforeDBSearch(type);
DBCollection dbCollection = getDBCollectionForType(type);
DBObject dbObject = dbCollection.findOne(query);
if (dbObject == null) {
return null;
} else {
return convertDBObjectToEntity(type, dbObject, context);
}
}
@Override
public <T extends MongoIdentifiableEntity> List<T> loadEntities(Class<T> type, DBObject query, MongoStoreInvocationContext context) {
// First we should execute all pending tasks before searching DB
context.beforeDBSearch(type);
DBCollection dbCollection = getDBCollectionForType(type);
DBCursor cursor = dbCollection.find(query);
return convertCursor(type, cursor, context);
}
@Override
public boolean removeEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context) {
return removeEntity(entity.getClass(), entity.getId(), context);
}
@Override
public boolean removeEntity(Class<? extends MongoIdentifiableEntity> type, String id, MongoStoreInvocationContext context) {
MongoIdentifiableEntity found = loadEntity(type, id, context);
if (found == null) {
return false;
} else {
DBCollection dbCollection = getDBCollectionForType(type);
BasicDBObject dbQuery = new BasicDBObject("_id", id);
dbCollection.remove(dbQuery);
logger.info("Entity of type: " + type + ", id: " + id + " removed from MongoDB.");
context.addRemovedEntity(found);
return true;
}
}
@Override
public boolean removeEntities(Class<? extends MongoIdentifiableEntity> type, DBObject query, MongoStoreInvocationContext context) {
List<? extends MongoIdentifiableEntity> foundObjects = loadEntities(type, query, context);
if (foundObjects.size() == 0) {
return false;
} else {
DBCollection dbCollection = getDBCollectionForType(type);
dbCollection.remove(query);
logger.info("Removed " + foundObjects.size() + " entities of type: " + type + ", query: " + query);
for (MongoIdentifiableEntity found : foundObjects) {
context.addRemovedEntity(found);;
}
return true;
}
}
@Override
public <S> boolean pushItemToList(final MongoIdentifiableEntity entity, final String listPropertyName, S itemToPush, boolean skipIfAlreadyPresent, MongoStoreInvocationContext context) {
final Class<? extends MongoEntity> type = entity.getClass();
EntityInfo entityInfo = getEntityInfo(type);
// Add item to list directly in this object
Property<Object> listProperty = entityInfo.getPropertyByName(listPropertyName);
if (listProperty == null) {
throw new IllegalArgumentException("Property " + listPropertyName + " doesn't exist on object " + entity);
}
List<S> list = (List<S>)listProperty.getValue(entity);
if (list == null) {
list = new ArrayList<S>();
listProperty.setValue(entity, list);
}
// Skip if item is already in list
if (skipIfAlreadyPresent && list.contains(itemToPush)) {
return false;
}
// Update java object
list.add(itemToPush);
// Add update of list to pending tasks
final List<S> listt = list;
context.addUpdateTask(entity, new MongoTask() {
@Override
public void execute() {
// Now DB update of new list with usage of $set
BasicDBList dbList = mapperRegistry.convertApplicationObjectToDBObject(listt, BasicDBList.class);
BasicDBObject query = new BasicDBObject("_id", entity.getId());
BasicDBObject listObject = new BasicDBObject(listPropertyName, dbList);
BasicDBObject setCommand = new BasicDBObject("$set", listObject);
getDBCollectionForType(type).update(query, setCommand);
}
@Override
public boolean isFullUpdate() {
return false;
}
});
return true;
}
@Override
public <S> boolean pullItemFromList(final MongoIdentifiableEntity entity, final String listPropertyName, final S itemToPull, MongoStoreInvocationContext context) {
final Class<? extends MongoEntity> type = entity.getClass();
EntityInfo entityInfo = getEntityInfo(type);
// Remove item from list directly in this object
Property<Object> listProperty = entityInfo.getPropertyByName(listPropertyName);
if (listProperty == null) {
throw new IllegalArgumentException("Property " + listPropertyName + " doesn't exist on object " + entity);
}
List<S> list = (List<S>)listProperty.getValue(entity);
// If list is null, we skip both object and DB update
if (list == null || !list.contains(itemToPull)) {
return false;
} else {
// Update java object
list.remove(itemToPull);
// Add update of list to pending tasks
context.addUpdateTask(entity, new MongoTask() {
@Override
public void execute() {
// Pull item from DB
Object dbItemToPull = mapperRegistry.convertApplicationObjectToDBObject(itemToPull, Object.class);
BasicDBObject query = new BasicDBObject("_id", entity.getId());
BasicDBObject pullObject = new BasicDBObject(listPropertyName, dbItemToPull);
BasicDBObject pullCommand = new BasicDBObject("$pull", pullObject);
getDBCollectionForType(type).update(query, pullCommand);
}
@Override
public boolean isFullUpdate() {
return false;
}
});
return true;
}
}
// Possibility to add user-defined mappers
public void addAppObjectConverter(Mapper<?, ?> mapper) {
mapperRegistry.addAppObjectMapper(mapper);
}
public void addDBObjectConverter(Mapper<?, ?> mapper) {
mapperRegistry.addDBObjectMapper(mapper);
}
public EntityInfo getEntityInfo(Class<? extends MongoEntity> entityClass) {
EntityInfo entityInfo = entityInfoCache.get(entityClass);
if (entityInfo == null) {
List<Property<Object>> properties = PropertyQueries.createQuery(entityClass).addCriteria(new AnnotatedPropertyCriteria(MongoField.class)).getResultList();
MongoCollection classAnnotation = entityClass.getAnnotation(MongoCollection.class);
String dbCollectionName = classAnnotation==null ? null : classAnnotation.collectionName();
entityInfo = new EntityInfo(entityClass, dbCollectionName, properties);
EntityInfo existing = entityInfoCache.putIfAbsent(entityClass, entityInfo);
if (existing != null) {
entityInfo = existing;
}
}
return entityInfo;
}
protected <T extends MongoIdentifiableEntity> List<T> convertCursor(Class<T> type, DBCursor cursor, MongoStoreInvocationContext context) {
List<T> result = new ArrayList<T>();
try {
for (DBObject dbObject : cursor) {
T entity = convertDBObjectToEntity(type, dbObject, context);
result.add(entity);
}
} finally {
cursor.close();
}
return result;
}
protected <T extends MongoIdentifiableEntity> T convertDBObjectToEntity(Class<T> 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<Object, T> mapperContext = new MapperContext<Object, T>(dbObject, type, null);
object = mapperRegistry.convertDBObjectToApplicationObject(mapperContext);
context.addLoadedEntity(object);
}
return object;
}
protected DBCollection getDBCollectionForType(Class<? extends MongoEntity> type) {
EntityInfo entityInfo = getEntityInfo(type);
String dbCollectionName = entityInfo.getDbCollectionName();
return dbCollectionName==null ? null : database.getCollection(dbCollectionName);
}
}
package org.keycloak.models.mongo.impl;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import org.jboss.logging.Logger;
import org.keycloak.models.mongo.api.MongoCollection;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoField;
import org.keycloak.models.mongo.api.MongoIdentifiableEntity;
import org.keycloak.models.mongo.api.MongoStore;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.mongo.api.context.MongoTask;
import org.keycloak.models.mongo.api.types.Mapper;
import org.keycloak.models.mongo.api.types.MapperContext;
import org.keycloak.models.mongo.api.types.MapperRegistry;
import org.keycloak.models.mongo.impl.types.BasicDBListMapper;
import org.keycloak.models.mongo.impl.types.BasicDBObjectMapper;
import org.keycloak.models.mongo.impl.types.BasicDBObjectToMapMapper;
import org.keycloak.models.mongo.impl.types.EnumToStringMapper;
import org.keycloak.models.mongo.impl.types.ListMapper;
import org.keycloak.models.mongo.impl.types.MapMapper;
import org.keycloak.models.mongo.impl.types.MongoEntityMapper;
import org.keycloak.models.mongo.impl.types.SimpleMapper;
import org.keycloak.models.mongo.impl.types.StringToEnumMapper;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.picketlink.common.properties.Property;
import org.picketlink.common.properties.query.AnnotatedPropertyCriteria;
import org.picketlink.common.properties.query.PropertyQueries;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class MongoStoreImpl implements MongoStore {
private static final Class<?>[] SIMPLE_TYPES = { String.class, Integer.class, Boolean.class, Long.class, Double.class, Character.class, Date.class, byte[].class };
private final DB database;
private static final Logger logger = Logger.getLogger(MongoStoreImpl.class);
private final MapperRegistry mapperRegistry;
private ConcurrentMap<Class<? extends MongoEntity>, EntityInfo> entityInfoCache =
new ConcurrentHashMap<Class<? extends MongoEntity>, EntityInfo>();
public MongoStoreImpl(DB database, boolean clearCollectionsOnStartup, Class<? extends MongoEntity>[] managedEntityTypes) {
this.database = database;
mapperRegistry = new MapperRegistry();
for (Class<?> simpleConverterClass : SIMPLE_TYPES) {
SimpleMapper converter = new SimpleMapper(simpleConverterClass);
mapperRegistry.addAppObjectMapper(converter);
mapperRegistry.addDBObjectMapper(converter);
}
// Specific converter for ArrayList is added just for performance purposes to avoid recursive converter lookup (most of list impl will be ArrayList)
mapperRegistry.addAppObjectMapper(new ListMapper(mapperRegistry, ArrayList.class));
mapperRegistry.addAppObjectMapper(new ListMapper(mapperRegistry, List.class));
mapperRegistry.addDBObjectMapper(new BasicDBListMapper(mapperRegistry));
mapperRegistry.addAppObjectMapper(new MapMapper(HashMap.class));
mapperRegistry.addAppObjectMapper(new MapMapper(Map.class));
mapperRegistry.addDBObjectMapper(new BasicDBObjectToMapMapper());
// Enum converters
mapperRegistry.addAppObjectMapper(new EnumToStringMapper());
mapperRegistry.addDBObjectMapper(new StringToEnumMapper());
for (Class<? extends MongoEntity> type : managedEntityTypes) {
getEntityInfo(type);
mapperRegistry.addAppObjectMapper(new MongoEntityMapper(this, mapperRegistry, type));
mapperRegistry.addDBObjectMapper(new BasicDBObjectMapper(this, mapperRegistry, type));
}
if (clearCollectionsOnStartup) {
// dropDatabase();
clearManagedCollections(managedEntityTypes);
}
}
protected void dropDatabase() {
this.database.dropDatabase();
logger.info("Database " + this.database.getName() + " dropped in MongoDB");
}
// Don't drop database, but just clear all data in managed collections (useful for development)
protected void clearManagedCollections(Class<? extends MongoEntity>[] managedEntityTypes) {
for (Class<? extends MongoEntity> clazz : managedEntityTypes) {
DBCollection dbCollection = getDBCollectionForType(clazz);
if (dbCollection != null) {
dbCollection.remove(new BasicDBObject());
logger.debug("Collection " + dbCollection.getName() + " cleared from " + this.database.getName());
}
}
}
@Override
public void insertEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context) {
Class<? extends MongoEntity> clazz = entity.getClass();
// Find annotations for ID, for all the properties and for the name of the collection.
EntityInfo entityInfo = getEntityInfo(clazz);
// Create instance of BasicDBObject and add all declared properties to it (properties with null value probably should be skipped)
BasicDBObject dbObject = mapperRegistry.convertApplicationObjectToDBObject(entity, BasicDBObject.class);
DBCollection dbCollection = database.getCollection(entityInfo.getDbCollectionName());
String currentId = entity.getId();
// Generate random ID if not set already
if (currentId == null) {
currentId = KeycloakModelUtils.generateId();
entity.setId(currentId);
}
// Adding "_id"
dbObject.put("_id", currentId);
dbCollection.insert(dbObject);
// Treat object as created in this transaction (It is already submited to transaction)
context.addCreatedEntity(entity);
}
@Override
public void updateEntity(final MongoIdentifiableEntity entity, MongoStoreInvocationContext context) {
MongoTask fullUpdateTask = new MongoTask() {
@Override
public void execute() {
Class<? extends MongoEntity> clazz = entity.getClass();
EntityInfo entityInfo = getEntityInfo(clazz);
BasicDBObject dbObject = mapperRegistry.convertApplicationObjectToDBObject(entity, BasicDBObject.class);
DBCollection dbCollection = database.getCollection(entityInfo.getDbCollectionName());
String currentId = entity.getId();
if (currentId == null) {
throw new IllegalStateException("Can't update entity without id: " + entity);
} else {
BasicDBObject query = new BasicDBObject("_id", currentId);
dbCollection.update(query, dbObject);
}
}
@Override
public boolean isFullUpdate() {
return true;
}
};
// update is just added to context and postponed
context.addUpdateTask(entity, fullUpdateTask);
}
@Override
public <T extends MongoIdentifiableEntity> T loadEntity(Class<T> type, String id, MongoStoreInvocationContext context) {
// First look if we already read the object with this oid and type during this transaction. If yes, use it instead of DB lookup
T cached = context.getLoadedEntity(type, id);
if (cached != null) return cached;
DBCollection dbCollection = getDBCollectionForType(type);
BasicDBObject idQuery = new BasicDBObject("_id", id);
DBObject dbObject = dbCollection.findOne(idQuery);
if (dbObject == null) return null;
MapperContext<Object, T> mapperContext = new MapperContext<Object, T>(dbObject, type, null);
T converted = mapperRegistry.convertDBObjectToApplicationObject(mapperContext);
// Now add it to loaded objects
context.addLoadedEntity(converted);
return converted;
}
@Override
public <T extends MongoIdentifiableEntity> T loadSingleEntity(Class<T> type, DBObject query, MongoStoreInvocationContext context) {
// First we should execute all pending tasks before searching DB
context.beforeDBSearch(type);
DBCollection dbCollection = getDBCollectionForType(type);
DBObject dbObject = dbCollection.findOne(query);
if (dbObject == null) {
return null;
} else {
return convertDBObjectToEntity(type, dbObject, context);
}
}
@Override
public <T extends MongoIdentifiableEntity> List<T> loadEntities(Class<T> type, DBObject query, MongoStoreInvocationContext context) {
// First we should execute all pending tasks before searching DB
context.beforeDBSearch(type);
DBCollection dbCollection = getDBCollectionForType(type);
DBCursor cursor = dbCollection.find(query);
return convertCursor(type, cursor, context);
}
@Override
public boolean removeEntity(MongoIdentifiableEntity entity, MongoStoreInvocationContext context) {
return removeEntity(entity.getClass(), entity.getId(), context);
}
@Override
public boolean removeEntity(Class<? extends MongoIdentifiableEntity> type, String id, MongoStoreInvocationContext context) {
MongoIdentifiableEntity found = loadEntity(type, id, context);
if (found == null) {
return false;
} else {
DBCollection dbCollection = getDBCollectionForType(type);
BasicDBObject dbQuery = new BasicDBObject("_id", id);
dbCollection.remove(dbQuery);
logger.info("Entity of type: " + type + ", id: " + id + " removed from MongoDB.");
context.addRemovedEntity(found);
return true;
}
}
@Override
public boolean removeEntities(Class<? extends MongoIdentifiableEntity> type, DBObject query, MongoStoreInvocationContext context) {
List<? extends MongoIdentifiableEntity> foundObjects = loadEntities(type, query, context);
if (foundObjects.size() == 0) {
return false;
} else {
DBCollection dbCollection = getDBCollectionForType(type);
dbCollection.remove(query);
logger.info("Removed " + foundObjects.size() + " entities of type: " + type + ", query: " + query);
for (MongoIdentifiableEntity found : foundObjects) {
context.addRemovedEntity(found);;
}
return true;
}
}
@Override
public <S> boolean pushItemToList(final MongoIdentifiableEntity entity, final String listPropertyName, S itemToPush, boolean skipIfAlreadyPresent, MongoStoreInvocationContext context) {
final Class<? extends MongoEntity> type = entity.getClass();
EntityInfo entityInfo = getEntityInfo(type);
// Add item to list directly in this object
Property<Object> listProperty = entityInfo.getPropertyByName(listPropertyName);
if (listProperty == null) {
throw new IllegalArgumentException("Property " + listPropertyName + " doesn't exist on object " + entity);
}
List<S> list = (List<S>)listProperty.getValue(entity);
if (list == null) {
list = new ArrayList<S>();
listProperty.setValue(entity, list);
}
// Skip if item is already in list
if (skipIfAlreadyPresent && list.contains(itemToPush)) {
return false;
}
// Update java object
list.add(itemToPush);
// Add update of list to pending tasks
final List<S> listt = list;
context.addUpdateTask(entity, new MongoTask() {
@Override
public void execute() {
// Now DB update of new list with usage of $set
BasicDBList dbList = mapperRegistry.convertApplicationObjectToDBObject(listt, BasicDBList.class);
BasicDBObject query = new BasicDBObject("_id", entity.getId());
BasicDBObject listObject = new BasicDBObject(listPropertyName, dbList);
BasicDBObject setCommand = new BasicDBObject("$set", listObject);
getDBCollectionForType(type).update(query, setCommand);
}
@Override
public boolean isFullUpdate() {
return false;
}
});
return true;
}
@Override
public <S> boolean pullItemFromList(final MongoIdentifiableEntity entity, final String listPropertyName, final S itemToPull, MongoStoreInvocationContext context) {
final Class<? extends MongoEntity> type = entity.getClass();
EntityInfo entityInfo = getEntityInfo(type);
// Remove item from list directly in this object
Property<Object> listProperty = entityInfo.getPropertyByName(listPropertyName);
if (listProperty == null) {
throw new IllegalArgumentException("Property " + listPropertyName + " doesn't exist on object " + entity);
}
List<S> list = (List<S>)listProperty.getValue(entity);
// If list is null, we skip both object and DB update
if (list == null || !list.contains(itemToPull)) {
return false;
} else {
// Update java object
list.remove(itemToPull);
// Add update of list to pending tasks
context.addUpdateTask(entity, new MongoTask() {
@Override
public void execute() {
// Pull item from DB
Object dbItemToPull = mapperRegistry.convertApplicationObjectToDBObject(itemToPull, Object.class);
BasicDBObject query = new BasicDBObject("_id", entity.getId());
BasicDBObject pullObject = new BasicDBObject(listPropertyName, dbItemToPull);
BasicDBObject pullCommand = new BasicDBObject("$pull", pullObject);
getDBCollectionForType(type).update(query, pullCommand);
}
@Override
public boolean isFullUpdate() {
return false;
}
});
return true;
}
}
// Possibility to add user-defined mappers
public void addAppObjectConverter(Mapper<?, ?> mapper) {
mapperRegistry.addAppObjectMapper(mapper);
}
public void addDBObjectConverter(Mapper<?, ?> mapper) {
mapperRegistry.addDBObjectMapper(mapper);
}
public EntityInfo getEntityInfo(Class<? extends MongoEntity> entityClass) {
EntityInfo entityInfo = entityInfoCache.get(entityClass);
if (entityInfo == null) {
List<Property<Object>> properties = PropertyQueries.createQuery(entityClass).addCriteria(new AnnotatedPropertyCriteria(MongoField.class)).getResultList();
MongoCollection classAnnotation = entityClass.getAnnotation(MongoCollection.class);
String dbCollectionName = classAnnotation==null ? null : classAnnotation.collectionName();
entityInfo = new EntityInfo(entityClass, dbCollectionName, properties);
EntityInfo existing = entityInfoCache.putIfAbsent(entityClass, entityInfo);
if (existing != null) {
entityInfo = existing;
}
}
return entityInfo;
}
protected <T extends MongoIdentifiableEntity> List<T> convertCursor(Class<T> type, DBCursor cursor, MongoStoreInvocationContext context) {
List<T> result = new ArrayList<T>();
try {
for (DBObject dbObject : cursor) {
T entity = convertDBObjectToEntity(type, dbObject, context);
result.add(entity);
}
} finally {
cursor.close();
}
return result;
}
protected <T extends MongoIdentifiableEntity> T convertDBObjectToEntity(Class<T> 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<Object, T> mapperContext = new MapperContext<Object, T>(dbObject, type, null);
object = mapperRegistry.convertDBObjectToApplicationObject(mapperContext);
context.addLoadedEntity(object);
}
return object;
}
protected DBCollection getDBCollectionForType(Class<? extends MongoEntity> type) {
EntityInfo entityInfo = getEntityInfo(type);
String dbCollectionName = entityInfo.getDbCollectionName();
return dbCollectionName==null ? null : database.getCollection(dbCollectionName);
}
}

View file

@ -1,44 +1,44 @@
package org.keycloak.models.mongo.impl.types;
import com.mongodb.BasicDBList;
import org.keycloak.models.mongo.api.types.Mapper;
import org.keycloak.models.mongo.api.types.MapperContext;
import org.keycloak.models.mongo.api.types.MapperRegistry;
import java.util.ArrayList;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class BasicDBListMapper implements Mapper<BasicDBList, List> {
private final MapperRegistry mapperRegistry;
public BasicDBListMapper(MapperRegistry mapperRegistry) {
this.mapperRegistry = mapperRegistry;
}
@Override
public List convertObject(MapperContext<BasicDBList, List> context) {
BasicDBList dbList = context.getObjectToConvert();
ArrayList<Object> appObjects = new ArrayList<Object>();
Class<?> expectedListElementType = context.getGenericTypes().get(0);
for (Object dbObject : dbList) {
MapperContext<Object, Object> newContext = new MapperContext<Object, Object>(dbObject, expectedListElementType, null);
appObjects.add(mapperRegistry.convertDBObjectToApplicationObject(newContext));
}
return appObjects;
}
@Override
public Class<? extends BasicDBList> getTypeOfObjectToConvert() {
return BasicDBList.class;
}
@Override
public Class<List> getExpectedReturnType() {
return List.class;
}
}
package org.keycloak.models.mongo.impl.types;
import com.mongodb.BasicDBList;
import org.keycloak.models.mongo.api.types.Mapper;
import org.keycloak.models.mongo.api.types.MapperContext;
import org.keycloak.models.mongo.api.types.MapperRegistry;
import java.util.ArrayList;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class BasicDBListMapper implements Mapper<BasicDBList, List> {
private final MapperRegistry mapperRegistry;
public BasicDBListMapper(MapperRegistry mapperRegistry) {
this.mapperRegistry = mapperRegistry;
}
@Override
public List convertObject(MapperContext<BasicDBList, List> context) {
BasicDBList dbList = context.getObjectToConvert();
ArrayList<Object> appObjects = new ArrayList<Object>();
Class<?> expectedListElementType = context.getGenericTypes().get(0);
for (Object dbObject : dbList) {
MapperContext<Object, Object> newContext = new MapperContext<Object, Object>(dbObject, expectedListElementType, null);
appObjects.add(mapperRegistry.convertDBObjectToApplicationObject(newContext));
}
return appObjects;
}
@Override
public Class<? extends BasicDBList> getTypeOfObjectToConvert() {
return BasicDBList.class;
}
@Override
public Class<List> getExpectedReturnType() {
return List.class;
}
}

View file

@ -1,45 +1,45 @@
package org.keycloak.models.mongo.impl.types;
import com.mongodb.BasicDBList;
import org.keycloak.models.mongo.api.types.Mapper;
import org.keycloak.models.mongo.api.types.MapperContext;
import org.keycloak.models.mongo.api.types.MapperRegistry;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class ListMapper<T extends List> implements Mapper<T, BasicDBList> {
private final MapperRegistry mapperRegistry;
private final Class<T> listType;
public ListMapper(MapperRegistry mapperRegistry, Class<T> listType) {
this.mapperRegistry = mapperRegistry;
this.listType = listType;
}
@Override
public BasicDBList convertObject(MapperContext<T, BasicDBList> context) {
T appObjectsList = context.getObjectToConvert();
BasicDBList dbObjects = new BasicDBList();
for (Object appObject : appObjectsList) {
Object dbObject = mapperRegistry.convertApplicationObjectToDBObject(appObject, Object.class);
dbObjects.add(dbObject);
}
return dbObjects;
}
@Override
public Class<? extends T> getTypeOfObjectToConvert() {
return listType;
}
@Override
public Class<BasicDBList> getExpectedReturnType() {
return BasicDBList.class;
}
}
package org.keycloak.models.mongo.impl.types;
import com.mongodb.BasicDBList;
import org.keycloak.models.mongo.api.types.Mapper;
import org.keycloak.models.mongo.api.types.MapperContext;
import org.keycloak.models.mongo.api.types.MapperRegistry;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class ListMapper<T extends List> implements Mapper<T, BasicDBList> {
private final MapperRegistry mapperRegistry;
private final Class<T> listType;
public ListMapper(MapperRegistry mapperRegistry, Class<T> listType) {
this.mapperRegistry = mapperRegistry;
this.listType = listType;
}
@Override
public BasicDBList convertObject(MapperContext<T, BasicDBList> context) {
T appObjectsList = context.getObjectToConvert();
BasicDBList dbObjects = new BasicDBList();
for (Object appObject : appObjectsList) {
Object dbObject = mapperRegistry.convertApplicationObjectToDBObject(appObject, Object.class);
dbObjects.add(dbObject);
}
return dbObjects;
}
@Override
public Class<? extends T> getTypeOfObjectToConvert() {
return listType;
}
@Override
public Class<BasicDBList> getExpectedReturnType() {
return BasicDBList.class;
}
}

View file

@ -1,58 +1,58 @@
package org.keycloak.models.mongo.impl.types;
import com.mongodb.BasicDBObject;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.types.Mapper;
import org.keycloak.models.mongo.api.types.MapperContext;
import org.keycloak.models.mongo.api.types.MapperRegistry;
import org.keycloak.models.mongo.impl.MongoStoreImpl;
import org.keycloak.models.mongo.impl.EntityInfo;
import org.picketlink.common.properties.Property;
import java.util.Collection;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class MongoEntityMapper<T extends MongoEntity> implements Mapper<T, BasicDBObject> {
private final MongoStoreImpl mongoStoreImpl;
private final MapperRegistry mapperRegistry;
private final Class<T> expectedMongoEntityType;
public MongoEntityMapper(MongoStoreImpl mongoStoreImpl, MapperRegistry mapperRegistry, Class<T> expectedMongoEntityType) {
this.mongoStoreImpl = mongoStoreImpl;
this.mapperRegistry = mapperRegistry;
this.expectedMongoEntityType = expectedMongoEntityType;
}
@Override
public BasicDBObject convertObject(MapperContext<T, BasicDBObject> context) {
T applicationObject = context.getObjectToConvert();
EntityInfo entityInfo = mongoStoreImpl.getEntityInfo(applicationObject.getClass());
// Create instance of BasicDBObject and add all declared properties to it
BasicDBObject dbObject = new BasicDBObject();
Collection<Property<Object>> props = entityInfo.getProperties();
for (Property<Object> property : props) {
String propName = property.getName();
Object propValue = property.getValue(applicationObject);
Object dbValue = propValue == null ? null : mapperRegistry.convertApplicationObjectToDBObject(propValue, Object.class);
dbObject.put(propName, dbValue);
}
return dbObject;
}
@Override
public Class<? extends T> getTypeOfObjectToConvert() {
return expectedMongoEntityType;
}
@Override
public Class<BasicDBObject> getExpectedReturnType() {
return BasicDBObject.class;
}
}
package org.keycloak.models.mongo.impl.types;
import com.mongodb.BasicDBObject;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.types.Mapper;
import org.keycloak.models.mongo.api.types.MapperContext;
import org.keycloak.models.mongo.api.types.MapperRegistry;
import org.keycloak.models.mongo.impl.MongoStoreImpl;
import org.keycloak.models.mongo.impl.EntityInfo;
import org.picketlink.common.properties.Property;
import java.util.Collection;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class MongoEntityMapper<T extends MongoEntity> implements Mapper<T, BasicDBObject> {
private final MongoStoreImpl mongoStoreImpl;
private final MapperRegistry mapperRegistry;
private final Class<T> expectedMongoEntityType;
public MongoEntityMapper(MongoStoreImpl mongoStoreImpl, MapperRegistry mapperRegistry, Class<T> expectedMongoEntityType) {
this.mongoStoreImpl = mongoStoreImpl;
this.mapperRegistry = mapperRegistry;
this.expectedMongoEntityType = expectedMongoEntityType;
}
@Override
public BasicDBObject convertObject(MapperContext<T, BasicDBObject> context) {
T applicationObject = context.getObjectToConvert();
EntityInfo entityInfo = mongoStoreImpl.getEntityInfo(applicationObject.getClass());
// Create instance of BasicDBObject and add all declared properties to it
BasicDBObject dbObject = new BasicDBObject();
Collection<Property<Object>> props = entityInfo.getProperties();
for (Property<Object> property : props) {
String propName = property.getName();
Object propValue = property.getValue(applicationObject);
Object dbValue = propValue == null ? null : mapperRegistry.convertApplicationObjectToDBObject(propValue, Object.class);
dbObject.put(propName, dbValue);
}
return dbObject;
}
@Override
public Class<? extends T> getTypeOfObjectToConvert() {
return expectedMongoEntityType;
}
@Override
public Class<BasicDBObject> getExpectedReturnType() {
return BasicDBObject.class;
}
}

View file

@ -1,305 +1,317 @@
package org.keycloak.models.mongo.keycloak.adapters;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity;
import org.keycloak.models.mongo.keycloak.entities.RoleEntity;
import org.keycloak.models.mongo.keycloak.entities.UserEntity;
import org.keycloak.models.mongo.utils.MongoModelUtils;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class ApplicationAdapter extends AbstractAdapter implements ApplicationModel {
private final ApplicationEntity application;
public ApplicationAdapter(ApplicationEntity applicationEntity, MongoStoreInvocationContext invContext) {
super(invContext);
this.application = applicationEntity;
}
@Override
public void updateApplication() {
getMongoStore().updateEntity(application, invocationContext);
}
@Override
public String getId() {
return application.getId();
}
@Override
public String getClientId() {
return getName();
}
@Override
public String getName() {
return application.getName();
}
@Override
public void setName(String name) {
application.setName(name);
}
@Override
public boolean isEnabled() {
return application.isEnabled();
}
@Override
public void setEnabled(boolean enabled) {
application.setEnabled(enabled);
}
@Override
public boolean isSurrogateAuthRequired() {
return application.isSurrogateAuthRequired();
}
@Override
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
application.setSurrogateAuthRequired(surrogateAuthRequired);
}
@Override
public String getManagementUrl() {
return application.getManagementUrl();
}
@Override
public void setManagementUrl(String url) {
application.setManagementUrl(url);
}
@Override
public void setBaseUrl(String url) {
application.setBaseUrl(url);
}
@Override
public String getBaseUrl() {
return application.getBaseUrl();
}
@Override
public long getAllowedClaimsMask() {
return application.getAllowedClaimsMask();
}
@Override
public void setAllowedClaimsMask(long mask) {
application.setAllowedClaimsMask(mask);
}
@Override
public RoleAdapter getRole(String name) {
DBObject query = new QueryBuilder()
.and("name").is(name)
.and("applicationId").is(getId())
.get();
RoleEntity role = getMongoStore().loadSingleEntity(RoleEntity.class, query, invocationContext);
if (role == null) {
return null;
} else {
return new RoleAdapter(role, invocationContext);
}
}
@Override
public RoleModel getRoleById(String id) {
RoleEntity role = getMongoStore().loadEntity(RoleEntity.class, id, invocationContext);
// Check that role belongs to this application
if (role == null || !getId().equals(role.getApplicationId())) {
return null;
} else {
return new RoleAdapter(role, this, invocationContext);
}
}
@Override
public RoleAdapter addRole(String name) {
RoleAdapter existing = getRole(name);
if (existing != null) {
return existing;
}
RoleEntity roleEntity = new RoleEntity();
roleEntity.setName(name);
roleEntity.setApplicationId(getId());
getMongoStore().insertEntity(roleEntity, invocationContext);
return new RoleAdapter(roleEntity, this, invocationContext);
}
@Override
public boolean removeRoleById(String id) {
return getMongoStore().removeEntity(RoleEntity.class, id, invocationContext);
}
@Override
public Set<RoleModel> getRoles() {
DBObject query = new QueryBuilder()
.and("applicationId").is(getId())
.get();
List<RoleEntity> roles = getMongoStore().loadEntities(RoleEntity.class, query, invocationContext);
Set<RoleModel> result = new HashSet<RoleModel>();
for (RoleEntity role : roles) {
result.add(new RoleAdapter(role, this, invocationContext));
}
return result;
}
@Override
public Set<RoleModel> getApplicationRoleMappings(UserModel user) {
Set<RoleModel> result = new HashSet<RoleModel>();
List<RoleEntity> roles = MongoModelUtils.getAllRolesOfUser(user, invocationContext);
for (RoleEntity role : roles) {
if (getId().equals(role.getApplicationId())) {
result.add(new RoleAdapter(role, this, invocationContext));
}
}
return result;
}
@Override
public void addScope(RoleModel role) {
getMongoStore().pushItemToList(application, "scopeIds", role.getId(), true, invocationContext);
}
@Override
public Set<RoleModel> getApplicationScopeMappings(ClientModel client) {
Set<RoleModel> result = new HashSet<RoleModel>();
List<RoleEntity> roles = MongoModelUtils.getAllScopesOfClient(client, invocationContext);
for (RoleEntity role : roles) {
if (getId().equals(role.getApplicationId())) {
result.add(new RoleAdapter(role, this, invocationContext));
}
}
return result;
}
@Override
public List<String> getDefaultRoles() {
return application.getDefaultRoles();
}
@Override
public void addDefaultRole(String name) {
RoleModel role = getRole(name);
if (role == null) {
addRole(name);
}
getMongoStore().pushItemToList(application, "defaultRoles", name, true, invocationContext);
}
@Override
public void updateDefaultRoles(String[] defaultRoles) {
List<String> roleNames = new ArrayList<String>();
for (String roleName : defaultRoles) {
RoleModel role = getRole(roleName);
if (role == null) {
addRole(roleName);
}
roleNames.add(roleName);
}
application.setDefaultRoles(roleNames);
}
@Override
public AbstractMongoIdentifiableEntity getMongoEntity() {
return application;
}
@Override
public Set<String> getWebOrigins() {
Set<String> result = new HashSet<String>();
if (application.getWebOrigins() != null) {
result.addAll(application.getWebOrigins());
}
return result;
}
@Override
public void setWebOrigins(Set<String> webOrigins) {
List<String> result = new ArrayList<String>();
result.addAll(webOrigins);
application.setWebOrigins(result);
}
@Override
public void addWebOrigin(String webOrigin) {
getMongoStore().pushItemToList(application, "webOrigins", webOrigin, true, invocationContext);
}
@Override
public void removeWebOrigin(String webOrigin) {
getMongoStore().pullItemFromList(application, "webOrigins", webOrigin, invocationContext);
}
@Override
public Set<String> getRedirectUris() {
Set<String> result = new HashSet<String>();
if (application.getRedirectUris() != null) {
result.addAll(application.getRedirectUris());
}
return result;
}
@Override
public void setRedirectUris(Set<String> redirectUris) {
List<String> result = new ArrayList<String>();
result.addAll(redirectUris);
application.setRedirectUris(result);
}
@Override
public void addRedirectUri(String redirectUri) {
getMongoStore().pushItemToList(application, "redirectUris", redirectUri, true, invocationContext);
}
@Override
public void removeRedirectUri(String redirectUri) {
getMongoStore().pullItemFromList(application, "redirectUris", redirectUri, invocationContext);
}
@Override
public String getSecret() {
return application.getSecret();
}
@Override
public void setSecret(String secret) {
application.setSecret(secret);
}
@Override
public boolean validateSecret(String secret) {
return secret.equals(application.getSecret());
}
}
package org.keycloak.models.mongo.keycloak.adapters;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity;
import org.keycloak.models.mongo.keycloak.entities.RoleEntity;
import org.keycloak.models.mongo.keycloak.entities.UserEntity;
import org.keycloak.models.mongo.utils.MongoModelUtils;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class ApplicationAdapter extends AbstractAdapter implements ApplicationModel {
private final ApplicationEntity application;
private final RealmModel realm;
public ApplicationAdapter(RealmModel realm, ApplicationEntity applicationEntity, MongoStoreInvocationContext invContext) {
super(invContext);
this.application = applicationEntity;
this.realm = realm;
}
@Override
public void updateApplication() {
getMongoStore().updateEntity(application, invocationContext);
}
@Override
public String getId() {
return application.getId();
}
@Override
public String getClientId() {
return getName();
}
@Override
public String getName() {
return application.getName();
}
@Override
public void setName(String name) {
application.setName(name);
}
@Override
public RealmModel getRealm() {
return realm;
}
@Override
public boolean isEnabled() {
return application.isEnabled();
}
@Override
public void setEnabled(boolean enabled) {
application.setEnabled(enabled);
}
@Override
public boolean isSurrogateAuthRequired() {
return application.isSurrogateAuthRequired();
}
@Override
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
application.setSurrogateAuthRequired(surrogateAuthRequired);
}
@Override
public String getManagementUrl() {
return application.getManagementUrl();
}
@Override
public void setManagementUrl(String url) {
application.setManagementUrl(url);
}
@Override
public void setBaseUrl(String url) {
application.setBaseUrl(url);
}
@Override
public String getBaseUrl() {
return application.getBaseUrl();
}
@Override
public long getAllowedClaimsMask() {
return application.getAllowedClaimsMask();
}
@Override
public void setAllowedClaimsMask(long mask) {
application.setAllowedClaimsMask(mask);
}
@Override
public RoleAdapter getRole(String name) {
DBObject query = new QueryBuilder()
.and("name").is(name)
.and("applicationId").is(getId())
.get();
RoleEntity role = getMongoStore().loadSingleEntity(RoleEntity.class, query, invocationContext);
if (role == null) {
return null;
} else {
return new RoleAdapter(getRealm(), role, invocationContext);
}
}
@Override
public RoleAdapter addRole(String name) {
RoleAdapter existing = getRole(name);
if (existing != null) {
return existing;
}
RoleEntity roleEntity = new RoleEntity();
roleEntity.setName(name);
roleEntity.setApplicationId(getId());
getMongoStore().insertEntity(roleEntity, invocationContext);
return new RoleAdapter(getRealm(), roleEntity, this, invocationContext);
}
@Override
public boolean removeRole(RoleModel role) {
return getMongoStore().removeEntity(RoleEntity.class, role.getId(), invocationContext);
}
@Override
public Set<RoleModel> getRoles() {
DBObject query = new QueryBuilder()
.and("applicationId").is(getId())
.get();
List<RoleEntity> roles = getMongoStore().loadEntities(RoleEntity.class, query, invocationContext);
Set<RoleModel> result = new HashSet<RoleModel>();
for (RoleEntity role : roles) {
result.add(new RoleAdapter(getRealm(), role, this, invocationContext));
}
return result;
}
@Override
public Set<RoleModel> getApplicationRoleMappings(UserModel user) {
Set<RoleModel> result = new HashSet<RoleModel>();
List<RoleEntity> roles = MongoModelUtils.getAllRolesOfUser(user, invocationContext);
for (RoleEntity role : roles) {
if (getId().equals(role.getApplicationId())) {
result.add(new RoleAdapter(getRealm(), role, this, invocationContext));
}
}
return result;
}
@Override
public void addScope(RoleModel role) {
getMongoStore().pushItemToList(application, "scopeIds", role.getId(), true, invocationContext);
}
@Override
public Set<RoleModel> getApplicationScopeMappings(ClientModel client) {
Set<RoleModel> result = new HashSet<RoleModel>();
List<RoleEntity> roles = MongoModelUtils.getAllScopesOfClient(client, invocationContext);
for (RoleEntity role : roles) {
if (getId().equals(role.getApplicationId())) {
result.add(new RoleAdapter(getRealm(), role, this, invocationContext));
}
}
return result;
}
@Override
public List<String> getDefaultRoles() {
return application.getDefaultRoles();
}
@Override
public void addDefaultRole(String name) {
RoleModel role = getRole(name);
if (role == null) {
addRole(name);
}
getMongoStore().pushItemToList(application, "defaultRoles", name, true, invocationContext);
}
@Override
public void updateDefaultRoles(String[] defaultRoles) {
List<String> roleNames = new ArrayList<String>();
for (String roleName : defaultRoles) {
RoleModel role = getRole(roleName);
if (role == null) {
addRole(roleName);
}
roleNames.add(roleName);
}
application.setDefaultRoles(roleNames);
}
@Override
public AbstractMongoIdentifiableEntity getMongoEntity() {
return application;
}
@Override
public Set<String> getWebOrigins() {
Set<String> result = new HashSet<String>();
if (application.getWebOrigins() != null) {
result.addAll(application.getWebOrigins());
}
return result;
}
@Override
public void setWebOrigins(Set<String> webOrigins) {
List<String> result = new ArrayList<String>();
result.addAll(webOrigins);
application.setWebOrigins(result);
}
@Override
public void addWebOrigin(String webOrigin) {
getMongoStore().pushItemToList(application, "webOrigins", webOrigin, true, invocationContext);
}
@Override
public void removeWebOrigin(String webOrigin) {
getMongoStore().pullItemFromList(application, "webOrigins", webOrigin, invocationContext);
}
@Override
public Set<String> getRedirectUris() {
Set<String> result = new HashSet<String>();
if (application.getRedirectUris() != null) {
result.addAll(application.getRedirectUris());
}
return result;
}
@Override
public void setRedirectUris(Set<String> redirectUris) {
List<String> result = new ArrayList<String>();
result.addAll(redirectUris);
application.setRedirectUris(result);
}
@Override
public void addRedirectUri(String redirectUri) {
getMongoStore().pushItemToList(application, "redirectUris", redirectUri, true, invocationContext);
}
@Override
public void removeRedirectUri(String redirectUri) {
getMongoStore().pullItemFromList(application, "redirectUris", redirectUri, invocationContext);
}
@Override
public String getSecret() {
return application.getSecret();
}
@Override
public void setSecret(String secret) {
application.setSecret(secret);
}
@Override
public boolean validateSecret(String secret) {
return secret.equals(application.getSecret());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ApplicationAdapter)) return false;
if (!super.equals(o)) return false;
ApplicationAdapter that = (ApplicationAdapter) o;
if (!application.getId().equals(that.application.getId())) return false;
return true;
}
@Override
public int hashCode() {
return application.getId().hashCode();
}
}

View file

@ -1,100 +1,100 @@
package org.keycloak.models.mongo.keycloak.adapters;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakTransaction;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.mongo.api.MongoStore;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.mongo.impl.context.TransactionMongoStoreInvocationContext;
import org.keycloak.models.mongo.keycloak.entities.RealmEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class MongoKeycloakSession implements KeycloakSession {
private final MongoStoreInvocationContext invocationContext;
private final MongoKeycloakTransaction transaction;
public MongoKeycloakSession(MongoStore mongoStore) {
// this.invocationContext = new SimpleMongoStoreInvocationContext(mongoStore);
this.invocationContext = new TransactionMongoStoreInvocationContext(mongoStore);
this.transaction = new MongoKeycloakTransaction(invocationContext);
}
@Override
public KeycloakTransaction getTransaction() {
return transaction;
}
@Override
public void close() {
// TODO
}
@Override
public RealmModel createRealm(String name) {
return createRealm(KeycloakModelUtils.generateId(), name);
}
@Override
public RealmModel createRealm(String id, String name) {
if (getRealm(id) != null) {
throw new IllegalStateException("Realm with id '" + id + "' already exists");
}
RealmEntity newRealm = new RealmEntity();
newRealm.setId(id);
newRealm.setName(name);
getMongoStore().insertEntity(newRealm, invocationContext);
return new RealmAdapter(newRealm, invocationContext);
}
@Override
public RealmModel getRealm(String id) {
RealmEntity realmEntity = getMongoStore().loadEntity(RealmEntity.class, id, invocationContext);
return realmEntity != null ? new RealmAdapter(realmEntity, invocationContext) : null;
}
@Override
public List<RealmModel> getRealms() {
DBObject query = new BasicDBObject();
List<RealmEntity> realms = getMongoStore().loadEntities(RealmEntity.class, query, invocationContext);
List<RealmModel> results = new ArrayList<RealmModel>();
for (RealmEntity realmEntity : realms) {
results.add(new RealmAdapter(realmEntity, invocationContext));
}
return results;
}
@Override
public RealmModel getRealmByName(String name) {
DBObject query = new QueryBuilder()
.and("name").is(name)
.get();
RealmEntity realm = getMongoStore().loadSingleEntity(RealmEntity.class, query, invocationContext);
if (realm == null) return null;
return new RealmAdapter(realm, invocationContext);
}
@Override
public boolean removeRealm(String id) {
return getMongoStore().removeEntity(RealmEntity.class, id, invocationContext);
}
protected MongoStore getMongoStore() {
return invocationContext.getMongoStore();
}
}
package org.keycloak.models.mongo.keycloak.adapters;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakTransaction;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.mongo.api.MongoStore;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.mongo.impl.context.TransactionMongoStoreInvocationContext;
import org.keycloak.models.mongo.keycloak.entities.RealmEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class MongoKeycloakSession implements KeycloakSession {
private final MongoStoreInvocationContext invocationContext;
private final MongoKeycloakTransaction transaction;
public MongoKeycloakSession(MongoStore mongoStore) {
// this.invocationContext = new SimpleMongoStoreInvocationContext(mongoStore);
this.invocationContext = new TransactionMongoStoreInvocationContext(mongoStore);
this.transaction = new MongoKeycloakTransaction(invocationContext);
}
@Override
public KeycloakTransaction getTransaction() {
return transaction;
}
@Override
public void close() {
// TODO
}
@Override
public RealmModel createRealm(String name) {
return createRealm(KeycloakModelUtils.generateId(), name);
}
@Override
public RealmModel createRealm(String id, String name) {
if (getRealm(id) != null) {
throw new IllegalStateException("Realm with id '" + id + "' already exists");
}
RealmEntity newRealm = new RealmEntity();
newRealm.setId(id);
newRealm.setName(name);
getMongoStore().insertEntity(newRealm, invocationContext);
return new RealmAdapter(newRealm, invocationContext);
}
@Override
public RealmModel getRealm(String id) {
RealmEntity realmEntity = getMongoStore().loadEntity(RealmEntity.class, id, invocationContext);
return realmEntity != null ? new RealmAdapter(realmEntity, invocationContext) : null;
}
@Override
public List<RealmModel> getRealms() {
DBObject query = new BasicDBObject();
List<RealmEntity> realms = getMongoStore().loadEntities(RealmEntity.class, query, invocationContext);
List<RealmModel> results = new ArrayList<RealmModel>();
for (RealmEntity realmEntity : realms) {
results.add(new RealmAdapter(realmEntity, invocationContext));
}
return results;
}
@Override
public RealmModel getRealmByName(String name) {
DBObject query = new QueryBuilder()
.and("name").is(name)
.get();
RealmEntity realm = getMongoStore().loadSingleEntity(RealmEntity.class, query, invocationContext);
if (realm == null) return null;
return new RealmAdapter(realm, invocationContext);
}
@Override
public boolean removeRealm(String id) {
return getMongoStore().removeEntity(RealmEntity.class, id, invocationContext);
}
protected MongoStore getMongoStore() {
return invocationContext.getMongoStore();
}
}

View file

@ -1,70 +1,70 @@
package org.keycloak.models.mongo.keycloak.adapters;
import com.mongodb.DB;
import com.mongodb.MongoClient;
import org.jboss.logging.Logger;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoStore;
import org.keycloak.models.mongo.impl.MongoStoreImpl;
import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity;
import org.keycloak.models.mongo.keycloak.entities.CredentialEntity;
import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity;
import org.keycloak.models.mongo.keycloak.entities.RealmEntity;
import org.keycloak.models.mongo.keycloak.entities.RequiredCredentialEntity;
import org.keycloak.models.mongo.keycloak.entities.RoleEntity;
import org.keycloak.models.mongo.keycloak.entities.SocialLinkEntity;
import org.keycloak.models.mongo.keycloak.entities.UserEntity;
import org.keycloak.models.mongo.utils.MongoConfiguration;
import java.net.UnknownHostException;
/**
* KeycloakSessionFactory implementation based on MongoDB
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class MongoKeycloakSessionFactory implements KeycloakSessionFactory {
protected static final Logger logger = Logger.getLogger(MongoKeycloakSessionFactory.class);
private static final Class<? extends MongoEntity>[] MANAGED_ENTITY_TYPES = (Class<? extends MongoEntity>[])new Class<?>[] {
RealmEntity.class,
UserEntity.class,
RoleEntity.class,
RequiredCredentialEntity.class,
CredentialEntity.class,
SocialLinkEntity.class,
ApplicationEntity.class,
OAuthClientEntity.class
};
private final MongoClient mongoClient;
private final MongoStore mongoStore;
public MongoKeycloakSessionFactory(MongoConfiguration config) {
logger.info(String.format("Configuring MongoStore with: " + config));
try {
// TODO: authentication support
mongoClient = new MongoClient(config.getHost(), config.getPort());
DB db = mongoClient.getDB(config.getDbName());
mongoStore = new MongoStoreImpl(db, config.isClearCollectionsOnStartup(), MANAGED_ENTITY_TYPES);
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
@Override
public KeycloakSession createSession() {
return new MongoKeycloakSession(mongoStore);
}
@Override
public void close() {
logger.info("Closing MongoDB client");
mongoClient.close();
}
}
package org.keycloak.models.mongo.keycloak.adapters;
import com.mongodb.DB;
import com.mongodb.MongoClient;
import org.jboss.logging.Logger;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoStore;
import org.keycloak.models.mongo.impl.MongoStoreImpl;
import org.keycloak.models.mongo.keycloak.entities.ApplicationEntity;
import org.keycloak.models.mongo.keycloak.entities.CredentialEntity;
import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity;
import org.keycloak.models.mongo.keycloak.entities.RealmEntity;
import org.keycloak.models.mongo.keycloak.entities.RequiredCredentialEntity;
import org.keycloak.models.mongo.keycloak.entities.RoleEntity;
import org.keycloak.models.mongo.keycloak.entities.SocialLinkEntity;
import org.keycloak.models.mongo.keycloak.entities.UserEntity;
import org.keycloak.models.mongo.utils.MongoConfiguration;
import java.net.UnknownHostException;
/**
* KeycloakSessionFactory implementation based on MongoDB
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class MongoKeycloakSessionFactory implements KeycloakSessionFactory {
protected static final Logger logger = Logger.getLogger(MongoKeycloakSessionFactory.class);
private static final Class<? extends MongoEntity>[] MANAGED_ENTITY_TYPES = (Class<? extends MongoEntity>[])new Class<?>[] {
RealmEntity.class,
UserEntity.class,
RoleEntity.class,
RequiredCredentialEntity.class,
CredentialEntity.class,
SocialLinkEntity.class,
ApplicationEntity.class,
OAuthClientEntity.class
};
private final MongoClient mongoClient;
private final MongoStore mongoStore;
public MongoKeycloakSessionFactory(MongoConfiguration config) {
logger.info(String.format("Configuring MongoStore with: " + config));
try {
// TODO: authentication support
mongoClient = new MongoClient(config.getHost(), config.getPort());
DB db = mongoClient.getDB(config.getDbName());
mongoStore = new MongoStoreImpl(db, config.isClearCollectionsOnStartup(), MANAGED_ENTITY_TYPES);
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
@Override
public KeycloakSession createSession() {
return new MongoKeycloakSession(mongoStore);
}
@Override
public void close() {
logger.info("Closing MongoDB client");
mongoClient.close();
}
}

View file

@ -1,131 +1,139 @@
package org.keycloak.models.mongo.keycloak.adapters;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity;
import org.keycloak.models.mongo.keycloak.entities.UserEntity;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class OAuthClientAdapter extends AbstractAdapter implements OAuthClientModel {
private final OAuthClientEntity delegate;
public OAuthClientAdapter(OAuthClientEntity oauthClientEntity, MongoStoreInvocationContext invContext) {
super(invContext);
this.delegate = oauthClientEntity;
}
@Override
public String getId() {
return delegate.getId();
}
@Override
public String getClientId() {
return delegate.getName();
}
@Override
public long getAllowedClaimsMask() {
return delegate.getAllowedClaimsMask();
}
@Override
public void setAllowedClaimsMask(long mask) {
delegate.setAllowedClaimsMask(mask);
}
@Override
public boolean isEnabled() {
return delegate.isEnabled();
}
@Override
public void setEnabled(boolean enabled) {
delegate.setEnabled(enabled);
}
@Override
public AbstractMongoIdentifiableEntity getMongoEntity() {
return delegate;
}
@Override
public Set<String> getWebOrigins() {
Set<String> result = new HashSet<String>();
if (delegate.getWebOrigins() != null) {
result.addAll(delegate.getWebOrigins());
}
return result;
}
@Override
public void setWebOrigins(Set<String> webOrigins) {
List<String> result = new ArrayList<String>();
result.addAll(webOrigins);
delegate.setWebOrigins(result);
}
@Override
public void addWebOrigin(String webOrigin) {
getMongoStore().pushItemToList(delegate, "webOrigins", webOrigin, true, invocationContext);
}
@Override
public void removeWebOrigin(String webOrigin) {
getMongoStore().pullItemFromList(delegate, "webOrigins", webOrigin, invocationContext);
}
@Override
public Set<String> getRedirectUris() {
Set<String> result = new HashSet<String>();
if (delegate.getRedirectUris() != null) {
result.addAll(delegate.getRedirectUris());
}
return result;
}
@Override
public void setRedirectUris(Set<String> redirectUris) {
List<String> result = new ArrayList<String>();
result.addAll(redirectUris);
delegate.setRedirectUris(result);
}
@Override
public void addRedirectUri(String redirectUri) {
getMongoStore().pushItemToList(delegate, "redirectUris", redirectUri, true, invocationContext);
}
@Override
public void removeRedirectUri(String redirectUri) {
getMongoStore().pullItemFromList(delegate, "redirectUris", redirectUri, invocationContext);
}
@Override
public String getSecret() {
return delegate.getSecret();
}
@Override
public void setSecret(String secret) {
delegate.setSecret(secret);
}
@Override
public boolean validateSecret(String secret) {
return secret.equals(delegate.getSecret());
}
}
package org.keycloak.models.mongo.keycloak.adapters;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.mongo.keycloak.entities.OAuthClientEntity;
import org.keycloak.models.mongo.keycloak.entities.UserEntity;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class OAuthClientAdapter extends AbstractAdapter implements OAuthClientModel {
private final OAuthClientEntity delegate;
private final RealmModel realm;
public OAuthClientAdapter(RealmModel realm, OAuthClientEntity oauthClientEntity, MongoStoreInvocationContext invContext) {
super(invContext);
this.delegate = oauthClientEntity;
this.realm = realm;
}
@Override
public String getId() {
return delegate.getId();
}
@Override
public String getClientId() {
return delegate.getName();
}
@Override
public RealmModel getRealm() {
return realm;
}
@Override
public long getAllowedClaimsMask() {
return delegate.getAllowedClaimsMask();
}
@Override
public void setAllowedClaimsMask(long mask) {
delegate.setAllowedClaimsMask(mask);
}
@Override
public boolean isEnabled() {
return delegate.isEnabled();
}
@Override
public void setEnabled(boolean enabled) {
delegate.setEnabled(enabled);
}
@Override
public AbstractMongoIdentifiableEntity getMongoEntity() {
return delegate;
}
@Override
public Set<String> getWebOrigins() {
Set<String> result = new HashSet<String>();
if (delegate.getWebOrigins() != null) {
result.addAll(delegate.getWebOrigins());
}
return result;
}
@Override
public void setWebOrigins(Set<String> webOrigins) {
List<String> result = new ArrayList<String>();
result.addAll(webOrigins);
delegate.setWebOrigins(result);
}
@Override
public void addWebOrigin(String webOrigin) {
getMongoStore().pushItemToList(delegate, "webOrigins", webOrigin, true, invocationContext);
}
@Override
public void removeWebOrigin(String webOrigin) {
getMongoStore().pullItemFromList(delegate, "webOrigins", webOrigin, invocationContext);
}
@Override
public Set<String> getRedirectUris() {
Set<String> result = new HashSet<String>();
if (delegate.getRedirectUris() != null) {
result.addAll(delegate.getRedirectUris());
}
return result;
}
@Override
public void setRedirectUris(Set<String> redirectUris) {
List<String> result = new ArrayList<String>();
result.addAll(redirectUris);
delegate.setRedirectUris(result);
}
@Override
public void addRedirectUri(String redirectUri) {
getMongoStore().pushItemToList(delegate, "redirectUris", redirectUri, true, invocationContext);
}
@Override
public void removeRedirectUri(String redirectUri) {
getMongoStore().pullItemFromList(delegate, "redirectUris", redirectUri, invocationContext);
}
@Override
public String getSecret() {
return delegate.getSecret();
}
@Override
public void setSecret(String secret) {
delegate.setSecret(secret);
}
@Override
public boolean validateSecret(String secret) {
return secret.equals(delegate.getSecret());
}
}

View file

@ -7,6 +7,7 @@ import java.util.Set;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
@ -26,15 +27,17 @@ public class RoleAdapter extends AbstractAdapter implements RoleModel {
private final RoleEntity role;
private RoleContainerModel roleContainer;
private RealmModel realm;
public RoleAdapter(RoleEntity roleEntity, MongoStoreInvocationContext invContext) {
this(roleEntity, null, invContext);
public RoleAdapter(RealmModel realm, RoleEntity roleEntity, MongoStoreInvocationContext invContext) {
this(realm, roleEntity, null, invContext);
}
public RoleAdapter(RoleEntity roleEntity, RoleContainerModel roleContainer, MongoStoreInvocationContext invContext) {
public RoleAdapter(RealmModel realm, RoleEntity roleEntity, RoleContainerModel roleContainer, MongoStoreInvocationContext invContext) {
super(invContext);
this.role = roleEntity;
this.roleContainer = roleContainer;
this.realm = realm;
}
@Override
@ -96,7 +99,7 @@ public class RoleAdapter extends AbstractAdapter implements RoleModel {
Set<RoleModel> set = new HashSet<RoleModel>();
for (RoleEntity childRole : childRoles) {
set.add(new RoleAdapter(childRole, invocationContext));
set.add(new RoleAdapter(realm, childRole, invocationContext));
}
return set;
}
@ -116,7 +119,7 @@ public class RoleAdapter extends AbstractAdapter implements RoleModel {
if (appEntity == null) {
throw new IllegalStateException("Application with id: " + role.getApplicationId() + " doesn't exists");
}
roleContainer = new ApplicationAdapter(appEntity, invocationContext);
roleContainer = new ApplicationAdapter(realm, appEntity, invocationContext);
} else {
throw new IllegalStateException("Both realmId and applicationId are null for role: " + this);
}
@ -141,4 +144,22 @@ public class RoleAdapter extends AbstractAdapter implements RoleModel {
public AbstractMongoIdentifiableEntity getMongoEntity() {
return role;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RoleAdapter that = (RoleAdapter) o;
if (!role.getId().equals(that.role.getId())) return false;
return true;
}
@Override
public int hashCode() {
return role.getId().hashCode();
}
}

View file

@ -1,166 +1,166 @@
package org.keycloak.models.mongo.keycloak.adapters;
import org.keycloak.models.UserModel;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.mongo.keycloak.entities.UserEntity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Wrapper around UserData object, which will persist wrapped object after each set operation (compatibility with picketlink based impl)
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class UserAdapter extends AbstractAdapter implements UserModel {
private final UserEntity user;
public UserAdapter(UserEntity userEntity, MongoStoreInvocationContext invContext) {
super(invContext);
this.user = userEntity;
}
@Override
public String getId() {
return user.getId();
}
@Override
public String getLoginName() {
return user.getLoginName();
}
@Override
public boolean isEnabled() {
return user.isEnabled();
}
@Override
public void setEnabled(boolean enabled) {
user.setEnabled(enabled);
updateUser();
}
@Override
public String getFirstName() {
return user.getFirstName();
}
@Override
public void setFirstName(String firstName) {
user.setFirstName(firstName);
updateUser();
}
@Override
public String getLastName() {
return user.getLastName();
}
@Override
public void setLastName(String lastName) {
user.setLastName(lastName);
updateUser();
}
@Override
public String getEmail() {
return user.getEmail();
}
@Override
public void setEmail(String email) {
user.setEmail(email);
updateUser();
}
@Override
public boolean isEmailVerified() {
return user.isEmailVerified();
}
@Override
public void setEmailVerified(boolean verified) {
user.setEmailVerified(verified);
updateUser();
}
@Override
public void setAttribute(String name, String value) {
if (user.getAttributes() == null) {
user.setAttributes(new HashMap<String, String>());
}
user.getAttributes().put(name, value);
updateUser();
}
@Override
public void removeAttribute(String name) {
if (user.getAttributes() == null) return;
user.getAttributes().remove(name);
updateUser();
}
@Override
public String getAttribute(String name) {
return user.getAttributes()==null ? null : user.getAttributes().get(name);
}
@Override
public Map<String, String> getAttributes() {
return user.getAttributes()==null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(user.getAttributes());
}
public UserEntity getUser() {
return user;
}
@Override
public Set<RequiredAction> getRequiredActions() {
Set<RequiredAction> result = new HashSet<RequiredAction>();
if (user.getRequiredActions() != null) {
result.addAll(user.getRequiredActions());
}
return result;
}
@Override
public void addRequiredAction(RequiredAction action) {
getMongoStore().pushItemToList(user, "requiredActions", action, true, invocationContext);
}
@Override
public void removeRequiredAction(RequiredAction action) {
getMongoStore().pullItemFromList(user, "requiredActions", action, invocationContext);
}
@Override
public boolean isTotp() {
return user.isTotp();
}
@Override
public void setTotp(boolean totp) {
user.setTotp(totp);
updateUser();
}
protected void updateUser() {
getMongoStore().updateEntity(user, invocationContext);
}
@Override
public AbstractMongoIdentifiableEntity getMongoEntity() {
return user;
}
}
package org.keycloak.models.mongo.keycloak.adapters;
import org.keycloak.models.UserModel;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.mongo.keycloak.entities.UserEntity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Wrapper around UserData object, which will persist wrapped object after each set operation (compatibility with picketlink based impl)
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class UserAdapter extends AbstractAdapter implements UserModel {
private final UserEntity user;
public UserAdapter(UserEntity userEntity, MongoStoreInvocationContext invContext) {
super(invContext);
this.user = userEntity;
}
@Override
public String getId() {
return user.getId();
}
@Override
public String getLoginName() {
return user.getLoginName();
}
@Override
public boolean isEnabled() {
return user.isEnabled();
}
@Override
public void setEnabled(boolean enabled) {
user.setEnabled(enabled);
updateUser();
}
@Override
public String getFirstName() {
return user.getFirstName();
}
@Override
public void setFirstName(String firstName) {
user.setFirstName(firstName);
updateUser();
}
@Override
public String getLastName() {
return user.getLastName();
}
@Override
public void setLastName(String lastName) {
user.setLastName(lastName);
updateUser();
}
@Override
public String getEmail() {
return user.getEmail();
}
@Override
public void setEmail(String email) {
user.setEmail(email);
updateUser();
}
@Override
public boolean isEmailVerified() {
return user.isEmailVerified();
}
@Override
public void setEmailVerified(boolean verified) {
user.setEmailVerified(verified);
updateUser();
}
@Override
public void setAttribute(String name, String value) {
if (user.getAttributes() == null) {
user.setAttributes(new HashMap<String, String>());
}
user.getAttributes().put(name, value);
updateUser();
}
@Override
public void removeAttribute(String name) {
if (user.getAttributes() == null) return;
user.getAttributes().remove(name);
updateUser();
}
@Override
public String getAttribute(String name) {
return user.getAttributes()==null ? null : user.getAttributes().get(name);
}
@Override
public Map<String, String> getAttributes() {
return user.getAttributes()==null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(user.getAttributes());
}
public UserEntity getUser() {
return user;
}
@Override
public Set<RequiredAction> getRequiredActions() {
Set<RequiredAction> result = new HashSet<RequiredAction>();
if (user.getRequiredActions() != null) {
result.addAll(user.getRequiredActions());
}
return result;
}
@Override
public void addRequiredAction(RequiredAction action) {
getMongoStore().pushItemToList(user, "requiredActions", action, true, invocationContext);
}
@Override
public void removeRequiredAction(RequiredAction action) {
getMongoStore().pullItemFromList(user, "requiredActions", action, invocationContext);
}
@Override
public boolean isTotp() {
return user.isTotp();
}
@Override
public void setTotp(boolean totp) {
user.setTotp(totp);
updateUser();
}
protected void updateUser() {
getMongoStore().updateEntity(user, invocationContext);
}
@Override
public AbstractMongoIdentifiableEntity getMongoEntity() {
return user;
}
}

View file

@ -1,157 +1,157 @@
package org.keycloak.models.mongo.keycloak.entities;
import java.util.ArrayList;
import java.util.List;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.MongoCollection;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoField;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@MongoCollection(collectionName = "applications")
public class ApplicationEntity extends AbstractMongoIdentifiableEntity implements MongoEntity, ScopedEntity {
private String name;
private boolean enabled;
private boolean surrogateAuthRequired;
private String managementUrl;
private String baseUrl;
private String secret;
private String realmId;
private long allowedClaimsMask;
private List<String> scopeIds;
private List<String> webOrigins;
private List<String> redirectUris;
// We are using names of defaultRoles (not ids)
private List<String> defaultRoles = new ArrayList<String>();
@MongoField
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@MongoField
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@MongoField
public boolean isSurrogateAuthRequired() {
return surrogateAuthRequired;
}
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
this.surrogateAuthRequired = surrogateAuthRequired;
}
@MongoField
public String getManagementUrl() {
return managementUrl;
}
public void setManagementUrl(String managementUrl) {
this.managementUrl = managementUrl;
}
@MongoField
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
@Override
@MongoField
public List<String> getScopeIds() {
return scopeIds;
}
@Override
public void setScopeIds(List<String> scopeIds) {
this.scopeIds = scopeIds;
}
@MongoField
public List<String> getWebOrigins() {
return webOrigins;
}
public void setWebOrigins(List<String> webOrigins) {
this.webOrigins = webOrigins;
}
@MongoField
public List<String> getRedirectUris() {
return redirectUris;
}
public void setRedirectUris(List<String> redirectUris) {
this.redirectUris = redirectUris;
}
@MongoField
public long getAllowedClaimsMask() {
return allowedClaimsMask;
}
public void setAllowedClaimsMask(long allowedClaimsMask) {
this.allowedClaimsMask = allowedClaimsMask;
}
@MongoField
public String getRealmId() {
return realmId;
}
public void setRealmId(String realmId) {
this.realmId = realmId;
}
@MongoField
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
@MongoField
public List<String> getDefaultRoles() {
return defaultRoles;
}
public void setDefaultRoles(List<String> defaultRoles) {
this.defaultRoles = defaultRoles;
}
@Override
public void afterRemove(MongoStoreInvocationContext context) {
// Remove all roles, which belongs to this application
DBObject query = new QueryBuilder()
.and("applicationId").is(getId())
.get();
context.getMongoStore().removeEntities(RoleEntity.class, query, context);
}
}
package org.keycloak.models.mongo.keycloak.entities;
import java.util.ArrayList;
import java.util.List;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.MongoCollection;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoField;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@MongoCollection(collectionName = "applications")
public class ApplicationEntity extends AbstractMongoIdentifiableEntity implements MongoEntity, ScopedEntity {
private String name;
private boolean enabled;
private boolean surrogateAuthRequired;
private String managementUrl;
private String baseUrl;
private String secret;
private String realmId;
private long allowedClaimsMask;
private List<String> scopeIds;
private List<String> webOrigins;
private List<String> redirectUris;
// We are using names of defaultRoles (not ids)
private List<String> defaultRoles = new ArrayList<String>();
@MongoField
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@MongoField
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@MongoField
public boolean isSurrogateAuthRequired() {
return surrogateAuthRequired;
}
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
this.surrogateAuthRequired = surrogateAuthRequired;
}
@MongoField
public String getManagementUrl() {
return managementUrl;
}
public void setManagementUrl(String managementUrl) {
this.managementUrl = managementUrl;
}
@MongoField
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
@Override
@MongoField
public List<String> getScopeIds() {
return scopeIds;
}
@Override
public void setScopeIds(List<String> scopeIds) {
this.scopeIds = scopeIds;
}
@MongoField
public List<String> getWebOrigins() {
return webOrigins;
}
public void setWebOrigins(List<String> webOrigins) {
this.webOrigins = webOrigins;
}
@MongoField
public List<String> getRedirectUris() {
return redirectUris;
}
public void setRedirectUris(List<String> redirectUris) {
this.redirectUris = redirectUris;
}
@MongoField
public long getAllowedClaimsMask() {
return allowedClaimsMask;
}
public void setAllowedClaimsMask(long allowedClaimsMask) {
this.allowedClaimsMask = allowedClaimsMask;
}
@MongoField
public String getRealmId() {
return realmId;
}
public void setRealmId(String realmId) {
this.realmId = realmId;
}
@MongoField
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
@MongoField
public List<String> getDefaultRoles() {
return defaultRoles;
}
public void setDefaultRoles(List<String> defaultRoles) {
this.defaultRoles = defaultRoles;
}
@Override
public void afterRemove(MongoStoreInvocationContext context) {
// Remove all roles, which belongs to this application
DBObject query = new QueryBuilder()
.and("applicationId").is(getId())
.get();
context.getMongoStore().removeEntities(RoleEntity.class, query, context);
}
}

View file

@ -1,105 +1,105 @@
package org.keycloak.models.mongo.keycloak.entities;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.MongoCollection;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoField;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@MongoCollection(collectionName = "oauthClients")
public class OAuthClientEntity extends AbstractMongoIdentifiableEntity implements MongoEntity, ScopedEntity {
private String name;
private boolean enabled;
private String realmId;
private String secret;
private long allowedClaimsMask;
private List<String> scopeIds;
private List<String> webOrigins;
private List<String> redirectUris;
@MongoField
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@MongoField
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@MongoField
public String getRealmId() {
return realmId;
}
public void setRealmId(String realmId) {
this.realmId = realmId;
}
@MongoField
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
@MongoField
public long getAllowedClaimsMask() {
return allowedClaimsMask;
}
public void setAllowedClaimsMask(long allowedClaimsMask) {
this.allowedClaimsMask = allowedClaimsMask;
}
@MongoField
public List<String> getWebOrigins() {
return webOrigins;
}
public void setWebOrigins(List<String> webOrigins) {
this.webOrigins = webOrigins;
}
@MongoField
public List<String> getRedirectUris() {
return redirectUris;
}
public void setRedirectUris(List<String> redirectUris) {
this.redirectUris = redirectUris;
}
@MongoField
public List<String> getScopeIds() {
return scopeIds;
}
public void setScopeIds(List<String> scopeIds) {
this.scopeIds = scopeIds;
}
@Override
public void afterRemove(MongoStoreInvocationContext context) {
}
}
package org.keycloak.models.mongo.keycloak.entities;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.MongoCollection;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoField;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@MongoCollection(collectionName = "oauthClients")
public class OAuthClientEntity extends AbstractMongoIdentifiableEntity implements MongoEntity, ScopedEntity {
private String name;
private boolean enabled;
private String realmId;
private String secret;
private long allowedClaimsMask;
private List<String> scopeIds;
private List<String> webOrigins;
private List<String> redirectUris;
@MongoField
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@MongoField
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@MongoField
public String getRealmId() {
return realmId;
}
public void setRealmId(String realmId) {
this.realmId = realmId;
}
@MongoField
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
@MongoField
public long getAllowedClaimsMask() {
return allowedClaimsMask;
}
public void setAllowedClaimsMask(long allowedClaimsMask) {
this.allowedClaimsMask = allowedClaimsMask;
}
@MongoField
public List<String> getWebOrigins() {
return webOrigins;
}
public void setWebOrigins(List<String> webOrigins) {
this.webOrigins = webOrigins;
}
@MongoField
public List<String> getRedirectUris() {
return redirectUris;
}
public void setRedirectUris(List<String> redirectUris) {
this.redirectUris = redirectUris;
}
@MongoField
public List<String> getScopeIds() {
return scopeIds;
}
public void setScopeIds(List<String> scopeIds) {
this.scopeIds = scopeIds;
}
@Override
public void afterRemove(MongoStoreInvocationContext context) {
}
}

View file

@ -1,285 +1,285 @@
package org.keycloak.models.mongo.keycloak.entities;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.MongoCollection;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoField;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@MongoCollection(collectionName = "realms")
public class RealmEntity extends AbstractMongoIdentifiableEntity implements MongoEntity {
private String name;
private boolean enabled;
private boolean sslNotRequired;
private boolean registrationAllowed;
private boolean rememberMe;
private boolean verifyEmail;
private boolean resetPasswordAllowed;
private boolean social;
private boolean updateProfileOnInitialSocialLogin;
private String passwordPolicy;
private int centralLoginLifespan;
private int accessTokenLifespan;
private int accessCodeLifespan;
private int accessCodeLifespanUserAction;
private int refreshTokenLifespan;
private int notBefore;
private String publicKeyPem;
private String privateKeyPem;
private String loginTheme;
private String accountTheme;
// We are using names of defaultRoles (not ids)
private List<String> defaultRoles = new ArrayList<String>();
private List<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
private Map<String, String> smtpConfig = new HashMap<String, String>();
private Map<String, String> socialConfig = new HashMap<String, String>();
@MongoField
public String getName() {
return name;
}
public void setName(String realmName) {
this.name = realmName;
}
@MongoField
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@MongoField
public boolean isSslNotRequired() {
return sslNotRequired;
}
public void setSslNotRequired(boolean sslNotRequired) {
this.sslNotRequired = sslNotRequired;
}
@MongoField
public boolean isRegistrationAllowed() {
return registrationAllowed;
}
public void setRegistrationAllowed(boolean registrationAllowed) {
this.registrationAllowed = registrationAllowed;
}
@MongoField
public boolean isRememberMe() {
return rememberMe;
}
public void setRememberMe(boolean rememberMe) {
this.rememberMe = rememberMe;
}
@MongoField
public boolean isVerifyEmail() {
return verifyEmail;
}
public void setVerifyEmail(boolean verifyEmail) {
this.verifyEmail = verifyEmail;
}
@MongoField
public boolean isResetPasswordAllowed() {
return resetPasswordAllowed;
}
public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
this.resetPasswordAllowed = resetPasswordAllowed;
}
@MongoField
public boolean isSocial() {
return social;
}
public void setSocial(boolean social) {
this.social = social;
}
@MongoField
public boolean isUpdateProfileOnInitialSocialLogin() {
return updateProfileOnInitialSocialLogin;
}
public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) {
this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin;
}
@MongoField
public String getPasswordPolicy() {
return passwordPolicy;
}
public void setPasswordPolicy(String passwordPolicy) {
this.passwordPolicy = passwordPolicy;
}
@MongoField
public int getNotBefore() {
return notBefore;
}
public void setNotBefore(int notBefore) {
this.notBefore = notBefore;
}
@MongoField
public int getCentralLoginLifespan() {
return centralLoginLifespan;
}
public void setCentralLoginLifespan(int centralLoginLifespan) {
this.centralLoginLifespan = centralLoginLifespan;
}
@MongoField
public int getAccessTokenLifespan() {
return accessTokenLifespan;
}
public void setAccessTokenLifespan(int accessTokenLifespan) {
this.accessTokenLifespan = accessTokenLifespan;
}
@MongoField
public int getRefreshTokenLifespan() {
return refreshTokenLifespan;
}
public void setRefreshTokenLifespan(int refreshTokenLifespan) {
this.refreshTokenLifespan = refreshTokenLifespan;
}
@MongoField
public int getAccessCodeLifespan() {
return accessCodeLifespan;
}
public void setAccessCodeLifespan(int accessCodeLifespan) {
this.accessCodeLifespan = accessCodeLifespan;
}
@MongoField
public int getAccessCodeLifespanUserAction() {
return accessCodeLifespanUserAction;
}
public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
this.accessCodeLifespanUserAction = accessCodeLifespanUserAction;
}
@MongoField
public String getPublicKeyPem() {
return publicKeyPem;
}
public void setPublicKeyPem(String publicKeyPem) {
this.publicKeyPem = publicKeyPem;
}
@MongoField
public String getPrivateKeyPem() {
return privateKeyPem;
}
public void setPrivateKeyPem(String privateKeyPem) {
this.privateKeyPem = privateKeyPem;
}
@MongoField
public String getLoginTheme() {
return loginTheme;
}
public void setLoginTheme(String loginTheme) {
this.loginTheme = loginTheme;
}
@MongoField
public String getAccountTheme() {
return accountTheme;
}
public void setAccountTheme(String accountTheme) {
this.accountTheme = accountTheme;
}
@MongoField
public List<String> getDefaultRoles() {
return defaultRoles;
}
public void setDefaultRoles(List<String> defaultRoles) {
this.defaultRoles = defaultRoles;
}
@MongoField
public List<RequiredCredentialEntity> getRequiredCredentials() {
return requiredCredentials;
}
public void setRequiredCredentials(List<RequiredCredentialEntity> requiredCredentials) {
this.requiredCredentials = requiredCredentials;
}
@MongoField
public Map<String, String> getSmtpConfig() {
return smtpConfig;
}
public void setSmtpConfig(Map<String, String> smptConfig) {
this.smtpConfig = smptConfig;
}
@MongoField
public Map<String, String> getSocialConfig() {
return socialConfig;
}
public void setSocialConfig(Map<String, String> socialConfig) {
this.socialConfig = socialConfig;
}
@Override
public void afterRemove(MongoStoreInvocationContext context) {
DBObject query = new QueryBuilder()
.and("realmId").is(getId())
.get();
// Remove all users of this realm
context.getMongoStore().removeEntities(UserEntity.class, query, context);
// Remove all roles of this realm
context.getMongoStore().removeEntities(RoleEntity.class, query, context);
// Remove all applications of this realm
context.getMongoStore().removeEntities(ApplicationEntity.class, query, context);
}
}
package org.keycloak.models.mongo.keycloak.entities;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.MongoCollection;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoField;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@MongoCollection(collectionName = "realms")
public class RealmEntity extends AbstractMongoIdentifiableEntity implements MongoEntity {
private String name;
private boolean enabled;
private boolean sslNotRequired;
private boolean registrationAllowed;
private boolean rememberMe;
private boolean verifyEmail;
private boolean resetPasswordAllowed;
private boolean social;
private boolean updateProfileOnInitialSocialLogin;
private String passwordPolicy;
private int centralLoginLifespan;
private int accessTokenLifespan;
private int accessCodeLifespan;
private int accessCodeLifespanUserAction;
private int refreshTokenLifespan;
private int notBefore;
private String publicKeyPem;
private String privateKeyPem;
private String loginTheme;
private String accountTheme;
// We are using names of defaultRoles (not ids)
private List<String> defaultRoles = new ArrayList<String>();
private List<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
private Map<String, String> smtpConfig = new HashMap<String, String>();
private Map<String, String> socialConfig = new HashMap<String, String>();
@MongoField
public String getName() {
return name;
}
public void setName(String realmName) {
this.name = realmName;
}
@MongoField
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@MongoField
public boolean isSslNotRequired() {
return sslNotRequired;
}
public void setSslNotRequired(boolean sslNotRequired) {
this.sslNotRequired = sslNotRequired;
}
@MongoField
public boolean isRegistrationAllowed() {
return registrationAllowed;
}
public void setRegistrationAllowed(boolean registrationAllowed) {
this.registrationAllowed = registrationAllowed;
}
@MongoField
public boolean isRememberMe() {
return rememberMe;
}
public void setRememberMe(boolean rememberMe) {
this.rememberMe = rememberMe;
}
@MongoField
public boolean isVerifyEmail() {
return verifyEmail;
}
public void setVerifyEmail(boolean verifyEmail) {
this.verifyEmail = verifyEmail;
}
@MongoField
public boolean isResetPasswordAllowed() {
return resetPasswordAllowed;
}
public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
this.resetPasswordAllowed = resetPasswordAllowed;
}
@MongoField
public boolean isSocial() {
return social;
}
public void setSocial(boolean social) {
this.social = social;
}
@MongoField
public boolean isUpdateProfileOnInitialSocialLogin() {
return updateProfileOnInitialSocialLogin;
}
public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) {
this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin;
}
@MongoField
public String getPasswordPolicy() {
return passwordPolicy;
}
public void setPasswordPolicy(String passwordPolicy) {
this.passwordPolicy = passwordPolicy;
}
@MongoField
public int getNotBefore() {
return notBefore;
}
public void setNotBefore(int notBefore) {
this.notBefore = notBefore;
}
@MongoField
public int getCentralLoginLifespan() {
return centralLoginLifespan;
}
public void setCentralLoginLifespan(int centralLoginLifespan) {
this.centralLoginLifespan = centralLoginLifespan;
}
@MongoField
public int getAccessTokenLifespan() {
return accessTokenLifespan;
}
public void setAccessTokenLifespan(int accessTokenLifespan) {
this.accessTokenLifespan = accessTokenLifespan;
}
@MongoField
public int getRefreshTokenLifespan() {
return refreshTokenLifespan;
}
public void setRefreshTokenLifespan(int refreshTokenLifespan) {
this.refreshTokenLifespan = refreshTokenLifespan;
}
@MongoField
public int getAccessCodeLifespan() {
return accessCodeLifespan;
}
public void setAccessCodeLifespan(int accessCodeLifespan) {
this.accessCodeLifespan = accessCodeLifespan;
}
@MongoField
public int getAccessCodeLifespanUserAction() {
return accessCodeLifespanUserAction;
}
public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
this.accessCodeLifespanUserAction = accessCodeLifespanUserAction;
}
@MongoField
public String getPublicKeyPem() {
return publicKeyPem;
}
public void setPublicKeyPem(String publicKeyPem) {
this.publicKeyPem = publicKeyPem;
}
@MongoField
public String getPrivateKeyPem() {
return privateKeyPem;
}
public void setPrivateKeyPem(String privateKeyPem) {
this.privateKeyPem = privateKeyPem;
}
@MongoField
public String getLoginTheme() {
return loginTheme;
}
public void setLoginTheme(String loginTheme) {
this.loginTheme = loginTheme;
}
@MongoField
public String getAccountTheme() {
return accountTheme;
}
public void setAccountTheme(String accountTheme) {
this.accountTheme = accountTheme;
}
@MongoField
public List<String> getDefaultRoles() {
return defaultRoles;
}
public void setDefaultRoles(List<String> defaultRoles) {
this.defaultRoles = defaultRoles;
}
@MongoField
public List<RequiredCredentialEntity> getRequiredCredentials() {
return requiredCredentials;
}
public void setRequiredCredentials(List<RequiredCredentialEntity> requiredCredentials) {
this.requiredCredentials = requiredCredentials;
}
@MongoField
public Map<String, String> getSmtpConfig() {
return smtpConfig;
}
public void setSmtpConfig(Map<String, String> smptConfig) {
this.smtpConfig = smptConfig;
}
@MongoField
public Map<String, String> getSocialConfig() {
return socialConfig;
}
public void setSocialConfig(Map<String, String> socialConfig) {
this.socialConfig = socialConfig;
}
@Override
public void afterRemove(MongoStoreInvocationContext context) {
DBObject query = new QueryBuilder()
.and("realmId").is(getId())
.get();
// Remove all users of this realm
context.getMongoStore().removeEntities(UserEntity.class, query, context);
// Remove all roles of this realm
context.getMongoStore().removeEntities(RoleEntity.class, query, context);
// Remove all applications of this realm
context.getMongoStore().removeEntities(ApplicationEntity.class, query, context);
}
}

View file

@ -1,131 +1,131 @@
package org.keycloak.models.mongo.keycloak.entities;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import org.jboss.logging.Logger;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.MongoCollection;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoField;
import org.keycloak.models.mongo.api.MongoStore;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@MongoCollection(collectionName = "roles")
public class RoleEntity extends AbstractMongoIdentifiableEntity implements MongoEntity {
private static final Logger logger = Logger.getLogger(RoleEntity.class);
private String name;
private String description;
private List<String> compositeRoleIds;
private String realmId;
private String applicationId;
@MongoField
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@MongoField
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@MongoField
public List<String> getCompositeRoleIds() {
return compositeRoleIds;
}
public void setCompositeRoleIds(List<String> compositeRoleIds) {
this.compositeRoleIds = compositeRoleIds;
}
@MongoField
public String getRealmId() {
return realmId;
}
public void setRealmId(String realmId) {
this.realmId = realmId;
}
@MongoField
public String getApplicationId() {
return applicationId;
}
public void setApplicationId(String applicationId) {
this.applicationId = applicationId;
}
@Override
public void afterRemove(MongoStoreInvocationContext invContext) {
MongoStore mongoStore = invContext.getMongoStore();
// Remove this role from all users, which has it
DBObject query = new QueryBuilder()
.and("roleIds").is(getId())
.get();
List<UserEntity> users = mongoStore.loadEntities(UserEntity.class, query, invContext);
for (UserEntity user : users) {
logger.info("Removing role " + getName() + " from user " + user.getLoginName());
mongoStore.pullItemFromList(user, "roleIds", getId(), invContext);
}
// Remove this scope from all users, which has it
query = new QueryBuilder()
.and("scopeIds").is(getId())
.get();
users = mongoStore.loadEntities(UserEntity.class, query, invContext);
for (UserEntity user : users) {
logger.info("Removing scope " + getName() + " from user " + user.getLoginName());
mongoStore.pullItemFromList(user, "scopeIds", getId(), invContext);
}
// Remove defaultRoles from realm
if (realmId != null) {
RealmEntity realmEntity = mongoStore.loadEntity(RealmEntity.class, realmId, invContext);
// Realm might be already removed at this point
if (realmEntity != null) {
mongoStore.pullItemFromList(realmEntity, "defaultRoles", getId(), invContext);
}
}
// Remove defaultRoles from application
if (applicationId != null) {
ApplicationEntity appEntity = mongoStore.loadEntity(ApplicationEntity.class, applicationId, invContext);
// Application might be already removed at this point
if (appEntity != null) {
mongoStore.pullItemFromList(appEntity, "defaultRoles", getId(), invContext);
}
}
// Remove this role from others who has it as composite
query = new QueryBuilder()
.and("compositeRoleIds").is(getId())
.get();
List<RoleEntity> parentRoles = mongoStore.loadEntities(RoleEntity.class, query, invContext);
for (RoleEntity role : parentRoles) {
mongoStore.pullItemFromList(role, "compositeRoleIds", getId(), invContext);
}
}
}
package org.keycloak.models.mongo.keycloak.entities;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import org.jboss.logging.Logger;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.MongoCollection;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoField;
import org.keycloak.models.mongo.api.MongoStore;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@MongoCollection(collectionName = "roles")
public class RoleEntity extends AbstractMongoIdentifiableEntity implements MongoEntity {
private static final Logger logger = Logger.getLogger(RoleEntity.class);
private String name;
private String description;
private List<String> compositeRoleIds;
private String realmId;
private String applicationId;
@MongoField
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@MongoField
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@MongoField
public List<String> getCompositeRoleIds() {
return compositeRoleIds;
}
public void setCompositeRoleIds(List<String> compositeRoleIds) {
this.compositeRoleIds = compositeRoleIds;
}
@MongoField
public String getRealmId() {
return realmId;
}
public void setRealmId(String realmId) {
this.realmId = realmId;
}
@MongoField
public String getApplicationId() {
return applicationId;
}
public void setApplicationId(String applicationId) {
this.applicationId = applicationId;
}
@Override
public void afterRemove(MongoStoreInvocationContext invContext) {
MongoStore mongoStore = invContext.getMongoStore();
// Remove this role from all users, which has it
DBObject query = new QueryBuilder()
.and("roleIds").is(getId())
.get();
List<UserEntity> users = mongoStore.loadEntities(UserEntity.class, query, invContext);
for (UserEntity user : users) {
logger.info("Removing role " + getName() + " from user " + user.getLoginName());
mongoStore.pullItemFromList(user, "roleIds", getId(), invContext);
}
// Remove this scope from all users, which has it
query = new QueryBuilder()
.and("scopeIds").is(getId())
.get();
users = mongoStore.loadEntities(UserEntity.class, query, invContext);
for (UserEntity user : users) {
logger.info("Removing scope " + getName() + " from user " + user.getLoginName());
mongoStore.pullItemFromList(user, "scopeIds", getId(), invContext);
}
// Remove defaultRoles from realm
if (realmId != null) {
RealmEntity realmEntity = mongoStore.loadEntity(RealmEntity.class, realmId, invContext);
// Realm might be already removed at this point
if (realmEntity != null) {
mongoStore.pullItemFromList(realmEntity, "defaultRoles", getId(), invContext);
}
}
// Remove defaultRoles from application
if (applicationId != null) {
ApplicationEntity appEntity = mongoStore.loadEntity(ApplicationEntity.class, applicationId, invContext);
// Application might be already removed at this point
if (appEntity != null) {
mongoStore.pullItemFromList(appEntity, "defaultRoles", getId(), invContext);
}
}
// Remove this role from others who has it as composite
query = new QueryBuilder()
.and("compositeRoleIds").is(getId())
.get();
List<RoleEntity> parentRoles = mongoStore.loadEntities(RoleEntity.class, query, invContext);
for (RoleEntity role : parentRoles) {
mongoStore.pullItemFromList(role, "compositeRoleIds", getId(), invContext);
}
}
}

View file

@ -1,153 +1,153 @@
package org.keycloak.models.mongo.keycloak.entities;
import org.keycloak.models.UserModel;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.MongoCollection;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoField;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@MongoCollection(collectionName = "users")
public class UserEntity extends AbstractMongoIdentifiableEntity implements MongoEntity {
private String loginName;
private String firstName;
private String lastName;
private String email;
private boolean emailVerified;
private boolean totp;
private boolean enabled;
private String realmId;
private List<String> roleIds;
private Map<String, String> attributes;
private List<UserModel.RequiredAction> requiredActions;
private List<CredentialEntity> credentials = new ArrayList<CredentialEntity>();
private List<SocialLinkEntity> socialLinks;
@MongoField
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
@MongoField
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@MongoField
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@MongoField
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@MongoField
public boolean isEmailVerified() {
return emailVerified;
}
public void setEmailVerified(boolean emailVerified) {
this.emailVerified = emailVerified;
}
@MongoField
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@MongoField
public boolean isTotp() {
return totp;
}
public void setTotp(boolean totp) {
this.totp = totp;
}
@MongoField
public String getRealmId() {
return realmId;
}
public void setRealmId(String realmId) {
this.realmId = realmId;
}
@MongoField
public List<String> getRoleIds() {
return roleIds;
}
public void setRoleIds(List<String> roleIds) {
this.roleIds = roleIds;
}
@MongoField
public Map<String, String> getAttributes() {
return attributes;
}
public void setAttributes(Map<String, String> attributes) {
this.attributes = attributes;
}
@MongoField
public List<UserModel.RequiredAction> getRequiredActions() {
return requiredActions;
}
public void setRequiredActions(List<UserModel.RequiredAction> requiredActions) {
this.requiredActions = requiredActions;
}
@MongoField
public List<CredentialEntity> getCredentials() {
return credentials;
}
public void setCredentials(List<CredentialEntity> credentials) {
this.credentials = credentials;
}
@MongoField
public List<SocialLinkEntity> getSocialLinks() {
return socialLinks;
}
public void setSocialLinks(List<SocialLinkEntity> socialLinks) {
this.socialLinks = socialLinks;
}
}
package org.keycloak.models.mongo.keycloak.entities;
import org.keycloak.models.UserModel;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.MongoCollection;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoField;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@MongoCollection(collectionName = "users")
public class UserEntity extends AbstractMongoIdentifiableEntity implements MongoEntity {
private String loginName;
private String firstName;
private String lastName;
private String email;
private boolean emailVerified;
private boolean totp;
private boolean enabled;
private String realmId;
private List<String> roleIds;
private Map<String, String> attributes;
private List<UserModel.RequiredAction> requiredActions;
private List<CredentialEntity> credentials = new ArrayList<CredentialEntity>();
private List<SocialLinkEntity> socialLinks;
@MongoField
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
@MongoField
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@MongoField
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@MongoField
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@MongoField
public boolean isEmailVerified() {
return emailVerified;
}
public void setEmailVerified(boolean emailVerified) {
this.emailVerified = emailVerified;
}
@MongoField
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@MongoField
public boolean isTotp() {
return totp;
}
public void setTotp(boolean totp) {
this.totp = totp;
}
@MongoField
public String getRealmId() {
return realmId;
}
public void setRealmId(String realmId) {
this.realmId = realmId;
}
@MongoField
public List<String> getRoleIds() {
return roleIds;
}
public void setRoleIds(List<String> roleIds) {
this.roleIds = roleIds;
}
@MongoField
public Map<String, String> getAttributes() {
return attributes;
}
public void setAttributes(Map<String, String> attributes) {
this.attributes = attributes;
}
@MongoField
public List<UserModel.RequiredAction> getRequiredActions() {
return requiredActions;
}
public void setRequiredActions(List<UserModel.RequiredAction> requiredActions) {
this.requiredActions = requiredActions;
}
@MongoField
public List<CredentialEntity> getCredentials() {
return credentials;
}
public void setCredentials(List<CredentialEntity> credentials) {
this.credentials = credentials;
}
@MongoField
public List<SocialLinkEntity> getSocialLinks() {
return socialLinks;
}
public void setSocialLinks(List<SocialLinkEntity> socialLinks) {
this.socialLinks = socialLinks;
}
}

View file

@ -1,54 +1,54 @@
package org.keycloak.models.mongo.utils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import org.bson.types.ObjectId;
import org.keycloak.models.ClientModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.mongo.keycloak.adapters.AbstractAdapter;
import org.keycloak.models.mongo.keycloak.adapters.UserAdapter;
import org.keycloak.models.mongo.keycloak.entities.RoleEntity;
import org.keycloak.models.mongo.keycloak.entities.ScopedEntity;
import org.keycloak.models.mongo.keycloak.entities.UserEntity;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class MongoModelUtils {
// Get everything including both application and realm roles
public static List<RoleEntity> getAllRolesOfUser(UserModel user, MongoStoreInvocationContext invContext) {
UserEntity userEntity = ((UserAdapter)user).getUser();
List<String> roleIds = userEntity.getRoleIds();
if (roleIds == null || roleIds.isEmpty()) {
return Collections.EMPTY_LIST;
}
DBObject query = new QueryBuilder()
.and("_id").in(roleIds)
.get();
return invContext.getMongoStore().loadEntities(RoleEntity.class, query, invContext);
}
// Get everything including both application and realm scopes
public static List<RoleEntity> getAllScopesOfClient(ClientModel client, MongoStoreInvocationContext invContext) {
ScopedEntity scopedEntity = (ScopedEntity)((AbstractAdapter)client).getMongoEntity();
List<String> scopeIds = scopedEntity.getScopeIds();
if (scopeIds == null || scopeIds.isEmpty()) {
return Collections.EMPTY_LIST;
}
DBObject query = new QueryBuilder()
.and("_id").in(scopeIds)
.get();
return invContext.getMongoStore().loadEntities(RoleEntity.class, query, invContext);
}
}
package org.keycloak.models.mongo.utils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import org.bson.types.ObjectId;
import org.keycloak.models.ClientModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.mongo.keycloak.adapters.AbstractAdapter;
import org.keycloak.models.mongo.keycloak.adapters.UserAdapter;
import org.keycloak.models.mongo.keycloak.entities.RoleEntity;
import org.keycloak.models.mongo.keycloak.entities.ScopedEntity;
import org.keycloak.models.mongo.keycloak.entities.UserEntity;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class MongoModelUtils {
// Get everything including both application and realm roles
public static List<RoleEntity> getAllRolesOfUser(UserModel user, MongoStoreInvocationContext invContext) {
UserEntity userEntity = ((UserAdapter)user).getUser();
List<String> roleIds = userEntity.getRoleIds();
if (roleIds == null || roleIds.isEmpty()) {
return Collections.EMPTY_LIST;
}
DBObject query = new QueryBuilder()
.and("_id").in(roleIds)
.get();
return invContext.getMongoStore().loadEntities(RoleEntity.class, query, invContext);
}
// Get everything including both application and realm scopes
public static List<RoleEntity> getAllScopesOfClient(ClientModel client, MongoStoreInvocationContext invContext) {
ScopedEntity scopedEntity = (ScopedEntity)((AbstractAdapter)client).getMongoEntity();
List<String> scopeIds = scopedEntity.getScopeIds();
if (scopeIds == null || scopeIds.isEmpty()) {
return Collections.EMPTY_LIST;
}
DBObject query = new QueryBuilder()
.and("_id").in(scopeIds)
.get();
return invContext.getMongoStore().loadEntities(RoleEntity.class, query, invContext);
}
}

View file

@ -1,55 +1,55 @@
package org.keycloak.models.mongo.utils;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class SystemPropertiesConfigurationProvider {
private static final String MONGO_HOST = "keycloak.mongo.host";
private static final String MONGO_PORT = "keycloak.mongo.port";
private static final String MONGO_DB_NAME = "keycloak.mongo.db";
private static final String MONGO_CLEAR_ON_STARTUP = "keycloak.mongo.clearOnStartup";
// Property names from Liveoak . Those are used as fallback in case that original value is not available
private static final String MONGO_HOST_2 = "mongo.host";
private static final String MONGO_PORT_2 = "mongo.port";
private static final String MONGO_DB_NAME_2 = "mongo.db";
private static final String MONGO_CLEAR_ON_STARTUP_2 = "mongo.clearCollectionsOnStartup";
// Port where MongoDB instance is normally started on linux. This port should be used if we're not starting embedded instance
private static final String MONGO_DEFAULT_PORT = "27017";
public static String getMongoHost() {
return getSystemPropertyWithFallback(MONGO_HOST, MONGO_HOST_2, "localhost");
}
public static int getMongoPort() {
String portProp = getSystemPropertyWithFallback(MONGO_PORT, MONGO_PORT_2, MONGO_DEFAULT_PORT);
return Integer.parseInt(portProp);
}
public static String getMongoDbName() {
return getSystemPropertyWithFallback(MONGO_DB_NAME, MONGO_DB_NAME_2, "keycloak");
}
public static boolean isClearCollectionsOnStartup() {
String property = getSystemPropertyWithFallback(MONGO_CLEAR_ON_STARTUP, MONGO_CLEAR_ON_STARTUP_2, "false");
return "true".equalsIgnoreCase(property);
}
// Check if property propName1 (like "keycloak.mongo.host" is available and if not, then fallback to property "mongo.host" )
private static String getSystemPropertyWithFallback(String propName1, String propName2, String defaultValue) {
String propValue1 = System.getProperty(propName1);
return propValue1!=null ? propValue1 : System.getProperty(propName2, defaultValue);
}
// Create configuration based on system properties
public static MongoConfiguration createConfiguration() {
return new MongoConfiguration(
getMongoHost(),
getMongoPort(),
getMongoDbName(),
isClearCollectionsOnStartup()
);
}
}
package org.keycloak.models.mongo.utils;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class SystemPropertiesConfigurationProvider {
private static final String MONGO_HOST = "keycloak.mongo.host";
private static final String MONGO_PORT = "keycloak.mongo.port";
private static final String MONGO_DB_NAME = "keycloak.mongo.db";
private static final String MONGO_CLEAR_ON_STARTUP = "keycloak.mongo.clearOnStartup";
// Property names from Liveoak . Those are used as fallback in case that original value is not available
private static final String MONGO_HOST_2 = "mongo.host";
private static final String MONGO_PORT_2 = "mongo.port";
private static final String MONGO_DB_NAME_2 = "mongo.db";
private static final String MONGO_CLEAR_ON_STARTUP_2 = "mongo.clearCollectionsOnStartup";
// Port where MongoDB instance is normally started on linux. This port should be used if we're not starting embedded instance
private static final String MONGO_DEFAULT_PORT = "27017";
public static String getMongoHost() {
return getSystemPropertyWithFallback(MONGO_HOST, MONGO_HOST_2, "localhost");
}
public static int getMongoPort() {
String portProp = getSystemPropertyWithFallback(MONGO_PORT, MONGO_PORT_2, MONGO_DEFAULT_PORT);
return Integer.parseInt(portProp);
}
public static String getMongoDbName() {
return getSystemPropertyWithFallback(MONGO_DB_NAME, MONGO_DB_NAME_2, "keycloak");
}
public static boolean isClearCollectionsOnStartup() {
String property = getSystemPropertyWithFallback(MONGO_CLEAR_ON_STARTUP, MONGO_CLEAR_ON_STARTUP_2, "false");
return "true".equalsIgnoreCase(property);
}
// Check if property propName1 (like "keycloak.mongo.host" is available and if not, then fallback to property "mongo.host" )
private static String getSystemPropertyWithFallback(String propName1, String propName2, String defaultValue) {
String propValue1 = System.getProperty(propName1);
return propValue1!=null ? propValue1 : System.getProperty(propName2, defaultValue);
}
// Create configuration based on system properties
public static MongoConfiguration createConfiguration() {
return new MongoConfiguration(
getMongoHost(),
getMongoPort(),
getMongoDbName(),
isClearCollectionsOnStartup()
);
}
}

View file

@ -1,43 +1,43 @@
package org.keycloak.models.mongo.test;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoField;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class Address implements MongoEntity {
private String street;
private int number;
private List<String> flatNumbers;
@MongoField
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
@MongoField
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@MongoField
public List<String> getFlatNumbers() {
return flatNumbers;
}
public void setFlatNumbers(List<String> flatNumbers) {
this.flatNumbers = flatNumbers;
}
}
package org.keycloak.models.mongo.test;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoField;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class Address implements MongoEntity {
private String street;
private int number;
private List<String> flatNumbers;
@MongoField
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
@MongoField
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@MongoField
public List<String> getFlatNumbers() {
return flatNumbers;
}
public void setFlatNumbers(List<String> flatNumbers) {
this.flatNumbers = flatNumbers;
}
}

View file

@ -1,146 +1,146 @@
package org.keycloak.models.mongo.test;
import com.mongodb.DB;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
import com.mongodb.QueryBuilder;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoStore;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.mongo.impl.MongoStoreImpl;
import org.keycloak.models.mongo.impl.context.TransactionMongoStoreInvocationContext;
import org.keycloak.models.mongo.utils.SystemPropertiesConfigurationProvider;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class MongoStoreTest {
private static final Class<? extends MongoEntity>[] MANAGED_DATA_TYPES = (Class<? extends MongoEntity>[])new Class<?>[] {
Person.class,
Address.class,
};
private MongoClient mongoClient;
private MongoStore mongoStore;
@Before
public void before() throws Exception {
try {
// TODO: authentication support
mongoClient = new MongoClient("localhost", SystemPropertiesConfigurationProvider.getMongoPort());
DB db = mongoClient.getDB("keycloakTest");
mongoStore = new MongoStoreImpl(db, true, MANAGED_DATA_TYPES);
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
@After
public void after() throws Exception {
mongoClient.close();
}
@Test
public void mongoModelTest() throws Exception {
MongoStoreInvocationContext context = new TransactionMongoStoreInvocationContext(mongoStore);
// Add some user
Person john = new Person();
john.setFirstName("john");
john.setAge(25);
john.setGender(Person.Gender.MALE);
mongoStore.insertEntity(john, context);
// Add another user
Person mary = new Person();
mary.setFirstName("mary");
mary.setKids(asList("Peter", "Paul", "Wendy"));
Address addr1 = new Address();
addr1.setStreet("Elm");
addr1.setNumber(5);
addr1.setFlatNumbers(asList("flat1", "flat2"));
Address addr2 = new Address();
List<Address> addresses = new ArrayList<Address>();
addresses.add(addr1);
addresses.add(addr2);
mary.setAddresses(addresses);
mary.setMainAddress(addr1);
mary.setGender(Person.Gender.FEMALE);
mary.setGenders(asList(Person.Gender.FEMALE));
mongoStore.insertEntity(mary, context);
Assert.assertEquals(2, mongoStore.loadEntities(Person.class, new QueryBuilder().get(), context).size());
DBObject query = new QueryBuilder().and("addresses.flatNumbers").is("flat1").get();
List<Person> persons = mongoStore.loadEntities(Person.class, query, context);
Assert.assertEquals(1, persons.size());
mary = persons.get(0);
Assert.assertEquals(mary.getFirstName(), "mary");
Assert.assertTrue(mary.getKids().contains("Paul"));
Assert.assertEquals(2, mary.getAddresses().size());
Assert.assertEquals(Address.class, mary.getAddresses().get(0).getClass());
// Test push/pull
mongoStore.pushItemToList(mary, "kids", "Pauline", true, context);
mongoStore.pullItemFromList(mary, "kids", "Paul", context);
Address addr3 = new Address();
addr3.setNumber(6);
addr3.setStreet("Broadway");
mongoStore.pushItemToList(mary, "addresses", addr3, true, context);
mary = mongoStore.loadEntity(Person.class, mary.getId(), context);
Assert.assertEquals(3, mary.getKids().size());
Assert.assertTrue(mary.getKids().contains("Pauline"));
Assert.assertFalse(mary.getKids().contains("Paul"));
Assert.assertEquals(3, mary.getAddresses().size());
Address mainAddress = mary.getMainAddress();
Assert.assertEquals("Elm", mainAddress.getStreet());
Assert.assertEquals(5, mainAddress.getNumber());
Assert.assertEquals(Person.Gender.FEMALE, mary.getGender());
Assert.assertTrue(mary.getGenders().contains(Person.Gender.FEMALE));
// Some test of Map (attributes)
mary.addAttribute("attr1", "value1");
mary.addAttribute("attr2", "value2");
mary.addAttribute("attr.some3", "value3");
mongoStore.updateEntity(mary, context);
mary = mongoStore.loadEntity(Person.class, mary.getId(), context);
Assert.assertEquals(3, mary.getAttributes().size());
mary.removeAttribute("attr2");
mary.removeAttribute("nonExisting");
mongoStore.updateEntity(mary, context);
mary = mongoStore.loadEntity(Person.class, mary.getId(), context);
Assert.assertEquals(2, mary.getAttributes().size());
Assert.assertEquals("value1", mary.getAttributes().get("attr1"));
Assert.assertEquals("value3", mary.getAttributes().get("attr.some3"));
context.commit();
}
private <T> List<T> asList(T... objects) {
List<T> list = new ArrayList<T>();
list.addAll(Arrays.asList(objects));
return list;
}
}
package org.keycloak.models.mongo.test;
import com.mongodb.DB;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
import com.mongodb.QueryBuilder;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.models.mongo.api.MongoEntity;
import org.keycloak.models.mongo.api.MongoStore;
import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.models.mongo.impl.MongoStoreImpl;
import org.keycloak.models.mongo.impl.context.TransactionMongoStoreInvocationContext;
import org.keycloak.models.mongo.utils.SystemPropertiesConfigurationProvider;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class MongoStoreTest {
private static final Class<? extends MongoEntity>[] MANAGED_DATA_TYPES = (Class<? extends MongoEntity>[])new Class<?>[] {
Person.class,
Address.class,
};
private MongoClient mongoClient;
private MongoStore mongoStore;
@Before
public void before() throws Exception {
try {
// TODO: authentication support
mongoClient = new MongoClient("localhost", SystemPropertiesConfigurationProvider.getMongoPort());
DB db = mongoClient.getDB("keycloakTest");
mongoStore = new MongoStoreImpl(db, true, MANAGED_DATA_TYPES);
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
@After
public void after() throws Exception {
mongoClient.close();
}
@Test
public void mongoModelTest() throws Exception {
MongoStoreInvocationContext context = new TransactionMongoStoreInvocationContext(mongoStore);
// Add some user
Person john = new Person();
john.setFirstName("john");
john.setAge(25);
john.setGender(Person.Gender.MALE);
mongoStore.insertEntity(john, context);
// Add another user
Person mary = new Person();
mary.setFirstName("mary");
mary.setKids(asList("Peter", "Paul", "Wendy"));
Address addr1 = new Address();
addr1.setStreet("Elm");
addr1.setNumber(5);
addr1.setFlatNumbers(asList("flat1", "flat2"));
Address addr2 = new Address();
List<Address> addresses = new ArrayList<Address>();
addresses.add(addr1);
addresses.add(addr2);
mary.setAddresses(addresses);
mary.setMainAddress(addr1);
mary.setGender(Person.Gender.FEMALE);
mary.setGenders(asList(Person.Gender.FEMALE));
mongoStore.insertEntity(mary, context);
Assert.assertEquals(2, mongoStore.loadEntities(Person.class, new QueryBuilder().get(), context).size());
DBObject query = new QueryBuilder().and("addresses.flatNumbers").is("flat1").get();
List<Person> persons = mongoStore.loadEntities(Person.class, query, context);
Assert.assertEquals(1, persons.size());
mary = persons.get(0);
Assert.assertEquals(mary.getFirstName(), "mary");
Assert.assertTrue(mary.getKids().contains("Paul"));
Assert.assertEquals(2, mary.getAddresses().size());
Assert.assertEquals(Address.class, mary.getAddresses().get(0).getClass());
// Test push/pull
mongoStore.pushItemToList(mary, "kids", "Pauline", true, context);
mongoStore.pullItemFromList(mary, "kids", "Paul", context);
Address addr3 = new Address();
addr3.setNumber(6);
addr3.setStreet("Broadway");
mongoStore.pushItemToList(mary, "addresses", addr3, true, context);
mary = mongoStore.loadEntity(Person.class, mary.getId(), context);
Assert.assertEquals(3, mary.getKids().size());
Assert.assertTrue(mary.getKids().contains("Pauline"));
Assert.assertFalse(mary.getKids().contains("Paul"));
Assert.assertEquals(3, mary.getAddresses().size());
Address mainAddress = mary.getMainAddress();
Assert.assertEquals("Elm", mainAddress.getStreet());
Assert.assertEquals(5, mainAddress.getNumber());
Assert.assertEquals(Person.Gender.FEMALE, mary.getGender());
Assert.assertTrue(mary.getGenders().contains(Person.Gender.FEMALE));
// Some test of Map (attributes)
mary.addAttribute("attr1", "value1");
mary.addAttribute("attr2", "value2");
mary.addAttribute("attr.some3", "value3");
mongoStore.updateEntity(mary, context);
mary = mongoStore.loadEntity(Person.class, mary.getId(), context);
Assert.assertEquals(3, mary.getAttributes().size());
mary.removeAttribute("attr2");
mary.removeAttribute("nonExisting");
mongoStore.updateEntity(mary, context);
mary = mongoStore.loadEntity(Person.class, mary.getId(), context);
Assert.assertEquals(2, mary.getAttributes().size());
Assert.assertEquals("value1", mary.getAttributes().get("attr1"));
Assert.assertEquals("value3", mary.getAttributes().get("attr.some3"));
context.commit();
}
private <T> List<T> asList(T... objects) {
List<T> list = new ArrayList<T>();
list.addAll(Arrays.asList(objects));
return list;
}
}

View file

@ -1,109 +1,109 @@
package org.keycloak.models.mongo.test;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.MongoCollection;
import org.keycloak.models.mongo.api.MongoField;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@MongoCollection(collectionName = "persons")
public class Person extends AbstractMongoIdentifiableEntity {
private String firstName;
private int age;
private List<String> kids;
private List<Address> addresses;
private Address mainAddress;
private Gender gender;
private List<Gender> genders;
private Map<String, String> attributes = new HashMap<String, String>();
@MongoField
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@MongoField
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@MongoField
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
@MongoField
public List<Gender> getGenders() {
return genders;
}
public void setGenders(List<Gender> genders) {
this.genders = genders;
}
@MongoField
public List<String> getKids() {
return kids;
}
public void setKids(List<String> kids) {
this.kids = kids;
}
@MongoField
public List<Address> getAddresses() {
return addresses;
}
public void setAddresses(List<Address> addresses) {
this.addresses = addresses;
}
@MongoField
public Address getMainAddress() {
return mainAddress;
}
public void setMainAddress(Address mainAddress) {
this.mainAddress = mainAddress;
}
@MongoField
public Map<String, String> getAttributes() {
return attributes;
}
public void setAttributes(Map<String, String> attributes) {
this.attributes = attributes;
}
public void addAttribute(String key, String value) {
attributes.put(key, value);
}
public void removeAttribute(String key) {
attributes.remove(key);
}
public static enum Gender {
MALE, FEMALE
}
}
package org.keycloak.models.mongo.test;
import org.keycloak.models.mongo.api.AbstractMongoIdentifiableEntity;
import org.keycloak.models.mongo.api.MongoCollection;
import org.keycloak.models.mongo.api.MongoField;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@MongoCollection(collectionName = "persons")
public class Person extends AbstractMongoIdentifiableEntity {
private String firstName;
private int age;
private List<String> kids;
private List<Address> addresses;
private Address mainAddress;
private Gender gender;
private List<Gender> genders;
private Map<String, String> attributes = new HashMap<String, String>();
@MongoField
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@MongoField
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@MongoField
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
@MongoField
public List<Gender> getGenders() {
return genders;
}
public void setGenders(List<Gender> genders) {
this.genders = genders;
}
@MongoField
public List<String> getKids() {
return kids;
}
public void setKids(List<String> kids) {
this.kids = kids;
}
@MongoField
public List<Address> getAddresses() {
return addresses;
}
public void setAddresses(List<Address> addresses) {
this.addresses = addresses;
}
@MongoField
public Address getMainAddress() {
return mainAddress;
}
public void setMainAddress(Address mainAddress) {
this.mainAddress = mainAddress;
}
@MongoField
public Map<String, String> getAttributes() {
return attributes;
}
public void setAttributes(Map<String, String> attributes) {
this.attributes = attributes;
}
public void addAttribute(String key, String value) {
attributes.put(key, value);
}
public void removeAttribute(String key) {
attributes.remove(key);
}
public static enum Gender {
MALE, FEMALE
}
}

View file

@ -1,308 +1,308 @@
package org.keycloak.models.picketlink;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.picketlink.mappings.ApplicationData;
import org.keycloak.models.picketlink.relationships.ScopeRelationship;
import org.picketlink.idm.IdentityManagementException;
import org.picketlink.idm.IdentityManager;
import org.picketlink.idm.PartitionManager;
import org.picketlink.idm.RelationshipManager;
import org.picketlink.idm.model.IdentityType;
import org.picketlink.idm.model.sample.Grant;
import org.picketlink.idm.model.sample.Role;
import org.picketlink.idm.model.sample.SampleModel;
import org.picketlink.idm.query.IdentityQuery;
import org.picketlink.idm.query.RelationshipQuery;
import java.util.*;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ApplicationAdapter implements ApplicationModel {
protected ApplicationData applicationData;
protected RealmAdapter realm;
protected IdentityManager idm;
protected PartitionManager partitionManager;
protected RelationshipManager relationshipManager;
public ApplicationAdapter(ApplicationData applicationData, RealmAdapter realm, PartitionManager partitionManager) {
this.applicationData = applicationData;
this.realm = realm;
this.partitionManager = partitionManager;
}
protected IdentityManager getIdm() {
if (idm == null) idm = partitionManager.createIdentityManager(applicationData);
return idm;
}
protected RelationshipManager getRelationshipManager() {
if (relationshipManager == null) relationshipManager = partitionManager.createRelationshipManager();
return relationshipManager;
}
@Override
public void updateApplication() {
partitionManager.update(applicationData);
}
@Override
public UserAdapter getApplicationUser() {
return new UserAdapter(applicationData.getResourceUser(), realm.getIdm());
}
@Override
public String getId() {
// for some reason picketlink queries by name when finding partition, don't know what ID is used for now
return applicationData.getName();
}
@Override
public String getName() {
return applicationData.getResourceName();
}
@Override
public void setName(String name) {
applicationData.setResourceName(name);
updateApplication();
}
@Override
public boolean isEnabled() {
return applicationData.isEnabled();
}
@Override
public void setEnabled(boolean enabled) {
applicationData.setEnabled(enabled);
updateApplication();
}
@Override
public boolean isSurrogateAuthRequired() {
return applicationData.isSurrogateAuthRequired();
}
@Override
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
applicationData.setSurrogateAuthRequired(surrogateAuthRequired);
updateApplication();
}
@Override
public String getManagementUrl() {
return applicationData.getManagementUrl();
}
@Override
public void setManagementUrl(String url) {
applicationData.setManagementUrl(url);
updateApplication();
}
@Override
public String getBaseUrl() {
return applicationData.getBaseUrl();
}
@Override
public void setBaseUrl(String url) {
applicationData.setBaseUrl(url);
updateApplication();
}
@Override
public RoleAdapter getRole(String name) {
Role role = SampleModel.getRole(getIdm(), name);
if (role == null) return null;
return new RoleAdapter(role, getIdm());
}
@Override
public RoleModel getRoleById(String id) {
IdentityQuery<Role> query = getIdm().createIdentityQuery(Role.class);
query.setParameter(IdentityType.ID, id);
List<Role> roles = query.getResultList();
if (roles.size() == 0) return null;
return new RoleAdapter(roles.get(0), getIdm());
}
@Override
public void grantRole(UserModel user, RoleModel role) {
SampleModel.grantRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole());
}
@Override
public boolean hasRole(UserModel user, RoleModel role) {
return SampleModel.hasRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole());
}
@Override
public boolean hasRole(UserModel user, String role) {
RoleModel roleModel = getRole(role);
return hasRole(user, roleModel);
}
@Override
public RoleAdapter addRole(String name) {
Role role = new Role(name);
getIdm().add(role);
return new RoleAdapter(role, getIdm());
}
@Override
public boolean removeRoleById(String id) {
try {
getIdm().remove(getIdm().lookupIdentityById(Role.class, id));
return true;
} catch (IdentityManagementException e) {
return false;
}
}
@Override
public List<RoleModel> getRoles() {
IdentityQuery<Role> query = getIdm().createIdentityQuery(Role.class);
query.setParameter(Role.PARTITION, applicationData);
List<Role> roles = query.getResultList();
List<RoleModel> roleModels = new ArrayList<RoleModel>();
for (Role role : roles) {
roleModels.add(new RoleAdapter(role, idm));
}
return roleModels;
}
@Override
public Set<String> getRoleMappingValues(UserModel user) {
RelationshipQuery<Grant> query = getRelationshipManager().createRelationshipQuery(Grant.class);
query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser());
List<Grant> grants = query.getResultList();
HashSet<String> set = new HashSet<String>();
for (Grant grant : grants) {
if (grant.getRole().getPartition().getId().equals(applicationData.getId())) set.add(grant.getRole().getName());
}
return set;
}
@Override
public List<RoleModel> getRoleMappings(UserModel user) {
RelationshipQuery<Grant> query = getRelationshipManager().createRelationshipQuery(Grant.class);
query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser());
List<Grant> grants = query.getResultList();
List<RoleModel> set = new ArrayList<RoleModel>();
for (Grant grant : grants) {
if (grant.getRole().getPartition().getId().equals(applicationData.getId())) set.add(new RoleAdapter(grant.getRole(), getIdm()));
}
return set;
}
@Override
public void deleteRoleMapping(UserModel user, RoleModel role) {
RelationshipQuery<Grant> query = getRelationshipManager().createRelationshipQuery(Grant.class);
query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser());
query.setParameter(Grant.ROLE, ((RoleAdapter)role).getRole());
List<Grant> grants = query.getResultList();
for (Grant grant : grants) {
getRelationshipManager().remove(grant);
}
}
@Override
public void addScopeMapping(UserModel agent, String roleName) {
IdentityManager idm = getIdm();
Role role = SampleModel.getRole(idm,roleName);
if (role == null) throw new RuntimeException("role not found");
addScopeMapping(agent, new RoleAdapter(role, idm));
}
@Override
public void addScopeMapping(UserModel agent, RoleModel role) {
ScopeRelationship scope = new ScopeRelationship();
scope.setClient(((UserAdapter)agent).getUser());
scope.setScope(((RoleAdapter)role).getRole());
getRelationshipManager().add(scope);
}
@Override
public void deleteScopeMapping(UserModel user, RoleModel role) {
RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)user).getUser());
query.setParameter(ScopeRelationship.SCOPE, ((RoleAdapter)role).getRole());
List<ScopeRelationship> grants = query.getResultList();
for (ScopeRelationship grant : grants) {
getRelationshipManager().remove(grant);
}
}
@Override
public Set<String> getScopeMappingValues(UserModel agent) {
RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
List<ScopeRelationship> scope = query.getResultList();
HashSet<String> set = new HashSet<String>();
for (ScopeRelationship rel : scope) {
if (rel.getScope().getPartition().getId().equals(applicationData.getId())) set.add(rel.getScope().getName());
}
return set;
}
@Override
public List<RoleModel> getScopeMappings(UserModel agent) {
RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
List<ScopeRelationship> scope = query.getResultList();
List<RoleModel> roles = new ArrayList<RoleModel>();
for (ScopeRelationship rel : scope) {
if (rel.getScope().getPartition().getId().equals(applicationData.getId())) roles.add(new RoleAdapter(rel.getScope(), getIdm()));
}
return roles;
}
@Override
public List<String> getDefaultRoles() {
if ( applicationData.getDefaultRoles() != null) {
return Arrays.asList(applicationData.getDefaultRoles());
}
else {
return Collections.emptyList();
}
}
@Override
public void addDefaultRole(String name) {
if (getRole(name) == null) {
addRole(name);
}
String[] defaultRoles = applicationData.getDefaultRoles();
if (defaultRoles == null) {
defaultRoles = new String[1];
} else {
defaultRoles = Arrays.copyOf(defaultRoles, defaultRoles.length + 1);
}
defaultRoles[defaultRoles.length - 1] = name;
applicationData.setDefaultRoles(defaultRoles);
updateApplication();
}
@Override
public void updateDefaultRoles(String[] defaultRoles) {
for (String name : defaultRoles) {
if (getRole(name) == null) {
addRole(name);
}
}
applicationData.setDefaultRoles(defaultRoles);
updateApplication();
}
}
package org.keycloak.models.picketlink;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.picketlink.mappings.ApplicationData;
import org.keycloak.models.picketlink.relationships.ScopeRelationship;
import org.picketlink.idm.IdentityManagementException;
import org.picketlink.idm.IdentityManager;
import org.picketlink.idm.PartitionManager;
import org.picketlink.idm.RelationshipManager;
import org.picketlink.idm.model.IdentityType;
import org.picketlink.idm.model.sample.Grant;
import org.picketlink.idm.model.sample.Role;
import org.picketlink.idm.model.sample.SampleModel;
import org.picketlink.idm.query.IdentityQuery;
import org.picketlink.idm.query.RelationshipQuery;
import java.util.*;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ApplicationAdapter implements ApplicationModel {
protected ApplicationData applicationData;
protected RealmAdapter realm;
protected IdentityManager idm;
protected PartitionManager partitionManager;
protected RelationshipManager relationshipManager;
public ApplicationAdapter(ApplicationData applicationData, RealmAdapter realm, PartitionManager partitionManager) {
this.applicationData = applicationData;
this.realm = realm;
this.partitionManager = partitionManager;
}
protected IdentityManager getIdm() {
if (idm == null) idm = partitionManager.createIdentityManager(applicationData);
return idm;
}
protected RelationshipManager getRelationshipManager() {
if (relationshipManager == null) relationshipManager = partitionManager.createRelationshipManager();
return relationshipManager;
}
@Override
public void updateApplication() {
partitionManager.update(applicationData);
}
@Override
public UserAdapter getApplicationUser() {
return new UserAdapter(applicationData.getResourceUser(), realm.getIdm());
}
@Override
public String getId() {
// for some reason picketlink queries by name when finding partition, don't know what ID is used for now
return applicationData.getName();
}
@Override
public String getName() {
return applicationData.getResourceName();
}
@Override
public void setName(String name) {
applicationData.setResourceName(name);
updateApplication();
}
@Override
public boolean isEnabled() {
return applicationData.isEnabled();
}
@Override
public void setEnabled(boolean enabled) {
applicationData.setEnabled(enabled);
updateApplication();
}
@Override
public boolean isSurrogateAuthRequired() {
return applicationData.isSurrogateAuthRequired();
}
@Override
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
applicationData.setSurrogateAuthRequired(surrogateAuthRequired);
updateApplication();
}
@Override
public String getManagementUrl() {
return applicationData.getManagementUrl();
}
@Override
public void setManagementUrl(String url) {
applicationData.setManagementUrl(url);
updateApplication();
}
@Override
public String getBaseUrl() {
return applicationData.getBaseUrl();
}
@Override
public void setBaseUrl(String url) {
applicationData.setBaseUrl(url);
updateApplication();
}
@Override
public RoleAdapter getRole(String name) {
Role role = SampleModel.getRole(getIdm(), name);
if (role == null) return null;
return new RoleAdapter(role, getIdm());
}
@Override
public RoleModel getRoleById(String id) {
IdentityQuery<Role> query = getIdm().createIdentityQuery(Role.class);
query.setParameter(IdentityType.ID, id);
List<Role> roles = query.getResultList();
if (roles.size() == 0) return null;
return new RoleAdapter(roles.get(0), getIdm());
}
@Override
public void grantRole(UserModel user, RoleModel role) {
SampleModel.grantRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole());
}
@Override
public boolean hasRole(UserModel user, RoleModel role) {
return SampleModel.hasRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole());
}
@Override
public boolean hasRole(UserModel user, String role) {
RoleModel roleModel = getRole(role);
return hasRole(user, roleModel);
}
@Override
public RoleAdapter addRole(String name) {
Role role = new Role(name);
getIdm().add(role);
return new RoleAdapter(role, getIdm());
}
@Override
public boolean removeRoleById(String id) {
try {
getIdm().remove(getIdm().lookupIdentityById(Role.class, id));
return true;
} catch (IdentityManagementException e) {
return false;
}
}
@Override
public List<RoleModel> getRoles() {
IdentityQuery<Role> query = getIdm().createIdentityQuery(Role.class);
query.setParameter(Role.PARTITION, applicationData);
List<Role> roles = query.getResultList();
List<RoleModel> roleModels = new ArrayList<RoleModel>();
for (Role role : roles) {
roleModels.add(new RoleAdapter(role, idm));
}
return roleModels;
}
@Override
public Set<String> getRoleMappingValues(UserModel user) {
RelationshipQuery<Grant> query = getRelationshipManager().createRelationshipQuery(Grant.class);
query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser());
List<Grant> grants = query.getResultList();
HashSet<String> set = new HashSet<String>();
for (Grant grant : grants) {
if (grant.getRole().getPartition().getId().equals(applicationData.getId())) set.add(grant.getRole().getName());
}
return set;
}
@Override
public List<RoleModel> getRoleMappings(UserModel user) {
RelationshipQuery<Grant> query = getRelationshipManager().createRelationshipQuery(Grant.class);
query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser());
List<Grant> grants = query.getResultList();
List<RoleModel> set = new ArrayList<RoleModel>();
for (Grant grant : grants) {
if (grant.getRole().getPartition().getId().equals(applicationData.getId())) set.add(new RoleAdapter(grant.getRole(), getIdm()));
}
return set;
}
@Override
public void deleteRoleMapping(UserModel user, RoleModel role) {
RelationshipQuery<Grant> query = getRelationshipManager().createRelationshipQuery(Grant.class);
query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser());
query.setParameter(Grant.ROLE, ((RoleAdapter)role).getRole());
List<Grant> grants = query.getResultList();
for (Grant grant : grants) {
getRelationshipManager().remove(grant);
}
}
@Override
public void addScopeMapping(UserModel agent, String roleName) {
IdentityManager idm = getIdm();
Role role = SampleModel.getRole(idm,roleName);
if (role == null) throw new RuntimeException("role not found");
addScopeMapping(agent, new RoleAdapter(role, idm));
}
@Override
public void addScopeMapping(UserModel agent, RoleModel role) {
ScopeRelationship scope = new ScopeRelationship();
scope.setClient(((UserAdapter)agent).getUser());
scope.setScope(((RoleAdapter)role).getRole());
getRelationshipManager().add(scope);
}
@Override
public void deleteScopeMapping(UserModel user, RoleModel role) {
RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)user).getUser());
query.setParameter(ScopeRelationship.SCOPE, ((RoleAdapter)role).getRole());
List<ScopeRelationship> grants = query.getResultList();
for (ScopeRelationship grant : grants) {
getRelationshipManager().remove(grant);
}
}
@Override
public Set<String> getScopeMappingValues(UserModel agent) {
RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
List<ScopeRelationship> scope = query.getResultList();
HashSet<String> set = new HashSet<String>();
for (ScopeRelationship rel : scope) {
if (rel.getScope().getPartition().getId().equals(applicationData.getId())) set.add(rel.getScope().getName());
}
return set;
}
@Override
public List<RoleModel> getScopeMappings(UserModel agent) {
RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
List<ScopeRelationship> scope = query.getResultList();
List<RoleModel> roles = new ArrayList<RoleModel>();
for (ScopeRelationship rel : scope) {
if (rel.getScope().getPartition().getId().equals(applicationData.getId())) roles.add(new RoleAdapter(rel.getScope(), getIdm()));
}
return roles;
}
@Override
public List<String> getDefaultRoles() {
if ( applicationData.getDefaultRoles() != null) {
return Arrays.asList(applicationData.getDefaultRoles());
}
else {
return Collections.emptyList();
}
}
@Override
public void addDefaultRole(String name) {
if (getRole(name) == null) {
addRole(name);
}
String[] defaultRoles = applicationData.getDefaultRoles();
if (defaultRoles == null) {
defaultRoles = new String[1];
} else {
defaultRoles = Arrays.copyOf(defaultRoles, defaultRoles.length + 1);
}
defaultRoles[defaultRoles.length - 1] = name;
applicationData.setDefaultRoles(defaultRoles);
updateApplication();
}
@Override
public void updateDefaultRoles(String[] defaultRoles) {
for (String name : defaultRoles) {
if (getRole(name) == null) {
addRole(name);
}
}
applicationData.setDefaultRoles(defaultRoles);
updateApplication();
}
}

View file

@ -1,73 +1,73 @@
package org.keycloak.models.picketlink.relationships;
import org.picketlink.idm.model.AbstractAttributedType;
import org.picketlink.idm.model.Attribute;
import org.picketlink.idm.model.Relationship;
import org.picketlink.idm.model.annotation.AttributeProperty;
import org.picketlink.idm.model.sample.User;
import org.picketlink.idm.query.AttributeParameter;
import org.picketlink.idm.query.RelationshipQueryParameter;
/**
* Binding between user and his social username for particular Social provider
*
* Example: Keycloak user "john" has username "john123" in social provider "facebook"
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class SocialLinkRelationship extends AbstractAttributedType implements Relationship {
private static final long serialVersionUID = 154879L;
public static final AttributeParameter SOCIAL_PROVIDER = new AttributeParameter("socialProvider");
public static final AttributeParameter SOCIAL_USERNAME = new AttributeParameter("socialUsername");
// realm is needed to allow searching as combination socialUsername+socialProvider may not be unique
// (Same user could have mapped same facebook account to username "foo" in "realm1" and to username "bar" in "realm2")
public static final AttributeParameter REALM = new AttributeParameter("realm");
public static final RelationshipQueryParameter USER = new RelationshipQueryParameter() {
@Override
public String getName() {
return "user";
}
};
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@AttributeProperty
public String getSocialProvider() {
return (String)getAttribute("socialProvider").getValue();
}
public void setSocialProvider(String socialProvider) {
setAttribute(new Attribute<String>("socialProvider", socialProvider));
}
@AttributeProperty
public String getSocialUsername() {
return (String)getAttribute("socialUsername").getValue();
}
public void setSocialUsername(String socialProviderUserId) {
setAttribute(new Attribute<String>("socialUsername", socialProviderUserId));
}
@AttributeProperty
public String getRealm() {
return (String)getAttribute("realm").getValue();
}
public void setRealm(String realm) {
setAttribute(new Attribute<String>("realm", realm));
}
}
package org.keycloak.models.picketlink.relationships;
import org.picketlink.idm.model.AbstractAttributedType;
import org.picketlink.idm.model.Attribute;
import org.picketlink.idm.model.Relationship;
import org.picketlink.idm.model.annotation.AttributeProperty;
import org.picketlink.idm.model.sample.User;
import org.picketlink.idm.query.AttributeParameter;
import org.picketlink.idm.query.RelationshipQueryParameter;
/**
* Binding between user and his social username for particular Social provider
*
* Example: Keycloak user "john" has username "john123" in social provider "facebook"
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class SocialLinkRelationship extends AbstractAttributedType implements Relationship {
private static final long serialVersionUID = 154879L;
public static final AttributeParameter SOCIAL_PROVIDER = new AttributeParameter("socialProvider");
public static final AttributeParameter SOCIAL_USERNAME = new AttributeParameter("socialUsername");
// realm is needed to allow searching as combination socialUsername+socialProvider may not be unique
// (Same user could have mapped same facebook account to username "foo" in "realm1" and to username "bar" in "realm2")
public static final AttributeParameter REALM = new AttributeParameter("realm");
public static final RelationshipQueryParameter USER = new RelationshipQueryParameter() {
@Override
public String getName() {
return "user";
}
};
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@AttributeProperty
public String getSocialProvider() {
return (String)getAttribute("socialProvider").getValue();
}
public void setSocialProvider(String socialProvider) {
setAttribute(new Attribute<String>("socialProvider", socialProvider));
}
@AttributeProperty
public String getSocialUsername() {
return (String)getAttribute("socialUsername").getValue();
}
public void setSocialUsername(String socialProviderUserId) {
setAttribute(new Attribute<String>("socialUsername", socialProviderUserId));
}
@AttributeProperty
public String getRealm() {
return (String)getAttribute("realm").getValue();
}
public void setRealm(String realm) {
setAttribute(new Attribute<String>("realm", realm));
}
}

View file

@ -1,69 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-alpha-3-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-model-tests</artifactId>
<name>Keycloak Model Tests</name>
<description/>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-services</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>package-tests-jar</id>
<phase>package</phase>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-alpha-3-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-model-tests</artifactId>
<name>Keycloak Model Tests</name>
<description/>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-services</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>package-tests-jar</id>
<phase>package</phase>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -241,8 +241,8 @@ public class AdapterTest extends AbstractModelTest {
Assert.assertFalse(realmModel.removeRoleById(realmRole.getId()));
Assert.assertNull(realmModel.getRole(realmRole.getName()));
Assert.assertTrue(app.removeRoleById(appRole.getId()));
Assert.assertFalse(app.removeRoleById(appRole.getId()));
Assert.assertTrue(realmModel.removeRoleById(appRole.getId()));
Assert.assertFalse(realmModel.removeRoleById(appRole.getId()));
Assert.assertNull(app.getRole(appRole.getName()));
}
@ -431,13 +431,9 @@ public class AdapterTest extends AbstractModelTest {
Set<RoleModel> appRoles = application.getRoles();
Assert.assertEquals(2, appRoles.size());
RoleModel appBarRole = application.getRole("bar");
Assert.assertNotNull(appBarRole);
// This should return null because it's realmRole
Assert.assertNull(application.getRoleById(realmUserRole.getId()));
// This should return null because appBarRole is application role
Assert.assertNull(realmModel.getRoleById(appBarRole.getId()));
found = application.getRoleById(appBarRole.getId());
found = realmModel.getRoleById(appBarRole.getId());
Assert.assertNotNull(found);
assertRolesEquals(found, appBarRole);

View file

@ -1,86 +1,86 @@
package org.keycloak.model.test;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.services.managers.ApplicationManager;
import java.util.Iterator;
import java.util.List;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class ApplicationModelTest extends AbstractModelTest {
private ApplicationModel application;
private RealmModel realm;
private ApplicationManager appManager;
@Before
public void before() throws Exception {
super.before();
appManager = new ApplicationManager(realmManager);
realm = realmManager.createRealm("original");
application = realm.addApplication("application");
application.setBaseUrl("http://base");
application.setManagementUrl("http://management");
application.setName("app-name");
application.addRole("role-1");
application.addRole("role-2");
application.addRole("role-3");
application.addDefaultRole("role-1");
application.addDefaultRole("role-2");
application.addRedirectUri("redirect-1");
application.addRedirectUri("redirect-2");
application.addWebOrigin("origin-1");
application.addWebOrigin("origin-2");
application.updateApplication();
}
@Test
public void persist() {
RealmModel persisted = realmManager.getRealm(realm.getId());
assertEquals(application, persisted.getApplicationNameMap().get("app-name"));
}
@Test
public void json() {
ApplicationRepresentation representation = appManager.toRepresentation(application);
RealmModel realm = realmManager.createRealm("copy");
ApplicationModel copy = appManager.createApplication(realm, representation);
assertEquals(application, copy);
}
public static void assertEquals(ApplicationModel expected, ApplicationModel actual) {
Assert.assertEquals(expected.getName(), actual.getName());
Assert.assertEquals(expected.getBaseUrl(), actual.getBaseUrl());
Assert.assertEquals(expected.getManagementUrl(), actual.getManagementUrl());
Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles());
Assert.assertTrue(expected.getRedirectUris().containsAll(actual.getRedirectUris()));
Assert.assertTrue(expected.getWebOrigins().containsAll(actual.getWebOrigins()));
}
public static void assertEquals(List<RoleModel> expected, List<RoleModel> actual) {
Assert.assertEquals(expected.size(), actual.size());
Iterator<RoleModel> exp = expected.iterator();
Iterator<RoleModel> act = actual.iterator();
while (exp.hasNext()) {
Assert.assertEquals(exp.next().getName(), act.next().getName());
}
}
}
package org.keycloak.model.test;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.services.managers.ApplicationManager;
import java.util.Iterator;
import java.util.List;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class ApplicationModelTest extends AbstractModelTest {
private ApplicationModel application;
private RealmModel realm;
private ApplicationManager appManager;
@Before
public void before() throws Exception {
super.before();
appManager = new ApplicationManager(realmManager);
realm = realmManager.createRealm("original");
application = realm.addApplication("application");
application.setBaseUrl("http://base");
application.setManagementUrl("http://management");
application.setName("app-name");
application.addRole("role-1");
application.addRole("role-2");
application.addRole("role-3");
application.addDefaultRole("role-1");
application.addDefaultRole("role-2");
application.addRedirectUri("redirect-1");
application.addRedirectUri("redirect-2");
application.addWebOrigin("origin-1");
application.addWebOrigin("origin-2");
application.updateApplication();
}
@Test
public void persist() {
RealmModel persisted = realmManager.getRealm(realm.getId());
assertEquals(application, persisted.getApplicationNameMap().get("app-name"));
}
@Test
public void json() {
ApplicationRepresentation representation = appManager.toRepresentation(application);
RealmModel realm = realmManager.createRealm("copy");
ApplicationModel copy = appManager.createApplication(realm, representation);
assertEquals(application, copy);
}
public static void assertEquals(ApplicationModel expected, ApplicationModel actual) {
Assert.assertEquals(expected.getName(), actual.getName());
Assert.assertEquals(expected.getBaseUrl(), actual.getBaseUrl());
Assert.assertEquals(expected.getManagementUrl(), actual.getManagementUrl());
Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles());
Assert.assertTrue(expected.getRedirectUris().containsAll(actual.getRedirectUris()));
Assert.assertTrue(expected.getWebOrigins().containsAll(actual.getWebOrigins()));
}
public static void assertEquals(List<RoleModel> expected, List<RoleModel> actual) {
Assert.assertEquals(expected.size(), actual.size());
Iterator<RoleModel> exp = expected.iterator();
Iterator<RoleModel> act = actual.iterator();
while (exp.hasNext()) {
Assert.assertEquals(exp.next().getName(), act.next().getName());
}
}
}

View file

@ -1,150 +1,150 @@
package org.keycloak.model.test;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserModel.RequiredAction;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import java.util.UUID;
public class AuthenticationManagerTest extends AbstractModelTest {
private AuthenticationManager am;
private MultivaluedMap<String, String> formData;
private TimeBasedOTP otp;
private RealmModel realm;
private UserModel user;
@Test
public void authForm() {
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.SUCCESS, status);
}
@Test
public void authFormInvalidPassword() {
formData.remove(CredentialRepresentation.PASSWORD);
formData.add(CredentialRepresentation.PASSWORD, "invalid");
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
}
@Test
public void authFormMissingPassword() {
formData.remove(CredentialRepresentation.PASSWORD);
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.MISSING_PASSWORD, status);
}
@Test
public void authFormRequiredAction() {
realm.addRequiredCredential(CredentialRepresentation.TOTP);
user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.ACTIONS_REQUIRED, status);
}
@Test
public void authFormUserDisabled() {
user.setEnabled(false);
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.ACCOUNT_DISABLED, status);
}
@Test
public void authFormWithTotp() {
realm.addRequiredCredential(CredentialRepresentation.TOTP);
String totpSecret = UUID.randomUUID().toString();
UserCredentialModel credential = new UserCredentialModel();
credential.setType(CredentialRepresentation.TOTP);
credential.setValue(totpSecret);
realm.updateCredential(user, credential);
user.setTotp(true);
String token = otp.generate(totpSecret);
formData.add(CredentialRepresentation.TOTP, token);
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.SUCCESS, status);
}
@Test
public void authFormWithTotpInvalidPassword() {
authFormWithTotp();
formData.remove(CredentialRepresentation.PASSWORD);
formData.add(CredentialRepresentation.PASSWORD, "invalid");
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
}
@Test
public void authFormWithTotpInvalidTotp() {
authFormWithTotp();
formData.remove(CredentialRepresentation.TOTP);
formData.add(CredentialRepresentation.TOTP, "invalid");
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
}
@Test
public void authFormWithTotpMissingTotp() {
authFormWithTotp();
formData.remove(CredentialRepresentation.TOTP);
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.MISSING_TOTP, status);
}
@Before
public void before() throws Exception {
super.before();
realm = realmManager.createRealm("Test");
realm.setAccessCodeLifespan(100);
realm.setEnabled(true);
realm.setName("Test");
realm.setPrivateKeyPem("0234234");
realm.setPublicKeyPem("0234234");
realm.setAccessTokenLifespan(1000);
realm.addRequiredCredential(CredentialRepresentation.PASSWORD);
am = new AuthenticationManager();
user = realm.addUser("test");
user.setEnabled(true);
UserCredentialModel credential = new UserCredentialModel();
credential.setType(CredentialRepresentation.PASSWORD);
credential.setValue("password");
realm.updateCredential(user, credential);
formData = new MultivaluedHashMap<String, String>();
formData.add(CredentialRepresentation.PASSWORD, "password");
otp = new TimeBasedOTP();
}
}
package org.keycloak.model.test;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserModel.RequiredAction;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import java.util.UUID;
public class AuthenticationManagerTest extends AbstractModelTest {
private AuthenticationManager am;
private MultivaluedMap<String, String> formData;
private TimeBasedOTP otp;
private RealmModel realm;
private UserModel user;
@Test
public void authForm() {
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.SUCCESS, status);
}
@Test
public void authFormInvalidPassword() {
formData.remove(CredentialRepresentation.PASSWORD);
formData.add(CredentialRepresentation.PASSWORD, "invalid");
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
}
@Test
public void authFormMissingPassword() {
formData.remove(CredentialRepresentation.PASSWORD);
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.MISSING_PASSWORD, status);
}
@Test
public void authFormRequiredAction() {
realm.addRequiredCredential(CredentialRepresentation.TOTP);
user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.ACTIONS_REQUIRED, status);
}
@Test
public void authFormUserDisabled() {
user.setEnabled(false);
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.ACCOUNT_DISABLED, status);
}
@Test
public void authFormWithTotp() {
realm.addRequiredCredential(CredentialRepresentation.TOTP);
String totpSecret = UUID.randomUUID().toString();
UserCredentialModel credential = new UserCredentialModel();
credential.setType(CredentialRepresentation.TOTP);
credential.setValue(totpSecret);
realm.updateCredential(user, credential);
user.setTotp(true);
String token = otp.generate(totpSecret);
formData.add(CredentialRepresentation.TOTP, token);
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.SUCCESS, status);
}
@Test
public void authFormWithTotpInvalidPassword() {
authFormWithTotp();
formData.remove(CredentialRepresentation.PASSWORD);
formData.add(CredentialRepresentation.PASSWORD, "invalid");
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
}
@Test
public void authFormWithTotpInvalidTotp() {
authFormWithTotp();
formData.remove(CredentialRepresentation.TOTP);
formData.add(CredentialRepresentation.TOTP, "invalid");
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
}
@Test
public void authFormWithTotpMissingTotp() {
authFormWithTotp();
formData.remove(CredentialRepresentation.TOTP);
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.MISSING_TOTP, status);
}
@Before
public void before() throws Exception {
super.before();
realm = realmManager.createRealm("Test");
realm.setAccessCodeLifespan(100);
realm.setEnabled(true);
realm.setName("Test");
realm.setPrivateKeyPem("0234234");
realm.setPublicKeyPem("0234234");
realm.setAccessTokenLifespan(1000);
realm.addRequiredCredential(CredentialRepresentation.PASSWORD);
am = new AuthenticationManager();
user = realm.addUser("test");
user.setEnabled(true);
UserCredentialModel credential = new UserCredentialModel();
credential.setType(CredentialRepresentation.PASSWORD);
credential.setValue("password");
realm.updateCredential(user, credential);
formData = new MultivaluedHashMap<String, String>();
formData.add(CredentialRepresentation.PASSWORD, "password");
otp = new TimeBasedOTP();
}
}

View file

@ -1,113 +1,113 @@
package org.keycloak.model.test;
import java.util.HashSet;
import java.util.Set;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.RealmManager;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class CompositeRolesModelTest extends AbstractModelTest {
@Before
public void before() throws Exception {
super.before();
RealmManager manager = realmManager;
RealmRepresentation rep = AbstractModelTest.loadJson("testcomposites.json");
RealmModel realm = manager.createRealm("Test", rep.getRealm());
manager.importRealm(rep, realm);
}
@Test
public void testComposites() {
Set<RoleModel> requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "APP_COMPOSITE_USER");
Assert.assertEquals(2, requestedRoles.size());
assertContains("APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles);
assertContains("realm", "REALM_ROLE_1", requestedRoles);
requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "REALM_APP_COMPOSITE_USER");
Assert.assertEquals(1, requestedRoles.size());
assertContains("APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles);
requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_COMPOSITE_1_USER");
Assert.assertEquals(1, requestedRoles.size());
assertContains("realm", "REALM_COMPOSITE_1", requestedRoles);
requestedRoles = getRequestedRoles("REALM_ROLE_1_APPLICATION", "REALM_COMPOSITE_1_USER");
Assert.assertEquals(1, requestedRoles.size());
assertContains("realm", "REALM_ROLE_1", requestedRoles);
requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_ROLE_1_USER");
Assert.assertEquals(1, requestedRoles.size());
assertContains("realm", "REALM_ROLE_1", requestedRoles);
}
// Same algorithm as in TokenManager.createAccessCode
private Set<RoleModel> getRequestedRoles(String applicationName, String username) {
Set<RoleModel> requestedRoles = new HashSet<RoleModel>();
RealmModel realm = realmManager.getRealm("Test");
UserModel user = realm.getUser(username);
ApplicationModel application = realm.getApplicationByName(applicationName);
Set<RoleModel> roleMappings = realm.getRoleMappings(user);
Set<RoleModel> scopeMappings = realm.getScopeMappings(application);
Set<RoleModel> appRoles = application.getRoles();
if (appRoles != null) scopeMappings.addAll(appRoles);
for (RoleModel role : roleMappings) {
if (role.getContainer().equals(application)) requestedRoles.add(role);
for (RoleModel desiredRole : scopeMappings) {
Set<RoleModel> visited = new HashSet<RoleModel>();
applyScope(role, desiredRole, visited, requestedRoles);
}
}
return requestedRoles;
}
private static void applyScope(RoleModel role, RoleModel scope, Set<RoleModel> visited, Set<RoleModel> requested) {
if (visited.contains(scope)) return;
visited.add(scope);
if (role.hasRole(scope)) {
requested.add(scope);
return;
}
if (!scope.isComposite()) return;
for (RoleModel contained : scope.getComposites()) {
applyScope(role, contained, visited, requested);
}
}
private RoleModel getRole(String appName, String roleName) {
RealmModel realm = realmManager.getRealm("Test");
if ("realm".equals(appName)) {
return realm.getRole(roleName);
} else {
return realm.getApplicationByName(appName).getRole(roleName);
}
}
private void assertContains(String appName, String roleName, Set<RoleModel> requestedRoles) {
RoleModel expectedRole = getRole(appName, roleName);
Assert.assertTrue(requestedRoles.contains(expectedRole));
// Check if requestedRole has correct role container
for (RoleModel role : requestedRoles) {
if (role.equals(expectedRole)) {
Assert.assertEquals(role.getContainer(), expectedRole.getContainer());
}
}
}
}
package org.keycloak.model.test;
import java.util.HashSet;
import java.util.Set;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.RealmManager;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class CompositeRolesModelTest extends AbstractModelTest {
@Before
public void before() throws Exception {
super.before();
RealmManager manager = realmManager;
RealmRepresentation rep = AbstractModelTest.loadJson("testcomposites.json");
RealmModel realm = manager.createRealm("Test", rep.getRealm());
manager.importRealm(rep, realm);
}
@Test
public void testComposites() {
Set<RoleModel> requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "APP_COMPOSITE_USER");
Assert.assertEquals(2, requestedRoles.size());
assertContains("APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles);
assertContains("realm", "REALM_ROLE_1", requestedRoles);
requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "REALM_APP_COMPOSITE_USER");
Assert.assertEquals(1, requestedRoles.size());
assertContains("APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles);
requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_COMPOSITE_1_USER");
Assert.assertEquals(1, requestedRoles.size());
assertContains("realm", "REALM_COMPOSITE_1", requestedRoles);
requestedRoles = getRequestedRoles("REALM_ROLE_1_APPLICATION", "REALM_COMPOSITE_1_USER");
Assert.assertEquals(1, requestedRoles.size());
assertContains("realm", "REALM_ROLE_1", requestedRoles);
requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_ROLE_1_USER");
Assert.assertEquals(1, requestedRoles.size());
assertContains("realm", "REALM_ROLE_1", requestedRoles);
}
// Same algorithm as in TokenManager.createAccessCode
private Set<RoleModel> getRequestedRoles(String applicationName, String username) {
Set<RoleModel> requestedRoles = new HashSet<RoleModel>();
RealmModel realm = realmManager.getRealm("Test");
UserModel user = realm.getUser(username);
ApplicationModel application = realm.getApplicationByName(applicationName);
Set<RoleModel> roleMappings = realm.getRoleMappings(user);
Set<RoleModel> scopeMappings = realm.getScopeMappings(application);
Set<RoleModel> appRoles = application.getRoles();
if (appRoles != null) scopeMappings.addAll(appRoles);
for (RoleModel role : roleMappings) {
if (role.getContainer().equals(application)) requestedRoles.add(role);
for (RoleModel desiredRole : scopeMappings) {
Set<RoleModel> visited = new HashSet<RoleModel>();
applyScope(role, desiredRole, visited, requestedRoles);
}
}
return requestedRoles;
}
private static void applyScope(RoleModel role, RoleModel scope, Set<RoleModel> visited, Set<RoleModel> requested) {
if (visited.contains(scope)) return;
visited.add(scope);
if (role.hasRole(scope)) {
requested.add(scope);
return;
}
if (!scope.isComposite()) return;
for (RoleModel contained : scope.getComposites()) {
applyScope(role, contained, visited, requested);
}
}
private RoleModel getRole(String appName, String roleName) {
RealmModel realm = realmManager.getRealm("Test");
if ("realm".equals(appName)) {
return realm.getRole(roleName);
} else {
return realm.getApplicationByName(appName).getRole(roleName);
}
}
private void assertContains(String appName, String roleName, Set<RoleModel> requestedRoles) {
RoleModel expectedRole = getRole(appName, roleName);
Assert.assertTrue(requestedRoles.contains(expectedRole));
// Check if requestedRole has correct role container
for (RoleModel role : requestedRoles) {
if (role.equals(expectedRole)) {
Assert.assertEquals(role.getContainer(), expectedRole.getContainer());
}
}
}
}

View file

@ -1,78 +1,78 @@
package org.keycloak.model.test;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.ModelToRepresentation;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
public class ModelTest extends AbstractModelTest {
@Test
public void importExportRealm() {
RealmModel realm = realmManager.createRealm("original");
realm.setRegistrationAllowed(true);
realm.setResetPasswordAllowed(true);
realm.setSocial(true);
realm.setSslNotRequired(true);
realm.setVerifyEmail(true);
realm.setAccessTokenLifespan(1000);
realm.setPasswordPolicy(new PasswordPolicy("length"));
realm.setAccessCodeLifespan(1001);
realm.setAccessCodeLifespanUserAction(1002);
realm.setPublicKeyPem("0234234");
realm.setPrivateKeyPem("1234234");
realm.addDefaultRole("default-role");
HashMap<String, String> smtp = new HashMap<String,String>();
smtp.put("from", "auto@keycloak");
smtp.put("hostname", "localhost");
realm.setSmtpConfig(smtp);
HashMap<String, String> social = new HashMap<String,String>();
social.put("google.key", "1234");
social.put("google.secret", "5678");
realm.setSocialConfig(social);
RealmModel persisted = realmManager.getRealm(realm.getId());
assertEquals(realm, persisted);
RealmModel copy = importExport(realm, "copy");
assertEquals(realm, copy);
}
public static void assertEquals(RealmModel expected, RealmModel actual) {
Assert.assertEquals(expected.isUpdateProfileOnInitialSocialLogin(),
actual.isUpdateProfileOnInitialSocialLogin());
Assert.assertEquals(expected.isRegistrationAllowed(), actual.isRegistrationAllowed());
Assert.assertEquals(expected.isResetPasswordAllowed(), actual.isResetPasswordAllowed());
Assert.assertEquals(expected.isSocial(), actual.isSocial());
Assert.assertEquals(expected.isSslNotRequired(), actual.isSslNotRequired());
Assert.assertEquals(expected.isVerifyEmail(), actual.isVerifyEmail());
Assert.assertEquals(expected.getAccessTokenLifespan(), actual.getAccessTokenLifespan());
Assert.assertEquals(expected.getAccessCodeLifespan(), actual.getAccessCodeLifespan());
Assert.assertEquals(expected.getAccessCodeLifespanUserAction(), actual.getAccessCodeLifespanUserAction());
Assert.assertEquals(expected.getPublicKeyPem(), actual.getPublicKeyPem());
Assert.assertEquals(expected.getPrivateKeyPem(), actual.getPrivateKeyPem());
Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles());
Assert.assertEquals(expected.getSmtpConfig(), actual.getSmtpConfig());
Assert.assertEquals(expected.getSocialConfig(), actual.getSocialConfig());
}
private RealmModel importExport(RealmModel src, String copyName) {
RealmRepresentation representation = ModelToRepresentation.toRepresentation(src);
RealmModel copy = realmManager.createRealm(copyName);
realmManager.importRealm(representation, copy);
return realmManager.getRealm(copy.getId());
}
}
package org.keycloak.model.test;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.ModelToRepresentation;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
public class ModelTest extends AbstractModelTest {
@Test
public void importExportRealm() {
RealmModel realm = realmManager.createRealm("original");
realm.setRegistrationAllowed(true);
realm.setResetPasswordAllowed(true);
realm.setSocial(true);
realm.setSslNotRequired(true);
realm.setVerifyEmail(true);
realm.setAccessTokenLifespan(1000);
realm.setPasswordPolicy(new PasswordPolicy("length"));
realm.setAccessCodeLifespan(1001);
realm.setAccessCodeLifespanUserAction(1002);
realm.setPublicKeyPem("0234234");
realm.setPrivateKeyPem("1234234");
realm.addDefaultRole("default-role");
HashMap<String, String> smtp = new HashMap<String,String>();
smtp.put("from", "auto@keycloak");
smtp.put("hostname", "localhost");
realm.setSmtpConfig(smtp);
HashMap<String, String> social = new HashMap<String,String>();
social.put("google.key", "1234");
social.put("google.secret", "5678");
realm.setSocialConfig(social);
RealmModel persisted = realmManager.getRealm(realm.getId());
assertEquals(realm, persisted);
RealmModel copy = importExport(realm, "copy");
assertEquals(realm, copy);
}
public static void assertEquals(RealmModel expected, RealmModel actual) {
Assert.assertEquals(expected.isUpdateProfileOnInitialSocialLogin(),
actual.isUpdateProfileOnInitialSocialLogin());
Assert.assertEquals(expected.isRegistrationAllowed(), actual.isRegistrationAllowed());
Assert.assertEquals(expected.isResetPasswordAllowed(), actual.isResetPasswordAllowed());
Assert.assertEquals(expected.isSocial(), actual.isSocial());
Assert.assertEquals(expected.isSslNotRequired(), actual.isSslNotRequired());
Assert.assertEquals(expected.isVerifyEmail(), actual.isVerifyEmail());
Assert.assertEquals(expected.getAccessTokenLifespan(), actual.getAccessTokenLifespan());
Assert.assertEquals(expected.getAccessCodeLifespan(), actual.getAccessCodeLifespan());
Assert.assertEquals(expected.getAccessCodeLifespanUserAction(), actual.getAccessCodeLifespanUserAction());
Assert.assertEquals(expected.getPublicKeyPem(), actual.getPublicKeyPem());
Assert.assertEquals(expected.getPrivateKeyPem(), actual.getPrivateKeyPem());
Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles());
Assert.assertEquals(expected.getSmtpConfig(), actual.getSmtpConfig());
Assert.assertEquals(expected.getSocialConfig(), actual.getSocialConfig());
}
private RealmModel importExport(RealmModel src, String copyName) {
RealmRepresentation representation = ModelToRepresentation.toRepresentation(src);
RealmModel copy = realmManager.createRealm(copyName);
realmManager.importRealm(representation, copy);
return realmManager.getRealm(copy.getId());
}
}

View file

@ -75,20 +75,11 @@ public class MultipleRealmsTest extends AbstractModelTest {
Assert.assertEquals(r2cl1.getId(), realm2.getOAuthClientById(r2cl1.getId()).getId());
RoleModel r1App1Role = r1app1.getRole("app1Role1");
Assert.assertNull(realm1.getRoleById(r1App1Role.getId()));
Assert.assertNull(realm2.getRoleById(r1App1Role.getId()));
Assert.assertEquals(r1App1Role, r1app1.getRoleById(r1App1Role.getId()));
Assert.assertNull(r1app2.getRoleById(r1App1Role.getId()));
Assert.assertNull(r2app1.getRoleById(r1App1Role.getId()));
Assert.assertNull(r2app2.getRoleById(r1App1Role.getId()));
Assert.assertEquals(r1App1Role, realm1.getRoleById(r1App1Role.getId()));
RoleModel r2Role1 = realm2.getRole("role2");
Assert.assertNull(realm1.getRoleById(r2Role1.getId()));
Assert.assertEquals(r2Role1, realm2.getRoleById(r2Role1.getId()));
Assert.assertNull(r1app1.getRoleById(r2Role1.getId()));
Assert.assertNull(r1app2.getRoleById(r2Role1.getId()));
Assert.assertNull(r2app1.getRoleById(r2Role1.getId()));
Assert.assertNull(r2app2.getRoleById(r2Role1.getId()));
}
private void createObjects(RealmModel realm) {

View file

@ -1,121 +1,121 @@
package org.keycloak.model.test;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserModel.RequiredAction;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class UserModelTest extends AbstractModelTest {
@Test
public void persistUser() {
RealmModel realm = realmManager.createRealm("original");
UserModel user = realm.addUser("user");
user.setFirstName("first-name");
user.setLastName("last-name");
user.setEmail("email");
user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
user.addRequiredAction(RequiredAction.UPDATE_PASSWORD);
UserModel persisted = realmManager.getRealm(realm.getId()).getUser("user");
assertEquals(user, persisted);
UserModel persisted2 = realmManager.getRealm(realm.getId()).getUserById(user.getId());
assertEquals(user, persisted2);
}
@Test
public void webOriginSetTest() {
RealmModel realm = realmManager.createRealm("original");
ClientModel client = realm.addApplication("user");
Assert.assertTrue(client.getWebOrigins().isEmpty());
client.addWebOrigin("origin-1");
Assert.assertEquals(1, client.getWebOrigins().size());
client.addWebOrigin("origin-2");
Assert.assertEquals(2, client.getWebOrigins().size());
client.removeWebOrigin("origin-2");
Assert.assertEquals(1, client.getWebOrigins().size());
client.removeWebOrigin("origin-1");
Assert.assertTrue(client.getWebOrigins().isEmpty());
client = realm.addOAuthClient("oauthclient2");
Assert.assertTrue(client.getWebOrigins().isEmpty());
client.addWebOrigin("origin-1");
Assert.assertEquals(1, client.getWebOrigins().size());
client.addWebOrigin("origin-2");
Assert.assertEquals(2, client.getWebOrigins().size());
client.removeWebOrigin("origin-2");
Assert.assertEquals(1, client.getWebOrigins().size());
client.removeWebOrigin("origin-1");
Assert.assertTrue(client.getWebOrigins().isEmpty());
}
@Test
public void testUserRequiredActions() throws Exception {
RealmModel realm = realmManager.createRealm("original");
UserModel user = realm.addUser("user");
Assert.assertTrue(user.getRequiredActions().isEmpty());
user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
String id = realm.getId();
commit();
realm = realmManager.getRealm(id);
user = realm.getUser("user");
Assert.assertEquals(1, user.getRequiredActions().size());
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
user = realm.getUser("user");
Assert.assertEquals(1, user.getRequiredActions().size());
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
user.addRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
user = realm.getUser("user");
Assert.assertEquals(2, user.getRequiredActions().size());
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL));
user.removeRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
user = realm.getUser("user");
Assert.assertEquals(1, user.getRequiredActions().size());
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL));
user.removeRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
user = realm.getUser("user");
Assert.assertTrue(user.getRequiredActions().isEmpty());
}
public static void assertEquals(UserModel expected, UserModel actual) {
Assert.assertEquals(expected.getLoginName(), actual.getLoginName());
Assert.assertEquals(expected.getFirstName(), actual.getFirstName());
Assert.assertEquals(expected.getLastName(), actual.getLastName());
Assert.assertArrayEquals(expected.getRequiredActions().toArray(), actual.getRequiredActions().toArray());
}
}
package org.keycloak.model.test;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserModel.RequiredAction;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class UserModelTest extends AbstractModelTest {
@Test
public void persistUser() {
RealmModel realm = realmManager.createRealm("original");
UserModel user = realm.addUser("user");
user.setFirstName("first-name");
user.setLastName("last-name");
user.setEmail("email");
user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
user.addRequiredAction(RequiredAction.UPDATE_PASSWORD);
UserModel persisted = realmManager.getRealm(realm.getId()).getUser("user");
assertEquals(user, persisted);
UserModel persisted2 = realmManager.getRealm(realm.getId()).getUserById(user.getId());
assertEquals(user, persisted2);
}
@Test
public void webOriginSetTest() {
RealmModel realm = realmManager.createRealm("original");
ClientModel client = realm.addApplication("user");
Assert.assertTrue(client.getWebOrigins().isEmpty());
client.addWebOrigin("origin-1");
Assert.assertEquals(1, client.getWebOrigins().size());
client.addWebOrigin("origin-2");
Assert.assertEquals(2, client.getWebOrigins().size());
client.removeWebOrigin("origin-2");
Assert.assertEquals(1, client.getWebOrigins().size());
client.removeWebOrigin("origin-1");
Assert.assertTrue(client.getWebOrigins().isEmpty());
client = realm.addOAuthClient("oauthclient2");
Assert.assertTrue(client.getWebOrigins().isEmpty());
client.addWebOrigin("origin-1");
Assert.assertEquals(1, client.getWebOrigins().size());
client.addWebOrigin("origin-2");
Assert.assertEquals(2, client.getWebOrigins().size());
client.removeWebOrigin("origin-2");
Assert.assertEquals(1, client.getWebOrigins().size());
client.removeWebOrigin("origin-1");
Assert.assertTrue(client.getWebOrigins().isEmpty());
}
@Test
public void testUserRequiredActions() throws Exception {
RealmModel realm = realmManager.createRealm("original");
UserModel user = realm.addUser("user");
Assert.assertTrue(user.getRequiredActions().isEmpty());
user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
String id = realm.getId();
commit();
realm = realmManager.getRealm(id);
user = realm.getUser("user");
Assert.assertEquals(1, user.getRequiredActions().size());
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
user = realm.getUser("user");
Assert.assertEquals(1, user.getRequiredActions().size());
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
user.addRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
user = realm.getUser("user");
Assert.assertEquals(2, user.getRequiredActions().size());
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL));
user.removeRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
user = realm.getUser("user");
Assert.assertEquals(1, user.getRequiredActions().size());
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL));
user.removeRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
user = realm.getUser("user");
Assert.assertTrue(user.getRequiredActions().isEmpty());
}
public static void assertEquals(UserModel expected, UserModel actual) {
Assert.assertEquals(expected.getLoginName(), actual.getLoginName());
Assert.assertEquals(expected.getFirstName(), actual.getFirstName());
Assert.assertEquals(expected.getLastName(), actual.getLastName());
Assert.assertArrayEquals(expected.getRequiredActions().toArray(), actual.getRequiredActions().toArray());
}
}

View file

@ -1,206 +1,206 @@
{
"id": "Test",
"realm": "Test",
"enabled": true,
"accessTokenLifespan": 600,
"accessCodeLifespan": 600,
"accessCodeLifespanUserAction": 600,
"sslNotRequired": true,
"registrationAllowed": true,
"resetPasswordAllowed": true,
"requiredCredentials": [ "password" ],
"smtpServer": {
"from": "auto@keycloak.org",
"host": "localhost",
"port":"3025"
},
"users" : [
{
"username" : "REALM_COMPOSITE_1_USER",
"enabled": true,
"email" : "test-user@localhost",
"credentials" : [
{ "type" : "password",
"value" : "password" }
]
},
{
"username" : "REALM_ROLE_1_USER",
"enabled": true,
"email" : "test-user@localhost",
"credentials" : [
{ "type" : "password",
"value" : "password" }
]
},
{
"username" : "REALM_APP_COMPOSITE_USER",
"enabled": true,
"email" : "test-user@localhost",
"credentials" : [
{ "type" : "password",
"value" : "password" }
]
},
{
"username" : "REALM_APP_ROLE_USER",
"enabled": true,
"email" : "test-user@localhost",
"credentials" : [
{ "type" : "password",
"value" : "password" }
]
},
{
"username" : "APP_COMPOSITE_USER",
"enabled": true,
"email" : "test-user@localhost",
"credentials" : [
{ "type" : "password",
"value" : "password" }
]
}
],
"oauthClients" : [
{
"name" : "third-party",
"enabled": true,
"secret": "password"
}
],
"roleMappings": [
{
"username": "REALM_COMPOSITE_1_USER",
"roles": ["REALM_COMPOSITE_1"]
},
{
"username": "REALM_ROLE_1_USER",
"roles": ["REALM_ROLE_1"]
},
{
"username": "REALM_APP_COMPOSITE_USER",
"roles": ["REALM_APP_COMPOSITE_ROLE"]
},
{
"username": "APP_COMPOSITE_USER",
"roles": ["REALM_APP_COMPOSITE_ROLE", "REALM_COMPOSITE_1"]
}
],
"scopeMappings": [
{
"client": "REALM_COMPOSITE_1_APPLICATION",
"roles": ["REALM_COMPOSITE_1"]
},
{
"client": "REALM_ROLE_1_APPLICATION",
"roles": ["REALM_ROLE_1"]
}
],
"applications": [
{
"name": "REALM_COMPOSITE_1_APPLICATION",
"enabled": true,
"baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout",
"secret": "password"
},
{
"name": "REALM_ROLE_1_APPLICATION",
"enabled": true,
"baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout",
"secret": "password"
},
{
"name": "APP_ROLE_APPLICATION",
"enabled": true,
"baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout",
"secret": "password"
},
{
"name": "APP_COMPOSITE_APPLICATION",
"enabled": true,
"baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout",
"secret": "password"
}
],
"roles" : {
"realm" : [
{
"name": "REALM_ROLE_1"
},
{
"name": "REALM_ROLE_2"
},
{
"name": "REALM_ROLE_3"
},
{
"name": "REALM_COMPOSITE_1",
"composites": {
"realm": ["REALM_ROLE_1"]
}
},
{
"name": "REALM_APP_COMPOSITE_ROLE",
"composites": {
"application": {
"APP_ROLE_APPLICATION" :[
"APP_ROLE_1"
]
}
}
}
],
"application" : {
"APP_ROLE_APPLICATION" : [
{
"name": "APP_ROLE_1"
},
{
"name": "APP_ROLE_2"
}
],
"APP_COMPOSITE_APPLICATION" : [
{
"name": "APP_COMPOSITE_ROLE",
"composites": {
"realm" : [
"REALM_ROLE_1",
"REALM_ROLE_2",
"REALM_ROLE_3"
],
"application": {
"APP_ROLE_APPLICATION" :[
"APP_ROLE_1"
]
}
}
},
{
"name": "APP_ROLE_2"
}
]
}
},
"applicationRoleMappings": {
"APP_ROLE_APPLICATION": [
{
"username": "REALM_APP_ROLE_USER",
"roles": ["APP_ROLE_2"]
}
]
},
"applicationScopeMappings": {
"APP_ROLE_APPLICATION": [
{
"client": "APP_COMPOSITE_APPLICATION",
"roles": ["APP_ROLE_2"]
}
]
}
{
"id": "Test",
"realm": "Test",
"enabled": true,
"accessTokenLifespan": 600,
"accessCodeLifespan": 600,
"accessCodeLifespanUserAction": 600,
"sslNotRequired": true,
"registrationAllowed": true,
"resetPasswordAllowed": true,
"requiredCredentials": [ "password" ],
"smtpServer": {
"from": "auto@keycloak.org",
"host": "localhost",
"port":"3025"
},
"users" : [
{
"username" : "REALM_COMPOSITE_1_USER",
"enabled": true,
"email" : "test-user@localhost",
"credentials" : [
{ "type" : "password",
"value" : "password" }
]
},
{
"username" : "REALM_ROLE_1_USER",
"enabled": true,
"email" : "test-user@localhost",
"credentials" : [
{ "type" : "password",
"value" : "password" }
]
},
{
"username" : "REALM_APP_COMPOSITE_USER",
"enabled": true,
"email" : "test-user@localhost",
"credentials" : [
{ "type" : "password",
"value" : "password" }
]
},
{
"username" : "REALM_APP_ROLE_USER",
"enabled": true,
"email" : "test-user@localhost",
"credentials" : [
{ "type" : "password",
"value" : "password" }
]
},
{
"username" : "APP_COMPOSITE_USER",
"enabled": true,
"email" : "test-user@localhost",
"credentials" : [
{ "type" : "password",
"value" : "password" }
]
}
],
"oauthClients" : [
{
"name" : "third-party",
"enabled": true,
"secret": "password"
}
],
"roleMappings": [
{
"username": "REALM_COMPOSITE_1_USER",
"roles": ["REALM_COMPOSITE_1"]
},
{
"username": "REALM_ROLE_1_USER",
"roles": ["REALM_ROLE_1"]
},
{
"username": "REALM_APP_COMPOSITE_USER",
"roles": ["REALM_APP_COMPOSITE_ROLE"]
},
{
"username": "APP_COMPOSITE_USER",
"roles": ["REALM_APP_COMPOSITE_ROLE", "REALM_COMPOSITE_1"]
}
],
"scopeMappings": [
{
"client": "REALM_COMPOSITE_1_APPLICATION",
"roles": ["REALM_COMPOSITE_1"]
},
{
"client": "REALM_ROLE_1_APPLICATION",
"roles": ["REALM_ROLE_1"]
}
],
"applications": [
{
"name": "REALM_COMPOSITE_1_APPLICATION",
"enabled": true,
"baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout",
"secret": "password"
},
{
"name": "REALM_ROLE_1_APPLICATION",
"enabled": true,
"baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout",
"secret": "password"
},
{
"name": "APP_ROLE_APPLICATION",
"enabled": true,
"baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout",
"secret": "password"
},
{
"name": "APP_COMPOSITE_APPLICATION",
"enabled": true,
"baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout",
"secret": "password"
}
],
"roles" : {
"realm" : [
{
"name": "REALM_ROLE_1"
},
{
"name": "REALM_ROLE_2"
},
{
"name": "REALM_ROLE_3"
},
{
"name": "REALM_COMPOSITE_1",
"composites": {
"realm": ["REALM_ROLE_1"]
}
},
{
"name": "REALM_APP_COMPOSITE_ROLE",
"composites": {
"application": {
"APP_ROLE_APPLICATION" :[
"APP_ROLE_1"
]
}
}
}
],
"application" : {
"APP_ROLE_APPLICATION" : [
{
"name": "APP_ROLE_1"
},
{
"name": "APP_ROLE_2"
}
],
"APP_COMPOSITE_APPLICATION" : [
{
"name": "APP_COMPOSITE_ROLE",
"composites": {
"realm" : [
"REALM_ROLE_1",
"REALM_ROLE_2",
"REALM_ROLE_3"
],
"application": {
"APP_ROLE_APPLICATION" :[
"APP_ROLE_1"
]
}
}
},
{
"name": "APP_ROLE_2"
}
]
}
},
"applicationRoleMappings": {
"APP_ROLE_APPLICATION": [
{
"username": "REALM_APP_ROLE_USER",
"roles": ["APP_ROLE_2"]
}
]
},
"applicationScopeMappings": {
"APP_ROLE_APPLICATION": [
{
"client": "APP_COMPOSITE_APPLICATION",
"roles": ["APP_ROLE_2"]
}
]
}
}

View file

@ -1,6 +1,7 @@
package org.keycloak.services.resources.admin;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.logging.Logger;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.Constants;
import org.keycloak.models.OAuthClientModel;
@ -28,6 +29,7 @@ import java.util.Set;
* @version $Revision: 1 $
*/
public class RoleByIdResource extends RoleResource {
protected static final Logger logger = Logger.getLogger(RoleByIdResource.class);
private final RealmModel realm;
private final RealmAuth auth;
@ -101,6 +103,8 @@ public class RoleByIdResource extends RoleResource {
@NoCache
@Produces("application/json")
public Set<RoleRepresentation> getRoleComposites(final @PathParam("role-id") String id) {
logger.info("*** getRoleComposites: '" + id + "'");
RoleModel role = getRoleModel(id);
auth.requireView();
return getRoleComposites(role);

View file

@ -28,7 +28,7 @@ public abstract class RoleResource {
}
protected void deleteRole(RoleModel role) {
if (!role.getContainer().removeRoleById(role.getId())) {
if (!role.getContainer().removeRole(role)) {
throw new NotFoundException();
}
}

View file

@ -173,7 +173,7 @@ public class ScopeMappedResource {
}
for (RoleRepresentation role : roles) {
RoleModel roleModel = app.getRoleById(role.getId());
RoleModel roleModel = app.getRole(role.getName());
if (roleModel == null) {
throw new NotFoundException();
}
@ -202,7 +202,7 @@ public class ScopeMappedResource {
} else {
for (RoleRepresentation role : roles) {
RoleModel roleModel = app.getRoleById(role.getId());
RoleModel roleModel = app.getRole(role.getName());
if (roleModel == null) {
throw new NotFoundException();
}

View file

@ -281,8 +281,8 @@ public class UsersResource {
}
for (RoleRepresentation role : roles) {
RoleModel roleModel = realm.getRoleById(role.getId());
if (roleModel == null) {
RoleModel roleModel = realm.getRole(role.getName());
if (roleModel == null || !roleModel.getId().equals(role.getId())) {
throw new NotFoundException();
}
realm.grantRole(user, roleModel);
@ -311,8 +311,8 @@ public class UsersResource {
} else {
for (RoleRepresentation role : roles) {
RoleModel roleModel = realm.getRoleById(role.getId());
if (roleModel == null) {
RoleModel roleModel = realm.getRole(role.getName());
if (roleModel == null || !roleModel.getId().equals(role.getId())) {
throw new NotFoundException();
}
realm.deleteRoleMapping(user, roleModel);
@ -368,8 +368,8 @@ public class UsersResource {
}
for (RoleRepresentation role : roles) {
RoleModel roleModel = application.getRoleById(role.getId());
if (roleModel == null) {
RoleModel roleModel = application.getRole(role.getName());
if (roleModel == null || !roleModel.getId().equals(role.getId())) {
throw new NotFoundException();
}
realm.grantRole(user, roleModel);
@ -406,8 +406,8 @@ public class UsersResource {
} else {
for (RoleRepresentation role : roles) {
RoleModel roleModel = application.getRoleById(role.getId());
if (roleModel == null) {
RoleModel roleModel = application.getRole(role.getName());
if (roleModel == null || !roleModel.getId().equals(role.getId())) {
throw new NotFoundException();
}
realm.deleteRoleMapping(user, roleModel);