commit
4f673117af
39 changed files with 1566 additions and 778 deletions
|
@ -40,7 +40,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-schema</artifactId>
|
||||
<artifactId>picketlink-idm-simple-schema</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
|
|
|
@ -5,15 +5,23 @@
|
|||
<persistence-unit name="keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
|
||||
<provider>org.hibernate.ejb.HibernatePersistence</provider>
|
||||
|
||||
<class>org.picketlink.idm.jpa.schema.IdentityObject</class>
|
||||
<class>org.picketlink.idm.jpa.schema.PartitionObject</class>
|
||||
<class>org.picketlink.idm.jpa.schema.RelationshipObject</class>
|
||||
<class>org.picketlink.idm.jpa.schema.RelationshipIdentityObject</class>
|
||||
<class>org.picketlink.idm.jpa.schema.RelationshipIdentityWeakObject</class>
|
||||
<class>org.picketlink.idm.jpa.schema.RelationshipObjectAttribute</class>
|
||||
<class>org.picketlink.idm.jpa.schema.IdentityObjectAttribute</class>
|
||||
<class>org.picketlink.idm.jpa.schema.CredentialObject</class>
|
||||
<class>org.picketlink.idm.jpa.schema.CredentialObjectAttribute</class>
|
||||
<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.services.models.picketlink.mappings.RealmEntity</class>
|
||||
<class>org.keycloak.services.models.picketlink.mappings.ResourceEntity</class>
|
||||
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
|
||||
<properties>
|
||||
<property name="hibernate.connection.url" value="jdbc:h2:mem:test"/>
|
||||
|
@ -21,8 +29,8 @@
|
|||
<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="false" />
|
||||
<property name="hibernate.show_sql" value="false" />
|
||||
<property name="hibernate.format_sql" value="false" />
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
|
|
7
pom.xml
7
pom.xml
|
@ -10,7 +10,7 @@
|
|||
|
||||
<properties>
|
||||
<resteasy.version>3.0.2.Final</resteasy.version>
|
||||
<picketlink.version>2.5.0.Keycloak-alpha-1</picketlink.version>
|
||||
<picketlink.version>2.5.0.Beta6</picketlink.version>
|
||||
</properties>
|
||||
|
||||
<url>http://keycloak.org</url>
|
||||
|
@ -57,10 +57,11 @@
|
|||
<module>services</module>
|
||||
<module>integration</module>
|
||||
<module>examples</module>
|
||||
<!--
|
||||
<module>sdk-html</module>
|
||||
<module>social</module>
|
||||
<module>server</module>
|
||||
<module>ui</module>
|
||||
<module>ui</module> -->
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
|
@ -158,7 +159,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-schema</artifactId>
|
||||
<artifactId>picketlink-idm-simple-schema</artifactId>
|
||||
<version>${picketlink.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-schema</artifactId>
|
||||
<artifactId>picketlink-idm-simple-schema</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -17,11 +17,11 @@ import java.io.IOException;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
@PreMatching
|
||||
public class KeycloakSessionFilter implements ContainerRequestFilter, ContainerResponseFilter {
|
||||
protected static final Logger logger = Logger.getLogger(KeycloakSessionFilter.class);
|
||||
public class KeycloakSessionRequestFilter implements ContainerRequestFilter, ContainerResponseFilter {
|
||||
protected static final Logger logger = Logger.getLogger(KeycloakSessionRequestFilter.class);
|
||||
protected KeycloakSessionFactory factory;
|
||||
|
||||
public KeycloakSessionFilter(KeycloakSessionFactory factory) {
|
||||
public KeycloakSessionRequestFilter(KeycloakSessionFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package org.keycloak.services.filters;
|
||||
|
||||
import org.jboss.resteasy.logging.Logger;
|
||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
|
||||
import javax.ws.rs.container.ContainerRequestContext;
|
||||
import javax.ws.rs.container.ContainerRequestFilter;
|
||||
import javax.ws.rs.container.ContainerResponseContext;
|
||||
import javax.ws.rs.container.ContainerResponseFilter;
|
||||
import javax.ws.rs.container.PreMatching;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class KeycloakSessionResponseFilter implements ContainerResponseFilter {
|
||||
protected static final Logger logger = Logger.getLogger(KeycloakSessionResponseFilter.class);
|
||||
|
||||
@Override
|
||||
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
|
||||
KeycloakSession ctx = (KeycloakSession)requestContext.getProperty(KeycloakSession.class.getName());
|
||||
if (ctx != null) ctx.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package org.keycloak.services.models.jpa.entities;
|
||||
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MapKey;
|
||||
import javax.persistence.OneToMany;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class RealmEntity {
|
||||
@Id
|
||||
protected String id;
|
||||
|
||||
protected String realmName;
|
||||
protected boolean enabled;
|
||||
protected boolean sslNotRequired;
|
||||
protected boolean cookieLoginAllowed;
|
||||
protected boolean registrationAllowed;
|
||||
protected int tokenLifespan;
|
||||
protected int accessCodeLifespan;
|
||||
@Column(length = 2048)
|
||||
protected String publicKeyPem;
|
||||
@Column(length = 2048)
|
||||
protected String privateKeyPem;
|
||||
|
||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
||||
Collection<RequiredCredentailEntity> requiredCredentials;
|
||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
||||
Collection<ResourceEntity> resources;
|
||||
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
||||
Collection<RoleEntity> roles;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package org.keycloak.services.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Entity
|
||||
public class RequiredCredentailEntity {
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package org.keycloak.services.models.jpa.entities;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OneToOne;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Entity
|
||||
public class ResourceEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private String id;
|
||||
|
||||
private String resourceName;
|
||||
private boolean enabled;
|
||||
private boolean surrogateAuthRequired;
|
||||
private String managementUrl;
|
||||
@ManyToOne
|
||||
private UserEntity resourceUser;
|
||||
|
||||
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
||||
Collection<RoleEntity> roles;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getResourceName() {
|
||||
return resourceName;
|
||||
}
|
||||
|
||||
public void setResourceName(String resourceName) {
|
||||
this.resourceName = resourceName;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isSurrogateAuthRequired() {
|
||||
return surrogateAuthRequired;
|
||||
}
|
||||
|
||||
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
|
||||
this.surrogateAuthRequired = surrogateAuthRequired;
|
||||
}
|
||||
|
||||
public String getManagementUrl() {
|
||||
return managementUrl;
|
||||
}
|
||||
|
||||
public void setManagementUrl(String managementUrl) {
|
||||
this.managementUrl = managementUrl;
|
||||
}
|
||||
|
||||
public UserEntity getResourceUser() {
|
||||
return resourceUser;
|
||||
}
|
||||
|
||||
public void setResourceUser(UserEntity resourceUser) {
|
||||
this.resourceUser = resourceUser;
|
||||
}
|
||||
|
||||
public Collection<RoleEntity> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setRoles(Collection<RoleEntity> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package org.keycloak.services.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Entity
|
||||
public class RoleEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
private String description;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package org.keycloak.services.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Entity
|
||||
public class ScopeMappingEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private long id;
|
||||
|
||||
@ManyToOne
|
||||
private UserEntity user;
|
||||
@ManyToOne
|
||||
private RoleEntity role;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public UserEntity getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(UserEntity user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public RoleEntity getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(RoleEntity role) {
|
||||
this.role = role;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package org.keycloak.services.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Entity
|
||||
public class UserEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private String id;
|
||||
|
||||
private String loginName;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getLoginName() {
|
||||
return loginName;
|
||||
}
|
||||
|
||||
public void setLoginName(String loginName) {
|
||||
this.loginName = loginName;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package org.keycloak.services.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToOne;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Entity
|
||||
public class UserRoleMappingEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private long id;
|
||||
|
||||
@ManyToOne
|
||||
private UserEntity user;
|
||||
@ManyToOne
|
||||
private RoleEntity role;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public UserEntity getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(UserEntity user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public RoleEntity getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(RoleEntity role) {
|
||||
this.role = role;
|
||||
}
|
||||
}
|
|
@ -4,11 +4,10 @@ import org.jboss.resteasy.spi.NotImplementedYetException;
|
|||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.KeycloakTransaction;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.model.Realm;
|
||||
import org.picketlink.idm.model.SimpleAgent;
|
||||
import org.keycloak.services.models.picketlink.mappings.RealmData;
|
||||
import org.picketlink.idm.PartitionManager;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
|
@ -16,20 +15,31 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class PicketlinkKeycloakSession implements KeycloakSession {
|
||||
protected IdentitySession session;
|
||||
public static ThreadLocal<EntityManager> currentEntityManager = new ThreadLocal<EntityManager>();
|
||||
public static ThreadLocal<Exception> setWhere = new ThreadLocal<Exception>();
|
||||
protected PartitionManager partitionManager;
|
||||
protected EntityManager entityManager;
|
||||
|
||||
private static AtomicLong counter = new AtomicLong(1);
|
||||
public static String generateId() {
|
||||
return counter.getAndIncrement() + "-" + System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public PicketlinkKeycloakSession(IdentitySession session) {
|
||||
this.session = session;
|
||||
public PicketlinkKeycloakSession(PartitionManager partitionManager, EntityManager entityManager) {
|
||||
this.partitionManager = partitionManager;
|
||||
this.entityManager = entityManager;
|
||||
if (currentEntityManager.get() != null)
|
||||
{
|
||||
setWhere.get().printStackTrace();
|
||||
throw new IllegalStateException("Thread local was leaked!");
|
||||
}
|
||||
currentEntityManager.set(entityManager);
|
||||
setWhere.set(new Exception());
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeycloakTransaction getTransaction() {
|
||||
return new PicketlinkKeycloakTransaction(session.getTransaction());
|
||||
return new PicketlinkKeycloakTransaction(entityManager.getTransaction());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -39,21 +49,22 @@ public class PicketlinkKeycloakSession implements KeycloakSession {
|
|||
|
||||
@Override
|
||||
public RealmAdapter createRealm(String id, String name) {
|
||||
Realm newRealm = session.createRealm(id);
|
||||
IdentityManager idm = session.createIdentityManager(newRealm);
|
||||
SimpleAgent agent = new SimpleAgent(RealmAdapter.REALM_AGENT_ID);
|
||||
idm.add(agent);
|
||||
RealmAdapter realm = new RealmAdapter(newRealm, session);
|
||||
// Picketlink beta 6 uses name attribute for getPartition()
|
||||
RealmData newRealm = new RealmData(id);
|
||||
newRealm.setId(id);
|
||||
newRealm.setRealmName(name);
|
||||
partitionManager.add(newRealm);
|
||||
RealmAdapter realm = new RealmAdapter(this, newRealm, partitionManager);
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RealmAdapter getRealm(String id) {
|
||||
Realm existing = session.findRealm(id);
|
||||
RealmData existing = partitionManager.getPartition(RealmData.class, id);
|
||||
if (existing == null) {
|
||||
return null;
|
||||
}
|
||||
return new RealmAdapter(existing, session);
|
||||
return new RealmAdapter(this, existing, partitionManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -64,6 +75,9 @@ public class PicketlinkKeycloakSession implements KeycloakSession {
|
|||
|
||||
@Override
|
||||
public void close() {
|
||||
session.close();
|
||||
if (entityManager.getTransaction().isActive()) entityManager.getTransaction().rollback();
|
||||
setWhere.set(null);
|
||||
currentEntityManager.set(null);
|
||||
if (entityManager.isOpen()) entityManager.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,22 +2,26 @@ package org.keycloak.services.models.picketlink;
|
|||
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
import org.picketlink.idm.IdentitySessionFactory;
|
||||
import org.picketlink.idm.PartitionManager;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class PicketlinkKeycloakSessionFactory implements KeycloakSessionFactory {
|
||||
protected IdentitySessionFactory factory;
|
||||
protected EntityManagerFactory factory;
|
||||
protected PartitionManager partitionManager;
|
||||
|
||||
public PicketlinkKeycloakSessionFactory(IdentitySessionFactory factory) {
|
||||
public PicketlinkKeycloakSessionFactory(EntityManagerFactory factory, PartitionManager partitionManager) {
|
||||
this.factory = factory;
|
||||
this.partitionManager = partitionManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeycloakSession createSession() {
|
||||
return new PicketlinkKeycloakSession(factory.createIdentitySession());
|
||||
return new PicketlinkKeycloakSession(partitionManager, factory.createEntityManager());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
package org.keycloak.services.models.picketlink;
|
||||
|
||||
import org.keycloak.services.models.KeycloakTransaction;
|
||||
import org.picketlink.idm.IdentityTransaction;
|
||||
|
||||
import javax.persistence.EntityTransaction;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class PicketlinkKeycloakTransaction implements KeycloakTransaction{
|
||||
protected IdentityTransaction transaction;
|
||||
public class PicketlinkKeycloakTransaction implements KeycloakTransaction {
|
||||
protected EntityTransaction transaction;
|
||||
|
||||
public PicketlinkKeycloakTransaction(IdentityTransaction transaction) {
|
||||
public PicketlinkKeycloakTransaction(EntityTransaction transaction) {
|
||||
this.transaction = transaction;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,33 +4,32 @@ import org.bouncycastle.openssl.PEMWriter;
|
|||
import org.jboss.resteasy.security.PemUtils;
|
||||
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RequiredCredentialModel;
|
||||
import org.keycloak.services.models.ResourceModel;
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserCredentialModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
import org.keycloak.services.models.picketlink.mappings.RealmData;
|
||||
import org.keycloak.services.models.picketlink.mappings.ResourceData;
|
||||
import org.keycloak.services.models.picketlink.relationships.RealmAdminRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.RequiredCredentialRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ScopeRelationship;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.PartitionManager;
|
||||
import org.picketlink.idm.RelationshipManager;
|
||||
import org.picketlink.idm.credential.Credentials;
|
||||
import org.picketlink.idm.credential.Password;
|
||||
import org.picketlink.idm.credential.TOTPCredential;
|
||||
import org.picketlink.idm.credential.TOTPCredentials;
|
||||
import org.picketlink.idm.credential.UsernamePasswordCredentials;
|
||||
import org.picketlink.idm.credential.X509CertificateCredentials;
|
||||
import org.picketlink.idm.model.Agent;
|
||||
import org.picketlink.idm.model.Attribute;
|
||||
import org.picketlink.idm.model.Grant;
|
||||
import org.picketlink.idm.model.Realm;
|
||||
import org.picketlink.idm.model.Role;
|
||||
import org.picketlink.idm.model.SimpleRole;
|
||||
import org.picketlink.idm.model.SimpleUser;
|
||||
import org.picketlink.idm.model.Tier;
|
||||
import org.picketlink.idm.model.User;
|
||||
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.model.sample.User;
|
||||
import org.picketlink.idm.query.IdentityQuery;
|
||||
import org.picketlink.idm.query.RelationshipQuery;
|
||||
|
||||
|
@ -53,140 +52,138 @@ import java.util.Set;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class RealmAdapter implements RealmModel {
|
||||
public static final String REALM_AGENT_ID = "_realm_";
|
||||
public static final String REALM_NAME = "name";
|
||||
public static final String REALM_ACCESS_CODE_LIFESPAN = "accessCodeLifespan";
|
||||
public static final String REALM_TOKEN_LIFESPAN = "tokenLifespan";
|
||||
public static final String REALM_PRIVATE_KEY = "privateKey";
|
||||
public static final String REALM_PUBLIC_KEY = "publicKey";
|
||||
public static final String REALM_IS_SSL_NOT_REQUIRED = "isSSLNotRequired";
|
||||
public static final String REALM_IS_COOKIE_LOGIN_ALLOWED = "isCookieLoginAllowed";
|
||||
public static final String REALM_IS_REGISTRATION_ALLOWED = "isRegistrationAllowed";
|
||||
|
||||
protected Realm realm;
|
||||
protected Agent realmAgent;
|
||||
protected IdentitySession identitySession;
|
||||
protected RealmData realm;
|
||||
protected volatile transient PublicKey publicKey;
|
||||
protected volatile transient PrivateKey privateKey;
|
||||
protected IdentityManager idm;
|
||||
protected PartitionManager partitionManager;
|
||||
protected RelationshipManager relationshipManager;
|
||||
protected KeycloakSession session;
|
||||
|
||||
public RealmAdapter(Realm realm, IdentitySession session) {
|
||||
public RealmAdapter(KeycloakSession session, RealmData realm, PartitionManager partitionManager) {
|
||||
this.session = session;
|
||||
this.realm = realm;
|
||||
this.identitySession = session;
|
||||
realmAgent = getIdm().getAgent(REALM_AGENT_ID);
|
||||
this.partitionManager = partitionManager;
|
||||
}
|
||||
|
||||
protected IdentityManager getIdm() {
|
||||
if (idm == null) idm = identitySession.createIdentityManager(realm);
|
||||
if (idm == null) idm = partitionManager.createIdentityManager(realm);
|
||||
return idm;
|
||||
}
|
||||
|
||||
protected RelationshipManager getRelationshipManager() {
|
||||
if (relationshipManager == null) relationshipManager = partitionManager.createRelationshipManager();
|
||||
return relationshipManager;
|
||||
}
|
||||
|
||||
protected void updateRealm() {
|
||||
getIdm().update(realmAgent);
|
||||
partitionManager.update(realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return realm.getId();
|
||||
// for some reason picketlink queries by name when finding partition, don't know what ID is used for now
|
||||
return realm.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return (String) realmAgent.getAttribute(REALM_NAME).getValue();
|
||||
return realm.getRealmName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
realmAgent.setAttribute(new Attribute<String>(REALM_NAME, name));
|
||||
realm.setRealmName(name);
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return realmAgent.isEnabled();
|
||||
return realm.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
realmAgent.setEnabled(enabled);
|
||||
realm.setEnabled(enabled);
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSslNotRequired() {
|
||||
return (Boolean) realmAgent.getAttribute(REALM_IS_SSL_NOT_REQUIRED).getValue();
|
||||
return realm.isSslNotRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSslNotRequired(boolean sslNotRequired) {
|
||||
realmAgent.setAttribute(new Attribute<Boolean>(REALM_IS_SSL_NOT_REQUIRED, sslNotRequired));
|
||||
realm.setSslNotRequired(sslNotRequired);
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCookieLoginAllowed() {
|
||||
return (Boolean) realmAgent.getAttribute(REALM_IS_COOKIE_LOGIN_ALLOWED).getValue();
|
||||
return realm.isCookieLoginAllowed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCookieLoginAllowed(boolean cookieLoginAllowed) {
|
||||
realmAgent.setAttribute(new Attribute<Boolean>(REALM_IS_COOKIE_LOGIN_ALLOWED, cookieLoginAllowed));
|
||||
realm.setCookieLoginAllowed(cookieLoginAllowed);
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegistrationAllowed() {
|
||||
return (Boolean) realmAgent.getAttribute(REALM_IS_REGISTRATION_ALLOWED).getValue();
|
||||
return realm.isRegistrationAllowed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRegistrationAllowed(boolean registrationAllowed) {
|
||||
realmAgent.setAttribute(new Attribute<Boolean>(REALM_IS_REGISTRATION_ALLOWED, registrationAllowed));
|
||||
realm.setRegistrationAllowed(registrationAllowed);
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTokenLifespan() {
|
||||
return (Integer) realmAgent.getAttribute(REALM_TOKEN_LIFESPAN).getValue();
|
||||
return realm.getTokenLifespan();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTokenLifespan(int tokenLifespan) {
|
||||
realmAgent.setAttribute(new Attribute<Integer>(REALM_TOKEN_LIFESPAN, tokenLifespan));
|
||||
realm.setTokenLifespan(tokenLifespan);
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAccessCodeLifespan() {
|
||||
return (Integer) realmAgent.getAttribute(REALM_ACCESS_CODE_LIFESPAN).getValue();
|
||||
return realm.getAccessCodeLifespan();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccessCodeLifespan(int accessCodeLifespan) {
|
||||
realmAgent.setAttribute(new Attribute<Integer>(REALM_ACCESS_CODE_LIFESPAN, accessCodeLifespan));
|
||||
realm.setAccessCodeLifespan(accessCodeLifespan);
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPublicKeyPem() {
|
||||
return (String) realmAgent.getAttribute(REALM_PUBLIC_KEY).getValue();
|
||||
return realm.getPublicKeyPem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPublicKeyPem(String publicKeyPem) {
|
||||
realmAgent.setAttribute(new Attribute<String>(REALM_PUBLIC_KEY, publicKeyPem));
|
||||
realm.setPublicKeyPem(publicKeyPem);
|
||||
this.publicKey = null;
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrivateKeyPem() {
|
||||
return (String) realmAgent.getAttribute(REALM_PRIVATE_KEY).getValue();
|
||||
return realm.getPrivateKeyPem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrivateKeyPem(String privateKeyPem) {
|
||||
realmAgent.setAttribute(new Attribute<String>(REALM_PRIVATE_KEY, privateKeyPem));
|
||||
realm.setPrivateKeyPem(privateKeyPem);
|
||||
this.privateKey = null;
|
||||
updateRealm();
|
||||
}
|
||||
|
@ -251,10 +248,8 @@ public class RealmAdapter implements RealmModel {
|
|||
|
||||
@Override
|
||||
public List<RequiredCredentialModel> getRequiredCredentials() {
|
||||
IdentityManager idm = getIdm();
|
||||
Agent realmAgent = idm.getAgent(REALM_AGENT_ID);
|
||||
RelationshipQuery<RequiredCredentialRelationship> query = idm.createRelationshipQuery(RequiredCredentialRelationship.class);
|
||||
query.setParameter(RequiredCredentialRelationship.REALM_AGENT, realmAgent);
|
||||
RelationshipQuery<RequiredCredentialRelationship> query = getRelationshipManager().createRelationshipQuery(RequiredCredentialRelationship.class);
|
||||
query.setParameter(RequiredCredentialRelationship.REALM, realm.getName());
|
||||
List<RequiredCredentialRelationship> results = query.getResultList();
|
||||
List<RequiredCredentialModel> rtn = new ArrayList<RequiredCredentialModel>();
|
||||
for (RequiredCredentialRelationship relationship : results) {
|
||||
|
@ -269,16 +264,15 @@ public class RealmAdapter implements RealmModel {
|
|||
|
||||
@Override
|
||||
public void addRequiredCredential(RequiredCredentialModel cred) {
|
||||
IdentityManager idm = getIdm();
|
||||
Agent realmAgent = idm.getAgent(REALM_AGENT_ID);
|
||||
RequiredCredentialRelationship relationship = new RequiredCredentialRelationship();
|
||||
relationship.setCredentialType(cred.getType());
|
||||
relationship.setInput(cred.isInput());
|
||||
relationship.setSecret(cred.isSecret());
|
||||
relationship.setRealmAgent(realmAgent);
|
||||
idm.add(relationship);
|
||||
relationship.setRealm(realm.getName());
|
||||
getRelationshipManager().add(relationship);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean validatePassword(UserModel user, String password) {
|
||||
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(user.getLoginName(), new Password(password));
|
||||
|
@ -319,30 +313,34 @@ public class RealmAdapter implements RealmModel {
|
|||
|
||||
@Override
|
||||
public UserAdapter getUser(String name) {
|
||||
User user = getIdm().getUser(name);
|
||||
User user = findPicketlinkUser(name);
|
||||
if (user == null) return null;
|
||||
return new UserAdapter(user, getIdm());
|
||||
}
|
||||
|
||||
protected User findPicketlinkUser(String name) {
|
||||
return SampleModel.getUser(getIdm(), name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserAdapter addUser(String username) {
|
||||
User user = getIdm().getUser(username);
|
||||
User user = findPicketlinkUser(username);
|
||||
if (user != null) throw new IllegalStateException("User already exists");
|
||||
user = new SimpleUser(username);
|
||||
user = new User(username);
|
||||
getIdm().add(user);
|
||||
return new UserAdapter(user, getIdm());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleAdapter getRole(String name) {
|
||||
Role role = getIdm().getRole(name);
|
||||
Role role = SampleModel.getRole(getIdm(), name);
|
||||
if (role == null) return null;
|
||||
return new RoleAdapter(role, getIdm());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleAdapter addRole(String name) {
|
||||
Role role = new SimpleRole(name);
|
||||
Role role = new Role(name);
|
||||
getIdm().add(role);
|
||||
return new RoleAdapter(role, getIdm());
|
||||
}
|
||||
|
@ -377,14 +375,13 @@ public class RealmAdapter implements RealmModel {
|
|||
|
||||
@Override
|
||||
public List<ResourceModel> getResources() {
|
||||
IdentityManager idm = getIdm();
|
||||
RelationshipQuery<ResourceRelationship> query = idm.createRelationshipQuery(ResourceRelationship.class);
|
||||
query.setParameter(ResourceRelationship.REALM_AGENT, realmAgent);
|
||||
RelationshipQuery<ResourceRelationship> query = getRelationshipManager().createRelationshipQuery(ResourceRelationship.class);
|
||||
query.setParameter(ResourceRelationship.REALM, realm.getName());
|
||||
List<ResourceRelationship> results = query.getResultList();
|
||||
List<ResourceModel> resources = new ArrayList<ResourceModel>();
|
||||
for (ResourceRelationship relationship : results) {
|
||||
Tier resourceTier = identitySession.findTier(relationship.getResourceId());
|
||||
ResourceModel model = new ResourceAdapter(resourceTier,relationship, this, identitySession);
|
||||
ResourceData resource = partitionManager.getPartition(ResourceData.class, relationship.getResource());
|
||||
ResourceModel model = new ResourceAdapter(resource, this, partitionManager);
|
||||
resources.add(model);
|
||||
}
|
||||
|
||||
|
@ -393,18 +390,12 @@ public class RealmAdapter implements RealmModel {
|
|||
|
||||
@Override
|
||||
public ResourceModel addResource(String name) {
|
||||
Tier newTier = identitySession.createTier(RealmManager.generateId());
|
||||
IdentityManager idm = getIdm();
|
||||
ResourceRelationship relationship = new ResourceRelationship();
|
||||
relationship.setResourceName(name);
|
||||
relationship.setRealmAgent(realmAgent);
|
||||
relationship.setResourceId(newTier.getId());
|
||||
relationship.setManagementUrl(""); // Picketlink doesn't like null attribute values
|
||||
User resourceUser = new SimpleUser(name);
|
||||
ResourceData resourceData = new ResourceData(name);
|
||||
User resourceUser = new User(name);
|
||||
idm.add(resourceUser);
|
||||
relationship.setResourceUser(resourceUser);
|
||||
idm.add(relationship);
|
||||
ResourceModel resource = new ResourceAdapter(newTier, relationship, this, identitySession);
|
||||
resourceData.setResourceUser(resourceUser);
|
||||
partitionManager.add(resourceData);
|
||||
ResourceModel resource = new ResourceAdapter(resourceData, this, partitionManager);
|
||||
resource.addRole("*");
|
||||
resource.addScope(new UserAdapter(resourceUser, idm), "*");
|
||||
return resource;
|
||||
|
@ -412,17 +403,17 @@ public class RealmAdapter implements RealmModel {
|
|||
|
||||
@Override
|
||||
public boolean hasRole(UserModel user, RoleModel role) {
|
||||
return getIdm().hasRole(((UserAdapter)user).getUser(), ((RoleAdapter)role).getRole());
|
||||
return SampleModel.hasRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grantRole(UserModel user, RoleModel role) {
|
||||
getIdm().grantRole(((UserAdapter)user).getUser(), ((RoleAdapter)role).getRole());
|
||||
SampleModel.grantRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRoleMappings(UserModel user) {
|
||||
RelationshipQuery<Grant> query = getIdm().createRelationshipQuery(Grant.class);
|
||||
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>();
|
||||
|
@ -435,19 +426,18 @@ public class RealmAdapter implements RealmModel {
|
|||
@Override
|
||||
public void addScope(UserModel agent, String roleName) {
|
||||
IdentityManager idm = getIdm();
|
||||
Role role = idm.getRole(roleName);
|
||||
Role role = SampleModel.getRole(idm, roleName);
|
||||
if (role == null) throw new RuntimeException("role not found");
|
||||
ScopeRelationship scope = new ScopeRelationship();
|
||||
scope.setClient(((UserAdapter)agent).getUser());
|
||||
scope.setScope(role);
|
||||
idm.add(scope);
|
||||
|
||||
getRelationshipManager().add(scope);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<String> getScope(UserModel agent) {
|
||||
RelationshipQuery<ScopeRelationship> query = getIdm().createRelationshipQuery(ScopeRelationship.class);
|
||||
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>();
|
||||
|
@ -459,10 +449,9 @@ public class RealmAdapter implements RealmModel {
|
|||
|
||||
@Override
|
||||
public boolean isRealmAdmin(UserModel agent) {
|
||||
RealmAdapter realmModel = (RealmAdapter)new RealmManager(new PicketlinkKeycloakSession(identitySession)).defaultRealm();
|
||||
IdentityManager idm = realmModel.getIdm();
|
||||
RelationshipQuery<RealmAdminRelationship> query = idm.createRelationshipQuery(RealmAdminRelationship.class);
|
||||
query.setParameter(RealmAdminRelationship.REALM, realm.getId());
|
||||
RealmAdapter realmModel = (RealmAdapter)new RealmManager(session).defaultRealm();
|
||||
RelationshipQuery<RealmAdminRelationship> query = getRelationshipManager().createRelationshipQuery(RealmAdminRelationship.class);
|
||||
query.setParameter(RealmAdminRelationship.REALM, realm.getName());
|
||||
query.setParameter(RealmAdminRelationship.ADMIN, ((UserAdapter)agent).getUser());
|
||||
List<RealmAdminRelationship> results = query.getResultList();
|
||||
return results.size() > 0;
|
||||
|
@ -470,10 +459,9 @@ public class RealmAdapter implements RealmModel {
|
|||
|
||||
@Override
|
||||
public void addRealmAdmin(UserModel agent) {
|
||||
RealmAdapter realmModel = (RealmAdapter)new RealmManager(new PicketlinkKeycloakSession(identitySession)).defaultRealm();
|
||||
RealmAdminRelationship relationship = new RealmAdminRelationship();
|
||||
relationship.setAdmin(((UserAdapter)agent).getUser());
|
||||
relationship.setRealm(realm.getId());
|
||||
idm.add(relationship);
|
||||
relationship.setRealm(realm.getName());
|
||||
getRelationshipManager().add(relationship);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,15 @@ package org.keycloak.services.models.picketlink;
|
|||
import org.keycloak.services.models.ResourceModel;
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
import org.keycloak.services.models.picketlink.mappings.ResourceData;
|
||||
import org.keycloak.services.models.picketlink.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ScopeRelationship;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.model.Grant;
|
||||
import org.picketlink.idm.model.Role;
|
||||
import org.picketlink.idm.model.SimpleRole;
|
||||
import org.picketlink.idm.model.Tier;
|
||||
import org.picketlink.idm.PartitionManager;
|
||||
import org.picketlink.idm.RelationshipManager;
|
||||
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;
|
||||
|
||||
|
@ -24,89 +25,94 @@ import java.util.Set;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class ResourceAdapter implements ResourceModel {
|
||||
protected Tier tier;
|
||||
protected ResourceRelationship agent;
|
||||
protected ResourceData resource;
|
||||
protected RealmAdapter realm;
|
||||
protected IdentitySession identitySession;
|
||||
protected IdentityManager idm;
|
||||
protected PartitionManager partitionManager;
|
||||
protected RelationshipManager relationshipManager;
|
||||
|
||||
public ResourceAdapter(Tier tier, ResourceRelationship agent, RealmAdapter realm, IdentitySession session) {
|
||||
this.tier = tier;
|
||||
this.agent = agent;
|
||||
public ResourceAdapter(ResourceData resource, RealmAdapter realm, PartitionManager partitionManager) {
|
||||
this.resource = resource;
|
||||
this.realm = realm;
|
||||
this.identitySession = session;
|
||||
this.partitionManager = partitionManager;
|
||||
}
|
||||
|
||||
protected IdentityManager getIdm() {
|
||||
if (idm == null) idm = identitySession.createIdentityManager(tier);
|
||||
if (idm == null) idm = partitionManager.createIdentityManager(resource);
|
||||
return idm;
|
||||
}
|
||||
|
||||
protected RelationshipManager getRelationshipManager() {
|
||||
if (relationshipManager == null) relationshipManager = partitionManager.createRelationshipManager();
|
||||
return relationshipManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateResource() {
|
||||
getIdm().update(agent);
|
||||
partitionManager.update(resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserAdapter getResourceUser() {
|
||||
return new UserAdapter(agent.getResourceUser(), realm.getIdm());
|
||||
return new UserAdapter(resource.getResourceUser(), realm.getIdm());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return tier.getId();
|
||||
// for some reason picketlink queries by name when finding partition, don't know what ID is used for now
|
||||
return resource.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return agent.getResourceName();
|
||||
return resource.getResourceName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
agent.setResourceName(name);
|
||||
resource.setResourceName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return agent.getEnabled();
|
||||
return resource.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
agent.setEnabled(enabled);
|
||||
resource.setEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSurrogateAuthRequired() {
|
||||
return agent.getSurrogateAuthRequired();
|
||||
return resource.isSurrogateAuthRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
|
||||
agent.setSurrogateAuthRequired(surrogateAuthRequired);
|
||||
resource.setSurrogateAuthRequired(surrogateAuthRequired);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getManagementUrl() {
|
||||
return agent.getManagementUrl();
|
||||
return resource.getManagementUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setManagementUrl(String url) {
|
||||
agent.setManagementUrl(url);
|
||||
resource.setManagementUrl(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleAdapter getRole(String name) {
|
||||
Role role = getIdm().getRole(name);
|
||||
Role role = SampleModel.getRole(getIdm(), name);
|
||||
if (role == null) return null;
|
||||
return new RoleAdapter(role, getIdm());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleAdapter addRole(String name) {
|
||||
Role role = new SimpleRole(name);
|
||||
Role role = new Role(name);
|
||||
getIdm().add(role);
|
||||
return new RoleAdapter(role, getIdm());
|
||||
}
|
||||
|
@ -114,7 +120,7 @@ public class ResourceAdapter implements ResourceModel {
|
|||
@Override
|
||||
public List<RoleModel> getRoles() {
|
||||
IdentityQuery<Role> query = getIdm().createIdentityQuery(Role.class);
|
||||
query.setParameter(Role.PARTITION, tier);
|
||||
query.setParameter(Role.PARTITION, resource);
|
||||
List<Role> roles = query.getResultList();
|
||||
List<RoleModel> roleModels = new ArrayList<RoleModel>();
|
||||
for (Role role : roles) {
|
||||
|
@ -125,12 +131,12 @@ public class ResourceAdapter implements ResourceModel {
|
|||
|
||||
@Override
|
||||
public Set<String> getRoleMappings(UserModel user) {
|
||||
RelationshipQuery<Grant> query = getIdm().createRelationshipQuery(Grant.class);
|
||||
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(tier.getId())) set.add(grant.getRole().getName());
|
||||
if (grant.getRole().getPartition().getId().equals(resource.getId())) set.add(grant.getRole().getName());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
@ -138,7 +144,7 @@ public class ResourceAdapter implements ResourceModel {
|
|||
@Override
|
||||
public void addScope(UserModel agent, String roleName) {
|
||||
IdentityManager idm = getIdm();
|
||||
Role role = idm.getRole(roleName);
|
||||
Role role = SampleModel.getRole(idm,roleName);
|
||||
if (role == null) throw new RuntimeException("role not found");
|
||||
addScope(agent, new RoleAdapter(role, idm));
|
||||
|
||||
|
@ -153,12 +159,12 @@ public class ResourceAdapter implements ResourceModel {
|
|||
|
||||
@Override
|
||||
public Set<String> getScope(UserModel agent) {
|
||||
RelationshipQuery<ScopeRelationship> query = getIdm().createRelationshipQuery(ScopeRelationship.class);
|
||||
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(tier.getId())) set.add(rel.getScope().getName());
|
||||
if (rel.getScope().getPartition().getId().equals(resource.getId())) set.add(rel.getScope().getName());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package org.keycloak.services.models.picketlink;
|
|||
import org.keycloak.services.models.RoleModel;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.model.Attribute;
|
||||
import org.picketlink.idm.model.Role;
|
||||
import org.picketlink.idm.model.sample.Role;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package org.keycloak.services.models.picketlink;
|
|||
import org.keycloak.services.models.UserModel;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.model.Attribute;
|
||||
import org.picketlink.idm.model.User;
|
||||
import org.picketlink.idm.model.sample.User;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
package org.keycloak.services.models.picketlink.mappings;
|
||||
|
||||
import org.picketlink.idm.jpa.annotations.AttributeValue;
|
||||
import org.picketlink.idm.model.AbstractPartition;
|
||||
import org.picketlink.idm.model.annotation.AttributeProperty;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class RealmData extends AbstractPartition {
|
||||
private String realmName;
|
||||
private boolean enabled;
|
||||
private boolean sslNotRequired;
|
||||
private boolean cookieLoginAllowed;
|
||||
private boolean registrationAllowed;
|
||||
private int tokenLifespan;
|
||||
private int accessCodeLifespan;
|
||||
private String publicKeyPem;
|
||||
private String privateKeyPem;
|
||||
|
||||
public RealmData() {
|
||||
super(null);
|
||||
}
|
||||
public RealmData(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public String getRealmName() {
|
||||
return realmName;
|
||||
}
|
||||
|
||||
public void setRealmName(String realmName) {
|
||||
this.realmName = realmName;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public boolean isSslNotRequired() {
|
||||
return sslNotRequired;
|
||||
}
|
||||
|
||||
public void setSslNotRequired(boolean sslNotRequired) {
|
||||
this.sslNotRequired = sslNotRequired;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public boolean isCookieLoginAllowed() {
|
||||
return cookieLoginAllowed;
|
||||
}
|
||||
|
||||
public void setCookieLoginAllowed(boolean cookieLoginAllowed) {
|
||||
this.cookieLoginAllowed = cookieLoginAllowed;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public boolean isRegistrationAllowed() {
|
||||
return registrationAllowed;
|
||||
}
|
||||
|
||||
public void setRegistrationAllowed(boolean registrationAllowed) {
|
||||
this.registrationAllowed = registrationAllowed;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public int getTokenLifespan() {
|
||||
return tokenLifespan;
|
||||
}
|
||||
|
||||
public void setTokenLifespan(int tokenLifespan) {
|
||||
this.tokenLifespan = tokenLifespan;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public int getAccessCodeLifespan() {
|
||||
return accessCodeLifespan;
|
||||
}
|
||||
|
||||
public void setAccessCodeLifespan(int accessCodeLifespan) {
|
||||
this.accessCodeLifespan = accessCodeLifespan;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public String getPublicKeyPem() {
|
||||
return publicKeyPem;
|
||||
}
|
||||
|
||||
public void setPublicKeyPem(String publicKeyPem) {
|
||||
this.publicKeyPem = publicKeyPem;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public String getPrivateKeyPem() {
|
||||
return privateKeyPem;
|
||||
}
|
||||
|
||||
public void setPrivateKeyPem(String privateKeyPem) {
|
||||
this.privateKeyPem = privateKeyPem;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
package org.keycloak.services.models.picketlink.mappings;
|
||||
|
||||
import org.picketlink.idm.jpa.annotations.AttributeValue;
|
||||
import org.picketlink.idm.jpa.annotations.OwnerReference;
|
||||
import org.picketlink.idm.jpa.annotations.entity.IdentityManaged;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.PartitionTypeEntity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToOne;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@IdentityManaged(RealmData.class)
|
||||
@Entity
|
||||
public class RealmEntity implements Serializable {
|
||||
@OneToOne
|
||||
@Id
|
||||
@OwnerReference
|
||||
private PartitionTypeEntity partitionTypeEntity;
|
||||
|
||||
|
||||
@AttributeValue
|
||||
private String realmName;
|
||||
@AttributeValue
|
||||
private boolean enabled;
|
||||
@AttributeValue
|
||||
private boolean sslNotRequired;
|
||||
@AttributeValue
|
||||
private boolean cookieLoginAllowed;
|
||||
@AttributeValue
|
||||
private boolean registrationAllowed;
|
||||
@AttributeValue
|
||||
private int tokenLifespan;
|
||||
@AttributeValue
|
||||
private int accessCodeLifespan;
|
||||
@AttributeValue
|
||||
@Column(length = 2048)
|
||||
private String publicKeyPem;
|
||||
@AttributeValue
|
||||
@Column(length = 2048)
|
||||
private String privateKeyPem;
|
||||
|
||||
|
||||
public PartitionTypeEntity getPartitionTypeEntity() {
|
||||
return partitionTypeEntity;
|
||||
}
|
||||
|
||||
public void setPartitionTypeEntity(PartitionTypeEntity partitionTypeEntity) {
|
||||
this.partitionTypeEntity = partitionTypeEntity;
|
||||
}
|
||||
|
||||
public String getRealmName() {
|
||||
return realmName;
|
||||
}
|
||||
|
||||
public void setRealmName(String realmName) {
|
||||
this.realmName = realmName;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isSslNotRequired() {
|
||||
return sslNotRequired;
|
||||
}
|
||||
|
||||
public void setSslNotRequired(boolean sslNotRequired) {
|
||||
this.sslNotRequired = sslNotRequired;
|
||||
}
|
||||
|
||||
public boolean isCookieLoginAllowed() {
|
||||
return cookieLoginAllowed;
|
||||
}
|
||||
|
||||
public void setCookieLoginAllowed(boolean cookieLoginAllowed) {
|
||||
this.cookieLoginAllowed = cookieLoginAllowed;
|
||||
}
|
||||
|
||||
public boolean isRegistrationAllowed() {
|
||||
return registrationAllowed;
|
||||
}
|
||||
|
||||
public void setRegistrationAllowed(boolean registrationAllowed) {
|
||||
this.registrationAllowed = registrationAllowed;
|
||||
}
|
||||
|
||||
public int getTokenLifespan() {
|
||||
return tokenLifespan;
|
||||
}
|
||||
|
||||
public void setTokenLifespan(int tokenLifespan) {
|
||||
this.tokenLifespan = tokenLifespan;
|
||||
}
|
||||
|
||||
public int getAccessCodeLifespan() {
|
||||
return accessCodeLifespan;
|
||||
}
|
||||
|
||||
public void setAccessCodeLifespan(int accessCodeLifespan) {
|
||||
this.accessCodeLifespan = accessCodeLifespan;
|
||||
}
|
||||
|
||||
public String getPublicKeyPem() {
|
||||
return publicKeyPem;
|
||||
}
|
||||
|
||||
public void setPublicKeyPem(String publicKeyPem) {
|
||||
this.publicKeyPem = publicKeyPem;
|
||||
}
|
||||
|
||||
public String getPrivateKeyPem() {
|
||||
return privateKeyPem;
|
||||
}
|
||||
|
||||
public void setPrivateKeyPem(String privateKeyPem) {
|
||||
this.privateKeyPem = privateKeyPem;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package org.keycloak.services.models.picketlink.mappings;
|
||||
|
||||
import org.picketlink.idm.jpa.annotations.AttributeValue;
|
||||
import org.picketlink.idm.model.AbstractPartition;
|
||||
import org.picketlink.idm.model.annotation.AttributeProperty;
|
||||
import org.picketlink.idm.model.sample.User;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class ResourceData extends AbstractPartition {
|
||||
private String resourceName;
|
||||
private boolean enabled;
|
||||
private boolean surrogateAuthRequired;
|
||||
private String managementUrl;
|
||||
private User resourceUser;
|
||||
|
||||
public ResourceData() {
|
||||
super(null);
|
||||
}
|
||||
public ResourceData(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public String getResourceName() {
|
||||
return resourceName;
|
||||
}
|
||||
|
||||
public void setResourceName(String resourceName) {
|
||||
this.resourceName = resourceName;
|
||||
}
|
||||
|
||||
public User getResourceUser() {
|
||||
return resourceUser;
|
||||
}
|
||||
|
||||
public void setResourceUser(User resourceUser) {
|
||||
this.resourceUser = resourceUser;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public boolean isSurrogateAuthRequired() {
|
||||
return surrogateAuthRequired;
|
||||
}
|
||||
|
||||
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
|
||||
this.surrogateAuthRequired = surrogateAuthRequired;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public String getManagementUrl() {
|
||||
return managementUrl;
|
||||
}
|
||||
|
||||
public void setManagementUrl(String managementUrl) {
|
||||
this.managementUrl = managementUrl;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package org.keycloak.services.models.picketlink.mappings;
|
||||
|
||||
import org.picketlink.idm.jpa.annotations.AttributeValue;
|
||||
import org.picketlink.idm.jpa.annotations.OwnerReference;
|
||||
import org.picketlink.idm.jpa.annotations.entity.IdentityManaged;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.AccountTypeEntity;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.PartitionTypeEntity;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToOne;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@IdentityManaged(ResourceData.class)
|
||||
@Entity
|
||||
public class ResourceEntity implements Serializable {
|
||||
@OneToOne
|
||||
@Id
|
||||
@OwnerReference
|
||||
private PartitionTypeEntity partitionTypeEntity;
|
||||
|
||||
@AttributeValue
|
||||
private String realmName;
|
||||
@AttributeValue
|
||||
private boolean enabled;
|
||||
@AttributeValue
|
||||
private boolean surrogateAuthRequired;
|
||||
@AttributeValue
|
||||
private String managementUrl;
|
||||
|
||||
@OneToOne
|
||||
@AttributeValue
|
||||
AccountTypeEntity resourceUser;
|
||||
|
||||
|
||||
public PartitionTypeEntity getPartitionTypeEntity() {
|
||||
return partitionTypeEntity;
|
||||
}
|
||||
|
||||
public void setPartitionTypeEntity(PartitionTypeEntity partitionTypeEntity) {
|
||||
this.partitionTypeEntity = partitionTypeEntity;
|
||||
}
|
||||
|
||||
public String getRealmName() {
|
||||
return realmName;
|
||||
}
|
||||
|
||||
public void setRealmName(String realmName) {
|
||||
this.realmName = realmName;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isSurrogateAuthRequired() {
|
||||
return surrogateAuthRequired;
|
||||
}
|
||||
|
||||
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
|
||||
this.surrogateAuthRequired = surrogateAuthRequired;
|
||||
}
|
||||
|
||||
public String getManagementUrl() {
|
||||
return managementUrl;
|
||||
}
|
||||
|
||||
public void setManagementUrl(String managementUrl) {
|
||||
this.managementUrl = managementUrl;
|
||||
}
|
||||
|
||||
public AccountTypeEntity getResourceUser() {
|
||||
return resourceUser;
|
||||
}
|
||||
|
||||
public void setResourceUser(AccountTypeEntity resourceUser) {
|
||||
this.resourceUser = resourceUser;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
package org.keycloak.services.models.picketlink.relationships;
|
||||
|
||||
import org.keycloak.services.models.picketlink.mappings.RealmData;
|
||||
import org.picketlink.idm.model.AbstractAttributedType;
|
||||
import org.picketlink.idm.model.Agent;
|
||||
import org.picketlink.idm.model.Attribute;
|
||||
import org.picketlink.idm.model.Relationship;
|
||||
import org.picketlink.idm.model.annotation.AttributeProperty;
|
||||
import org.picketlink.idm.model.annotation.IdentityProperty;
|
||||
import org.picketlink.idm.model.sample.User;
|
||||
import org.picketlink.idm.query.AttributeParameter;
|
||||
import org.picketlink.idm.query.RelationshipQueryParameter;
|
||||
|
||||
/**
|
||||
|
@ -14,13 +16,7 @@ import org.picketlink.idm.query.RelationshipQueryParameter;
|
|||
public class RealmAdminRelationship extends AbstractAttributedType implements Relationship {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final RelationshipQueryParameter REALM = new RelationshipQueryParameter() {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "realm";
|
||||
}
|
||||
};
|
||||
public static final AttributeParameter REALM = new AttributeParameter("realm");
|
||||
|
||||
public static final RelationshipQueryParameter ADMIN = new RelationshipQueryParameter() {
|
||||
|
||||
|
@ -30,24 +26,22 @@ public class RealmAdminRelationship extends AbstractAttributedType implements Re
|
|||
}
|
||||
};
|
||||
|
||||
protected String realm;
|
||||
protected Agent admin;
|
||||
//protected String realm;
|
||||
protected User admin;
|
||||
|
||||
@AttributeProperty
|
||||
public String getRealm() {
|
||||
return realm;
|
||||
return (String)getAttribute("realm").getValue();
|
||||
}
|
||||
|
||||
public void setRealm(String realm) {
|
||||
this.realm = realm;
|
||||
setAttribute(new Attribute<String>("realm", realm));
|
||||
}
|
||||
|
||||
@IdentityProperty
|
||||
public Agent getAdmin() {
|
||||
public User getAdmin() {
|
||||
return admin;
|
||||
}
|
||||
|
||||
public void setAdmin(Agent admin) {
|
||||
public void setAdmin(User admin) {
|
||||
this.admin = admin;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package org.keycloak.services.models.picketlink.relationships;
|
||||
|
||||
import org.keycloak.services.models.picketlink.mappings.RealmData;
|
||||
import org.picketlink.idm.model.AbstractAttributedType;
|
||||
import org.picketlink.idm.model.Agent;
|
||||
import org.picketlink.idm.model.Attribute;
|
||||
import org.picketlink.idm.model.Relationship;
|
||||
import org.picketlink.idm.model.annotation.AttributeProperty;
|
||||
import org.picketlink.idm.model.annotation.IdentityProperty;
|
||||
import org.picketlink.idm.query.AttributeParameter;
|
||||
import org.picketlink.idm.query.RelationshipQueryParameter;
|
||||
|
||||
/**
|
||||
|
@ -14,56 +15,59 @@ import org.picketlink.idm.query.RelationshipQueryParameter;
|
|||
public class RequiredCredentialRelationship extends AbstractAttributedType implements Relationship {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final RelationshipQueryParameter REALM_AGENT = new RelationshipQueryParameter() {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "realmAgent";
|
||||
}
|
||||
};
|
||||
public static final AttributeParameter REALM = new AttributeParameter("realm");
|
||||
|
||||
|
||||
protected Agent realmAgent;
|
||||
protected String credentialType;
|
||||
protected boolean input;
|
||||
protected boolean secret;
|
||||
//protected String realm;
|
||||
//protected String credentialType;
|
||||
//protected boolean input;
|
||||
//protected boolean secret;
|
||||
|
||||
public RequiredCredentialRelationship() {
|
||||
}
|
||||
|
||||
@IdentityProperty
|
||||
public Agent getRealmAgent() {
|
||||
return realmAgent;
|
||||
/*
|
||||
@AttributeProperty
|
||||
public String getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
public void setRealmAgent(Agent realmAgent) {
|
||||
this.realmAgent = realmAgent;
|
||||
public void setRealm(String realm) {
|
||||
this.realm = realm;
|
||||
}*/
|
||||
|
||||
public String getRealm() {
|
||||
return (String)getAttribute("realm").getValue();
|
||||
}
|
||||
|
||||
public void setRealm(String realm) {
|
||||
setAttribute(new Attribute<String>("realm", realm));
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public String getCredentialType() {
|
||||
return credentialType;
|
||||
return (String)getAttribute("credentialType").getValue();
|
||||
}
|
||||
|
||||
public void setCredentialType(String credentialType) {
|
||||
this.credentialType = credentialType;
|
||||
setAttribute(new Attribute<String>("credentialType", credentialType));
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public boolean isInput() {
|
||||
return input;
|
||||
return (Boolean)getAttribute("input").getValue();
|
||||
}
|
||||
|
||||
public void setInput(boolean input) {
|
||||
this.input = input;
|
||||
setAttribute(new Attribute<Boolean>("input", input));
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public boolean isSecret() {
|
||||
return secret;
|
||||
return (Boolean)getAttribute("secret").getValue();
|
||||
}
|
||||
|
||||
public void setSecret(boolean secret) {
|
||||
this.secret = secret;
|
||||
setAttribute(new Attribute<Boolean>("secret", secret));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
package org.keycloak.services.models.picketlink.relationships;
|
||||
|
||||
import org.keycloak.services.models.picketlink.mappings.RealmData;
|
||||
import org.keycloak.services.models.picketlink.mappings.ResourceData;
|
||||
import org.picketlink.idm.model.AbstractAttributedType;
|
||||
import org.picketlink.idm.model.Agent;
|
||||
import org.picketlink.idm.model.Attribute;
|
||||
import org.picketlink.idm.model.Relationship;
|
||||
import org.picketlink.idm.model.User;
|
||||
import org.picketlink.idm.model.annotation.AttributeProperty;
|
||||
import org.picketlink.idm.model.annotation.IdentityProperty;
|
||||
import org.picketlink.idm.model.sample.Agent;
|
||||
import org.picketlink.idm.model.sample.User;
|
||||
import org.picketlink.idm.query.AttributeParameter;
|
||||
import org.picketlink.idm.query.RelationshipQueryParameter;
|
||||
|
||||
/**
|
||||
|
@ -15,84 +18,26 @@ import org.picketlink.idm.query.RelationshipQueryParameter;
|
|||
public class ResourceRelationship extends AbstractAttributedType implements Relationship {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final RelationshipQueryParameter REALM_AGENT = new RelationshipQueryParameter() {
|
||||
public static final AttributeParameter REALM = new AttributeParameter("realm");
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "realmAgent";
|
||||
}
|
||||
};
|
||||
protected String realm;
|
||||
protected String resource;
|
||||
|
||||
protected Agent realmAgent;
|
||||
protected User resourceUser;
|
||||
protected String resourceId;
|
||||
protected String resourceName;
|
||||
protected String managementUrl = ""; // Picketlink doesn't like null attribute values
|
||||
protected boolean surrogateAuthRequired;
|
||||
protected boolean enabled;
|
||||
|
||||
@IdentityProperty
|
||||
public Agent getRealmAgent() {
|
||||
return realmAgent;
|
||||
public String getRealm() {
|
||||
return (String)getAttribute("realm").getValue();
|
||||
}
|
||||
|
||||
public void setRealmAgent(Agent realmAgent) {
|
||||
this.realmAgent = realmAgent;
|
||||
public void setRealm(String realm) {
|
||||
setAttribute(new Attribute<String>("realm", realm));
|
||||
}
|
||||
|
||||
@IdentityProperty
|
||||
public User getResourceUser() {
|
||||
return resourceUser;
|
||||
|
||||
public String getResource() {
|
||||
return (String)getAttribute("resource").getValue();
|
||||
}
|
||||
|
||||
public void setResourceUser(User resourceUser) {
|
||||
this.resourceUser = resourceUser;
|
||||
public void setResource(String realm) {
|
||||
setAttribute(new Attribute<String>("resource", realm));
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public String getResourceName() {
|
||||
return resourceName;
|
||||
}
|
||||
|
||||
public void setResourceName(String resourceName) {
|
||||
this.resourceName = resourceName;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public boolean getSurrogateAuthRequired() {
|
||||
return surrogateAuthRequired;
|
||||
}
|
||||
|
||||
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
|
||||
this.surrogateAuthRequired = surrogateAuthRequired;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public String getManagementUrl()
|
||||
{
|
||||
return managementUrl;
|
||||
}
|
||||
|
||||
public void setManagementUrl(String managementUrl) {
|
||||
if (managementUrl == null) managementUrl = ""; // Picketlink doesn't like NULL attribute values.
|
||||
this.managementUrl = managementUrl;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package org.keycloak.services.models.picketlink.relationships;
|
||||
|
||||
import org.picketlink.idm.model.AbstractAttributedType;
|
||||
import org.picketlink.idm.model.Agent;
|
||||
import org.picketlink.idm.model.Relationship;
|
||||
import org.picketlink.idm.model.Role;
|
||||
import org.picketlink.idm.model.annotation.IdentityProperty;
|
||||
import org.picketlink.idm.model.sample.Role;
|
||||
import org.picketlink.idm.model.sample.User;
|
||||
import org.picketlink.idm.query.RelationshipQueryParameter;
|
||||
|
||||
/**
|
||||
|
@ -22,19 +21,17 @@ public class ScopeRelationship extends AbstractAttributedType implements Relatio
|
|||
}
|
||||
};
|
||||
|
||||
protected Agent client;
|
||||
protected User client;
|
||||
protected Role scope;
|
||||
|
||||
@IdentityProperty
|
||||
public Agent getClient() {
|
||||
public User getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public void setClient(Agent client) {
|
||||
public void setClient(User client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@IdentityProperty
|
||||
public Role getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
|
|
@ -1,29 +1,36 @@
|
|||
package org.keycloak.services.resources;
|
||||
|
||||
import org.keycloak.SkeletonKeyContextResolver;
|
||||
import org.keycloak.services.filters.KeycloakSessionFilter;
|
||||
import org.keycloak.services.filters.KeycloakSessionRequestFilter;
|
||||
import org.keycloak.services.filters.KeycloakSessionResponseFilter;
|
||||
import org.keycloak.services.managers.TokenManager;
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
import org.keycloak.services.models.picketlink.PicketlinkKeycloakSession;
|
||||
import org.keycloak.services.models.picketlink.PicketlinkKeycloakSessionFactory;
|
||||
import org.keycloak.services.models.picketlink.relationships.RealmAdminRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.RequiredCredentialRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ScopeRelationship;
|
||||
import org.picketlink.idm.IdentitySessionFactory;
|
||||
import org.picketlink.idm.config.IdentityConfiguration;
|
||||
import org.keycloak.services.models.picketlink.mappings.RealmEntity;
|
||||
import org.keycloak.services.models.picketlink.mappings.ResourceEntity;
|
||||
import org.picketlink.idm.PartitionManager;
|
||||
import org.picketlink.idm.config.IdentityConfigurationBuilder;
|
||||
import org.picketlink.idm.internal.DefaultIdentitySessionFactory;
|
||||
import org.picketlink.idm.jpa.internal.ResourceLocalJpaIdentitySessionHandler;
|
||||
import org.picketlink.idm.jpa.schema.CredentialObject;
|
||||
import org.picketlink.idm.jpa.schema.CredentialObjectAttribute;
|
||||
import org.picketlink.idm.jpa.schema.IdentityObject;
|
||||
import org.picketlink.idm.jpa.schema.IdentityObjectAttribute;
|
||||
import org.picketlink.idm.jpa.schema.PartitionObject;
|
||||
import org.picketlink.idm.jpa.schema.RelationshipIdentityObject;
|
||||
import org.picketlink.idm.jpa.schema.RelationshipObject;
|
||||
import org.picketlink.idm.jpa.schema.RelationshipObjectAttribute;
|
||||
import org.picketlink.idm.internal.DefaultPartitionManager;
|
||||
import org.picketlink.idm.jpa.internal.JPAContextInitializer;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.AccountTypeEntity;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.AttributeTypeEntity;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.AttributedTypeEntity;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.DigestCredentialTypeEntity;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.GroupTypeEntity;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.IdentityTypeEntity;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.OTPCredentialTypeEntity;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.PartitionTypeEntity;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.PasswordCredentialTypeEntity;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.RelationshipIdentityTypeEntity;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.RelationshipTypeEntity;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.RoleTypeEntity;
|
||||
import org.picketlink.idm.jpa.model.sample.simple.X509CredentialTypeEntity;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
import javax.ws.rs.core.Application;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
@ -39,14 +46,25 @@ public class KeycloakApplication extends Application {
|
|||
protected KeycloakSessionFactory factory;
|
||||
|
||||
public KeycloakApplication() {
|
||||
this.factory = new PicketlinkKeycloakSessionFactory(createFactory());
|
||||
KeycloakSessionFilter filter = new KeycloakSessionFilter(factory);
|
||||
KeycloakSessionFactory f = createSessionFactory();
|
||||
this.factory = f;
|
||||
KeycloakSessionRequestFilter filter = new KeycloakSessionRequestFilter(factory);
|
||||
singletons.add(new RealmsResource(new TokenManager()));
|
||||
singletons.add(filter);
|
||||
classes.add(KeycloakSessionResponseFilter.class);
|
||||
classes.add(SkeletonKeyContextResolver.class);
|
||||
classes.add(RegistrationService.class);
|
||||
}
|
||||
|
||||
protected KeycloakSessionFactory createSessionFactory() {
|
||||
return buildSessionFactory();
|
||||
}
|
||||
|
||||
public static KeycloakSessionFactory buildSessionFactory() {
|
||||
EntityManagerFactory emf = Persistence.createEntityManagerFactory("keycloak-identity-store");
|
||||
return new PicketlinkKeycloakSessionFactory(emf, buildPartitionManager());
|
||||
}
|
||||
|
||||
public KeycloakSessionFactory getFactory() {
|
||||
return factory;
|
||||
}
|
||||
|
@ -56,27 +74,45 @@ public class KeycloakApplication extends Application {
|
|||
factory.close();
|
||||
}
|
||||
|
||||
public IdentitySessionFactory createFactory() {
|
||||
ResourceLocalJpaIdentitySessionHandler handler = new ResourceLocalJpaIdentitySessionHandler("keycloak-identity-store");
|
||||
public PartitionManager createPartitionManager() {
|
||||
return buildPartitionManager();
|
||||
}
|
||||
|
||||
public static PartitionManager buildPartitionManager() {
|
||||
IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder();
|
||||
|
||||
builder
|
||||
.named("KEYCLOAK_JPA_CONFIG")
|
||||
.stores()
|
||||
.jpa()
|
||||
.identityClass(IdentityObject.class)
|
||||
.attributeClass(IdentityObjectAttribute.class)
|
||||
.relationshipClass(RelationshipObject.class)
|
||||
.relationshipIdentityClass(RelationshipIdentityObject.class)
|
||||
.relationshipAttributeClass(RelationshipObjectAttribute.class)
|
||||
.credentialClass(CredentialObject.class)
|
||||
.credentialAttributeClass(CredentialObjectAttribute.class)
|
||||
.partitionClass(PartitionObject.class)
|
||||
.supportAllFeatures()
|
||||
.supportRelationshipType(RealmAdminRelationship.class, ResourceRelationship.class, RequiredCredentialRelationship.class, ScopeRelationship.class)
|
||||
.setIdentitySessionHandler(handler);
|
||||
.mappedEntity(
|
||||
AttributedTypeEntity.class,
|
||||
AccountTypeEntity.class,
|
||||
RoleTypeEntity.class,
|
||||
GroupTypeEntity.class,
|
||||
IdentityTypeEntity.class,
|
||||
RelationshipTypeEntity.class,
|
||||
RelationshipIdentityTypeEntity.class,
|
||||
PartitionTypeEntity.class,
|
||||
PasswordCredentialTypeEntity.class,
|
||||
DigestCredentialTypeEntity.class,
|
||||
X509CredentialTypeEntity.class,
|
||||
OTPCredentialTypeEntity.class,
|
||||
AttributeTypeEntity.class,
|
||||
RealmEntity.class,
|
||||
ResourceEntity.class
|
||||
)
|
||||
.supportGlobalRelationship(org.picketlink.idm.model.Relationship.class)
|
||||
.addContextInitializer(new JPAContextInitializer(null) {
|
||||
@Override
|
||||
public EntityManager getEntityManager() {
|
||||
return PicketlinkKeycloakSession.currentEntityManager.get();
|
||||
}
|
||||
})
|
||||
.supportAllFeatures();
|
||||
|
||||
IdentityConfiguration build = builder.build();
|
||||
return new DefaultIdentitySessionFactory(build);
|
||||
DefaultPartitionManager partitionManager = new DefaultPartitionManager(builder.buildAll());
|
||||
return partitionManager;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,9 +24,6 @@ public class RealmSubResource {
|
|||
@Context
|
||||
protected UriInfo uriInfo;
|
||||
|
||||
@Context
|
||||
protected KeycloakSession identitySession;
|
||||
|
||||
protected RealmModel realm;
|
||||
|
||||
public RealmSubResource(RealmModel realm) {
|
||||
|
@ -42,29 +39,37 @@ public class RealmSubResource {
|
|||
@GET
|
||||
@Produces("application/json")
|
||||
public PublishedRealmRepresentation getRealm(@PathParam("realm") String id) {
|
||||
return realmRep(realm, uriInfo);
|
||||
return new Transaction() {
|
||||
protected PublishedRealmRepresentation callImpl() {
|
||||
return realmRep(realm, uriInfo);
|
||||
}
|
||||
}.call();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("html")
|
||||
@Produces("text/html")
|
||||
public String getRealmHtml(@PathParam("realm") String id) {
|
||||
StringBuffer html = new StringBuffer();
|
||||
return new Transaction() {
|
||||
protected String callImpl() {
|
||||
StringBuffer html = new StringBuffer();
|
||||
|
||||
String authUri = TokenService.loginPageUrl(uriInfo).build(realm.getId()).toString();
|
||||
String codeUri = TokenService.accessCodeToTokenUrl(uriInfo).build(realm.getId()).toString();
|
||||
String grantUrl = TokenService.grantAccessTokenUrl(uriInfo).build(realm.getId()).toString();
|
||||
String idGrantUrl = TokenService.grantIdentityTokenUrl(uriInfo).build(realm.getId()).toString();
|
||||
String authUri = TokenService.loginPageUrl(uriInfo).build(realm.getId()).toString();
|
||||
String codeUri = TokenService.accessCodeToTokenUrl(uriInfo).build(realm.getId()).toString();
|
||||
String grantUrl = TokenService.grantAccessTokenUrl(uriInfo).build(realm.getId()).toString();
|
||||
String idGrantUrl = TokenService.grantIdentityTokenUrl(uriInfo).build(realm.getId()).toString();
|
||||
|
||||
html.append("<html><body><h1>Realm: ").append(realm.getName()).append("</h1>");
|
||||
html.append("<p>auth: ").append(authUri).append("</p>");
|
||||
html.append("<p>code: ").append(codeUri).append("</p>");
|
||||
html.append("<p>grant: ").append(grantUrl).append("</p>");
|
||||
html.append("<p>identity grant: ").append(idGrantUrl).append("</p>");
|
||||
html.append("<p>public key: ").append(realm.getPublicKeyPem()).append("</p>");
|
||||
html.append("</body></html>");
|
||||
html.append("<html><body><h1>Realm: ").append(realm.getName()).append("</h1>");
|
||||
html.append("<p>auth: ").append(authUri).append("</p>");
|
||||
html.append("<p>code: ").append(codeUri).append("</p>");
|
||||
html.append("<p>grant: ").append(grantUrl).append("</p>");
|
||||
html.append("<p>identity grant: ").append(idGrantUrl).append("</p>");
|
||||
html.append("<p>public key: ").append(realm.getPublicKeyPem()).append("</p>");
|
||||
html.append("</body></html>");
|
||||
|
||||
return html.toString();
|
||||
return html.toString();
|
||||
}
|
||||
}.call();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import org.keycloak.services.managers.AuthenticationManager;
|
|||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.managers.TokenManager;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
|
@ -38,9 +39,6 @@ public class RealmsResource {
|
|||
@Context
|
||||
protected HttpHeaders headers;
|
||||
|
||||
@Context
|
||||
protected KeycloakSession identitySession;
|
||||
|
||||
@Context
|
||||
ResourceContext resourceContext;
|
||||
|
||||
|
@ -55,58 +53,64 @@ public class RealmsResource {
|
|||
}
|
||||
|
||||
@Path("{realm}/tokens")
|
||||
public TokenService getTokenService(@PathParam("realm") String id) {
|
||||
RealmManager realmManager = new RealmManager(identitySession);
|
||||
RealmModel realm = realmManager.getRealm(id);
|
||||
if (realm == null) {
|
||||
logger.debug("realm not found");
|
||||
throw new NotFoundException();
|
||||
}
|
||||
TokenService tokenService = new TokenService(realm, tokenManager);
|
||||
resourceContext.initResource(tokenService);
|
||||
return tokenService;
|
||||
public TokenService getTokenService(final @PathParam("realm") String id) {
|
||||
return new Transaction(false) {
|
||||
@Override
|
||||
protected TokenService callImpl() {
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
RealmModel realm = realmManager.getRealm(id);
|
||||
if (realm == null) {
|
||||
logger.debug("realm not found");
|
||||
throw new NotFoundException();
|
||||
}
|
||||
TokenService tokenService = new TokenService(realm, tokenManager);
|
||||
resourceContext.initResource(tokenService);
|
||||
return tokenService;
|
||||
}
|
||||
}.call();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Path("{realm}")
|
||||
public RealmSubResource getRealmResource(@PathParam("realm") String id) {
|
||||
RealmManager realmManager = new RealmManager(identitySession);
|
||||
RealmModel realm = realmManager.getRealm(id);
|
||||
if (realm == null) {
|
||||
logger.debug("realm not found");
|
||||
throw new NotFoundException();
|
||||
}
|
||||
RealmSubResource realmResource = new RealmSubResource(realm);
|
||||
resourceContext.initResource(realmResource);
|
||||
return realmResource;
|
||||
|
||||
public RealmSubResource getRealmResource(final @PathParam("realm") String id) {
|
||||
return new Transaction(false) {
|
||||
@Override
|
||||
protected RealmSubResource callImpl() {
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
RealmModel realm = realmManager.getRealm(id);
|
||||
if (realm == null) {
|
||||
logger.debug("realm not found");
|
||||
throw new NotFoundException();
|
||||
}
|
||||
RealmSubResource realmResource = new RealmSubResource(realm);
|
||||
resourceContext.initResource(realmResource);
|
||||
return realmResource;
|
||||
}
|
||||
}.call();
|
||||
}
|
||||
|
||||
|
||||
@POST
|
||||
@Consumes("application/json")
|
||||
public Response importRealm(RealmRepresentation rep) {
|
||||
identitySession.getTransaction().begin();
|
||||
RealmModel realm;
|
||||
try {
|
||||
RealmManager realmManager = new RealmManager(identitySession);
|
||||
RealmModel defaultRealm = realmManager.getRealm(RealmModel.DEFAULT_REALM);
|
||||
UserModel realmCreator = new AuthenticationManager().authenticateBearerToken(defaultRealm, headers);
|
||||
RoleModel creatorRole = defaultRealm.getRole(RegistrationService.REALM_CREATOR_ROLE);
|
||||
if (!defaultRealm.hasRole(realmCreator, creatorRole)) {
|
||||
logger.warn("not a realm creator");
|
||||
throw new NotAuthorizedException("Bearer");
|
||||
public Response importRealm(final RealmRepresentation rep) {
|
||||
return new Transaction() {
|
||||
@Override
|
||||
protected Response callImpl() {
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
RealmModel defaultRealm = realmManager.getRealm(RealmModel.DEFAULT_REALM);
|
||||
UserModel realmCreator = new AuthenticationManager().authenticateBearerToken(defaultRealm, headers);
|
||||
RoleModel creatorRole = defaultRealm.getRole(RegistrationService.REALM_CREATOR_ROLE);
|
||||
if (!defaultRealm.hasRole(realmCreator, creatorRole)) {
|
||||
logger.warn("not a realm creator");
|
||||
throw new NotAuthorizedException("Bearer");
|
||||
}
|
||||
RealmModel realm = realmManager.importRealm(rep, realmCreator);
|
||||
UriBuilder builder = uriInfo.getRequestUriBuilder().path(realm.getId());
|
||||
return Response.created(builder.build())
|
||||
.entity(RealmSubResource.realmRep(realm, uriInfo))
|
||||
.type(MediaType.APPLICATION_JSON_TYPE).build();
|
||||
}
|
||||
realm = realmManager.importRealm(rep, realmCreator);
|
||||
identitySession.getTransaction().commit();
|
||||
} catch (RuntimeException re) {
|
||||
identitySession.getTransaction().rollback();
|
||||
throw re;
|
||||
}
|
||||
UriBuilder builder = uriInfo.getRequestUriBuilder().path(realm.getId());
|
||||
return Response.created(builder.build())
|
||||
.entity(RealmSubResource.realmRep(realm, uriInfo))
|
||||
.type(MediaType.APPLICATION_JSON_TYPE).build();
|
||||
}.call();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import org.jboss.resteasy.logging.Logger;
|
|||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
|
@ -32,44 +32,38 @@ public class RegistrationService {
|
|||
@Context
|
||||
protected UriInfo uriInfo;
|
||||
|
||||
@Context
|
||||
protected KeycloakSession identitySession;
|
||||
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Response register(UserRepresentation newUser) {
|
||||
identitySession.getTransaction().begin();
|
||||
try {
|
||||
RealmManager realmManager = new RealmManager(identitySession);
|
||||
RealmModel defaultRealm = realmManager.defaultRealm();
|
||||
if (!defaultRealm.isEnabled()) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
if (!defaultRealm.isRegistrationAllowed()) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
UserModel user = defaultRealm.getUser(newUser.getUsername());
|
||||
if (user != null) {
|
||||
return Response.status(400).type("text/plain").entity("user exists").build();
|
||||
}
|
||||
public Response register(final UserRepresentation newUser) {
|
||||
return new Transaction() {
|
||||
@Override
|
||||
protected Response callImpl() {
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
RealmModel defaultRealm = realmManager.defaultRealm();
|
||||
if (!defaultRealm.isEnabled()) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
if (!defaultRealm.isRegistrationAllowed()) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
UserModel user = defaultRealm.getUser(newUser.getUsername());
|
||||
if (user != null) {
|
||||
return Response.status(400).type("text/plain").entity("user exists").build();
|
||||
}
|
||||
|
||||
user = defaultRealm.addUser(newUser.getUsername());
|
||||
for (CredentialRepresentation cred : newUser.getCredentials()) {
|
||||
UserCredentialModel credModel = new UserCredentialModel();
|
||||
credModel.setType(cred.getType());
|
||||
credModel.setValue(cred.getValue());
|
||||
defaultRealm.updateCredential(user, credModel);
|
||||
user = defaultRealm.addUser(newUser.getUsername());
|
||||
for (CredentialRepresentation cred : newUser.getCredentials()) {
|
||||
UserCredentialModel credModel = new UserCredentialModel();
|
||||
credModel.setType(cred.getType());
|
||||
credModel.setValue(cred.getValue());
|
||||
defaultRealm.updateCredential(user, credModel);
|
||||
}
|
||||
RoleModel realmCreator = defaultRealm.getRole(REALM_CREATOR_ROLE);
|
||||
defaultRealm.grantRole(user, realmCreator);
|
||||
URI uri = uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(user.getLoginName()).build();
|
||||
return Response.created(uri).build();
|
||||
}
|
||||
RoleModel realmCreator = defaultRealm.getRole(REALM_CREATOR_ROLE);
|
||||
defaultRealm.grantRole(user, realmCreator);
|
||||
identitySession.getTransaction().commit();
|
||||
URI uri = uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(user.getLoginName()).build();
|
||||
return Response.created(uri).build();
|
||||
} catch (RuntimeException e) {
|
||||
logger.error("Failed to register", e);
|
||||
identitySession.getTransaction().rollback();
|
||||
throw e;
|
||||
}
|
||||
}.call();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -58,19 +58,17 @@ public class TokenService {
|
|||
@Context
|
||||
protected HttpHeaders headers;
|
||||
@Context
|
||||
protected KeycloakSession identitySession;
|
||||
@Context
|
||||
HttpRequest request;
|
||||
@Context
|
||||
HttpResponse response;
|
||||
|
||||
|
||||
protected String securityFailurePath = "/securityFailure.jsp";
|
||||
protected String loginFormPath = "/loginForm.jsp";
|
||||
protected String oauthFormPath = "/oauthGrantForm.jsp";
|
||||
|
||||
protected RealmModel realm;
|
||||
protected TokenManager tokenManager;
|
||||
|
||||
protected AuthenticationManager authManager = new AuthenticationManager();
|
||||
private ResourceAdminManager resourceAdminManager = new ResourceAdminManager();
|
||||
|
||||
|
@ -117,103 +115,116 @@ public class TokenService {
|
|||
@POST
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response grantIdentityToken(MultivaluedMap<String, String> form) {
|
||||
String username = form.getFirst(AuthenticationManager.FORM_USERNAME);
|
||||
if (username == null) {
|
||||
throw new NotAuthorizedException("No user");
|
||||
}
|
||||
if (!realm.isEnabled()) {
|
||||
throw new NotAuthorizedException("Disabled realm");
|
||||
}
|
||||
UserModel user = realm.getUser(username);
|
||||
if (user == null) {
|
||||
throw new NotAuthorizedException("No user");
|
||||
}
|
||||
if (!user.isEnabled()) {
|
||||
throw new NotAuthorizedException("Disabled user.");
|
||||
}
|
||||
if (!authManager.authenticateForm(realm, user, form)) {
|
||||
throw new NotAuthorizedException("FORM");
|
||||
}
|
||||
tokenManager = new TokenManager();
|
||||
SkeletonKeyToken token = tokenManager.createIdentityToken(realm, username);
|
||||
String encoded = tokenManager.encodeToken(realm, token);
|
||||
AccessTokenResponse res = accessTokenResponse(token, encoded);
|
||||
return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build();
|
||||
public Response grantIdentityToken(final MultivaluedMap<String, String> form) {
|
||||
return new Transaction() {
|
||||
protected Response callImpl() {
|
||||
String username = form.getFirst(AuthenticationManager.FORM_USERNAME);
|
||||
if (username == null) {
|
||||
throw new NotAuthorizedException("No user");
|
||||
}
|
||||
if (!realm.isEnabled()) {
|
||||
throw new NotAuthorizedException("Disabled realm");
|
||||
}
|
||||
UserModel user = realm.getUser(username);
|
||||
if (user == null) {
|
||||
throw new NotAuthorizedException("No user");
|
||||
}
|
||||
if (!user.isEnabled()) {
|
||||
throw new NotAuthorizedException("Disabled user.");
|
||||
}
|
||||
if (!authManager.authenticateForm(realm, user, form)) {
|
||||
throw new NotAuthorizedException("FORM");
|
||||
}
|
||||
tokenManager = new TokenManager();
|
||||
SkeletonKeyToken token = tokenManager.createIdentityToken(realm, username);
|
||||
String encoded = tokenManager.encodeToken(realm, token);
|
||||
AccessTokenResponse res = accessTokenResponse(token, encoded);
|
||||
return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build();
|
||||
}
|
||||
}.call();
|
||||
}
|
||||
|
||||
@Path("grants/access")
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response grantAccessToken(MultivaluedMap<String, String> form) {
|
||||
String username = form.getFirst(AuthenticationManager.FORM_USERNAME);
|
||||
if (username == null) {
|
||||
throw new NotAuthorizedException("No user");
|
||||
}
|
||||
if (!realm.isEnabled()) {
|
||||
throw new NotAuthorizedException("Disabled realm");
|
||||
}
|
||||
UserModel user = realm.getUser(username);
|
||||
if (user == null) {
|
||||
throw new NotAuthorizedException("No user");
|
||||
}
|
||||
if (!user.isEnabled()) {
|
||||
throw new NotAuthorizedException("Disabled user.");
|
||||
}
|
||||
if (authManager.authenticateForm(realm, user, form)) {
|
||||
throw new NotAuthorizedException("Auth failed");
|
||||
}
|
||||
SkeletonKeyToken token = tokenManager.createAccessToken(realm, user);
|
||||
String encoded = tokenManager.encodeToken(realm, token);
|
||||
AccessTokenResponse res = accessTokenResponse(token, encoded);
|
||||
return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build();
|
||||
public Response grantAccessToken(final MultivaluedMap<String, String> form) {
|
||||
return new Transaction() {
|
||||
protected Response callImpl() {
|
||||
String username = form.getFirst(AuthenticationManager.FORM_USERNAME);
|
||||
if (username == null) {
|
||||
throw new NotAuthorizedException("No user");
|
||||
}
|
||||
if (!realm.isEnabled()) {
|
||||
throw new NotAuthorizedException("Disabled realm");
|
||||
}
|
||||
UserModel user = realm.getUser(username);
|
||||
if (user == null) {
|
||||
throw new NotAuthorizedException("No user");
|
||||
}
|
||||
if (!user.isEnabled()) {
|
||||
throw new NotAuthorizedException("Disabled user.");
|
||||
}
|
||||
if (authManager.authenticateForm(realm, user, form)) {
|
||||
throw new NotAuthorizedException("Auth failed");
|
||||
}
|
||||
SkeletonKeyToken token = tokenManager.createAccessToken(realm, user);
|
||||
String encoded = tokenManager.encodeToken(realm, token);
|
||||
AccessTokenResponse res = accessTokenResponse(token, encoded);
|
||||
return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build();
|
||||
}
|
||||
}.call();
|
||||
|
||||
}
|
||||
|
||||
@Path("auth/request/login")
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
public Response processLogin(MultivaluedMap<String, String> formData) {
|
||||
String clientId = formData.getFirst("client_id");
|
||||
String scopeParam = formData.getFirst("scope");
|
||||
String state = formData.getFirst("state");
|
||||
String redirect = formData.getFirst("redirect_uri");
|
||||
public Response processLogin(final MultivaluedMap<String, String> formData) {
|
||||
return new Transaction() {
|
||||
protected Response callImpl() {
|
||||
String clientId = formData.getFirst("client_id");
|
||||
String scopeParam = formData.getFirst("scope");
|
||||
String state = formData.getFirst("state");
|
||||
String redirect = formData.getFirst("redirect_uri");
|
||||
|
||||
if (!realm.isEnabled()) {
|
||||
securityFailureForward("Realm not enabled.");
|
||||
return null;
|
||||
}
|
||||
UserModel client = realm.getUser(clientId);
|
||||
if (client == null) {
|
||||
securityFailureForward("Unknown login requester.");
|
||||
return null;
|
||||
}
|
||||
if (!client.isEnabled()) {
|
||||
securityFailureForward("Login requester not enabled.");
|
||||
return null;
|
||||
}
|
||||
String username = formData.getFirst("username");
|
||||
UserModel user = realm.getUser(username);
|
||||
if (user == null) {
|
||||
logger.error("Incorrect user name.");
|
||||
request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Incorrect user name.");
|
||||
forwardToLoginForm(redirect, clientId, scopeParam, state);
|
||||
return null;
|
||||
}
|
||||
if (!user.isEnabled()) {
|
||||
securityFailureForward("Your account is not enabled.");
|
||||
return null;
|
||||
}
|
||||
boolean authenticated = authManager.authenticateForm(realm, user, formData);
|
||||
if (!authenticated) {
|
||||
logger.error("Authentication failed");
|
||||
request.setAttribute("username", username);
|
||||
request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Invalid credentials.");
|
||||
forwardToLoginForm(redirect, clientId, scopeParam, state);
|
||||
return null;
|
||||
}
|
||||
if (!realm.isEnabled()) {
|
||||
securityFailureForward("Realm not enabled.");
|
||||
return null;
|
||||
}
|
||||
UserModel client = realm.getUser(clientId);
|
||||
if (client == null) {
|
||||
securityFailureForward("Unknown login requester.");
|
||||
return null;
|
||||
}
|
||||
if (!client.isEnabled()) {
|
||||
securityFailureForward("Login requester not enabled.");
|
||||
return null;
|
||||
}
|
||||
String username = formData.getFirst("username");
|
||||
UserModel user = realm.getUser(username);
|
||||
if (user == null) {
|
||||
logger.error("Incorrect user name.");
|
||||
request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Incorrect user name.");
|
||||
forwardToLoginForm(redirect, clientId, scopeParam, state);
|
||||
return null;
|
||||
}
|
||||
if (!user.isEnabled()) {
|
||||
securityFailureForward("Your account is not enabled.");
|
||||
return null;
|
||||
}
|
||||
boolean authenticated = authManager.authenticateForm(realm, user, formData);
|
||||
if (!authenticated) {
|
||||
logger.error("Authentication failed");
|
||||
request.setAttribute("username", username);
|
||||
request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Invalid credentials.");
|
||||
forwardToLoginForm(redirect, clientId, scopeParam, state);
|
||||
return null;
|
||||
}
|
||||
|
||||
return processAccessCode(scopeParam, state, redirect, client, user);
|
||||
return processAccessCode(scopeParam, state, redirect, client, user);
|
||||
}
|
||||
}.call();
|
||||
}
|
||||
|
||||
protected Response processAccessCode(String scopeParam, String state, String redirect, UserModel client, UserModel user) {
|
||||
|
@ -222,7 +233,6 @@ public class TokenService {
|
|||
boolean isResource = realm.hasRole(client, resourceRole);
|
||||
if (!isResource && !realm.hasRole(client, identityRequestRole)) {
|
||||
securityFailureForward("Login requester not allowed to request login.");
|
||||
identitySession.close();
|
||||
return null;
|
||||
}
|
||||
AccessCodeEntry accessCode = tokenManager.createAccessCode(scopeParam, state, redirect, realm, client, user);
|
||||
|
@ -230,7 +240,6 @@ public class TokenService {
|
|||
logger.info("processAccessCode: go to oauth page?: " + (!isResource && (accessCode.getRealmRolesRequested().size() > 0 || accessCode.getResourceRolesRequested().size() > 0)));
|
||||
if (!isResource && (accessCode.getRealmRolesRequested().size() > 0 || accessCode.getResourceRolesRequested().size() > 0)) {
|
||||
oauthGrantPage(accessCode, client);
|
||||
identitySession.close();
|
||||
return null;
|
||||
}
|
||||
return redirectAccessCode(accessCode, state, redirect);
|
||||
|
@ -251,96 +260,100 @@ public class TokenService {
|
|||
@Path("access/codes")
|
||||
@POST
|
||||
@Produces("application/json")
|
||||
public Response accessCodeToToken(MultivaluedMap<String, String> formData) {
|
||||
logger.info("accessRequest <---");
|
||||
if (!realm.isEnabled()) {
|
||||
throw new NotAuthorizedException("Realm not enabled");
|
||||
}
|
||||
public Response accessCodeToToken(final MultivaluedMap<String, String> formData) {
|
||||
return new Transaction() {
|
||||
protected Response callImpl() {
|
||||
logger.info("accessRequest <---");
|
||||
if (!realm.isEnabled()) {
|
||||
throw new NotAuthorizedException("Realm not enabled");
|
||||
}
|
||||
|
||||
String code = formData.getFirst("code");
|
||||
if (code == null) {
|
||||
logger.debug("code not specified");
|
||||
Map<String, String> error = new HashMap<String, String>();
|
||||
error.put("error", "invalid_request");
|
||||
error.put("error_description", "code not specified");
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
|
||||
String code = formData.getFirst("code");
|
||||
if (code == null) {
|
||||
logger.debug("code not specified");
|
||||
Map<String, String> error = new HashMap<String, String>();
|
||||
error.put("error", "invalid_request");
|
||||
error.put("error_description", "code not specified");
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
|
||||
|
||||
}
|
||||
String client_id = formData.getFirst("client_id");
|
||||
if (client_id == null) {
|
||||
logger.debug("client_id not specified");
|
||||
Map<String, String> error = new HashMap<String, String>();
|
||||
error.put("error", "invalid_request");
|
||||
error.put("error_description", "client_id not specified");
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
|
||||
}
|
||||
UserModel client = realm.getUser(client_id);
|
||||
if (client == null) {
|
||||
logger.debug("Could not find user");
|
||||
Map<String, String> error = new HashMap<String, String>();
|
||||
error.put("error", "invalid_client");
|
||||
error.put("error_description", "Could not find user");
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
|
||||
}
|
||||
}
|
||||
String client_id = formData.getFirst("client_id");
|
||||
if (client_id == null) {
|
||||
logger.debug("client_id not specified");
|
||||
Map<String, String> error = new HashMap<String, String>();
|
||||
error.put("error", "invalid_request");
|
||||
error.put("error_description", "client_id not specified");
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
|
||||
}
|
||||
UserModel client = realm.getUser(client_id);
|
||||
if (client == null) {
|
||||
logger.debug("Could not find user");
|
||||
Map<String, String> error = new HashMap<String, String>();
|
||||
error.put("error", "invalid_client");
|
||||
error.put("error_description", "Could not find user");
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
|
||||
}
|
||||
|
||||
if (!client.isEnabled()) {
|
||||
logger.debug("user is not enabled");
|
||||
Map<String, String> error = new HashMap<String, String>();
|
||||
error.put("error", "invalid_client");
|
||||
error.put("error_description", "User is not enabled");
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
|
||||
}
|
||||
if (!client.isEnabled()) {
|
||||
logger.debug("user is not enabled");
|
||||
Map<String, String> error = new HashMap<String, String>();
|
||||
error.put("error", "invalid_client");
|
||||
error.put("error_description", "User is not enabled");
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
|
||||
}
|
||||
|
||||
boolean authenticated = authManager.authenticateForm(realm, client, formData);
|
||||
if (!authenticated) {
|
||||
Map<String, String> error = new HashMap<String, String>();
|
||||
error.put("error", "unauthorized_client");
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
|
||||
}
|
||||
boolean authenticated = authManager.authenticateForm(realm, client, formData);
|
||||
if (!authenticated) {
|
||||
Map<String, String> error = new HashMap<String, String>();
|
||||
error.put("error", "unauthorized_client");
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
|
||||
}
|
||||
|
||||
|
||||
JWSInput input = new JWSInput(code, providers);
|
||||
boolean verifiedCode = false;
|
||||
try {
|
||||
verifiedCode = RSAProvider.verify(input, realm.getPublicKey());
|
||||
} catch (Exception ignored) {
|
||||
logger.debug("Failed to verify signature", ignored);
|
||||
}
|
||||
if (!verifiedCode) {
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Unable to verify code signature");
|
||||
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
|
||||
}
|
||||
String key = input.readContent(String.class);
|
||||
AccessCodeEntry accessCode = tokenManager.pullAccessCode(key);
|
||||
if (accessCode == null) {
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Code not found");
|
||||
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
|
||||
}
|
||||
if (accessCode.isExpired()) {
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Code is expired");
|
||||
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
|
||||
}
|
||||
if (!accessCode.getToken().isActive()) {
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Token expired");
|
||||
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
|
||||
}
|
||||
if (!client.getLoginName().equals(accessCode.getClient().getLoginName())) {
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Auth error");
|
||||
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
|
||||
}
|
||||
logger.info("accessRequest SUCCESS");
|
||||
AccessTokenResponse res = accessTokenResponse(realm.getPrivateKey(), accessCode.getToken());
|
||||
return Response.ok(res).build();
|
||||
JWSInput input = new JWSInput(code, providers);
|
||||
boolean verifiedCode = false;
|
||||
try {
|
||||
verifiedCode = RSAProvider.verify(input, realm.getPublicKey());
|
||||
} catch (Exception ignored) {
|
||||
logger.debug("Failed to verify signature", ignored);
|
||||
}
|
||||
if (!verifiedCode) {
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Unable to verify code signature");
|
||||
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
|
||||
}
|
||||
String key = input.readContent(String.class);
|
||||
AccessCodeEntry accessCode = tokenManager.pullAccessCode(key);
|
||||
if (accessCode == null) {
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Code not found");
|
||||
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
|
||||
}
|
||||
if (accessCode.isExpired()) {
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Code is expired");
|
||||
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
|
||||
}
|
||||
if (!accessCode.getToken().isActive()) {
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Token expired");
|
||||
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
|
||||
}
|
||||
if (!client.getLoginName().equals(accessCode.getClient().getLoginName())) {
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Auth error");
|
||||
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
|
||||
}
|
||||
logger.info("accessRequest SUCCESS");
|
||||
AccessTokenResponse res = accessTokenResponse(realm.getPrivateKey(), accessCode.getToken());
|
||||
return Response.ok(res).build();
|
||||
}
|
||||
}.call();
|
||||
|
||||
}
|
||||
|
||||
|
@ -373,7 +386,6 @@ public class TokenService {
|
|||
logger.error(message);
|
||||
request.setAttribute(JspRequestParameters.KEYCLOAK_SECURITY_FAILURE_MESSAGE, message);
|
||||
request.forward(securityFailurePath);
|
||||
identitySession.close();
|
||||
}
|
||||
|
||||
protected void forwardToLoginForm(String redirect,
|
||||
|
@ -389,99 +401,113 @@ public class TokenService {
|
|||
request.setAttribute("scope", scopeParam);
|
||||
request.setAttribute("state", state);
|
||||
request.forward(loginFormPath);
|
||||
identitySession.close();
|
||||
}
|
||||
|
||||
@Path("login")
|
||||
@GET
|
||||
public Response loginPage(@QueryParam("response_type") String responseType,
|
||||
@QueryParam("redirect_uri") String redirect,
|
||||
@QueryParam("client_id") String clientId,
|
||||
@QueryParam("scope") String scopeParam,
|
||||
@QueryParam("state") String state) {
|
||||
if (!realm.isEnabled()) {
|
||||
securityFailureForward("Realm not enabled");
|
||||
return null;
|
||||
}
|
||||
UserModel client = realm.getUser(clientId);
|
||||
if (client == null) {
|
||||
securityFailureForward("Unknown login requester.");
|
||||
return null;
|
||||
}
|
||||
public Response loginPage(final @QueryParam("response_type") String responseType,
|
||||
final @QueryParam("redirect_uri") String redirect,
|
||||
final @QueryParam("client_id") String clientId,
|
||||
final @QueryParam("scope") String scopeParam,
|
||||
final @QueryParam("state") String state) {
|
||||
return new Transaction() {
|
||||
protected Response callImpl() {
|
||||
if (!realm.isEnabled()) {
|
||||
securityFailureForward("Realm not enabled");
|
||||
return null;
|
||||
}
|
||||
UserModel client = realm.getUser(clientId);
|
||||
if (client == null) {
|
||||
securityFailureForward("Unknown login requester.");
|
||||
transaction.rollback();
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!client.isEnabled()) {
|
||||
securityFailureForward("Login requester not enabled.");
|
||||
identitySession.close();
|
||||
return null;
|
||||
}
|
||||
if (!client.isEnabled()) {
|
||||
securityFailureForward("Login requester not enabled.");
|
||||
transaction.rollback();
|
||||
session.close();
|
||||
return null;
|
||||
}
|
||||
|
||||
RoleModel resourceRole = realm.getRole(RealmManager.RESOURCE_ROLE);
|
||||
RoleModel identityRequestRole = realm.getRole(RealmManager.IDENTITY_REQUESTER_ROLE);
|
||||
boolean isResource = realm.hasRole(client, resourceRole);
|
||||
if (!isResource && !realm.hasRole(client, identityRequestRole)) {
|
||||
securityFailureForward("Login requester not allowed to request login.");
|
||||
identitySession.close();
|
||||
return null;
|
||||
}
|
||||
RoleModel resourceRole = realm.getRole(RealmManager.RESOURCE_ROLE);
|
||||
RoleModel identityRequestRole = realm.getRole(RealmManager.IDENTITY_REQUESTER_ROLE);
|
||||
boolean isResource = realm.hasRole(client, resourceRole);
|
||||
if (!isResource && !realm.hasRole(client, identityRequestRole)) {
|
||||
securityFailureForward("Login requester not allowed to request login.");
|
||||
transaction.rollback();
|
||||
session.close();
|
||||
return null;
|
||||
}
|
||||
|
||||
UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
|
||||
if (user != null) {
|
||||
logger.info(user.getLoginName() + " already logged in.");
|
||||
return processAccessCode(scopeParam, state, redirect, client, user);
|
||||
}
|
||||
UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
|
||||
if (user != null) {
|
||||
logger.info(user.getLoginName() + " already logged in.");
|
||||
return processAccessCode(scopeParam, state, redirect, client, user);
|
||||
}
|
||||
|
||||
forwardToLoginForm(redirect, clientId, scopeParam, state);
|
||||
return null;
|
||||
forwardToLoginForm(redirect, clientId, scopeParam, state);
|
||||
return null;
|
||||
}
|
||||
}.call();
|
||||
}
|
||||
|
||||
@Path("logout")
|
||||
@GET
|
||||
public Response logout(@QueryParam("redirect_uri") String redirectUri) {
|
||||
// todo do we care if anybody can trigger this?
|
||||
public Response logout(final @QueryParam("redirect_uri") String redirectUri) {
|
||||
return new Transaction() {
|
||||
protected Response callImpl() {
|
||||
// todo do we care if anybody can trigger this?
|
||||
|
||||
UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
|
||||
if (user != null) {
|
||||
logger.info("Logging out: " + user.getLoginName());
|
||||
authManager.expireIdentityCookie(realm, uriInfo);
|
||||
resourceAdminManager.singleLogOut(realm, user.getLoginName());
|
||||
}
|
||||
// todo manage legal redirects
|
||||
return Response.status(302).location(UriBuilder.fromUri(redirectUri).build()).build();
|
||||
UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
|
||||
if (user != null) {
|
||||
logger.info("Logging out: " + user.getLoginName());
|
||||
authManager.expireIdentityCookie(realm, uriInfo);
|
||||
resourceAdminManager.singleLogOut(realm, user.getLoginName());
|
||||
}
|
||||
// todo manage legal redirects
|
||||
return Response.status(302).location(UriBuilder.fromUri(redirectUri).build()).build();
|
||||
}
|
||||
}.call();
|
||||
}
|
||||
|
||||
@Path("oauth/grant")
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
public Response processOAuth(MultivaluedMap<String, String> formData) {
|
||||
String code = formData.getFirst("code");
|
||||
JWSInput input = new JWSInput(code, providers);
|
||||
boolean verifiedCode = false;
|
||||
try {
|
||||
verifiedCode = RSAProvider.verify(input, realm.getPublicKey());
|
||||
} catch (Exception ignored) {
|
||||
logger.debug("Failed to verify signature", ignored);
|
||||
}
|
||||
if (!verifiedCode) {
|
||||
securityFailureForward("Illegal access code.");
|
||||
identitySession.close();
|
||||
return null;
|
||||
}
|
||||
String key = input.readContent(String.class);
|
||||
AccessCodeEntry accessCodeEntry = tokenManager.getAccessCode(key);
|
||||
if (accessCodeEntry == null) {
|
||||
securityFailureForward("Unknown access code.");
|
||||
identitySession.close();
|
||||
return null;
|
||||
}
|
||||
public Response processOAuth(final MultivaluedMap<String, String> formData) {
|
||||
return new Transaction() {
|
||||
protected Response callImpl() {
|
||||
String code = formData.getFirst("code");
|
||||
JWSInput input = new JWSInput(code, providers);
|
||||
boolean verifiedCode = false;
|
||||
try {
|
||||
verifiedCode = RSAProvider.verify(input, realm.getPublicKey());
|
||||
} catch (Exception ignored) {
|
||||
logger.debug("Failed to verify signature", ignored);
|
||||
}
|
||||
if (!verifiedCode) {
|
||||
securityFailureForward("Illegal access code.");
|
||||
session.close();
|
||||
return null;
|
||||
}
|
||||
String key = input.readContent(String.class);
|
||||
AccessCodeEntry accessCodeEntry = tokenManager.getAccessCode(key);
|
||||
if (accessCodeEntry == null) {
|
||||
securityFailureForward("Unknown access code.");
|
||||
session.close();
|
||||
return null;
|
||||
}
|
||||
|
||||
String redirect = accessCodeEntry.getRedirectUri();
|
||||
String state = accessCodeEntry.getState();
|
||||
String redirect = accessCodeEntry.getRedirectUri();
|
||||
String state = accessCodeEntry.getState();
|
||||
|
||||
if (formData.containsKey("cancel")) {
|
||||
return redirectAccessDenied(redirect, state);
|
||||
}
|
||||
if (formData.containsKey("cancel")) {
|
||||
return redirectAccessDenied(redirect, state);
|
||||
}
|
||||
|
||||
return redirectAccessCode(accessCodeEntry, state, redirect);
|
||||
return redirectAccessCode(accessCodeEntry, state, redirect);
|
||||
}
|
||||
}.call();
|
||||
}
|
||||
|
||||
protected Response redirectAccessDenied(String redirect, String state) {
|
||||
|
|
96
services/src/main/java/org/keycloak/services/resources/Transaction.java
Executable file
96
services/src/main/java/org/keycloak/services/resources/Transaction.java
Executable file
|
@ -0,0 +1,96 @@
|
|||
package org.keycloak.services.resources;
|
||||
|
||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
import org.keycloak.services.models.KeycloakTransaction;
|
||||
|
||||
/**
|
||||
* Meant to be used as an inner class wrapper (I forget the pattern name, its been awhile).
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class Transaction {
|
||||
protected KeycloakSession session;
|
||||
protected KeycloakTransaction transaction;
|
||||
protected boolean closeSession;
|
||||
|
||||
/**
|
||||
* Pull KeycloakSession from @Context
|
||||
*
|
||||
* Will close session after finished
|
||||
*
|
||||
*/
|
||||
public Transaction() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull KeycloakSession from @Context
|
||||
*
|
||||
* @param close whether to close the session or not after completion
|
||||
*/
|
||||
public Transaction(boolean close) {
|
||||
this.session = ResteasyProviderFactory.getContextData(KeycloakSession.class);
|
||||
transaction = session.getTransaction();
|
||||
closeSession = close;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and manages its own session.
|
||||
*
|
||||
* @param factory
|
||||
*/
|
||||
public Transaction(KeycloakSessionFactory factory) {
|
||||
this.closeSession = true;
|
||||
this.session = factory.createSession();
|
||||
this.transaction = session.getTransaction();
|
||||
}
|
||||
|
||||
protected void runImpl() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Will not begin or end a transaction or close a session if the transaction was already active when called
|
||||
*
|
||||
*/
|
||||
public void run() {
|
||||
boolean wasActive = transaction.isActive();
|
||||
if (!wasActive) transaction.begin();
|
||||
try {
|
||||
runImpl();
|
||||
if (!wasActive && transaction.isActive()) transaction.commit();
|
||||
} catch (RuntimeException e) {
|
||||
if (!wasActive && transaction.isActive()) transaction.rollback();
|
||||
throw e;
|
||||
} finally {
|
||||
if (!wasActive && closeSession) session.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected <T> T callImpl() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will not begin or end a transaction or close a session if the transaction was already active when called
|
||||
*
|
||||
*/
|
||||
public <T> T call() {
|
||||
boolean wasActive = transaction.isActive();
|
||||
if (!wasActive) transaction.begin();
|
||||
try {
|
||||
T rtn = callImpl();
|
||||
if (!wasActive && transaction.isActive()) transaction.commit();
|
||||
return rtn;
|
||||
} catch (RuntimeException e) {
|
||||
if (!wasActive && transaction.isActive()) transaction.rollback();
|
||||
throw e;
|
||||
} finally {
|
||||
if (!wasActive && closeSession) session.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,24 +15,8 @@ import org.keycloak.services.models.RequiredCredentialModel;
|
|||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
import org.keycloak.services.models.UserCredentialModel;
|
||||
import org.keycloak.services.models.picketlink.PicketlinkKeycloakSessionFactory;
|
||||
import org.keycloak.services.models.picketlink.relationships.RealmAdminRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.RequiredCredentialRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ScopeRelationship;
|
||||
import org.picketlink.idm.IdentitySessionFactory;
|
||||
import org.picketlink.idm.config.IdentityConfiguration;
|
||||
import org.picketlink.idm.config.IdentityConfigurationBuilder;
|
||||
import org.picketlink.idm.internal.DefaultIdentitySessionFactory;
|
||||
import org.picketlink.idm.jpa.internal.ResourceLocalJpaIdentitySessionHandler;
|
||||
import org.picketlink.idm.jpa.schema.CredentialObject;
|
||||
import org.picketlink.idm.jpa.schema.CredentialObjectAttribute;
|
||||
import org.picketlink.idm.jpa.schema.IdentityObject;
|
||||
import org.picketlink.idm.jpa.schema.IdentityObjectAttribute;
|
||||
import org.picketlink.idm.jpa.schema.PartitionObject;
|
||||
import org.picketlink.idm.jpa.schema.RelationshipIdentityObject;
|
||||
import org.picketlink.idm.jpa.schema.RelationshipObject;
|
||||
import org.picketlink.idm.jpa.schema.RelationshipObjectAttribute;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -49,37 +33,15 @@ public class AdapterTest {
|
|||
|
||||
@Before
|
||||
public void before() throws Exception {
|
||||
factory = new PicketlinkKeycloakSessionFactory(createFactory());
|
||||
factory = KeycloakApplication.buildSessionFactory();
|
||||
identitySession = factory.createSession();
|
||||
identitySession.getTransaction().begin();
|
||||
adapter = new RealmManager(identitySession);
|
||||
}
|
||||
|
||||
public static IdentitySessionFactory createFactory() {
|
||||
ResourceLocalJpaIdentitySessionHandler handler = new ResourceLocalJpaIdentitySessionHandler("keycloak-identity-store");
|
||||
IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder();
|
||||
|
||||
builder
|
||||
.stores()
|
||||
.jpa()
|
||||
.identityClass(IdentityObject.class)
|
||||
.attributeClass(IdentityObjectAttribute.class)
|
||||
.relationshipClass(RelationshipObject.class)
|
||||
.relationshipIdentityClass(RelationshipIdentityObject.class)
|
||||
.relationshipAttributeClass(RelationshipObjectAttribute.class)
|
||||
.credentialClass(CredentialObject.class)
|
||||
.credentialAttributeClass(CredentialObjectAttribute.class)
|
||||
.partitionClass(PartitionObject.class)
|
||||
.supportAllFeatures()
|
||||
.supportRelationshipType(RealmAdminRelationship.class, ResourceRelationship.class, RequiredCredentialRelationship.class, ScopeRelationship.class)
|
||||
.setIdentitySessionHandler(handler);
|
||||
|
||||
IdentityConfiguration build = builder.build();
|
||||
return new DefaultIdentitySessionFactory(build);
|
||||
}
|
||||
|
||||
|
||||
@After
|
||||
public void after() throws Exception {
|
||||
identitySession.getTransaction().commit();
|
||||
identitySession.close();
|
||||
factory.close();
|
||||
}
|
||||
|
@ -132,6 +94,8 @@ public class AdapterTest {
|
|||
for (RequiredCredentialModel cred : storedCreds) {
|
||||
if (cred.getType().equals(RequiredCredentialRepresentation.PASSWORD)) password = true;
|
||||
else if (cred.getType().equals(RequiredCredentialRepresentation.TOTP)) totp = true;
|
||||
Assert.assertTrue(cred.isInput());
|
||||
Assert.assertTrue(cred.isSecret());
|
||||
}
|
||||
Assert.assertTrue(totp);
|
||||
Assert.assertTrue(password);
|
||||
|
|
|
@ -13,26 +13,8 @@ import org.keycloak.services.models.KeycloakSessionFactory;
|
|||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RequiredCredentialModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
import org.keycloak.services.models.picketlink.PicketlinkKeycloakSessionFactory;
|
||||
import org.keycloak.services.models.picketlink.relationships.RealmAdminRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.RequiredCredentialRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ScopeRelationship;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
import org.keycloak.services.resources.RegistrationService;
|
||||
import org.picketlink.idm.IdentitySessionFactory;
|
||||
import org.picketlink.idm.config.IdentityConfiguration;
|
||||
import org.picketlink.idm.config.IdentityConfigurationBuilder;
|
||||
import org.picketlink.idm.internal.DefaultIdentitySessionFactory;
|
||||
import org.picketlink.idm.jpa.internal.ResourceLocalJpaIdentitySessionHandler;
|
||||
import org.picketlink.idm.jpa.schema.CredentialObject;
|
||||
import org.picketlink.idm.jpa.schema.CredentialObjectAttribute;
|
||||
import org.picketlink.idm.jpa.schema.IdentityObject;
|
||||
import org.picketlink.idm.jpa.schema.IdentityObjectAttribute;
|
||||
import org.picketlink.idm.jpa.schema.PartitionObject;
|
||||
import org.picketlink.idm.jpa.schema.RelationshipIdentityObject;
|
||||
import org.picketlink.idm.jpa.schema.RelationshipObject;
|
||||
import org.picketlink.idm.jpa.schema.RelationshipObjectAttribute;
|
||||
import org.picketlink.idm.model.Realm;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -49,45 +31,23 @@ public class ImportTest {
|
|||
|
||||
@Before
|
||||
public void before() throws Exception {
|
||||
factory = new PicketlinkKeycloakSessionFactory(createFactory());
|
||||
factory = KeycloakApplication.buildSessionFactory();
|
||||
identitySession = factory.createSession();
|
||||
identitySession.getTransaction().begin();
|
||||
manager = new RealmManager(identitySession);
|
||||
}
|
||||
|
||||
public static IdentitySessionFactory createFactory() {
|
||||
ResourceLocalJpaIdentitySessionHandler handler = new ResourceLocalJpaIdentitySessionHandler("keycloak-identity-store");
|
||||
IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder();
|
||||
|
||||
builder
|
||||
.stores()
|
||||
.jpa()
|
||||
.identityClass(IdentityObject.class)
|
||||
.attributeClass(IdentityObjectAttribute.class)
|
||||
.relationshipClass(RelationshipObject.class)
|
||||
.relationshipIdentityClass(RelationshipIdentityObject.class)
|
||||
.relationshipAttributeClass(RelationshipObjectAttribute.class)
|
||||
.credentialClass(CredentialObject.class)
|
||||
.credentialAttributeClass(CredentialObjectAttribute.class)
|
||||
.partitionClass(PartitionObject.class)
|
||||
.supportAllFeatures()
|
||||
.supportRelationshipType(RealmAdminRelationship.class, ResourceRelationship.class, RequiredCredentialRelationship.class, ScopeRelationship.class)
|
||||
.setIdentitySessionHandler(handler);
|
||||
|
||||
IdentityConfiguration build = builder.build();
|
||||
return new DefaultIdentitySessionFactory(build);
|
||||
}
|
||||
|
||||
|
||||
@After
|
||||
public void after() throws Exception {
|
||||
identitySession.getTransaction().commit();
|
||||
identitySession.close();
|
||||
factory.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void install() throws Exception {
|
||||
RealmModel defaultRealm = manager.createRealm(Realm.DEFAULT_REALM, Realm.DEFAULT_REALM);
|
||||
defaultRealm.setName(Realm.DEFAULT_REALM);
|
||||
RealmModel defaultRealm = manager.createRealm(RealmModel.DEFAULT_REALM, RealmModel.DEFAULT_REALM);
|
||||
defaultRealm.setName(RealmModel.DEFAULT_REALM);
|
||||
defaultRealm.setEnabled(true);
|
||||
defaultRealm.setTokenLifespan(300);
|
||||
defaultRealm.setAccessCodeLifespan(60);
|
||||
|
|
|
@ -4,7 +4,6 @@ import org.keycloak.services.managers.RealmManager;
|
|||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RequiredCredentialModel;
|
||||
import org.keycloak.services.resources.RegistrationService;
|
||||
import org.picketlink.idm.model.Realm;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -12,8 +11,8 @@ import org.picketlink.idm.model.Realm;
|
|||
*/
|
||||
public class InstallationManager {
|
||||
public void install(RealmManager manager) {
|
||||
RealmModel defaultRealm = manager.createRealm(Realm.DEFAULT_REALM, Realm.DEFAULT_REALM);
|
||||
defaultRealm.setName(Realm.DEFAULT_REALM);
|
||||
RealmModel defaultRealm = manager.createRealm(RealmModel.DEFAULT_REALM, RealmModel.DEFAULT_REALM);
|
||||
defaultRealm.setName(RealmModel.DEFAULT_REALM);
|
||||
defaultRealm.setEnabled(true);
|
||||
defaultRealm.setTokenLifespan(300);
|
||||
defaultRealm.setAccessCodeLifespan(60);
|
||||
|
|
|
@ -14,9 +14,8 @@ import org.keycloak.representations.idm.UserRepresentation;
|
|||
import org.keycloak.services.managers.AuthenticationManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.model.Realm;
|
||||
|
||||
import javax.ws.rs.NotAuthorizedException;
|
||||
import javax.ws.rs.client.Client;
|
||||
|
@ -43,9 +42,12 @@ public class RealmCreationTest {
|
|||
deployment.setApplicationClass(KeycloakApplication.class.getName());
|
||||
EmbeddedContainer.start(deployment);
|
||||
KeycloakApplication application = (KeycloakApplication) deployment.getApplication();
|
||||
KeycloakSession IdentitySession = application.getFactory().createSession();
|
||||
RealmManager manager = new RealmManager(IdentitySession);
|
||||
KeycloakSession session = application.getFactory().createSession();
|
||||
session.getTransaction().begin();
|
||||
RealmManager manager = new RealmManager(session);
|
||||
new InstallationManager().install(manager);
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
client = new ResteasyClientBuilder().build();
|
||||
client.register(SkeletonKeyContextResolver.class);
|
||||
}
|
||||
|
@ -72,14 +74,14 @@ public class RealmCreationTest {
|
|||
Form form = new Form();
|
||||
form.param(AuthenticationManager.FORM_USERNAME, "bburke");
|
||||
form.param(RequiredCredentialRepresentation.PASSWORD, "badpassword");
|
||||
tokenResponse = target.path("realms").path(Realm.DEFAULT_REALM).path("tokens/grants/identity-token").request().post(Entity.form(form), AccessTokenResponse.class);
|
||||
tokenResponse = target.path("realms").path(RealmModel.DEFAULT_REALM).path("tokens/grants/identity-token").request().post(Entity.form(form), AccessTokenResponse.class);
|
||||
Assert.fail();
|
||||
} catch (NotAuthorizedException e) {
|
||||
}
|
||||
Form form = new Form();
|
||||
form.param(AuthenticationManager.FORM_USERNAME, "bburke");
|
||||
form.param(RequiredCredentialRepresentation.PASSWORD, "geheim");
|
||||
tokenResponse = target.path("realms").path(Realm.DEFAULT_REALM).path("tokens/grants/identity-token").request().post(Entity.form(form), AccessTokenResponse.class);
|
||||
tokenResponse = target.path("realms").path(RealmModel.DEFAULT_REALM).path("tokens/grants/identity-token").request().post(Entity.form(form), AccessTokenResponse.class);
|
||||
Assert.assertNotNull(tokenResponse);
|
||||
System.out.println(tokenResponse.getToken());
|
||||
//
|
||||
|
|
|
@ -5,15 +5,23 @@
|
|||
<persistence-unit name="keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
|
||||
<provider>org.hibernate.ejb.HibernatePersistence</provider>
|
||||
|
||||
<class>org.picketlink.idm.jpa.schema.IdentityObject</class>
|
||||
<class>org.picketlink.idm.jpa.schema.PartitionObject</class>
|
||||
<class>org.picketlink.idm.jpa.schema.RelationshipObject</class>
|
||||
<class>org.picketlink.idm.jpa.schema.RelationshipIdentityObject</class>
|
||||
<class>org.picketlink.idm.jpa.schema.RelationshipIdentityWeakObject</class>
|
||||
<class>org.picketlink.idm.jpa.schema.RelationshipObjectAttribute</class>
|
||||
<class>org.picketlink.idm.jpa.schema.IdentityObjectAttribute</class>
|
||||
<class>org.picketlink.idm.jpa.schema.CredentialObject</class>
|
||||
<class>org.picketlink.idm.jpa.schema.CredentialObjectAttribute</class>
|
||||
<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.services.models.picketlink.mappings.RealmEntity</class>
|
||||
<class>org.keycloak.services.models.picketlink.mappings.ResourceEntity</class>
|
||||
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
|
||||
<properties>
|
||||
<property name="hibernate.connection.url" value="jdbc:h2:mem:test"/>
|
||||
|
@ -21,9 +29,10 @@
|
|||
<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="false" />
|
||||
<property name="hibernate.show_sql" value="false" />
|
||||
<property name="hibernate.format_sql" value="true" />
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
|
||||
</persistence>
|
||||
|
|
Loading…
Reference in a new issue