jpa backend
This commit is contained in:
parent
d6ee6aef9f
commit
d04ca2c34f
182 changed files with 6199 additions and 1740 deletions
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-fragment version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd ">
|
||||
</web-fragment>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-fragment version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd ">
|
||||
</web-fragment>
|
||||
|
|
|
@ -37,7 +37,8 @@ public class JaxrsOAuthClient extends AbstractOAuthClient {
|
|||
.queryParam("state", state)
|
||||
.build();
|
||||
NewCookie cookie = new NewCookie(getStateCookieName(), state, getStateCookiePath(uriInfo), null, null, -1, isSecure, true);
|
||||
logger.info("NewCookie: " + cookie.toString());
|
||||
logger.debug("NewCookie: " + cookie.toString());
|
||||
logger.debug("Oauth Redirect to: " + url);
|
||||
return Response.status(302)
|
||||
.location(url)
|
||||
.cookie(cookie).build();
|
||||
|
|
|
@ -4,7 +4,10 @@ import org.codehaus.jackson.annotate.JsonIgnore;
|
|||
import org.codehaus.jackson.annotate.JsonProperty;
|
||||
import org.jboss.resteasy.jwt.JsonWebToken;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.keycloak.representations.idm.admin;
|
||||
|
||||
import org.codehaus.jackson.annotate.JsonIgnore;
|
||||
import org.codehaus.jackson.annotate.JsonProperty;
|
||||
|
||||
/**
|
||||
* Posted to managed client from admin server.
|
||||
|
|
|
@ -6,13 +6,10 @@ import org.bouncycastle.openssl.PEMWriter;
|
|||
import org.bouncycastle.x509.X509V1CertificateGenerator;
|
||||
import org.jboss.resteasy.jose.jws.JWSBuilder;
|
||||
import org.jboss.resteasy.jwt.JsonSerialization;
|
||||
import org.keycloak.RSATokenVerifier;
|
||||
import org.keycloak.ResourceMetadata;
|
||||
import org.keycloak.VerificationException;
|
||||
import org.keycloak.representations.SkeletonKeyToken;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.representations.SkeletonKeyToken;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -5,9 +5,9 @@ import org.jboss.resteasy.jose.jws.JWSBuilder;
|
|||
import org.jboss.resteasy.jose.jws.JWSInput;
|
||||
import org.jboss.resteasy.jose.jws.crypto.RSAProvider;
|
||||
import org.jboss.resteasy.jwt.JsonSerialization;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.representations.SkeletonKeyScope;
|
||||
import org.keycloak.representations.SkeletonKeyToken;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<%@ page import="javax.ws.rs.core.*" language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
<%@ page import="javax.ws.rs.core.UriBuilder" language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1"%>
|
||||
<html>
|
||||
<head>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<%@ page import="javax.ws.rs.core.*" language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
<%@ page import="javax.ws.rs.core.UriBuilder" language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1"%>
|
||||
<html>
|
||||
<head>
|
||||
|
|
|
@ -35,11 +35,6 @@
|
|||
<artifactId>keycloak-model-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-model-picketlink</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-social-core</artifactId>
|
||||
|
@ -75,22 +70,6 @@
|
|||
<artifactId>keycloak-admin-ui-styles</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-impl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-simple-schema</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-config</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-jaxrs</artifactId>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package org.keycloak.example.demo;
|
||||
|
||||
import org.jboss.resteasy.jwt.JsonSerialization;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.managers.ApplianceBootstrap;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
|
|
@ -2,24 +2,22 @@
|
|||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
<persistence-unit name="keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
|
||||
<persistence-unit name="jpa-keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
|
||||
<jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
|
||||
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.AttributedTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.AccountTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.RoleTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.GroupTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.IdentityTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.RelationshipTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.RelationshipIdentityTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.PartitionTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.PasswordCredentialTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.DigestCredentialTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.X509CredentialTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.OTPCredentialTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.AttributeTypeEntity</class>
|
||||
<class>org.keycloak.models.picketlink.mappings.RealmEntity</class>
|
||||
<class>org.keycloak.models.picketlink.mappings.ApplicationEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.ApplicationEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.ApplicationScopeMappingEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.ApplicationUserRoleMappingEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.CredentialEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.OAuthClientEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.RealmEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.RealmScopeMappingEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.RealmUserRoleMappingEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.RoleEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.SocialLinkEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.UserEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.UserRoleMappingEntity</class>
|
||||
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<%@ page import="org.keycloak.models.*,org.keycloak.services.resources.*,javax.ws.rs.core.*,java.util.*" language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
<%@ page import="org.keycloak.models.RealmModel,org.keycloak.models.RoleModel,org.keycloak.models.UserModel,javax.ws.rs.core.MultivaluedMap" language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1"%>
|
||||
<%@ page import="java.util.List" %>
|
||||
<%
|
||||
RealmModel realm = (RealmModel)request.getAttribute(RealmModel.class.getName());
|
||||
String username = (String)request.getAttribute("username");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<%@ page import="javax.ws.rs.core.*" language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1"%>
|
||||
<html>
|
||||
<head>
|
||||
|
|
|
@ -35,11 +35,6 @@
|
|||
<artifactId>keycloak-model-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-model-picketlink</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-social-core</artifactId>
|
||||
|
@ -65,22 +60,6 @@
|
|||
<artifactId>keycloak-forms</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-impl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-simple-schema</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-config</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-jaxrs</artifactId>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package org.keycloak.example.demo;
|
||||
|
||||
import org.jboss.resteasy.jwt.JsonSerialization;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.managers.ApplianceBootstrap;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
|
|
@ -2,24 +2,22 @@
|
|||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
<persistence-unit name="keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
|
||||
<persistence-unit name="jpa-keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
|
||||
<jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
|
||||
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.AttributedTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.AccountTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.RoleTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.GroupTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.IdentityTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.RelationshipTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.RelationshipIdentityTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.PartitionTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.PasswordCredentialTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.DigestCredentialTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.X509CredentialTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.OTPCredentialTypeEntity</class>
|
||||
<class>org.picketlink.idm.jpa.model.sample.simple.AttributeTypeEntity</class>
|
||||
<class>org.keycloak.models.picketlink.mappings.RealmEntity</class>
|
||||
<class>org.keycloak.models.picketlink.mappings.ApplicationEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.ApplicationEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.ApplicationScopeMappingEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.ApplicationUserRoleMappingEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.CredentialEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.OAuthClientEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.RealmEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.RealmScopeMappingEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.RealmUserRoleMappingEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.RoleEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.SocialLinkEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.UserEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.UserRoleMappingEntity</class>
|
||||
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
|
||||
|
@ -30,4 +28,5 @@
|
|||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
|
||||
</persistence>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<%@ page import="org.keycloak.models.*,org.keycloak.services.resources.*,javax.ws.rs.core.*,java.util.*" language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
<%@ page import="org.keycloak.models.RealmModel,org.keycloak.models.RoleModel,org.keycloak.models.UserModel,javax.ws.rs.core.MultivaluedMap" language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1"%>
|
||||
<%@ page import="java.util.List" %>
|
||||
<%
|
||||
RealmModel realm = (RealmModel)request.getAttribute(RealmModel.class.getName());
|
||||
String username = (String)request.getAttribute("username");
|
||||
|
|
|
@ -33,11 +33,6 @@
|
|||
<artifactId>keycloak-social-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-common</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-jaxrs</artifactId>
|
||||
|
|
|
@ -21,12 +21,11 @@
|
|||
*/
|
||||
package org.keycloak.forms;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.keycloak.forms.model.RequiredCredential;
|
||||
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
|
||||
import org.keycloak.forms.model.RequiredCredential;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
|
|
9
forms/src/main/java/org/keycloak/forms/OAuthGrantBean.java
Normal file → Executable file
9
forms/src/main/java/org/keycloak/forms/OAuthGrantBean.java
Normal file → Executable file
|
@ -21,14 +21,13 @@
|
|||
*/
|
||||
package org.keycloak.forms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:vrockai@redhat.com">Viliam Rockai</a>
|
||||
*/
|
||||
|
|
|
@ -21,11 +21,10 @@
|
|||
*/
|
||||
package org.keycloak.forms;
|
||||
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
|
|
11
forms/src/main/java/org/keycloak/forms/SocialBean.java
Normal file → Executable file
11
forms/src/main/java/org/keycloak/forms/SocialBean.java
Normal file → Executable file
|
@ -21,15 +21,14 @@
|
|||
*/
|
||||
package org.keycloak.forms;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.*;
|
||||
|
||||
import javax.imageio.spi.ServiceRegistry;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
import org.keycloak.forms.model.SocialProvider;
|
||||
import org.keycloak.services.resources.flows.Urls;
|
||||
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import java.net.URI;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
|
|
3
forms/src/main/java/org/keycloak/forms/TotpBean.java
Normal file → Executable file
3
forms/src/main/java/org/keycloak/forms/TotpBean.java
Normal file → Executable file
|
@ -21,11 +21,12 @@
|
|||
*/
|
||||
package org.keycloak.forms;
|
||||
|
||||
import org.keycloak.models.utils.Base32;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Random;
|
||||
|
||||
import org.picketlink.common.util.Base32;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
|
|
|
@ -21,10 +21,10 @@
|
|||
*/
|
||||
package org.keycloak.forms;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.keycloak.services.resources.flows.Urls;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
|
|
16
forms/src/main/java/org/keycloak/service/FormServiceImpl.java
Normal file → Executable file
16
forms/src/main/java/org/keycloak/service/FormServiceImpl.java
Normal file → Executable file
|
@ -21,19 +21,12 @@
|
|||
*/
|
||||
package org.keycloak.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateException;
|
||||
import org.jboss.resteasy.logging.Logger;
|
||||
import org.keycloak.forms.MessageBean;
|
||||
import org.keycloak.forms.LoginBean;
|
||||
import org.keycloak.forms.MessageBean;
|
||||
import org.keycloak.forms.OAuthGrantBean;
|
||||
import org.keycloak.forms.RealmBean;
|
||||
import org.keycloak.forms.RegisterBean;
|
||||
|
@ -45,6 +38,13 @@ import org.keycloak.forms.UserBean;
|
|||
import org.keycloak.services.FormService;
|
||||
import org.keycloak.services.resources.flows.Pages;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:vrockai@redhat.com">Viliam Rockai</a>
|
||||
*/
|
||||
|
|
|
@ -7,7 +7,6 @@ import org.apache.catalina.connector.Request;
|
|||
import org.apache.catalina.connector.Response;
|
||||
import org.apache.catalina.valves.ValveBase;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||
import org.keycloak.SkeletonKeySession;
|
||||
import org.keycloak.adapters.as7.config.ManagedResourceConfig;
|
||||
import org.keycloak.representations.SkeletonKeyToken;
|
||||
|
|
|
@ -1,879 +0,0 @@
|
|||
package org.keycloak.adapters.as7;
|
||||
|
||||
import org.apache.catalina.Lifecycle;
|
||||
import org.apache.catalina.LifecycleEvent;
|
||||
import org.apache.catalina.LifecycleException;
|
||||
import org.apache.catalina.LifecycleListener;
|
||||
import org.apache.catalina.authenticator.Constants;
|
||||
import org.apache.catalina.authenticator.FormAuthenticator;
|
||||
import org.apache.catalina.connector.Request;
|
||||
import org.apache.catalina.connector.Response;
|
||||
import org.apache.catalina.core.StandardContext;
|
||||
import org.apache.catalina.deploy.LoginConfig;
|
||||
import org.apache.catalina.realm.GenericPrincipal;
|
||||
import org.bouncycastle.openssl.PEMWriter;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.codehaus.jackson.map.ObjectWriter;
|
||||
import org.codehaus.jackson.map.SerializationConfig;
|
||||
import org.codehaus.jackson.map.annotate.JsonSerialize;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
|
||||
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
|
||||
import org.jboss.resteasy.jose.jws.JWSBuilder;
|
||||
import org.jboss.resteasy.jose.jws.JWSInput;
|
||||
import org.jboss.resteasy.jose.jws.crypto.RSAProvider;
|
||||
import org.jboss.resteasy.jwt.JsonSerialization;
|
||||
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
|
||||
import org.jboss.resteasy.plugins.server.servlet.ServletUtil;
|
||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||
import org.jboss.resteasy.spi.ResteasyUriInfo;
|
||||
import org.jboss.resteasy.util.BasicAuthHelper;
|
||||
import org.keycloak.EnvUtil;
|
||||
import org.keycloak.PemUtils;
|
||||
import org.keycloak.ResourceMetadata;
|
||||
import org.keycloak.SkeletonKeySession;
|
||||
import org.keycloak.adapters.as7.config.AuthServerConfig;
|
||||
import org.keycloak.adapters.as7.config.ManagedResourceConfig;
|
||||
import org.keycloak.representations.AccessTokenResponse;
|
||||
import org.keycloak.representations.SkeletonKeyToken;
|
||||
|
||||
import javax.security.auth.login.LoginException;
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.Principal;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Turns a web deployment into an authentication server that follwos the OAuth 2 protocol and Skeleton Key bearer tokens.
|
||||
* Authentication store is backed by a JBoss security domain.
|
||||
* <p/>
|
||||
* Servlet FORM authentication that uses the local security domain to authenticate and for role mappings.
|
||||
* <p/>
|
||||
* Supports bearer token creation and authentication. The client asking for access must be set up as a valid user
|
||||
* within the security domain.
|
||||
* <p/>
|
||||
* If no an OAuth access request, this works like normal FORM authentication and authorization.
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class OAuthAuthenticationServerValve extends FormAuthenticator implements LifecycleListener {
|
||||
|
||||
|
||||
public static class AccessCode {
|
||||
protected String id = UUID.randomUUID().toString() + System.currentTimeMillis();
|
||||
protected long expiration;
|
||||
protected SkeletonKeyToken token;
|
||||
protected String client;
|
||||
protected boolean sso;
|
||||
protected String redirect;
|
||||
|
||||
public boolean isExpired() {
|
||||
return expiration != 0 && (System.currentTimeMillis() / 1000) > expiration;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
|
||||
public void setExpiration(long expiration) {
|
||||
this.expiration = expiration;
|
||||
}
|
||||
|
||||
public SkeletonKeyToken getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(SkeletonKeyToken token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public void setClient(String client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public boolean isSso() {
|
||||
return sso;
|
||||
}
|
||||
|
||||
public void setSso(boolean sso) {
|
||||
this.sso = sso;
|
||||
}
|
||||
|
||||
public String getRedirect() {
|
||||
return redirect;
|
||||
}
|
||||
|
||||
public void setRedirect(String redirect) {
|
||||
this.redirect = redirect;
|
||||
}
|
||||
}
|
||||
|
||||
protected ConcurrentHashMap<String, AccessCode> accessCodeMap = new ConcurrentHashMap<String, AccessCode>();
|
||||
private static final Logger log = Logger.getLogger(OAuthAuthenticationServerValve.class);
|
||||
|
||||
private static AtomicLong counter = new AtomicLong(1);
|
||||
|
||||
private static String generateId() {
|
||||
return counter.getAndIncrement() + "." + UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
protected AuthServerConfig skeletonKeyConfig;
|
||||
protected PrivateKey realmPrivateKey;
|
||||
protected PublicKey realmPublicKey;
|
||||
protected String realmPublicKeyPem;
|
||||
protected ResteasyProviderFactory providers;
|
||||
protected ResourceMetadata resourceMetadata;
|
||||
protected UserSessionManagement userSessionManagement = new UserSessionManagement();
|
||||
protected ObjectMapper mapper;
|
||||
protected ObjectWriter accessTokenResponseWriter;
|
||||
protected ObjectWriter mapWriter;
|
||||
|
||||
private static KeyStore loadKeyStore(String filename, String password) throws Exception {
|
||||
KeyStore trustStore = KeyStore.getInstance(KeyStore
|
||||
.getDefaultType());
|
||||
File truststoreFile = new File(filename);
|
||||
FileInputStream trustStream = new FileInputStream(truststoreFile);
|
||||
trustStore.load(trustStream, password.toCharArray());
|
||||
trustStream.close();
|
||||
return trustStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws LifecycleException {
|
||||
super.start();
|
||||
StandardContext standardContext = (StandardContext) context;
|
||||
standardContext.addLifecycleListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lifecycleEvent(LifecycleEvent event) {
|
||||
if (event.getType() == Lifecycle.AFTER_START_EVENT) init();
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
mapper = new ObjectMapper();
|
||||
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT);
|
||||
accessTokenResponseWriter = mapper.writerWithType(AccessTokenResponse.class);
|
||||
mapWriter = mapper.writerWithType(mapper.getTypeFactory().constructMapType(Map.class, String.class, String.class));
|
||||
|
||||
InputStream is = null;
|
||||
String path = context.getServletContext().getInitParameter("skeleton.key.config.file");
|
||||
if (path == null) {
|
||||
is = context.getServletContext().getResourceAsStream("/WEB-INF/resteasy-oauth.json");
|
||||
} else {
|
||||
try {
|
||||
is = new FileInputStream(path);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
skeletonKeyConfig = mapper.readValue(is, AuthServerConfig.class);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (skeletonKeyConfig.getLoginRole() == null) {
|
||||
throw new RuntimeException("You must define the login-role in your config file");
|
||||
}
|
||||
if (skeletonKeyConfig.getClientRole() == null) {
|
||||
throw new RuntimeException("You must define the oauth-client-role in your config file");
|
||||
}
|
||||
if (skeletonKeyConfig.getRealmPrivateKey() != null) {
|
||||
try {
|
||||
realmPrivateKey = PemUtils.decodePrivateKey(skeletonKeyConfig.getRealmPrivateKey());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
if (skeletonKeyConfig.getRealmPublicKey() != null) {
|
||||
try {
|
||||
realmPublicKey = PemUtils.decodePublicKey(skeletonKeyConfig.getRealmPublicKey());
|
||||
realmPublicKeyPem = skeletonKeyConfig.getRealmPublicKey();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
if (skeletonKeyConfig.getRealmKeyStore() != null) {
|
||||
if (skeletonKeyConfig.getRealmKeyAlias() == null) throw new RuntimeException("Must define realm-key-alias");
|
||||
String keystorePath = EnvUtil.replace(skeletonKeyConfig.getRealmKeyStore());
|
||||
try {
|
||||
KeyStore ks = loadKeyStore(keystorePath, skeletonKeyConfig.getRealmKeystorePassword());
|
||||
if (realmPrivateKey == null) {
|
||||
realmPrivateKey = (PrivateKey) ks.getKey(skeletonKeyConfig.getRealmKeyAlias(), skeletonKeyConfig.getRealmPrivateKeyPassword().toCharArray());
|
||||
}
|
||||
if (realmPublicKey == null) {
|
||||
Certificate cert = ks.getCertificate(skeletonKeyConfig.getRealmKeyAlias());
|
||||
realmPublicKey = cert.getPublicKey();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
if (realmPublicKey == null) throw new RuntimeException("You have not declared a keystore or public key");
|
||||
if (realmPrivateKey == null) throw new RuntimeException("You have not declared a keystore or private key");
|
||||
if (realmPublicKeyPem == null) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PEMWriter writer = new PEMWriter(sw);
|
||||
try {
|
||||
writer.writeObject(realmPublicKey);
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
realmPublicKeyPem = sw.toString();
|
||||
realmPublicKeyPem = PemUtils.removeBeginEnd(realmPublicKeyPem);
|
||||
}
|
||||
providers = new ResteasyProviderFactory();
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(OAuthAuthenticationServerValve.class.getClassLoader());
|
||||
try {
|
||||
ResteasyProviderFactory.getInstance(); // initialize builtins
|
||||
RegisterBuiltin.register(providers);
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
resourceMetadata = new ResourceMetadata();
|
||||
resourceMetadata.setRealm(skeletonKeyConfig.getRealm());
|
||||
resourceMetadata.setRealmKey(realmPublicKey);
|
||||
String truststore = skeletonKeyConfig.getTruststore();
|
||||
if (truststore != null) {
|
||||
truststore = EnvUtil.replace(truststore);
|
||||
String truststorePassword = skeletonKeyConfig.getTruststorePassword();
|
||||
KeyStore trust = null;
|
||||
try {
|
||||
trust = loadKeyStore(truststore, truststorePassword);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to load truststore", e);
|
||||
}
|
||||
resourceMetadata.setTruststore(trust);
|
||||
}
|
||||
String clientKeystore = skeletonKeyConfig.getClientKeystore();
|
||||
String clientKeyPassword = null;
|
||||
if (clientKeystore != null) {
|
||||
clientKeystore = EnvUtil.replace(clientKeystore);
|
||||
String clientKeystorePassword = skeletonKeyConfig.getClientKeystorePassword();
|
||||
KeyStore serverKS = null;
|
||||
try {
|
||||
serverKS = loadKeyStore(clientKeystore, clientKeystorePassword);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to load keystore", e);
|
||||
}
|
||||
resourceMetadata.setClientKeystore(serverKS);
|
||||
clientKeyPassword = skeletonKeyConfig.getClientKeyPassword();
|
||||
resourceMetadata.setClientKeyPassword(clientKeyPassword);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(Request request, Response response) throws IOException, ServletException {
|
||||
try {
|
||||
String contextPath = request.getContextPath();
|
||||
String requestURI = request.getDecodedRequestURI();
|
||||
log.debug("--- invoke: " + requestURI);
|
||||
if (request.getMethod().equalsIgnoreCase("GET")
|
||||
&& context.getLoginConfig().getLoginPage().equals(request.getRequestPathMB().toString())) {
|
||||
if (handleLoginPage(request, response)) return;
|
||||
} else if (request.getMethod().equalsIgnoreCase("GET")
|
||||
&& requestURI.endsWith(Actions.J_OAUTH_LOGOUT)) {
|
||||
logoutCurrentUser(request, response);
|
||||
return;
|
||||
} else if (request.getMethod().equalsIgnoreCase("POST")
|
||||
&& requestURI.endsWith(Actions.J_OAUTH_ADMIN_FORCED_LOGOUT)) {
|
||||
adminLogout(request, response);
|
||||
return;
|
||||
} else if (request.getMethod().equalsIgnoreCase("POST")
|
||||
&& requestURI.startsWith(contextPath) &&
|
||||
requestURI.endsWith(Constants.FORM_ACTION)
|
||||
&& request.getParameter("client_id") != null) {
|
||||
handleOAuth(request, response);
|
||||
return;
|
||||
} else if (request.getMethod().equalsIgnoreCase("POST")
|
||||
&& requestURI.endsWith(Actions.J_OAUTH_TOKEN_GRANT)) {
|
||||
tokenGrant(request, response);
|
||||
return;
|
||||
} else if (request.getMethod().equalsIgnoreCase("POST")
|
||||
&& requestURI.startsWith(contextPath) &&
|
||||
requestURI.endsWith(Actions.J_OAUTH_RESOLVE_ACCESS_CODE)) {
|
||||
resolveAccessCode(request, response);
|
||||
return;
|
||||
} else if (request.getMethod().equalsIgnoreCase("GET")
|
||||
&& requestURI.startsWith(contextPath) &&
|
||||
requestURI.endsWith("j_oauth_realm_info.html")) {
|
||||
publishRealmInfoHtml(request, response);
|
||||
return;
|
||||
}
|
||||
// propagate the skeleton key token string?
|
||||
if (!skeletonKeyConfig.isCancelPropagation()) {
|
||||
if (request.getAttribute(SkeletonKeySession.class.getName()) == null && request.getSessionInternal() != null) {
|
||||
SkeletonKeySession skSession = (SkeletonKeySession) request.getSessionInternal().getNote(SkeletonKeySession.class.getName());
|
||||
if (skSession != null) {
|
||||
request.setAttribute(SkeletonKeySession.class.getName(), skSession);
|
||||
ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession);
|
||||
}
|
||||
}
|
||||
}
|
||||
request.setAttribute("OAUTH_FORM_ACTION", "j_security_check");
|
||||
super.invoke(request, response);
|
||||
} finally {
|
||||
ResteasyProviderFactory.clearContextData(); // to clear push of SkeletonKeySession
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean handleLoginPage(Request request, Response response) throws IOException, ServletException {
|
||||
String client_id = request.getParameter("client_id");
|
||||
// if this is not an OAUTH redirect, just return and let the default flow happen
|
||||
if (client_id == null) return false;
|
||||
|
||||
String redirect_uri = request.getParameter("redirect_uri");
|
||||
String state = request.getParameter("state");
|
||||
|
||||
if (redirect_uri == null) {
|
||||
response.sendError(400, "No oauth redirect query parameter set");
|
||||
return true;
|
||||
}
|
||||
// only bypass authentication if our session is authenticated,
|
||||
// the login query parameter is on request URL,
|
||||
// and we have configured the login-role
|
||||
else if (!skeletonKeyConfig.isSsoDisabled()
|
||||
&& request.getSessionInternal() != null
|
||||
&& request.getSessionInternal().getPrincipal() != null
|
||||
&& request.getParameter("login") != null) {
|
||||
log.debug("We're ALREADY LOGGED IN!!!");
|
||||
GenericPrincipal gp = (GenericPrincipal) request.getSessionInternal().getPrincipal();
|
||||
redirectAccessCode(true, response, redirect_uri, client_id, state, gp);
|
||||
} else {
|
||||
UriBuilder builder = UriBuilder.fromUri("j_security_check")
|
||||
.queryParam("redirect_uri", redirect_uri)
|
||||
.queryParam("client_id", client_id);
|
||||
if (state != null) builder.queryParam("state", state);
|
||||
String loginAction = builder.build().toString();
|
||||
request.setAttribute("OAUTH_FORM_ACTION", loginAction);
|
||||
getNext().invoke(request, response);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected GenericPrincipal checkLoggedIn(Request request, HttpServletResponse response) {
|
||||
if (request.getPrincipal() != null) {
|
||||
return (GenericPrincipal) request.getPrincipal();
|
||||
} else if (request.getSessionInternal() != null && request.getSessionInternal().getPrincipal() != null) {
|
||||
return (GenericPrincipal) request.getSessionInternal().getPrincipal();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected void adminLogout(Request request, HttpServletResponse response) throws IOException {
|
||||
log.debug("<< adminLogout");
|
||||
GenericPrincipal gp = checkLoggedIn(request, response);
|
||||
if (gp == null) {
|
||||
if (bearer(request, response, false)) {
|
||||
gp = (GenericPrincipal) request.getPrincipal();
|
||||
} else {
|
||||
response.sendError(403);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!gp.hasRole(skeletonKeyConfig.getAdminRole())) {
|
||||
response.sendError(403);
|
||||
return;
|
||||
}
|
||||
String logoutUser = request.getParameter("user");
|
||||
if (logoutUser != null) {
|
||||
userSessionManagement.logout(logoutUser);
|
||||
logoutResources(logoutUser, gp.getName());
|
||||
} else {
|
||||
userSessionManagement.logoutAllBut(gp.getName());
|
||||
logoutResources(null, gp.getName());
|
||||
}
|
||||
String forwardTo = request.getParameter("forward");
|
||||
if (forwardTo == null) {
|
||||
response.setStatus(204);
|
||||
return;
|
||||
}
|
||||
RequestDispatcher disp =
|
||||
context.getServletContext().getRequestDispatcher(forwardTo);
|
||||
try {
|
||||
disp.forward(request.getRequest(), response);
|
||||
} catch (Throwable t) {
|
||||
request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, t);
|
||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
|
||||
"failed to forward");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected void logoutCurrentUser(Request request, HttpServletResponse response) throws IOException {
|
||||
if (request.getSessionInternal() == null || request.getSessionInternal().getPrincipal() == null) {
|
||||
redirectToWelcomePage(request, response);
|
||||
return;
|
||||
}
|
||||
GenericPrincipal principal = (GenericPrincipal) request.getSessionInternal().getPrincipal();
|
||||
String username = principal.getName();
|
||||
String admin = username;
|
||||
userSessionManagement.logout(username);
|
||||
request.setUserPrincipal(null);
|
||||
request.setAuthType(null);
|
||||
// logout user on all declared authenticated applications
|
||||
logoutResources(username, admin);
|
||||
redirectToWelcomePage(request, response);
|
||||
}
|
||||
|
||||
protected void logoutResources(String username, String admin) {
|
||||
if (skeletonKeyConfig.getResources().size() != 0) {
|
||||
SkeletonKeyToken token = new SkeletonKeyToken();
|
||||
token.id(generateId());
|
||||
token.principal(admin);
|
||||
token.audience(skeletonKeyConfig.getRealm());
|
||||
SkeletonKeyToken.Access realmAccess = new SkeletonKeyToken.Access();
|
||||
realmAccess.addRole(skeletonKeyConfig.getAdminRole());
|
||||
token.setRealmAccess(realmAccess);
|
||||
String tokenString = buildTokenString(realmPrivateKey, token);
|
||||
ResteasyClient client = new ResteasyClientBuilder()
|
||||
.providerFactory(providers)
|
||||
.hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY)
|
||||
.trustStore(resourceMetadata.getTruststore())
|
||||
.keyStore(resourceMetadata.getClientKeystore(), resourceMetadata.getClientKeyPassword())
|
||||
.build();
|
||||
try {
|
||||
for (String resource : skeletonKeyConfig.getResources()) {
|
||||
try {
|
||||
log.debug("logging out: " + resource);
|
||||
WebTarget target = client.target(resource).path(Actions.J_OAUTH_REMOTE_LOGOUT);
|
||||
if (username != null) target = target.queryParam("user", username);
|
||||
javax.ws.rs.core.Response response = target.request()
|
||||
.header("Authorization", "Bearer " + tokenString)
|
||||
.put(null);
|
||||
if (response.getStatus() != 204) log.error("Failed to log out");
|
||||
response.close();
|
||||
} catch (Exception ignored) {
|
||||
log.error("Failed to log out", ignored);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void redirectToWelcomePage(Request request, HttpServletResponse response) throws IOException {
|
||||
ResteasyUriInfo uriInfo = ServletUtil.extractUriInfo(request, null);
|
||||
String[] welcomes = context.findWelcomeFiles();
|
||||
if (welcomes.length > 0) {
|
||||
UriBuilder welcome = uriInfo.getBaseUriBuilder().path(welcomes[0]);
|
||||
response.sendRedirect(welcome.toTemplate());
|
||||
} else {
|
||||
response.setStatus(204);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void publishRealmInfoHtml(Request request, HttpServletResponse response) throws IOException {
|
||||
ManagedResourceConfig rep = getRealmRepresentation(request);
|
||||
StringWriter writer;
|
||||
String json;
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT);
|
||||
mapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);
|
||||
|
||||
StringBuffer html = new StringBuffer();
|
||||
html.append("<html><body bgcolor=\"#CED8F6\">");
|
||||
html.append("<h1>Realm: ").append(rep.getRealm()).append("</h1>");
|
||||
|
||||
ManagedResourceConfig bearer = new ManagedResourceConfig();
|
||||
bearer.setRealm(rep.getRealm());
|
||||
bearer.setRealmKey(rep.getRealmKey());
|
||||
writer = new StringWriter();
|
||||
mapper.writeValue(writer, bearer);
|
||||
json = writer.toString();
|
||||
|
||||
html.append("<h3>BearerTokenAuthValve Json Config</h3>");
|
||||
html.append("<form><textarea rows=\"7\" cols=\"80\">").append(json).append("</textarea></form>");
|
||||
|
||||
html.append("<br>");
|
||||
|
||||
writer = new StringWriter();
|
||||
rep.getCredentials().put("password", "REQUIRED");
|
||||
//rep.setClientId("REQUIRED");
|
||||
rep.setTruststore("REQUIRED");
|
||||
rep.setTruststorePassword("REQUIRED");
|
||||
mapper.writeValue(writer, rep);
|
||||
json = writer.toString();
|
||||
html.append("<h3>OAuthManagedResourceValve Json Config</h3>");
|
||||
html.append("<form><textarea rows=\"20\" cols=\"80\">").append(json).append("</textarea></form>");
|
||||
|
||||
html.append("</body></html>");
|
||||
|
||||
response.setStatus(200);
|
||||
response.setContentType("text/html");
|
||||
response.getOutputStream().println(html.toString());
|
||||
response.getOutputStream().flush();
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected ManagedResourceConfig getRealmRepresentation(Request request) {
|
||||
ManagedResourceConfig rep = new ManagedResourceConfig();
|
||||
ResteasyUriInfo uriInfo = ServletUtil.extractUriInfo(request, null);
|
||||
UriBuilder authUrl = uriInfo.getBaseUriBuilder().path(context.getLoginConfig().getLoginPage());
|
||||
UriBuilder codeUrl = uriInfo.getBaseUriBuilder().path(Actions.J_OAUTH_RESOLVE_ACCESS_CODE);
|
||||
rep.setRealm(skeletonKeyConfig.getRealm());
|
||||
rep.setRealmKey(realmPublicKeyPem);
|
||||
rep.setAuthUrl(authUrl.toTemplate());
|
||||
rep.setCodeUrl(codeUrl.toTemplate());
|
||||
rep.setAdminRole(skeletonKeyConfig.getAdminRole());
|
||||
return rep;
|
||||
}
|
||||
|
||||
public boolean bearer(Request request, HttpServletResponse response, boolean propagate) throws IOException {
|
||||
if (request.getHeader("Authorization") != null) {
|
||||
CatalinaBearerTokenAuthenticator bearer = new CatalinaBearerTokenAuthenticator(resourceMetadata, false, false);
|
||||
try {
|
||||
if (bearer.login(request, response)) {
|
||||
return true;
|
||||
}
|
||||
} catch (LoginException e) {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void register(Request request, HttpServletResponse response, Principal principal, String authType, String username, String password) {
|
||||
super.register(request, response, principal, authType, username, password);
|
||||
log.debug("authenticate userSessionManage.login(): " + principal.getName());
|
||||
userSessionManagement.login(request.getSessionInternal(), principal.getName());
|
||||
if (!skeletonKeyConfig.isCancelPropagation()) {
|
||||
GenericPrincipal gp = (GenericPrincipal) request.getPrincipal();
|
||||
if (gp != null) {
|
||||
SkeletonKeyToken token = buildToken(gp);
|
||||
String stringToken = buildTokenString(realmPrivateKey, token);
|
||||
SkeletonKeySession skSession = new SkeletonKeySession(stringToken, token, resourceMetadata);
|
||||
request.setAttribute(SkeletonKeySession.class.getName(), skSession);
|
||||
ResteasyProviderFactory.pushContext(SkeletonKeySession.class, skSession);
|
||||
request.getSessionInternal(true).setNote(SkeletonKeySession.class.getName(), skSession);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException {
|
||||
if (bearer(request, response, true)) {
|
||||
return true;
|
||||
}
|
||||
return super.authenticate(request, response, config);
|
||||
}
|
||||
|
||||
|
||||
protected void resolveAccessCode(Request request, Response response) throws IOException {
|
||||
if (!request.isSecure()) {
|
||||
response.sendError(400);
|
||||
return;
|
||||
}
|
||||
// always verify code and remove access code from map before authenticating user
|
||||
// if user authentication fails, we want the code to be removed irreguardless just in case we're under attack
|
||||
String code = request.getParameter("code");
|
||||
JWSInput input = new JWSInput(code, providers);
|
||||
boolean verifiedCode = false;
|
||||
try {
|
||||
verifiedCode = RSAProvider.verify(input, realmPublicKey);
|
||||
} catch (Exception ignored) {
|
||||
log.error("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");
|
||||
response.sendError(400);
|
||||
response.setContentType("application/json");
|
||||
mapWriter.writeValue(response.getOutputStream(), res);
|
||||
response.getOutputStream().flush();
|
||||
return;
|
||||
}
|
||||
String key = input.readContent(String.class);
|
||||
AccessCode accessCode = accessCodeMap.remove(key);
|
||||
String redirect = request.getParameter("redirect_uri");
|
||||
|
||||
GenericPrincipal gp = basicAuth(request, response);
|
||||
if (gp == null) {
|
||||
log.error("Failed to authenticate client_id");
|
||||
return;
|
||||
}
|
||||
if (accessCode == null) {
|
||||
log.error("No access code: " + code);
|
||||
response.sendError(400);
|
||||
return;
|
||||
}
|
||||
if (accessCode.isExpired()) {
|
||||
log.debug("Access code expired");
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Code is expired");
|
||||
response.setStatus(400);
|
||||
response.setContentType("application/json");
|
||||
mapWriter.writeValue(response.getOutputStream(), res);
|
||||
response.getOutputStream().flush();
|
||||
return;
|
||||
}
|
||||
if (!accessCode.getToken().isActive()) {
|
||||
log.debug("token not active");
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Token expired");
|
||||
response.setStatus(400);
|
||||
response.setContentType("application/json");
|
||||
mapWriter.writeValue(response.getOutputStream(), res);
|
||||
response.getOutputStream().flush();
|
||||
return;
|
||||
}
|
||||
if (!gp.getName().equals(accessCode.getClient())) {
|
||||
log.debug("not equal client");
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Auth error");
|
||||
response.setStatus(400);
|
||||
response.setContentType("application/json");
|
||||
mapWriter.writeValue(response.getOutputStream(), res);
|
||||
response.getOutputStream().flush();
|
||||
return;
|
||||
}
|
||||
if (!accessCode.getRedirect().equals(redirect)) {
|
||||
log.debug("not equal redirect");
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Auth error");
|
||||
response.setStatus(400);
|
||||
response.setContentType("application/json");
|
||||
mapWriter.writeValue(response.getOutputStream(), res);
|
||||
response.getOutputStream().flush();
|
||||
return;
|
||||
}
|
||||
if (accessCode.isSso() && !gp.hasRole(skeletonKeyConfig.getLoginRole())) {
|
||||
// we did not authenticate user on an access code request because a session was already established
|
||||
// but, the client_id does not have permission to bypass this on a simple grant. We want
|
||||
// to always ask for credentials from a simple oath request
|
||||
|
||||
log.debug("does not have login permission");
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Auth error");
|
||||
response.setStatus(400);
|
||||
response.setContentType("application/json");
|
||||
mapWriter.writeValue(response.getOutputStream(), res);
|
||||
response.getOutputStream().flush();
|
||||
return;
|
||||
} else if (!gp.hasRole(skeletonKeyConfig.getClientRole()) && !gp.hasRole(skeletonKeyConfig.getLoginRole())) {
|
||||
log.debug("does not have login or client role permission for access token request");
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Auth error");
|
||||
response.setStatus(400);
|
||||
response.setContentType("application/json");
|
||||
mapWriter.writeValue(response.getOutputStream(), res);
|
||||
response.getOutputStream().flush();
|
||||
return;
|
||||
|
||||
}
|
||||
String wildcard = skeletonKeyConfig.getWildcardRole() == null ? "*" : skeletonKeyConfig.getWildcardRole();
|
||||
Set<String> codeRoles = accessCode.getToken().getRealmAccess().getRoles();
|
||||
if (codeRoles != null &&
|
||||
(codeRoles.contains(skeletonKeyConfig.getClientRole()) || codeRoles.contains(skeletonKeyConfig.getLoginRole()))) {
|
||||
// we store roles a oauth client is granted in the user role mapping, remove those roles as we don't want those clients with those
|
||||
// permissions if they are logging in.
|
||||
Set<String> newRoles = new HashSet<String>();
|
||||
if (codeRoles.contains(skeletonKeyConfig.getClientRole())) newRoles.add(skeletonKeyConfig.getClientRole());
|
||||
if (codeRoles.contains(skeletonKeyConfig.getLoginRole())) newRoles.add(skeletonKeyConfig.getLoginRole());
|
||||
if (codeRoles.contains(wildcard)) newRoles.add(wildcard);
|
||||
codeRoles.clear();
|
||||
codeRoles.addAll(newRoles);
|
||||
}
|
||||
|
||||
// is we have a login role, then we don't need to filter out roles, just grant all the roles the user has
|
||||
// Also, if the client has the "wildcard" role, then we don't need to filter out roles
|
||||
if (codeRoles != null
|
||||
&& !gp.hasRole(wildcard)
|
||||
&& !gp.hasRole(skeletonKeyConfig.getLoginRole())) {
|
||||
Set<String> clientAllowed = new HashSet<String>();
|
||||
for (String role : gp.getRoles()) {
|
||||
clientAllowed.add(role);
|
||||
}
|
||||
Set<String> newRoles = new HashSet<String>();
|
||||
newRoles.addAll(codeRoles);
|
||||
for (String role : newRoles) {
|
||||
if (!clientAllowed.contains(role)) {
|
||||
codeRoles.remove(role);
|
||||
}
|
||||
}
|
||||
}
|
||||
AccessTokenResponse res = accessTokenResponse(realmPrivateKey, accessCode.getToken());
|
||||
response.setStatus(200);
|
||||
response.setContentType("application/json");
|
||||
accessTokenResponseWriter.writeValue(response.getOutputStream(), res);
|
||||
response.getOutputStream().flush();
|
||||
}
|
||||
|
||||
protected AccessTokenResponse accessTokenResponse(PrivateKey privateKey, SkeletonKeyToken token) {
|
||||
String encodedToken = buildTokenString(privateKey, token);
|
||||
|
||||
AccessTokenResponse res = new AccessTokenResponse();
|
||||
res.setToken(encodedToken);
|
||||
res.setTokenType("bearer");
|
||||
if (token.getExpiration() != 0) {
|
||||
long time = token.getExpiration() - (System.currentTimeMillis() / 1000);
|
||||
res.setExpiresIn(time);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
protected String buildTokenString(PrivateKey privateKey, SkeletonKeyToken token) {
|
||||
byte[] tokenBytes = null;
|
||||
try {
|
||||
tokenBytes = JsonSerialization.toByteArray(token, false);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return new JWSBuilder()
|
||||
.content(tokenBytes)
|
||||
.rsa256(privateKey);
|
||||
}
|
||||
|
||||
|
||||
protected void handleOAuth(Request request, Response response) throws IOException {
|
||||
log.debug("<--- Begin oauthAuthenticate");
|
||||
String redirect_uri = request.getParameter("redirect_uri");
|
||||
String client_id = request.getParameter("client_id");
|
||||
String state = request.getParameter("state");
|
||||
String username = request.getParameter(Constants.FORM_USERNAME);
|
||||
String password = request.getParameter(Constants.FORM_PASSWORD);
|
||||
Principal principal = context.getRealm().authenticate(username, password);
|
||||
if (principal == null) {
|
||||
UriBuilder builder = UriBuilder.fromUri(redirect_uri).queryParam("error", "unauthorized_client");
|
||||
if (state != null) builder.queryParam("state", state);
|
||||
response.sendRedirect(builder.toTemplate());
|
||||
return;
|
||||
}
|
||||
GenericPrincipal gp = (GenericPrincipal) principal;
|
||||
register(request, response, principal, HttpServletRequest.FORM_AUTH, username, password);
|
||||
userSessionManagement.login(request.getSessionInternal(), username);
|
||||
redirectAccessCode(false, response, redirect_uri, client_id, state, gp);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
protected void tokenGrant(Request request, Response response) throws IOException {
|
||||
if (!request.isSecure()) {
|
||||
response.sendError(400);
|
||||
return;
|
||||
}
|
||||
GenericPrincipal gp = basicAuth(request, response);
|
||||
if (gp == null) return;
|
||||
SkeletonKeyToken token = buildToken(gp);
|
||||
AccessTokenResponse res = accessTokenResponse(realmPrivateKey, token);
|
||||
response.setStatus(200);
|
||||
response.setContentType("application/json");
|
||||
accessTokenResponseWriter.writeValue(response.getOutputStream(), res);
|
||||
response.getOutputStream().flush();
|
||||
}
|
||||
|
||||
protected GenericPrincipal basicAuth(Request request, Response response) throws IOException {
|
||||
String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
if (authHeader == null) {
|
||||
basicAuthError(response);
|
||||
return null;
|
||||
}
|
||||
String[] creds = BasicAuthHelper.parseHeader(authHeader);
|
||||
if (creds == null) {
|
||||
basicAuthError(response);
|
||||
return null;
|
||||
}
|
||||
String username = creds[0];
|
||||
String password = creds[1];
|
||||
GenericPrincipal gp = (GenericPrincipal) context.getRealm().authenticate(username, password);
|
||||
if (gp == null) {
|
||||
basicAuthError(response);
|
||||
return null;
|
||||
}
|
||||
return gp;
|
||||
}
|
||||
|
||||
protected void basicAuthError(Response response) throws IOException {
|
||||
response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"" + context.getLoginConfig().getRealmName() + "\"");
|
||||
response.sendError(401);
|
||||
}
|
||||
|
||||
protected void redirectAccessCode(boolean sso, Response response, String redirect_uri, String client_id, String state, GenericPrincipal gp) throws IOException {
|
||||
SkeletonKeyToken token = buildToken(gp);
|
||||
AccessCode code = new AccessCode();
|
||||
code.setToken(token);
|
||||
code.setClient(client_id);
|
||||
code.setSso(sso);
|
||||
code.setRedirect(redirect_uri);
|
||||
int expiration = skeletonKeyConfig.getAccessCodeLifetime() == 0 ? 300 : skeletonKeyConfig.getAccessCodeLifetime();
|
||||
code.setExpiration((System.currentTimeMillis() / 1000) + expiration);
|
||||
accessCodeMap.put(code.getId(), code);
|
||||
log.debug("--- sign access code");
|
||||
String accessCode = null;
|
||||
try {
|
||||
accessCode = new JWSBuilder().content(code.getId().getBytes("UTF-8")).rsa256(realmPrivateKey);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
log.debug("--- build redirect");
|
||||
UriBuilder redirectUri = UriBuilder.fromUri(redirect_uri).queryParam("code", accessCode);
|
||||
if (state != null) redirectUri.queryParam("state", state);
|
||||
response.sendRedirect(redirectUri.toTemplate());
|
||||
log.debug("<--- end oauthAuthenticate");
|
||||
}
|
||||
|
||||
protected SkeletonKeyToken buildToken(GenericPrincipal gp) {
|
||||
SkeletonKeyToken token = new SkeletonKeyToken();
|
||||
token.id(generateId());
|
||||
token.principal(gp.getName());
|
||||
token.audience(skeletonKeyConfig.getRealm());
|
||||
int expiration = skeletonKeyConfig.getAccessCodeLifetime() == 0 ? 3600 : skeletonKeyConfig.getAccessCodeLifetime();
|
||||
if (skeletonKeyConfig.getTokenLifetime() > 0) {
|
||||
token.expiration((System.currentTimeMillis() / 1000) + expiration);
|
||||
}
|
||||
SkeletonKeyToken.Access realmAccess = new SkeletonKeyToken.Access();
|
||||
for (String role : gp.getRoles()) {
|
||||
realmAccess.addRole(role);
|
||||
}
|
||||
token.setRealmAccess(realmAccess);
|
||||
return token;
|
||||
}
|
||||
|
||||
}
|
|
@ -5,7 +5,6 @@ import org.codehaus.jackson.annotate.JsonPropertyOrder;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
|
|
@ -13,7 +13,6 @@ import org.keycloak.PemUtils;
|
|||
import org.keycloak.ResourceMetadata;
|
||||
import org.keycloak.representations.idm.PublishedRealmRepresentation;
|
||||
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package org.keycloak.models;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
|
|
9
model/api/src/main/java/org/keycloak/models/ModelProvider.java
Executable file
9
model/api/src/main/java/org/keycloak/models/ModelProvider.java
Executable file
|
@ -0,0 +1,9 @@
|
|||
package org.keycloak.models;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface ModelProvider {
|
||||
KeycloakSessionFactory createFactory();
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
package org.keycloak.models;
|
||||
|
||||
import org.keycloak.models.UserModel;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
|
@ -10,8 +8,4 @@ public interface OAuthClientModel {
|
|||
String getId();
|
||||
|
||||
UserModel getOAuthAgent();
|
||||
|
||||
String getBaseUrl();
|
||||
|
||||
void setBaseUrl(String base);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package org.keycloak.models;
|
|||
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -138,11 +137,11 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
|
|||
|
||||
List<OAuthClientModel> getOAuthClients();
|
||||
|
||||
HashMap<String, String> getSmtpConfig();
|
||||
Map<String, String> getSmtpConfig();
|
||||
|
||||
void setSmtpConfig(HashMap<String, String> smtpConfig);
|
||||
void setSmtpConfig(Map<String, String> smtpConfig);
|
||||
|
||||
HashMap<String, String> getSocialConfig();
|
||||
Map<String, String> getSocialConfig();
|
||||
|
||||
void setSocialConfig(HashMap<String, String> socialConfig);
|
||||
void setSocialConfig(Map<String, String> socialConfig);
|
||||
}
|
||||
|
|
113
model/api/src/main/java/org/keycloak/models/utils/Base32.java
Executable file
113
model/api/src/main/java/org/keycloak/models/utils/Base32.java
Executable file
|
@ -0,0 +1,113 @@
|
|||
package org.keycloak.models.utils;
|
||||
|
||||
|
||||
/* (PD) 2006 The Bitzi Corporation
|
||||
* Please see http://bitzi.com/publicdomain for more info.
|
||||
*
|
||||
* $Id: Base32.java,v 1.2 2006/07/14 04:58:39 gojomo Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base32 - encodes and decodes RFC3548 Base32 (see http://www.faqs.org/rfcs/rfc3548.html )
|
||||
*
|
||||
* @author Robert Kaye
|
||||
* @author Gordon Mohr
|
||||
*/
|
||||
public class Base32 {
|
||||
private static final String base32Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
private static final int[] base32Lookup = { 0xFF, 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
|
||||
0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
|
||||
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,
|
||||
0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
|
||||
/**
|
||||
* Encodes byte array to Base32 String.
|
||||
*
|
||||
* @param bytes Bytes to encode.
|
||||
* @return Encoded byte array <code>bytes</code> as a String.
|
||||
*
|
||||
*/
|
||||
public static String encode(final byte[] bytes) {
|
||||
int i = 0, index = 0, digit = 0;
|
||||
int currByte, nextByte;
|
||||
StringBuffer base32 = new StringBuffer((bytes.length + 7) * 8 / 5);
|
||||
|
||||
while (i < bytes.length) {
|
||||
currByte = (bytes[i] >= 0) ? bytes[i] : (bytes[i] + 256);
|
||||
|
||||
/* Is the current digit going to span a byte boundary? */
|
||||
if (index > 3) {
|
||||
if ((i + 1) < bytes.length) {
|
||||
nextByte = (bytes[i + 1] >= 0) ? bytes[i + 1] : (bytes[i + 1] + 256);
|
||||
} else {
|
||||
nextByte = 0;
|
||||
}
|
||||
|
||||
digit = currByte & (0xFF >> index);
|
||||
index = (index + 5) % 8;
|
||||
digit <<= index;
|
||||
digit |= nextByte >> (8 - index);
|
||||
i++;
|
||||
} else {
|
||||
digit = (currByte >> (8 - (index + 5))) & 0x1F;
|
||||
index = (index + 5) % 8;
|
||||
if (index == 0)
|
||||
i++;
|
||||
}
|
||||
base32.append(base32Chars.charAt(digit));
|
||||
}
|
||||
|
||||
return base32.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the given Base32 String to a raw byte array.
|
||||
*
|
||||
* @param base32
|
||||
* @return Decoded <code>base32</code> String as a raw byte array.
|
||||
*/
|
||||
public static byte[] decode(final String base32) {
|
||||
int i, index, lookup, offset, digit;
|
||||
byte[] bytes = new byte[base32.length() * 5 / 8];
|
||||
|
||||
for (i = 0, index = 0, offset = 0; i < base32.length(); i++) {
|
||||
lookup = base32.charAt(i) - '0';
|
||||
|
||||
/* Skip chars outside the lookup table */
|
||||
if (lookup < 0 || lookup >= base32Lookup.length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
digit = base32Lookup[lookup];
|
||||
|
||||
/* If this digit is not in the table, ignore it */
|
||||
if (digit == 0xFF) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (index <= 3) {
|
||||
index = (index + 5) % 8;
|
||||
if (index == 0) {
|
||||
bytes[offset] |= digit;
|
||||
offset++;
|
||||
if (offset >= bytes.length)
|
||||
break;
|
||||
} else {
|
||||
bytes[offset] |= digit << (8 - index);
|
||||
}
|
||||
} else {
|
||||
index = (index + 5) % 8;
|
||||
bytes[offset] |= (digit >>> index);
|
||||
offset++;
|
||||
|
||||
if (offset >= bytes.length) {
|
||||
break;
|
||||
}
|
||||
bytes[offset] |= digit << (8 - index);
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
}
|
2282
model/api/src/main/java/org/keycloak/models/utils/Base64.java
Executable file
2282
model/api/src/main/java/org/keycloak/models/utils/Base64.java
Executable file
File diff suppressed because it is too large
Load diff
58
model/api/src/main/java/org/keycloak/models/utils/SHAPasswordEncoder.java
Executable file
58
model/api/src/main/java/org/keycloak/models/utils/SHAPasswordEncoder.java
Executable file
|
@ -0,0 +1,58 @@
|
|||
package org.keycloak.models.utils;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Password that uses SHA to encode passwords. You can always change the SHA strength by specifying a valid
|
||||
* integer when creating a new instance.
|
||||
* </p>
|
||||
* <p>Passwords are returned with a Base64 encoding.</p>
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Silva</a>
|
||||
*
|
||||
*/
|
||||
public class SHAPasswordEncoder {
|
||||
|
||||
private int strength;
|
||||
|
||||
public SHAPasswordEncoder(int strength) {
|
||||
this.strength = strength;
|
||||
}
|
||||
|
||||
public String encode(String rawPassword) {
|
||||
MessageDigest messageDigest = getMessageDigest();
|
||||
|
||||
String encodedPassword = null;
|
||||
|
||||
try {
|
||||
byte[] digest = messageDigest.digest(rawPassword.getBytes("UTF-8"));
|
||||
encodedPassword = Base64.encodeBytes(digest);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException("Credential could not be encoded");
|
||||
}
|
||||
|
||||
return encodedPassword;
|
||||
}
|
||||
|
||||
public boolean verify(String rawPassword, String encodedPassword) {
|
||||
return encode(rawPassword).equals(encodedPassword);
|
||||
}
|
||||
|
||||
protected final MessageDigest getMessageDigest() throws IllegalArgumentException {
|
||||
String algorithm = "SHA-" + this.strength;
|
||||
|
||||
try {
|
||||
return MessageDigest.getInstance(algorithm);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException("invalid credential encoding algorithm");
|
||||
}
|
||||
}
|
||||
|
||||
public int getStrength() {
|
||||
return this.strength;
|
||||
}
|
||||
}
|
216
model/api/src/main/java/org/keycloak/models/utils/TimeBasedOTP.java
Executable file
216
model/api/src/main/java/org/keycloak/models/utils/TimeBasedOTP.java
Executable file
|
@ -0,0 +1,216 @@
|
|||
package org.keycloak.models.utils;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* TOTP: Time-based One-time Password Algorithm Based on http://tools.ietf.org/html/draft-mraihi-totp-timebased-06
|
||||
*
|
||||
* @author anil saldhana
|
||||
* @since Sep 20, 2010
|
||||
*/
|
||||
public class TimeBasedOTP {
|
||||
|
||||
public static final String HMAC_SHA1 = "HmacSHA1";
|
||||
public static final String HMAC_SHA256 = "HmacSHA256";
|
||||
public static final String HMAC_SHA512 = "HmacSHA512";
|
||||
|
||||
public static final String DEFAULT_ALGORITHM = HMAC_SHA1;
|
||||
public static final int DEFAULT_NUMBER_DIGITS = 6;
|
||||
public static final int DEFAULT_INTERVAL_SECONDS = 30;
|
||||
public static final int DEFAULT_DELAY_WINDOW = 1;
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
private static final int[] DIGITS_POWER = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
|
||||
|
||||
private Clock clock;
|
||||
private final String algorithm;
|
||||
private final int numberDigits;
|
||||
private final int delayWindow;
|
||||
|
||||
public TimeBasedOTP() {
|
||||
this(DEFAULT_ALGORITHM, DEFAULT_NUMBER_DIGITS, DEFAULT_INTERVAL_SECONDS, DEFAULT_DELAY_WINDOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param algorithm the encryption algorithm
|
||||
* @param numberDigits the number of digits for tokens
|
||||
* @param timeIntervalInSeconds the number of seconds a token is valid
|
||||
* @param delayWindow the number of previous intervals that should be used to validate tokens.
|
||||
*/
|
||||
public TimeBasedOTP(String algorithm, int numberDigits, int timeIntervalInSeconds, int delayWindow) {
|
||||
this.algorithm = algorithm;
|
||||
this.numberDigits = numberDigits;
|
||||
this.clock = new Clock(timeIntervalInSeconds);
|
||||
this.delayWindow = delayWindow;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Generates a token.</p>
|
||||
*
|
||||
* @param secretKey the secret key to derive the token from.
|
||||
*/
|
||||
public String generate(String secretKey) {
|
||||
long T = this.clock.getCurrentInterval();
|
||||
|
||||
String steps = Long.toHexString(T).toUpperCase();
|
||||
|
||||
// Just get a 16 digit string
|
||||
while (steps.length() < 16)
|
||||
steps = "0" + steps;
|
||||
|
||||
return generateTOTP(secretKey, steps, this.numberDigits, this.algorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method generates an TOTP value for the given set of parameters.
|
||||
*
|
||||
* @param key the shared secret, HEX encoded
|
||||
* @param time a value that reflects a time
|
||||
* @param returnDigits number of digits to return
|
||||
* @param crypto the crypto function to use
|
||||
* @return A numeric String in base 10 that includes {@link truncationDigits} digits
|
||||
* @throws java.security.GeneralSecurityException
|
||||
*
|
||||
*/
|
||||
public String generateTOTP(String key, String time, int returnDigits, String crypto) {
|
||||
String result = null;
|
||||
byte[] hash;
|
||||
|
||||
// Using the counter
|
||||
// First 8 bytes are for the movingFactor
|
||||
// Complaint with base RFC 4226 (HOTP)
|
||||
while (time.length() < 16)
|
||||
time = "0" + time;
|
||||
|
||||
// Get the HEX in a Byte[]
|
||||
byte[] msg = hexStr2Bytes(time);
|
||||
|
||||
// Adding one byte to get the right conversion
|
||||
// byte[] k = hexStr2Bytes(key);
|
||||
byte[] k = key.getBytes();
|
||||
|
||||
hash = hmac_sha1(crypto, k, msg);
|
||||
|
||||
// put selected bytes into result int
|
||||
int offset = hash[hash.length - 1] & 0xf;
|
||||
|
||||
int binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) | ((hash[offset + 2] & 0xff) << 8)
|
||||
| (hash[offset + 3] & 0xff);
|
||||
|
||||
int otp = binary % DIGITS_POWER[returnDigits];
|
||||
|
||||
result = Integer.toString(otp);
|
||||
|
||||
while (result.length() < returnDigits) {
|
||||
result = "0" + result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Validates a token using a secret key.</p>
|
||||
*
|
||||
* @param token OTP string to validate
|
||||
* @param secret Shared secret
|
||||
* @return
|
||||
*/
|
||||
public boolean validate(String token, byte[] secret) {
|
||||
long currentInterval = this.clock.getCurrentInterval();
|
||||
|
||||
for (int i = this.delayWindow; i >= 0; --i) {
|
||||
String steps = Long.toHexString(currentInterval - i).toUpperCase();
|
||||
|
||||
// Just get a 16 digit string
|
||||
while (steps.length() < 16)
|
||||
steps = "0" + steps;
|
||||
|
||||
String candidate = generateTOTP(new String(secret), steps, this.numberDigits, this.algorithm);
|
||||
|
||||
if (candidate.equals(token)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setCalendar(Calendar calendar) {
|
||||
this.clock.setCalendar(calendar);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method uses the JCE to provide the crypto algorithm. HMAC computes a Hashed Message Authentication Code with the
|
||||
* crypto hash algorithm as a parameter.
|
||||
*
|
||||
* @param crypto the crypto algorithm (HmacSHA1, HmacSHA256, HmacSHA512)
|
||||
* @param keyBytes the bytes to use for the HMAC key
|
||||
* @param text the message or text to be authenticated.
|
||||
* @throws java.security.NoSuchAlgorithmException
|
||||
*
|
||||
* @throws java.security.InvalidKeyException
|
||||
*
|
||||
*/
|
||||
private byte[] hmac_sha1(String crypto, byte[] keyBytes, byte[] text) {
|
||||
byte[] value;
|
||||
|
||||
try {
|
||||
Mac hmac = Mac.getInstance(crypto);
|
||||
SecretKeySpec macKey = new SecretKeySpec(keyBytes, "RAW");
|
||||
|
||||
hmac.init(macKey);
|
||||
|
||||
value = hmac.doFinal(text);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method converts HEX string to Byte[]
|
||||
*
|
||||
* @param hex the HEX string
|
||||
* @return A byte array
|
||||
*/
|
||||
private byte[] hexStr2Bytes(String hex) {
|
||||
// Adding one byte to get the right conversion
|
||||
// values starting with "0" can be converted
|
||||
byte[] bArray = new BigInteger("10" + hex, 16).toByteArray();
|
||||
|
||||
// Copy all the REAL bytes, not the "first"
|
||||
byte[] ret = new byte[bArray.length - 1];
|
||||
for (int i = 0; i < ret.length; i++)
|
||||
ret[i] = bArray[i + 1];
|
||||
return ret;
|
||||
}
|
||||
|
||||
private class Clock {
|
||||
|
||||
private final int interval;
|
||||
private Calendar calendar;
|
||||
|
||||
public Clock(int interval) {
|
||||
this.interval = interval;
|
||||
}
|
||||
|
||||
public long getCurrentInterval() {
|
||||
Calendar currentCalendar = this.calendar;
|
||||
|
||||
if (currentCalendar == null) {
|
||||
currentCalendar = GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||
}
|
||||
|
||||
return (currentCalendar.getTimeInMillis() / 1000) / this.interval;
|
||||
}
|
||||
|
||||
public void setCalendar(Calendar calendar) {
|
||||
this.calendar = calendar;
|
||||
}
|
||||
}
|
||||
}
|
275
model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
Executable file
275
model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
Executable file
|
@ -0,0 +1,275 @@
|
|||
package org.keycloak.models.jpa;
|
||||
|
||||
import org.keycloak.models.ApplicationModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.jpa.entities.ApplicationEntity;
|
||||
import org.keycloak.models.jpa.entities.ApplicationScopeMappingEntity;
|
||||
import org.keycloak.models.jpa.entities.ApplicationUserRoleMappingEntity;
|
||||
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class ApplicationAdapter implements ApplicationModel {
|
||||
|
||||
protected EntityManager em;
|
||||
protected ApplicationEntity application;
|
||||
|
||||
public ApplicationAdapter(EntityManager em, ApplicationEntity application) {
|
||||
this.em = em;
|
||||
this.application = application;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateApplication() {
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserModel getApplicationUser() {
|
||||
return new UserAdapter(application.getApplicationUser());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return application.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return application.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
application.setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return application.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
application.setEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSurrogateAuthRequired() {
|
||||
return application.isSurrogateAuthRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
|
||||
application.setSurrogateAuthRequired(surrogateAuthRequired);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getManagementUrl() {
|
||||
return application.getManagementUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setManagementUrl(String url) {
|
||||
application.setManagementUrl(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseUrl() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBaseUrl(String url) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel getRole(String name) {
|
||||
Collection<RoleEntity> roles = application.getRoles();
|
||||
if (roles == null) return null;
|
||||
for (RoleEntity role : roles) {
|
||||
if (role.getName().equals(name)) {
|
||||
return new RoleAdapter(role);
|
||||
}
|
||||
}
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addRole(String name) {
|
||||
RoleModel role = getRole(name);
|
||||
if (role != null) return role;
|
||||
RoleEntity entity = new RoleEntity();
|
||||
entity.setName(name);
|
||||
em.persist(entity);
|
||||
application.getRoles().add(entity);
|
||||
em.flush();
|
||||
return new RoleAdapter(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoleModel> getRoles() {
|
||||
ArrayList<RoleModel> list = new ArrayList<RoleModel>();
|
||||
Collection<RoleEntity> roles = application.getRoles();
|
||||
if (roles == null) return list;
|
||||
for (RoleEntity entity : roles) {
|
||||
list.add(new RoleAdapter(entity));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel getRoleById(String id) {
|
||||
RoleEntity entity = em.find(RoleEntity.class, id);
|
||||
if (entity == null) return null;
|
||||
return new RoleAdapter(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRole(UserModel user, RoleModel role) {
|
||||
TypedQuery<ApplicationUserRoleMappingEntity> query = getApplicationUserRoleMappingEntityTypedQuery((UserAdapter) user, (RoleAdapter) role);
|
||||
return query.getResultList().size() > 0;
|
||||
}
|
||||
|
||||
protected TypedQuery<ApplicationUserRoleMappingEntity> getApplicationUserRoleMappingEntityTypedQuery(UserAdapter user, RoleAdapter role) {
|
||||
TypedQuery<ApplicationUserRoleMappingEntity> query = em.createNamedQuery("userHasApplicationRole", ApplicationUserRoleMappingEntity.class);
|
||||
query.setParameter("user", ((UserAdapter)user).getUser());
|
||||
query.setParameter("role", ((RoleAdapter)role).getRole());
|
||||
query.setParameter("application", application);
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grantRole(UserModel user, RoleModel role) {
|
||||
if (hasRole(user, role)) return;
|
||||
ApplicationUserRoleMappingEntity entity = new ApplicationUserRoleMappingEntity();
|
||||
entity.setApplication(application);
|
||||
entity.setUser(((UserAdapter) user).getUser());
|
||||
entity.setRole(((RoleAdapter)role).getRole());
|
||||
em.persist(entity);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoleModel> getRoleMappings(UserModel user) {
|
||||
TypedQuery<ApplicationUserRoleMappingEntity> query = em.createNamedQuery("userApplicationMappings", ApplicationUserRoleMappingEntity.class);
|
||||
query.setParameter("user", ((UserAdapter)user).getUser());
|
||||
query.setParameter("application", application);
|
||||
List<ApplicationUserRoleMappingEntity> entities = query.getResultList();
|
||||
List<RoleModel> roles = new ArrayList<RoleModel>();
|
||||
for (ApplicationUserRoleMappingEntity entity : entities) {
|
||||
roles.add(new RoleAdapter(entity.getRole()));
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRoleMappingValues(UserModel user) {
|
||||
TypedQuery<ApplicationUserRoleMappingEntity> query = em.createNamedQuery("userApplicationMappings", ApplicationUserRoleMappingEntity.class);
|
||||
query.setParameter("user", ((UserAdapter)user).getUser());
|
||||
query.setParameter("application", application);
|
||||
List<ApplicationUserRoleMappingEntity> entities = query.getResultList();
|
||||
Set<String> roles = new HashSet<String>();
|
||||
for (ApplicationUserRoleMappingEntity entity : entities) {
|
||||
roles.add(entity.getRole().getName());
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRoleMapping(UserModel user, RoleModel role) {
|
||||
TypedQuery<ApplicationUserRoleMappingEntity> query = getApplicationUserRoleMappingEntityTypedQuery((UserAdapter) user, (RoleAdapter) role);
|
||||
List<ApplicationUserRoleMappingEntity> results = query.getResultList();
|
||||
if (results.size() == 0) return;
|
||||
for (ApplicationUserRoleMappingEntity entity : results) {
|
||||
em.remove(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRole(UserModel user, String roleName) {
|
||||
RoleModel role = getRole(roleName);
|
||||
if (role == null) return false;
|
||||
return hasRole(user, role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addScopeMapping(UserModel agent, String roleName) {
|
||||
RoleModel role = getRole(roleName);
|
||||
if (role == null) throw new RuntimeException("role does not exist");
|
||||
addScopeMapping(agent, role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getScopeMappingValues(UserModel agent) {
|
||||
TypedQuery<ApplicationScopeMappingEntity> query = em.createNamedQuery("userApplicationScopeMappings", ApplicationScopeMappingEntity.class);
|
||||
query.setParameter("user", ((UserAdapter)agent).getUser());
|
||||
query.setParameter("application", application);
|
||||
List<ApplicationScopeMappingEntity> entities = query.getResultList();
|
||||
Set<String> roles = new HashSet<String>();
|
||||
for (ApplicationScopeMappingEntity entity : entities) {
|
||||
roles.add(entity.getRole().getName());
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoleModel> getScopeMappings(UserModel agent) {
|
||||
TypedQuery<ApplicationScopeMappingEntity> query = em.createNamedQuery("userApplicationScopeMappings", ApplicationScopeMappingEntity.class);
|
||||
query.setParameter("user", ((UserAdapter)agent).getUser());
|
||||
query.setParameter("application", application);
|
||||
List<ApplicationScopeMappingEntity> entities = query.getResultList();
|
||||
List<RoleModel> roles = new ArrayList<RoleModel>();
|
||||
for (ApplicationScopeMappingEntity entity : entities) {
|
||||
roles.add(new RoleAdapter(entity.getRole()));
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addScopeMapping(UserModel agent, RoleModel role) {
|
||||
if (hasScope(agent, role)) return;
|
||||
ApplicationScopeMappingEntity entity = new ApplicationScopeMappingEntity();
|
||||
entity.setApplication(application);
|
||||
entity.setUser(((UserAdapter) agent).getUser());
|
||||
entity.setRole(((RoleAdapter)role).getRole());
|
||||
em.persist(entity);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteScopeMapping(UserModel user, RoleModel role) {
|
||||
TypedQuery<ApplicationScopeMappingEntity> query = getApplicationScopeMappingQuery((UserAdapter) user, (RoleAdapter) role);
|
||||
List<ApplicationScopeMappingEntity> results = query.getResultList();
|
||||
if (results.size() == 0) return;
|
||||
for (ApplicationScopeMappingEntity entity : results) {
|
||||
em.remove(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasScope(UserModel user, RoleModel role) {
|
||||
TypedQuery<ApplicationScopeMappingEntity> query = getApplicationScopeMappingQuery((UserAdapter) user, (RoleAdapter) role);
|
||||
return query.getResultList().size() > 0;
|
||||
}
|
||||
|
||||
|
||||
protected TypedQuery<ApplicationScopeMappingEntity> getApplicationScopeMappingQuery(UserAdapter user, RoleAdapter role) {
|
||||
TypedQuery<ApplicationScopeMappingEntity> query = em.createNamedQuery("userHasApplicationScope", ApplicationScopeMappingEntity.class);
|
||||
query.setParameter("user", ((UserAdapter)user).getUser());
|
||||
query.setParameter("role", ((RoleAdapter)role).getRole());
|
||||
query.setParameter("application", application);
|
||||
return query;
|
||||
}
|
||||
|
||||
}
|
74
model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java
Executable file
74
model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java
Executable file
|
@ -0,0 +1,74 @@
|
|||
package org.keycloak.models.jpa;
|
||||
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakTransaction;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.jpa.entities.RealmEntity;
|
||||
import org.keycloak.models.utils.KeycloakSessionUtils;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class JpaKeycloakSession implements KeycloakSession {
|
||||
protected EntityManager em;
|
||||
|
||||
public JpaKeycloakSession(EntityManager em) {
|
||||
this.em = em;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeycloakTransaction getTransaction() {
|
||||
return new JpaKeycloakTransaction(em);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RealmModel createRealm(String name) {
|
||||
return createRealm(KeycloakSessionUtils.generateId(), name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RealmModel createRealm(String id, String name) {
|
||||
RealmEntity realm = new RealmEntity();
|
||||
realm.setName(name);
|
||||
realm.setId(id);
|
||||
em.persist(realm);
|
||||
em.flush();
|
||||
return new RealmAdapter(em, realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RealmModel getRealm(String id) {
|
||||
RealmEntity realm = em.find(RealmEntity.class, id);
|
||||
if (realm == null) return null;
|
||||
return new RealmAdapter(em, realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RealmModel> getRealms(UserModel admin) {
|
||||
TypedQuery<RealmEntity> query = em.createQuery("select r from RealmEntity r", RealmEntity.class);
|
||||
List<RealmEntity> entities = query.getResultList();
|
||||
List<RealmModel> realms = new ArrayList<RealmModel>();
|
||||
for (RealmEntity entity : entities) {
|
||||
realms.add(new RealmAdapter(em, entity));
|
||||
}
|
||||
return realms;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRealm(RealmModel realm) {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (em.getTransaction().isActive()) em.getTransaction().rollback();
|
||||
if (em.isOpen()) em.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package org.keycloak.models.jpa;
|
||||
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class JpaKeycloakSessionFactory implements KeycloakSessionFactory {
|
||||
protected EntityManagerFactory factory;
|
||||
|
||||
public JpaKeycloakSessionFactory(EntityManagerFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeycloakSession createSession() {
|
||||
return new JpaKeycloakSession(factory.createEntityManager());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
factory.close();
|
||||
}
|
||||
}
|
48
model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakTransaction.java
Executable file
48
model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakTransaction.java
Executable file
|
@ -0,0 +1,48 @@
|
|||
package org.keycloak.models.jpa;
|
||||
|
||||
import org.keycloak.models.KeycloakTransaction;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class JpaKeycloakTransaction implements KeycloakTransaction {
|
||||
|
||||
protected EntityManager em;
|
||||
|
||||
public JpaKeycloakTransaction(EntityManager em) {
|
||||
this.em = em;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin() {
|
||||
em.getTransaction().begin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() {
|
||||
em.getTransaction().commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() {
|
||||
em.getTransaction().rollback();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRollbackOnly() {
|
||||
em.getTransaction().setRollbackOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRollbackOnly() {
|
||||
return em.getTransaction().getRollbackOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return em.getTransaction().isActive();
|
||||
}
|
||||
}
|
20
model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java
Executable file
20
model/jpa/src/main/java/org/keycloak/models/jpa/JpaModelProvider.java
Executable file
|
@ -0,0 +1,20 @@
|
|||
package org.keycloak.models.jpa;
|
||||
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.ModelProvider;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class JpaModelProvider implements ModelProvider {
|
||||
@Override
|
||||
public KeycloakSessionFactory createFactory() {
|
||||
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa-keycloak-identity-store");
|
||||
return new JpaKeycloakSessionFactory(emf);
|
||||
|
||||
}
|
||||
}
|
32
model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
Executable file
32
model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
Executable file
|
@ -0,0 +1,32 @@
|
|||
package org.keycloak.models.jpa;
|
||||
|
||||
import org.keycloak.models.OAuthClientModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.jpa.entities.OAuthClientEntity;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class OAuthClientAdapter implements OAuthClientModel {
|
||||
protected OAuthClientEntity entity;
|
||||
|
||||
public OAuthClientAdapter(OAuthClientEntity entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public OAuthClientEntity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return entity.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserModel getOAuthAgent() {
|
||||
return new UserAdapter(entity.getAgent());
|
||||
}
|
||||
|
||||
}
|
954
model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
Executable file
954
model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
Executable file
|
@ -0,0 +1,954 @@
|
|||
package org.keycloak.models.jpa;
|
||||
|
||||
import org.bouncycastle.openssl.PEMWriter;
|
||||
import org.keycloak.PemUtils;
|
||||
import org.keycloak.models.ApplicationModel;
|
||||
import org.keycloak.models.OAuthClientModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RequiredCredentialModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.SocialLinkModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.jpa.entities.ApplicationEntity;
|
||||
import org.keycloak.models.jpa.entities.CredentialEntity;
|
||||
import org.keycloak.models.jpa.entities.OAuthClientEntity;
|
||||
import org.keycloak.models.jpa.entities.RealmEntity;
|
||||
import org.keycloak.models.jpa.entities.RealmScopeMappingEntity;
|
||||
import org.keycloak.models.jpa.entities.RealmUserRoleMappingEntity;
|
||||
import org.keycloak.models.jpa.entities.RequiredCredentialEntity;
|
||||
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||
import org.keycloak.models.jpa.entities.SocialLinkEntity;
|
||||
import org.keycloak.models.jpa.entities.UserEntity;
|
||||
import org.keycloak.models.utils.SHAPasswordEncoder;
|
||||
import org.keycloak.models.utils.TimeBasedOTP;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class RealmAdapter implements RealmModel {
|
||||
protected RealmEntity realm;
|
||||
protected EntityManager em;
|
||||
protected volatile transient PublicKey publicKey;
|
||||
protected volatile transient PrivateKey privateKey;
|
||||
|
||||
public RealmAdapter(EntityManager em, RealmEntity realm) {
|
||||
this.em = em;
|
||||
this.realm = realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return realm.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return realm.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
realm.setName(name);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return realm.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
realm.setEnabled(enabled);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSslNotRequired() {
|
||||
return realm.isSslNotRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSslNotRequired(boolean sslNotRequired) {
|
||||
realm.setSslNotRequired(sslNotRequired);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCookieLoginAllowed() {
|
||||
return realm.isCookieLoginAllowed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCookieLoginAllowed(boolean cookieLoginAllowed) {
|
||||
realm.setCookieLoginAllowed(cookieLoginAllowed);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegistrationAllowed() {
|
||||
return realm.isRegistrationAllowed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRegistrationAllowed(boolean registrationAllowed) {
|
||||
realm.setRegistrationAllowed(registrationAllowed);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVerifyEmail() {
|
||||
return realm.isVerifyEmail();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVerifyEmail(boolean verifyEmail) {
|
||||
realm.setVerifyEmail(verifyEmail);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResetPasswordAllowed() {
|
||||
return realm.isResetPasswordAllowed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
|
||||
realm.setResetPasswordAllowed(resetPasswordAllowed);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTokenLifespan() {
|
||||
return realm.getTokenLifespan();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTokenLifespan(int tokenLifespan) {
|
||||
realm.setTokenLifespan(tokenLifespan);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAccessCodeLifespan() {
|
||||
return realm.getAccessCodeLifespan();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccessCodeLifespan(int accessCodeLifespan) {
|
||||
realm.setAccessCodeLifespan(accessCodeLifespan);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAccessCodeLifespanUserAction() {
|
||||
return realm.getAccessCodeLifespanUserAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
|
||||
realm.setAccessCodeLifespanUserAction(accessCodeLifespanUserAction);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPublicKeyPem() {
|
||||
return realm.getPublicKeyPem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPublicKeyPem(String publicKeyPem) {
|
||||
realm.setPublicKeyPem(publicKeyPem);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrivateKeyPem() {
|
||||
return realm.getPrivateKeyPem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrivateKeyPem(String privateKeyPem) {
|
||||
realm.setPrivateKeyPem(privateKeyPem);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicKey getPublicKey() {
|
||||
if (publicKey != null) return publicKey;
|
||||
String pem = getPublicKeyPem();
|
||||
if (pem != null) {
|
||||
try {
|
||||
publicKey = PemUtils.decodePublicKey(pem);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPublicKey(PublicKey publicKey) {
|
||||
this.publicKey = publicKey;
|
||||
StringWriter writer = new StringWriter();
|
||||
PEMWriter pemWriter = new PEMWriter(writer);
|
||||
try {
|
||||
pemWriter.writeObject(publicKey);
|
||||
pemWriter.flush();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String s = writer.toString();
|
||||
setPublicKeyPem(PemUtils.removeBeginEnd(s));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrivateKey getPrivateKey() {
|
||||
if (privateKey != null) return privateKey;
|
||||
String pem = getPrivateKeyPem();
|
||||
if (pem != null) {
|
||||
try {
|
||||
privateKey = PemUtils.decodePrivateKey(pem);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrivateKey(PrivateKey privateKey) {
|
||||
this.privateKey = privateKey;
|
||||
StringWriter writer = new StringWriter();
|
||||
PEMWriter pemWriter = new PEMWriter(writer);
|
||||
try {
|
||||
pemWriter.writeObject(privateKey);
|
||||
pemWriter.flush();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String s = writer.toString();
|
||||
setPrivateKeyPem(PemUtils.removeBeginEnd(s));
|
||||
}
|
||||
|
||||
protected RequiredCredentialModel initRequiredCredentialModel(String type) {
|
||||
RequiredCredentialModel model = RequiredCredentialModel.BUILT_IN.get(type);
|
||||
if (model == null) {
|
||||
throw new RuntimeException("Unknown credential type " + type);
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRequiredCredential(String type) {
|
||||
RequiredCredentialModel model = initRequiredCredentialModel(type);
|
||||
addRequiredCredential(model);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
public void addRequiredCredential(RequiredCredentialModel model) {
|
||||
RequiredCredentialEntity entity = new RequiredCredentialEntity();
|
||||
entity.setInput(model.isInput());
|
||||
entity.setSecret(model.isSecret());
|
||||
entity.setType(model.getType());
|
||||
entity.setFormLabel(model.getFormLabel());
|
||||
em.persist(entity);
|
||||
realm.getRequiredCredentials().add(entity);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRequiredCredentials(Set<String> creds) {
|
||||
Collection<RequiredCredentialEntity> relationships = realm.getRequiredCredentials();
|
||||
if (relationships == null) relationships = new ArrayList<RequiredCredentialEntity>();
|
||||
|
||||
Set<String> already = new HashSet<String>();
|
||||
List<RequiredCredentialEntity> remove = new ArrayList<RequiredCredentialEntity>();
|
||||
for (RequiredCredentialEntity rel : relationships) {
|
||||
if (!creds.contains(rel.getType())) {
|
||||
remove.add(rel);
|
||||
} else {
|
||||
already.add(rel.getType());
|
||||
}
|
||||
}
|
||||
for (RequiredCredentialEntity entity : remove) {
|
||||
relationships.remove(entity);
|
||||
em.remove(entity);
|
||||
}
|
||||
for (String cred : creds) {
|
||||
if (!already.contains(cred)) {
|
||||
addRequiredCredential(cred);
|
||||
}
|
||||
}
|
||||
em.flush();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<RequiredCredentialModel> getRequiredCredentials() {
|
||||
List<RequiredCredentialModel> requiredCredentialModels = new ArrayList<RequiredCredentialModel>();
|
||||
Collection<RequiredCredentialEntity> entities = realm.getRequiredCredentials();
|
||||
if (entities == null) return requiredCredentialModels;
|
||||
for (RequiredCredentialEntity entity : entities) {
|
||||
RequiredCredentialModel model = new RequiredCredentialModel();
|
||||
model.setFormLabel(entity.getFormLabel());
|
||||
model.setType(entity.getType());
|
||||
model.setSecret(entity.isSecret());
|
||||
model.setInput(entity.isInput());
|
||||
requiredCredentialModels.add(model);
|
||||
}
|
||||
return requiredCredentialModels; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RequiredCredentialModel> getRequiredApplicationCredentials() {
|
||||
List<RequiredCredentialModel> requiredCredentialModels = new ArrayList<RequiredCredentialModel>();
|
||||
Collection<RequiredCredentialEntity> entities = realm.getRequiredApplicationCredentials();
|
||||
if (entities == null) return requiredCredentialModels;
|
||||
for (RequiredCredentialEntity entity : entities) {
|
||||
RequiredCredentialModel model = new RequiredCredentialModel();
|
||||
model.setFormLabel(entity.getFormLabel());
|
||||
model.setType(entity.getType());
|
||||
model.setSecret(entity.isSecret());
|
||||
model.setInput(entity.isInput());
|
||||
requiredCredentialModels.add(model);
|
||||
}
|
||||
return requiredCredentialModels; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RequiredCredentialModel> getRequiredOAuthClientCredentials() {
|
||||
List<RequiredCredentialModel> requiredCredentialModels = new ArrayList<RequiredCredentialModel>();
|
||||
Collection<RequiredCredentialEntity> entities = realm.getRequiredOAuthClientCredentials();
|
||||
if (entities == null) return requiredCredentialModels;
|
||||
for (RequiredCredentialEntity entity : entities) {
|
||||
RequiredCredentialModel model = new RequiredCredentialModel();
|
||||
model.setFormLabel(entity.getFormLabel());
|
||||
model.setType(entity.getType());
|
||||
model.setSecret(entity.isSecret());
|
||||
model.setInput(entity.isInput());
|
||||
requiredCredentialModels.add(model);
|
||||
}
|
||||
return requiredCredentialModels; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
public void addRequiredOAuthClientCredential(RequiredCredentialModel model) {
|
||||
RequiredCredentialEntity entity = new RequiredCredentialEntity();
|
||||
entity.setInput(model.isInput());
|
||||
entity.setSecret(model.isSecret());
|
||||
entity.setType(model.getType());
|
||||
entity.setFormLabel(model.getFormLabel());
|
||||
em.persist(entity);
|
||||
realm.getRequiredOAuthClientCredentials().add(entity);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRequiredOAuthClientCredential(String type) {
|
||||
RequiredCredentialModel model = initRequiredCredentialModel(type);
|
||||
addRequiredOAuthClientCredential(model);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
public void addRequiredResourceCredential(RequiredCredentialModel model) {
|
||||
RequiredCredentialEntity entity = new RequiredCredentialEntity();
|
||||
entity.setInput(model.isInput());
|
||||
entity.setSecret(model.isSecret());
|
||||
entity.setType(model.getType());
|
||||
entity.setFormLabel(model.getFormLabel());
|
||||
em.persist(entity);
|
||||
realm.getRequiredApplicationCredentials().add(entity);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRequiredResourceCredential(String type) {
|
||||
RequiredCredentialModel model = initRequiredCredentialModel(type);
|
||||
addRequiredResourceCredential(model);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRequiredOAuthClientCredentials(Set<String> creds) {
|
||||
Collection<RequiredCredentialEntity> relationships = realm.getRequiredOAuthClientCredentials();
|
||||
if (relationships == null) relationships = new ArrayList<RequiredCredentialEntity>();
|
||||
|
||||
Set<String> already = new HashSet<String>();
|
||||
List<RequiredCredentialEntity> remove = new ArrayList<RequiredCredentialEntity>();
|
||||
for (RequiredCredentialEntity rel : relationships) {
|
||||
if (!creds.contains(rel.getType())) {
|
||||
remove.add(rel);
|
||||
} else {
|
||||
already.add(rel.getType());
|
||||
}
|
||||
}
|
||||
for (RequiredCredentialEntity entity : remove) {
|
||||
relationships.remove(entity);
|
||||
em.remove(entity);
|
||||
}
|
||||
for (String cred : creds) {
|
||||
if (!already.contains(cred)) {
|
||||
addRequiredOAuthClientCredential(cred);
|
||||
}
|
||||
}
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRequiredApplicationCredentials(Set<String> creds) {
|
||||
Collection<RequiredCredentialEntity> relationships = realm.getRequiredApplicationCredentials();
|
||||
if (relationships == null) relationships = new ArrayList<RequiredCredentialEntity>();
|
||||
|
||||
Set<String> already = new HashSet<String>();
|
||||
List<RequiredCredentialEntity> remove = new ArrayList<RequiredCredentialEntity>();
|
||||
for (RequiredCredentialEntity rel : relationships) {
|
||||
if (!creds.contains(rel.getType())) {
|
||||
remove.add(rel);
|
||||
} else {
|
||||
already.add(rel.getType());
|
||||
}
|
||||
}
|
||||
for (RequiredCredentialEntity entity : remove) {
|
||||
relationships.remove(entity);
|
||||
em.remove(entity);
|
||||
}
|
||||
for (String cred : creds) {
|
||||
if (!already.contains(cred)) {
|
||||
addRequiredResourceCredential(cred);
|
||||
}
|
||||
}
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserModel getUser(String name) {
|
||||
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserByLoginName", UserEntity.class);
|
||||
query.setParameter("loginName", name);
|
||||
query.setParameter("realm", realm);
|
||||
List<UserEntity> results = query.getResultList();
|
||||
if (results.size() == 0) return null;
|
||||
return new UserAdapter(results.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserModel addUser(String username) {
|
||||
UserEntity entity = new UserEntity();
|
||||
entity.setLoginName(username);
|
||||
entity.setRealm(realm);
|
||||
em.persist(entity);
|
||||
em.flush();
|
||||
return new UserAdapter(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoleModel> getDefaultRoles() {
|
||||
Collection<RoleEntity> entities = realm.getDefaultRoles();
|
||||
List<RoleModel> roles = new ArrayList<RoleModel>();
|
||||
if (entities == null) return roles;
|
||||
for (RoleEntity entity : entities) {
|
||||
roles.add(new RoleAdapter(entity));
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDefaultRole(String name) {
|
||||
RoleModel role = getRole(name);
|
||||
if (role == null) {
|
||||
role = addRole(name);
|
||||
}
|
||||
Collection<RoleEntity> entities = realm.getDefaultRoles();
|
||||
for (RoleEntity entity : entities) {
|
||||
if (entity.getId().equals(role.getId())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
entities.add(((RoleAdapter) role).getRole());
|
||||
em.flush();
|
||||
}
|
||||
|
||||
public static boolean contains(String str, String[] array) {
|
||||
for (String s : array) {
|
||||
if (str.equals(s)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDefaultRoles(String[] defaultRoles) {
|
||||
Collection<RoleEntity> entities = realm.getDefaultRoles();
|
||||
Set<String> already = new HashSet<String>();
|
||||
List<RoleEntity> remove = new ArrayList<RoleEntity>();
|
||||
for (RoleEntity rel : entities) {
|
||||
if (!contains(rel.getName(), defaultRoles)) {
|
||||
remove.add(rel);
|
||||
} else {
|
||||
already.add(rel.getName());
|
||||
}
|
||||
}
|
||||
for (RoleEntity entity : remove) {
|
||||
entities.remove(entity);
|
||||
em.remove(entity);
|
||||
}
|
||||
for (String roleName : defaultRoles) {
|
||||
if (!already.contains(roleName)) {
|
||||
addDefaultRole(roleName);
|
||||
}
|
||||
}
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ApplicationModel> getApplicationNameMap() {
|
||||
Map<String, ApplicationModel> map = new HashMap<String, ApplicationModel>();
|
||||
for (ApplicationModel app : getApplications()) {
|
||||
map.put(app.getName(), app);
|
||||
}
|
||||
return map; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ApplicationModel> getApplications() {
|
||||
List<ApplicationModel> list = new ArrayList<ApplicationModel>();
|
||||
if (realm.getApplications() == null) return list;
|
||||
for (ApplicationEntity entity : realm.getApplications()) {
|
||||
list.add(new ApplicationAdapter(em, entity));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationModel addApplication(String name) {
|
||||
ApplicationEntity applicationData = new ApplicationEntity();
|
||||
UserEntity user = new UserEntity();
|
||||
user.setLoginName(name);
|
||||
user.setRealm(realm);
|
||||
user.setEnabled(true);
|
||||
em.persist(user);
|
||||
applicationData.setApplicationUser(user);
|
||||
applicationData.setName(name);
|
||||
realm.getApplications().add(applicationData);
|
||||
em.persist(applicationData);
|
||||
em.flush();
|
||||
ApplicationModel resource = new ApplicationAdapter(em, applicationData);
|
||||
resource.addRole("*");
|
||||
resource.addScopeMapping(new UserAdapter(user), "*");
|
||||
em.flush();
|
||||
return resource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationModel getApplicationById(String id) {
|
||||
ApplicationEntity app = em.find(ApplicationEntity.class, id);
|
||||
if (app == null) return null;
|
||||
return new ApplicationAdapter(em, app);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserModel getUserBySocialLink(SocialLinkModel socialLink) {
|
||||
TypedQuery<UserEntity> query = em.createNamedQuery("findUserByLinkAndRealm", UserEntity.class);
|
||||
query.setParameter("realm", realm);
|
||||
query.setParameter("socialProvider", socialLink.getSocialProvider());
|
||||
query.setParameter("socialUsername", socialLink.getSocialUsername());
|
||||
List<UserEntity> results = query.getResultList();
|
||||
if (results.isEmpty()) {
|
||||
return null;
|
||||
} else if (results.size() > 1) {
|
||||
throw new IllegalStateException("More results found for socialProvider=" + socialLink.getSocialProvider() +
|
||||
", socialUsername=" + socialLink.getSocialUsername() + ", results=" + results);
|
||||
} else {
|
||||
UserEntity user = results.get(0);
|
||||
return new UserAdapter(user);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SocialLinkModel> getSocialLinks(UserModel user) {
|
||||
TypedQuery<SocialLinkEntity> query = em.createNamedQuery("findSocialLinkByUser", SocialLinkEntity.class);
|
||||
query.setParameter("user", ((UserAdapter) user).getUser());
|
||||
List<SocialLinkEntity> results = query.getResultList();
|
||||
Set<SocialLinkModel> set = new HashSet<SocialLinkModel>();
|
||||
for (SocialLinkEntity entity : results) {
|
||||
set.add(new SocialLinkModel(entity.getSocialProvider(), entity.getSocialUsername()));
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSocialLink(UserModel user, SocialLinkModel socialLink) {
|
||||
SocialLinkEntity entity = new SocialLinkEntity();
|
||||
entity.setRealm(realm);
|
||||
entity.setSocialProvider(socialLink.getSocialProvider());
|
||||
entity.setSocialUsername(socialLink.getSocialUsername());
|
||||
entity.setUser(((UserAdapter) user).getUser());
|
||||
em.persist(entity);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSocialLink(UserModel user, SocialLinkModel socialLink) {
|
||||
TypedQuery<SocialLinkEntity> query = em.createNamedQuery("findSocialLinkByAll", SocialLinkEntity.class);
|
||||
query.setParameter("realm", realm);
|
||||
query.setParameter("user", ((UserAdapter) user).getUser());
|
||||
query.setParameter("socialProvider", socialLink.getSocialProvider());
|
||||
query.setParameter("socialUsername", socialLink.getSocialUsername());
|
||||
List<SocialLinkEntity> results = query.getResultList();
|
||||
for (SocialLinkEntity entity : results) em.remove(entity);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSocial() {
|
||||
return realm.isSocial();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSocial(boolean social) {
|
||||
realm.setSocial(social);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutomaticRegistrationAfterSocialLogin() {
|
||||
return realm.isAutomaticRegistrationAfterSocialLogin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin) {
|
||||
realm.setAutomaticRegistrationAfterSocialLogin(automaticRegistrationAfterSocialLogin);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserModel> searchForUserByAttributes(Map<String, String> attributes) {
|
||||
StringBuilder builder = new StringBuilder("select u from UserEntity u");
|
||||
boolean first = true;
|
||||
for (Map.Entry<String, String> entry : attributes.entrySet()) {
|
||||
String attribute = null;
|
||||
if (entry.getKey().equals(UserModel.LOGIN_NAME)) {
|
||||
attribute = "loginName";
|
||||
} else if (entry.getKey().equalsIgnoreCase(UserModel.FIRST_NAME)) {
|
||||
attribute = "firstName";
|
||||
} else if (entry.getKey().equalsIgnoreCase(UserModel.LAST_NAME)) {
|
||||
attribute = "lastName";
|
||||
} else if (entry.getKey().equalsIgnoreCase(UserModel.EMAIL)) {
|
||||
attribute = "email";
|
||||
}
|
||||
if (attribute == null) continue;
|
||||
if (first) {
|
||||
first = false;
|
||||
builder.append(" where ");
|
||||
} else {
|
||||
builder.append(" and ");
|
||||
}
|
||||
builder.append(attribute).append("='").append(entry.getValue()).append("'");
|
||||
}
|
||||
TypedQuery<UserEntity> query = em.createQuery(builder.toString(), UserEntity.class);
|
||||
List<UserEntity> results = query.getResultList();
|
||||
List<UserModel> users = new ArrayList<UserModel>();
|
||||
for (UserEntity entity : results) users.add(new UserAdapter(entity));
|
||||
return users;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuthClientModel addOAuthClient(String name) {
|
||||
OAuthClientEntity data = new OAuthClientEntity();
|
||||
UserEntity user = new UserEntity();
|
||||
user.setLoginName(name);
|
||||
user.setRealm(realm);
|
||||
user.setEnabled(true);
|
||||
em.persist(user);
|
||||
data.setAgent(user);
|
||||
data.setName(name);
|
||||
data.setRealm(realm);
|
||||
em.persist(data);
|
||||
em.flush();
|
||||
return new OAuthClientAdapter(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuthClientModel getOAuthClient(String name) {
|
||||
TypedQuery<OAuthClientEntity> query = em.createNamedQuery("findOAuthClientByUser", OAuthClientEntity.class);
|
||||
query.setParameter("name", name);
|
||||
query.setParameter("realm", realm);
|
||||
List<OAuthClientEntity> entities = query.getResultList();
|
||||
if (entities.size() == 0) return null;
|
||||
return new OAuthClientAdapter(entities.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OAuthClientModel> getOAuthClients() {
|
||||
TypedQuery<OAuthClientEntity> query = em.createNamedQuery("findOAuthClientByRealm", OAuthClientEntity.class);
|
||||
query.setParameter("realm", realm);
|
||||
List<OAuthClientEntity> entities = query.getResultList();
|
||||
List<OAuthClientModel> list = new ArrayList<OAuthClientModel>();
|
||||
for (OAuthClientEntity entity : entities) list.add(new OAuthClientAdapter(entity));
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getSmtpConfig() {
|
||||
return realm.getSmtpConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSmtpConfig(Map<String, String> smtpConfig) {
|
||||
realm.setSmtpConfig(smtpConfig);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getSocialConfig() {
|
||||
return realm.getSocialConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSocialConfig(Map<String, String> socialConfig) {
|
||||
realm.setSocialConfig(socialConfig);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel getRole(String name) {
|
||||
Collection<RoleEntity> roles = realm.getRoles();
|
||||
if (roles == null) return null;
|
||||
for (RoleEntity role : roles) {
|
||||
if (role.getName().equals(name)) {
|
||||
return new RoleAdapter(role);
|
||||
}
|
||||
}
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel addRole(String name) {
|
||||
RoleModel role = getRole(name);
|
||||
if (role != null) return role;
|
||||
RoleEntity entity = new RoleEntity();
|
||||
entity.setName(name);
|
||||
em.persist(entity);
|
||||
realm.getRoles().add(entity);
|
||||
em.flush();
|
||||
return new RoleAdapter(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoleModel> getRoles() {
|
||||
ArrayList<RoleModel> list = new ArrayList<RoleModel>();
|
||||
Collection<RoleEntity> roles = realm.getRoles();
|
||||
if (roles == null) return list;
|
||||
for (RoleEntity entity : roles) {
|
||||
list.add(new RoleAdapter(entity));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel getRoleById(String id) {
|
||||
RoleEntity entity = em.find(RoleEntity.class, id);
|
||||
if (entity == null) return null;
|
||||
return new RoleAdapter(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRole(UserModel user, RoleModel role) {
|
||||
TypedQuery<RealmUserRoleMappingEntity> query = getRealmUserRoleMappingEntityTypedQuery((UserAdapter) user, (RoleAdapter) role);
|
||||
return query.getResultList().size() > 0;
|
||||
}
|
||||
|
||||
protected TypedQuery<RealmUserRoleMappingEntity> getRealmUserRoleMappingEntityTypedQuery(UserAdapter user, RoleAdapter role) {
|
||||
TypedQuery<RealmUserRoleMappingEntity> query = em.createNamedQuery("userHasRealmRole", RealmUserRoleMappingEntity.class);
|
||||
query.setParameter("user", ((UserAdapter)user).getUser());
|
||||
query.setParameter("role", ((RoleAdapter)role).getRole());
|
||||
query.setParameter("realm", realm);
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grantRole(UserModel user, RoleModel role) {
|
||||
if (hasRole(user, role)) return;
|
||||
RealmUserRoleMappingEntity entity = new RealmUserRoleMappingEntity();
|
||||
entity.setRealm(realm);
|
||||
entity.setUser(((UserAdapter) user).getUser());
|
||||
entity.setRole(((RoleAdapter)role).getRole());
|
||||
em.persist(entity);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoleModel> getRoleMappings(UserModel user) {
|
||||
TypedQuery<RealmUserRoleMappingEntity> query = em.createNamedQuery("userRealmMappings", RealmUserRoleMappingEntity.class);
|
||||
query.setParameter("user", ((UserAdapter)user).getUser());
|
||||
query.setParameter("realm", realm);
|
||||
List<RealmUserRoleMappingEntity> entities = query.getResultList();
|
||||
List<RoleModel> roles = new ArrayList<RoleModel>();
|
||||
for (RealmUserRoleMappingEntity entity : entities) {
|
||||
roles.add(new RoleAdapter(entity.getRole()));
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRoleMappingValues(UserModel user) {
|
||||
TypedQuery<RealmUserRoleMappingEntity> query = em.createNamedQuery("userRealmMappings", RealmUserRoleMappingEntity.class);
|
||||
query.setParameter("user", ((UserAdapter)user).getUser());
|
||||
query.setParameter("realm", realm);
|
||||
List<RealmUserRoleMappingEntity> entities = query.getResultList();
|
||||
Set<String> roles = new HashSet<String>();
|
||||
for (RealmUserRoleMappingEntity entity : entities) {
|
||||
roles.add(entity.getRole().getName());
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRoleMapping(UserModel user, RoleModel role) {
|
||||
TypedQuery<RealmUserRoleMappingEntity> query = getRealmUserRoleMappingEntityTypedQuery((UserAdapter) user, (RoleAdapter) role);
|
||||
List<RealmUserRoleMappingEntity> results = query.getResultList();
|
||||
if (results.size() == 0) return;
|
||||
for (RealmUserRoleMappingEntity entity : results) {
|
||||
em.remove(entity);
|
||||
}
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRole(UserModel user, String roleName) {
|
||||
RoleModel role = getRole(roleName);
|
||||
if (role == null) return false;
|
||||
return hasRole(user, role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addScopeMapping(UserModel agent, String roleName) {
|
||||
RoleModel role = getRole(roleName);
|
||||
if (role == null) throw new RuntimeException("role does not exist");
|
||||
addScopeMapping(agent, role);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getScopeMappingValues(UserModel agent) {
|
||||
TypedQuery<RealmScopeMappingEntity> query = em.createNamedQuery("userRealmScopeMappings", RealmScopeMappingEntity.class);
|
||||
query.setParameter("user", ((UserAdapter)agent).getUser());
|
||||
query.setParameter("realm", realm);
|
||||
List<RealmScopeMappingEntity> entities = query.getResultList();
|
||||
Set<String> roles = new HashSet<String>();
|
||||
for (RealmScopeMappingEntity entity : entities) {
|
||||
roles.add(entity.getRole().getName());
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoleModel> getScopeMappings(UserModel agent) {
|
||||
TypedQuery<RealmScopeMappingEntity> query = em.createNamedQuery("userRealmScopeMappings", RealmScopeMappingEntity.class);
|
||||
query.setParameter("user", ((UserAdapter)agent).getUser());
|
||||
query.setParameter("realm", realm);
|
||||
List<RealmScopeMappingEntity> entities = query.getResultList();
|
||||
List<RoleModel> roles = new ArrayList<RoleModel>();
|
||||
for (RealmScopeMappingEntity entity : entities) {
|
||||
roles.add(new RoleAdapter(entity.getRole()));
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addScopeMapping(UserModel agent, RoleModel role) {
|
||||
if (hasScope(agent, role)) return;
|
||||
RealmScopeMappingEntity entity = new RealmScopeMappingEntity();
|
||||
entity.setRealm(realm);
|
||||
entity.setUser(((UserAdapter) agent).getUser());
|
||||
entity.setRole(((RoleAdapter)role).getRole());
|
||||
em.persist(entity);
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteScopeMapping(UserModel user, RoleModel role) {
|
||||
TypedQuery<RealmScopeMappingEntity> query = getRealmScopeMappingQuery((UserAdapter) user, (RoleAdapter) role);
|
||||
List<RealmScopeMappingEntity> results = query.getResultList();
|
||||
if (results.size() == 0) return;
|
||||
for (RealmScopeMappingEntity entity : results) {
|
||||
em.remove(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasScope(UserModel user, RoleModel role) {
|
||||
TypedQuery<RealmScopeMappingEntity> query = getRealmScopeMappingQuery((UserAdapter) user, (RoleAdapter) role);
|
||||
return query.getResultList().size() > 0;
|
||||
}
|
||||
|
||||
|
||||
protected TypedQuery<RealmScopeMappingEntity> getRealmScopeMappingQuery(UserAdapter user, RoleAdapter role) {
|
||||
TypedQuery<RealmScopeMappingEntity> query = em.createNamedQuery("userHasRealmScope", RealmScopeMappingEntity.class);
|
||||
query.setParameter("user", ((UserAdapter)user).getUser());
|
||||
query.setParameter("role", ((RoleAdapter)role).getRole());
|
||||
query.setParameter("realm", realm);
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validatePassword(UserModel user, String password) {
|
||||
for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) {
|
||||
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
|
||||
return new SHAPasswordEncoder(512).verify(password, cred.getValue());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateTOTP(UserModel user, String password, String token) {
|
||||
if (!validatePassword(user, password)) return false;
|
||||
for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) {
|
||||
if (cred.getType().equals(UserCredentialModel.TOTP)) {
|
||||
return new TimeBasedOTP().validate(token, cred.getValue().getBytes());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCredential(UserModel user, UserCredentialModel cred) {
|
||||
CredentialEntity credentialEntity = null;
|
||||
UserEntity userEntity = ((UserAdapter) user).getUser();
|
||||
for (CredentialEntity entity : userEntity.getCredentials()) {
|
||||
if (entity.getType().equals(cred.getType())) {
|
||||
credentialEntity = entity;
|
||||
}
|
||||
}
|
||||
if (credentialEntity == null) {
|
||||
credentialEntity = new CredentialEntity();
|
||||
credentialEntity.setType(cred.getType());
|
||||
credentialEntity.setDevice(cred.getDevice());
|
||||
credentialEntity.setUser(userEntity);
|
||||
em.persist(credentialEntity);
|
||||
userEntity.getCredentials().add(credentialEntity);
|
||||
}
|
||||
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
|
||||
credentialEntity.setValue(new SHAPasswordEncoder(512).encode(cred.getValue()));
|
||||
} else {
|
||||
credentialEntity.setValue(cred.getValue());
|
||||
}
|
||||
credentialEntity.setDevice(cred.getDevice());
|
||||
em.flush();
|
||||
}
|
||||
|
||||
}
|
49
model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
Executable file
49
model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
Executable file
|
@ -0,0 +1,49 @@
|
|||
package org.keycloak.models.jpa;
|
||||
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class RoleAdapter implements RoleModel {
|
||||
protected RoleEntity role;
|
||||
|
||||
public RoleAdapter(RoleEntity role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public RoleEntity getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(RoleEntity role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return role.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return role.getDescription();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDescription(String description) {
|
||||
role.setDescription(description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return role.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
role.setName(name);
|
||||
}
|
||||
}
|
185
model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
Executable file
185
model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
Executable file
|
@ -0,0 +1,185 @@
|
|||
package org.keycloak.models.jpa;
|
||||
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.jpa.entities.UserEntity;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class UserAdapter implements UserModel {
|
||||
|
||||
protected UserEntity user;
|
||||
|
||||
public UserAdapter(UserEntity user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public UserEntity getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLoginName() {
|
||||
return user.getLoginName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return user.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTotp() {
|
||||
return user.isTotp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
user.setEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, String value) {
|
||||
Map<String, String> attributes = user.getAttributes();
|
||||
if (attributes == null) {
|
||||
attributes = new HashMap<String, String>();
|
||||
}
|
||||
attributes.put(name, value);
|
||||
user.setAttributes(attributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttribute(String name) {
|
||||
Map<String, String> attributes = user.getAttributes();
|
||||
if (attributes == null) {
|
||||
attributes = new HashMap<String, String>();
|
||||
}
|
||||
attributes.remove(name);
|
||||
user.setAttributes(attributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttribute(String name) {
|
||||
if (user.getAttributes() == null) return null;
|
||||
return user.getAttributes().get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAttributes() {
|
||||
Map<String, String> result = new HashMap<String, String>();
|
||||
result.putAll(user.getAttributes());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RequiredAction> getRequiredActions() {
|
||||
Set<RequiredAction> result = new HashSet<RequiredAction>();
|
||||
result.addAll(user.getRequiredActions());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRequiredAction(RequiredAction action) {
|
||||
user.getRequiredActions().add(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRequiredAction(RequiredAction action) {
|
||||
user.getRequiredActions().remove(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getWebOrigins() {
|
||||
Set<String> result = new HashSet<String>();
|
||||
result.addAll(user.getWebOrigins());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWebOrigins(Set<String> webOrigins) {
|
||||
user.setWebOrigins(webOrigins);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addWebOrigin(String webOrigin) {
|
||||
user.getWebOrigins().add(webOrigin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWebOrigin(String webOrigin) {
|
||||
user.getWebOrigins().remove(webOrigin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRedirectUris() {
|
||||
Set<String> result = new HashSet<String>();
|
||||
result.addAll(user.getRedirectUris());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRedirectUris(Set<String> redirectUris) {
|
||||
user.setRedirectUris(redirectUris);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRedirectUri(String redirectUri) {
|
||||
user.getRedirectUris().add(redirectUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRedirectUri(String redirectUri) {
|
||||
user.getRedirectUris().remove(redirectUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFirstName() {
|
||||
return user.getFirstName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFirstName(String firstName) {
|
||||
user.setFirstName(firstName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLastName() {
|
||||
return user.getLastName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastName(String lastName) {
|
||||
user.setLastName(lastName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEmail() {
|
||||
return user.getEmail();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEmail(String email) {
|
||||
user.setEmail(email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmailVerified() {
|
||||
return user.isEmailVerified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEmailVerified(boolean verified) {
|
||||
user.setEmailVerified(verified);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTotp(boolean totp) {
|
||||
user.setTotp(totp);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,14 @@
|
|||
package org.keycloak.models.jpa.entities;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OneToOne;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
|
@ -8,37 +16,27 @@ import java.util.Collection;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Entity
|
||||
public class ResourceEntity {
|
||||
public class ApplicationEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private String id;
|
||||
|
||||
private String resourceName;
|
||||
private String name;
|
||||
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;
|
||||
@OneToOne(fetch = FetchType.EAGER)
|
||||
private UserEntity applicationUser;
|
||||
|
||||
@OneToMany(fetch = FetchType.EAGER, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
||||
@JoinTable(name="APPLICATION_ROLES")
|
||||
Collection<RoleEntity> roles = new ArrayList<RoleEntity>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -63,12 +61,12 @@ public class ResourceEntity {
|
|||
this.managementUrl = managementUrl;
|
||||
}
|
||||
|
||||
public UserEntity getResourceUser() {
|
||||
return resourceUser;
|
||||
public UserEntity getApplicationUser() {
|
||||
return applicationUser;
|
||||
}
|
||||
|
||||
public void setResourceUser(UserEntity resourceUser) {
|
||||
this.resourceUser = resourceUser;
|
||||
public void setApplicationUser(UserEntity applicationUser) {
|
||||
this.applicationUser = applicationUser;
|
||||
}
|
||||
|
||||
public Collection<RoleEntity> getRoles() {
|
||||
|
@ -78,4 +76,12 @@ public class ResourceEntity {
|
|||
public void setRoles(Collection<RoleEntity> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package org.keycloak.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="userHasApplicationScope", query="select m from ApplicationScopeMappingEntity m where m.user = :user and m.role = :role and m.application = :application"),
|
||||
@NamedQuery(name="userApplicationScopeMappings", query="select m from ApplicationScopeMappingEntity m where m.user = :user and m.application = :application")
|
||||
})
|
||||
@Entity
|
||||
public class ApplicationScopeMappingEntity extends UserRoleMappingEntity {
|
||||
|
||||
@ManyToOne
|
||||
protected ApplicationEntity application;
|
||||
|
||||
public ApplicationEntity getApplication() {
|
||||
return application;
|
||||
}
|
||||
|
||||
public void setApplication(ApplicationEntity application) {
|
||||
this.application = application;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package org.keycloak.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="userHasApplicationRole", query="select m from ApplicationUserRoleMappingEntity m where m.user = :user and m.role = :role and m.application = :application"),
|
||||
@NamedQuery(name="userApplicationMappings", query="select m from ApplicationUserRoleMappingEntity m where m.user = :user and m.application = :application")
|
||||
})
|
||||
@Entity
|
||||
public class ApplicationUserRoleMappingEntity extends UserRoleMappingEntity {
|
||||
|
||||
@ManyToOne
|
||||
protected ApplicationEntity application;
|
||||
|
||||
public ApplicationEntity getApplication() {
|
||||
return application;
|
||||
}
|
||||
|
||||
public void setApplication(ApplicationEntity application) {
|
||||
this.application = application;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package org.keycloak.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="credentialByUserAndType", query="select cred from CredentialEntity cred where cred.user = :user and cred.type = :type")
|
||||
})
|
||||
@Entity
|
||||
public class CredentialEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
protected String id;
|
||||
|
||||
protected String type;
|
||||
protected String value;
|
||||
protected String device;
|
||||
|
||||
@ManyToOne
|
||||
protected UserEntity user;
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
public void setDevice(String device) {
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
public UserEntity getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(UserEntity user) {
|
||||
this.user = user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package org.keycloak.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.OneToOne;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="findOAuthClientByUser", query="select o from OAuthClientEntity o where o.agent.loginName=:name and o.realm = :realm"),
|
||||
@NamedQuery(name="findOAuthClientByRealm", query="select o from OAuthClientEntity o where o.realm = :realm")
|
||||
|
||||
})
|
||||
@Entity
|
||||
public class OAuthClientEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
@OneToOne(fetch = FetchType.EAGER)
|
||||
private UserEntity agent;
|
||||
|
||||
@ManyToOne
|
||||
protected RealmEntity realm;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public UserEntity getAgent() {
|
||||
return agent;
|
||||
}
|
||||
|
||||
public void setAgent(UserEntity agent) {
|
||||
this.agent = agent;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public RealmEntity getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
public void setRealm(RealmEntity realm) {
|
||||
this.realm = realm;
|
||||
}
|
||||
}
|
|
@ -1,43 +1,272 @@
|
|||
package org.keycloak.models.jpa.entities;
|
||||
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.MapKeyColumn;
|
||||
import javax.persistence.OneToMany;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Entity
|
||||
public class RealmEntity {
|
||||
@Id
|
||||
protected String id;
|
||||
|
||||
protected String realmName;
|
||||
protected String name;
|
||||
protected boolean enabled;
|
||||
protected boolean sslNotRequired;
|
||||
protected boolean cookieLoginAllowed;
|
||||
protected boolean registrationAllowed;
|
||||
protected boolean verifyEmail;
|
||||
protected boolean resetPasswordAllowed;
|
||||
protected boolean social;
|
||||
protected boolean automaticRegistrationAfterSocialLogin;
|
||||
|
||||
protected int tokenLifespan;
|
||||
protected int accessCodeLifespan;
|
||||
protected int accessCodeLifespanUserAction;
|
||||
|
||||
@Column(length = 2048)
|
||||
protected String publicKeyPem;
|
||||
@Column(length = 2048)
|
||||
protected String privateKeyPem;
|
||||
protected String[] defaultRoles;
|
||||
@Lob
|
||||
protected HashMap<String, String> smtpConfig;
|
||||
@Lob
|
||||
protected HashMap<String, String> socialConfig;
|
||||
|
||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
||||
Collection<RequiredCredentailEntity> requiredCredentials;
|
||||
@JoinTable(name="USER_REQUIRED_CREDENTIALS")
|
||||
Collection<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
|
||||
|
||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
||||
Collection<ResourceEntity> resources;
|
||||
@JoinTable(name="APPLICATION_REQUIRED_CREDENTIALS")
|
||||
Collection<RequiredCredentialEntity> requiredApplicationCredentials = new ArrayList<RequiredCredentialEntity>();
|
||||
|
||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
||||
@JoinTable(name="OAUTH_CLIENT_REQUIRED_CREDENTIALS")
|
||||
Collection<RequiredCredentialEntity> requiredOAuthClientCredentials = new ArrayList<RequiredCredentialEntity>();
|
||||
|
||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
||||
Collection<ApplicationEntity> applications = new ArrayList<ApplicationEntity>();
|
||||
|
||||
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
||||
Collection<RoleEntity> roles;
|
||||
@JoinTable(name="REALM_ROLES")
|
||||
Collection<RoleEntity> roles = new ArrayList<RoleEntity>();
|
||||
|
||||
@ElementCollection
|
||||
@MapKeyColumn(name="name")
|
||||
@Column(name="value")
|
||||
@CollectionTable
|
||||
protected Map<String, String> smtpConfig = new HashMap<String, String>();
|
||||
|
||||
@ElementCollection
|
||||
@MapKeyColumn(name="name")
|
||||
@Column(name="value")
|
||||
@CollectionTable
|
||||
protected Map<String, String> socialConfig = new HashMap<String, String>();
|
||||
|
||||
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true)
|
||||
@JoinTable(name="REALM_DEFAULT_ROLES")
|
||||
Collection<RoleEntity> defaultRoles = new ArrayList<RoleEntity>();
|
||||
|
||||
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 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 boolean isVerifyEmail() {
|
||||
return verifyEmail;
|
||||
}
|
||||
|
||||
public void setVerifyEmail(boolean verifyEmail) {
|
||||
this.verifyEmail = verifyEmail;
|
||||
}
|
||||
|
||||
public boolean isResetPasswordAllowed() {
|
||||
return resetPasswordAllowed;
|
||||
}
|
||||
|
||||
public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
|
||||
this.resetPasswordAllowed = resetPasswordAllowed;
|
||||
}
|
||||
|
||||
public boolean isSocial() {
|
||||
return social;
|
||||
}
|
||||
|
||||
public void setSocial(boolean social) {
|
||||
this.social = social;
|
||||
}
|
||||
|
||||
public boolean isAutomaticRegistrationAfterSocialLogin() {
|
||||
return automaticRegistrationAfterSocialLogin;
|
||||
}
|
||||
|
||||
public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin) {
|
||||
this.automaticRegistrationAfterSocialLogin = automaticRegistrationAfterSocialLogin;
|
||||
}
|
||||
|
||||
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 int getAccessCodeLifespanUserAction() {
|
||||
return accessCodeLifespanUserAction;
|
||||
}
|
||||
|
||||
public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
|
||||
this.accessCodeLifespanUserAction = accessCodeLifespanUserAction;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public Collection<RequiredCredentialEntity> getRequiredCredentials() {
|
||||
return requiredCredentials;
|
||||
}
|
||||
|
||||
public void setRequiredCredentials(Collection<RequiredCredentialEntity> requiredCredentials) {
|
||||
this.requiredCredentials = requiredCredentials;
|
||||
}
|
||||
|
||||
public Collection<RequiredCredentialEntity> getRequiredApplicationCredentials() {
|
||||
return requiredApplicationCredentials;
|
||||
}
|
||||
|
||||
public void setRequiredApplicationCredentials(Collection<RequiredCredentialEntity> requiredApplicationCredentials) {
|
||||
this.requiredApplicationCredentials = requiredApplicationCredentials;
|
||||
}
|
||||
|
||||
public Collection<RequiredCredentialEntity> getRequiredOAuthClientCredentials() {
|
||||
return requiredOAuthClientCredentials;
|
||||
}
|
||||
|
||||
public void setRequiredOAuthClientCredentials(Collection<RequiredCredentialEntity> requiredOAuthClientCredentials) {
|
||||
this.requiredOAuthClientCredentials = requiredOAuthClientCredentials;
|
||||
}
|
||||
|
||||
public Collection<ApplicationEntity> getApplications() {
|
||||
return applications;
|
||||
}
|
||||
|
||||
public void setApplications(Collection<ApplicationEntity> applications) {
|
||||
this.applications = applications;
|
||||
}
|
||||
|
||||
public Collection<RoleEntity> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setRoles(Collection<RoleEntity> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
public void addRole(RoleEntity role) {
|
||||
if (roles == null) {
|
||||
roles = new ArrayList<RoleEntity>();
|
||||
}
|
||||
roles.add(role);
|
||||
}
|
||||
|
||||
public Map<String, String> getSmtpConfig() {
|
||||
return smtpConfig;
|
||||
}
|
||||
|
||||
public void setSmtpConfig(Map<String, String> smtpConfig) {
|
||||
this.smtpConfig = smtpConfig;
|
||||
}
|
||||
|
||||
public Map<String, String> getSocialConfig() {
|
||||
return socialConfig;
|
||||
}
|
||||
|
||||
public void setSocialConfig(Map<String, String> socialConfig) {
|
||||
this.socialConfig = socialConfig;
|
||||
}
|
||||
|
||||
public Collection<RoleEntity> getDefaultRoles() {
|
||||
return defaultRoles;
|
||||
}
|
||||
|
||||
public void setDefaultRoles(Collection<RoleEntity> defaultRoles) {
|
||||
this.defaultRoles = defaultRoles;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package org.keycloak.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="userHasRealmScope", query="select m from RealmScopeMappingEntity m where m.user = :user and m.role = :role and m.realm = :realm"),
|
||||
@NamedQuery(name="userRealmScopeMappings", query="select m from RealmScopeMappingEntity m where m.user = :user and m.realm = :realm")
|
||||
})
|
||||
@Entity
|
||||
public class RealmScopeMappingEntity extends UserRoleMappingEntity {
|
||||
|
||||
@ManyToOne
|
||||
protected RealmEntity realm;
|
||||
|
||||
public RealmEntity getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
public void setRealm(RealmEntity realm) {
|
||||
this.realm = realm;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package org.keycloak.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="userHasRealmRole", query="select m from RealmUserRoleMappingEntity m where m.user = :user and m.role = :role and m.realm = :realm"),
|
||||
@NamedQuery(name="userRealmMappings", query="select m from RealmUserRoleMappingEntity m where m.user = :user and m.realm = :realm")
|
||||
})
|
||||
@Entity
|
||||
public class RealmUserRoleMappingEntity extends UserRoleMappingEntity {
|
||||
|
||||
@ManyToOne
|
||||
protected RealmEntity realm;
|
||||
|
||||
public RealmEntity getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
public void setRealm(RealmEntity realm) {
|
||||
this.realm = realm;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package org.keycloak.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,61 @@
|
|||
package org.keycloak.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 RequiredCredentialEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
protected String id;
|
||||
|
||||
protected String type;
|
||||
protected boolean input;
|
||||
protected boolean secret;
|
||||
protected String formLabel;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public boolean isInput() {
|
||||
return input;
|
||||
}
|
||||
|
||||
public void setInput(boolean input) {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public boolean isSecret() {
|
||||
return secret;
|
||||
}
|
||||
|
||||
public void setSecret(boolean secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
public String getFormLabel() {
|
||||
return formLabel;
|
||||
}
|
||||
|
||||
public void setFormLabel(String formLabel) {
|
||||
this.formLabel = formLabel;
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package org.keycloak.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,73 @@
|
|||
package org.keycloak.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="findSocialLinkByUser", query="select link from SocialLinkEntity link where link.user = :user"),
|
||||
@NamedQuery(name="findUserByLinkAndRealm", query="select link.user from SocialLinkEntity link where link.realm = :realm and link.socialProvider = :socialProvider and link.socialUsername = :socialUsername"),
|
||||
@NamedQuery(name="findSocialLinkByAll", query="select link.user from SocialLinkEntity link where link.realm = :realm and link.socialProvider = :socialProvider and link.socialUsername = :socialUsername and link.user = :user")
|
||||
})
|
||||
@Entity
|
||||
public class SocialLinkEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private long id;
|
||||
|
||||
@ManyToOne
|
||||
private UserEntity user;
|
||||
|
||||
@ManyToOne
|
||||
protected RealmEntity realm;
|
||||
|
||||
protected String socialProvider;
|
||||
protected String socialUsername;
|
||||
|
||||
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 String getSocialProvider() {
|
||||
return socialProvider;
|
||||
}
|
||||
|
||||
public void setSocialProvider(String socialProvider) {
|
||||
this.socialProvider = socialProvider;
|
||||
}
|
||||
|
||||
public String getSocialUsername() {
|
||||
return socialUsername;
|
||||
}
|
||||
|
||||
public void setSocialUsername(String socialUsername) {
|
||||
this.socialUsername = socialUsername;
|
||||
}
|
||||
|
||||
public RealmEntity getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
public void setRealm(RealmEntity realm) {
|
||||
this.realm = realm;
|
||||
}
|
||||
}
|
|
@ -1,20 +1,72 @@
|
|||
package org.keycloak.models.jpa.entities;
|
||||
|
||||
import org.keycloak.models.UserModel;
|
||||
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.MapKeyColumn;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.OneToMany;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="getRealmUserByLoginName", query="select u from UserEntity u where u.loginName = :loginName and u.realm = :realm"),
|
||||
@NamedQuery(name="getRealmUserByEmail", query="select u from UserEntity u where u.email = :email and u.realm = :realm"),
|
||||
@NamedQuery(name="getRealmUserByLastName", query="select u from UserEntity u where u.lastName = :lastName and u.realm = :realm"),
|
||||
@NamedQuery(name="getRealmUserByFirstLastName", query="select u from UserEntity u where u.firstName = :first and u.lastName = :last and u.realm = :realm")
|
||||
})
|
||||
@Entity
|
||||
public class UserEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private String id;
|
||||
protected String id;
|
||||
|
||||
private String loginName;
|
||||
protected String loginName;
|
||||
protected String firstName;
|
||||
protected String lastName;
|
||||
protected String email;
|
||||
protected boolean enabled;
|
||||
protected boolean totp;
|
||||
protected boolean emailVerified;
|
||||
|
||||
@ManyToOne
|
||||
protected RealmEntity realm;
|
||||
|
||||
@ElementCollection
|
||||
@MapKeyColumn(name="name")
|
||||
@Column(name="value")
|
||||
@CollectionTable
|
||||
protected Map<String, String> attributes = new HashMap<String, String>();
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable
|
||||
protected Set<UserModel.RequiredAction> requiredActions = new HashSet<UserModel.RequiredAction>();
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable
|
||||
protected Set<String> webOrigins = new HashSet<String>();
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable
|
||||
protected Set<String> redirectUris = new HashSet<String>();
|
||||
|
||||
@OneToMany
|
||||
protected Collection<CredentialEntity> credentials = new ArrayList<CredentialEntity>();
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
|
@ -31,4 +83,100 @@ public class UserEntity {
|
|||
public void setLoginName(String loginName) {
|
||||
this.loginName = loginName;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isTotp() {
|
||||
return totp;
|
||||
}
|
||||
|
||||
public void setTotp(boolean totp) {
|
||||
this.totp = totp;
|
||||
}
|
||||
|
||||
public boolean isEmailVerified() {
|
||||
return emailVerified;
|
||||
}
|
||||
|
||||
public void setEmailVerified(boolean emailVerified) {
|
||||
this.emailVerified = emailVerified;
|
||||
}
|
||||
|
||||
public Map<String, String> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(Map<String, String> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public Set<UserModel.RequiredAction> getRequiredActions() {
|
||||
return requiredActions;
|
||||
}
|
||||
|
||||
public void setRequiredActions(Set<UserModel.RequiredAction> requiredActions) {
|
||||
this.requiredActions = requiredActions;
|
||||
}
|
||||
|
||||
public Set<String> getWebOrigins() {
|
||||
return webOrigins;
|
||||
}
|
||||
|
||||
public void setWebOrigins(Set<String> webOrigins) {
|
||||
this.webOrigins = webOrigins;
|
||||
}
|
||||
|
||||
public Set<String> getRedirectUris() {
|
||||
return redirectUris;
|
||||
}
|
||||
|
||||
public void setRedirectUris(Set<String> redirectUris) {
|
||||
this.redirectUris = redirectUris;
|
||||
}
|
||||
|
||||
public RealmEntity getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
public void setRealm(RealmEntity realm) {
|
||||
this.realm = realm;
|
||||
}
|
||||
|
||||
public Collection<CredentialEntity> getCredentials() {
|
||||
return credentials;
|
||||
}
|
||||
|
||||
public void setCredentials(Collection<CredentialEntity> credentials) {
|
||||
this.credentials = credentials;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
package org.keycloak.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Entity
|
||||
public class UserRoleMappingEntity {
|
||||
@MappedSuperclass
|
||||
public abstract class UserRoleMappingEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private long id;
|
||||
|
||||
protected long id;
|
||||
@ManyToOne
|
||||
private UserEntity user;
|
||||
protected UserEntity user;
|
||||
@ManyToOne
|
||||
private RoleEntity role;
|
||||
protected RoleEntity role;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
|
|
5
model/mongo/src/main/java/org/keycloak/models/mongo/api/NoSQL.java
Normal file → Executable file
5
model/mongo/src/main/java/org/keycloak/models/mongo/api/NoSQL.java
Normal file → Executable file
|
@ -1,10 +1,9 @@
|
|||
package org.keycloak.models.mongo.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.keycloak.models.mongo.api.query.NoSQLQuery;
|
||||
import org.keycloak.models.mongo.api.query.NoSQLQueryBuilder;
|
||||
import org.picketlink.common.properties.Property;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
|
|
2
model/mongo/src/main/java/org/keycloak/models/mongo/api/types/TypeConverter.java
Normal file → Executable file
2
model/mongo/src/main/java/org/keycloak/models/mongo/api/types/TypeConverter.java
Normal file → Executable file
|
@ -3,8 +3,6 @@ package org.keycloak.models.mongo.api.types;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.picketlink.common.reflection.Reflections;
|
||||
|
||||
/**
|
||||
* Registry of converters, which allow to convert application object to database objects. TypeConverter is main entry point to be used by application.
|
||||
* Application can create instance of TypeConverter and then register required Converter objects.
|
||||
|
|
18
model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoDBImpl.java
Normal file → Executable file
18
model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoDBImpl.java
Normal file → Executable file
|
@ -1,12 +1,5 @@
|
|||
package org.keycloak.models.mongo.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DB;
|
||||
|
@ -24,10 +17,10 @@ import org.keycloak.models.mongo.api.query.NoSQLQuery;
|
|||
import org.keycloak.models.mongo.api.query.NoSQLQueryBuilder;
|
||||
import org.keycloak.models.mongo.api.types.Converter;
|
||||
import org.keycloak.models.mongo.api.types.TypeConverter;
|
||||
import org.keycloak.models.mongo.impl.types.EnumToStringConverter;
|
||||
import org.keycloak.models.mongo.impl.types.ListConverter;
|
||||
import org.keycloak.models.mongo.impl.types.BasicDBListConverter;
|
||||
import org.keycloak.models.mongo.impl.types.BasicDBObjectConverter;
|
||||
import org.keycloak.models.mongo.impl.types.EnumToStringConverter;
|
||||
import org.keycloak.models.mongo.impl.types.ListConverter;
|
||||
import org.keycloak.models.mongo.impl.types.NoSQLObjectConverter;
|
||||
import org.keycloak.models.mongo.impl.types.SimpleConverter;
|
||||
import org.keycloak.models.mongo.impl.types.StringToEnumConverter;
|
||||
|
@ -35,6 +28,13 @@ import org.picketlink.common.properties.Property;
|
|||
import org.picketlink.common.properties.query.AnnotatedPropertyCriteria;
|
||||
import org.picketlink.common.properties.query.PropertyQueries;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
8
model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoDBQueryBuilder.java
Normal file → Executable file
8
model/mongo/src/main/java/org/keycloak/models/mongo/impl/MongoDBQueryBuilder.java
Normal file → Executable file
|
@ -1,13 +1,13 @@
|
|||
package org.keycloak.models.mongo.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.keycloak.models.mongo.api.query.NoSQLQueryBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
6
model/mongo/src/main/java/org/keycloak/models/mongo/impl/ObjectInfo.java
Normal file → Executable file
6
model/mongo/src/main/java/org/keycloak/models/mongo/impl/ObjectInfo.java
Normal file → Executable file
|
@ -1,14 +1,14 @@
|
|||
package org.keycloak.models.mongo.impl;
|
||||
|
||||
import org.keycloak.models.mongo.api.NoSQLObject;
|
||||
import org.picketlink.common.properties.Property;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.keycloak.models.mongo.api.NoSQLObject;
|
||||
import org.picketlink.common.properties.Property;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
4
model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/BasicDBListConverter.java
Normal file → Executable file
4
model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/BasicDBListConverter.java
Normal file → Executable file
|
@ -1,12 +1,12 @@
|
|||
package org.keycloak.models.mongo.impl.types;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import org.keycloak.models.mongo.api.types.Converter;
|
||||
import org.keycloak.models.mongo.api.types.TypeConverter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
4
model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/ListConverter.java
Normal file → Executable file
4
model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/ListConverter.java
Normal file → Executable file
|
@ -1,12 +1,12 @@
|
|||
package org.keycloak.models.mongo.impl.types;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import org.keycloak.models.mongo.api.types.Converter;
|
||||
import org.keycloak.models.mongo.api.types.TypeConverter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
6
model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/NoSQLObjectConverter.java
Normal file → Executable file
6
model/mongo/src/main/java/org/keycloak/models/mongo/impl/types/NoSQLObjectConverter.java
Normal file → Executable file
|
@ -1,8 +1,5 @@
|
|||
package org.keycloak.models.mongo.impl.types;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import org.keycloak.models.mongo.api.AttributedNoSQLObject;
|
||||
import org.keycloak.models.mongo.api.NoSQLObject;
|
||||
|
@ -12,6 +9,9 @@ import org.keycloak.models.mongo.impl.MongoDBImpl;
|
|||
import org.keycloak.models.mongo.impl.ObjectInfo;
|
||||
import org.picketlink.common.properties.Property;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package org.keycloak.models.mongo.keycloak;
|
||||
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.ModelProvider;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class MongoModelProvider implements ModelProvider {
|
||||
@Override
|
||||
public KeycloakSessionFactory createFactory() {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
}
|
10
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java
Normal file → Executable file
10
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java
Normal file → Executable file
|
@ -1,10 +1,5 @@
|
|||
package org.keycloak.models.mongo.keycloak.adapters;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.keycloak.models.ApplicationModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
@ -14,6 +9,11 @@ import org.keycloak.models.mongo.keycloak.data.ApplicationData;
|
|||
import org.keycloak.models.mongo.keycloak.data.RoleData;
|
||||
import org.keycloak.models.mongo.keycloak.data.UserData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
6
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoDBSessionFactory.java
Normal file → Executable file
6
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoDBSessionFactory.java
Normal file → Executable file
|
@ -1,7 +1,5 @@
|
|||
package org.keycloak.models.mongo.keycloak.adapters;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.MongoClient;
|
||||
import org.jboss.logging.Logger;
|
||||
|
@ -9,6 +7,7 @@ import org.keycloak.models.KeycloakSession;
|
|||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.mongo.api.NoSQL;
|
||||
import org.keycloak.models.mongo.api.NoSQLObject;
|
||||
import org.keycloak.models.mongo.impl.MongoDBImpl;
|
||||
import org.keycloak.models.mongo.keycloak.data.ApplicationData;
|
||||
import org.keycloak.models.mongo.keycloak.data.OAuthClientData;
|
||||
import org.keycloak.models.mongo.keycloak.data.RealmData;
|
||||
|
@ -16,10 +15,11 @@ import org.keycloak.models.mongo.keycloak.data.RequiredCredentialData;
|
|||
import org.keycloak.models.mongo.keycloak.data.RoleData;
|
||||
import org.keycloak.models.mongo.keycloak.data.SocialLinkData;
|
||||
import org.keycloak.models.mongo.keycloak.data.UserData;
|
||||
import org.keycloak.models.mongo.impl.MongoDBImpl;
|
||||
import org.keycloak.models.mongo.keycloak.data.credentials.OTPData;
|
||||
import org.keycloak.models.mongo.keycloak.data.credentials.PasswordData;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/**
|
||||
* NoSQL implementation based on MongoDB
|
||||
*
|
||||
|
|
8
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/NoSQLSession.java
Normal file → Executable file
8
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/NoSQLSession.java
Normal file → Executable file
|
@ -1,17 +1,17 @@
|
|||
package org.keycloak.models.mongo.keycloak.adapters;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakTransaction;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.mongo.api.NoSQL;
|
||||
import org.keycloak.models.mongo.api.query.NoSQLQuery;
|
||||
import org.keycloak.models.mongo.keycloak.data.RealmData;
|
||||
import org.keycloak.models.mongo.api.NoSQL;
|
||||
import org.keycloak.models.utils.KeycloakSessionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
10
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java
Normal file → Executable file
10
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java
Normal file → Executable file
|
@ -41,14 +41,4 @@ public class OAuthClientAdapter implements OAuthClientModel {
|
|||
return oauthAgent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseUrl() {
|
||||
return delegate.getBaseUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBaseUrl(String base) {
|
||||
delegate.setBaseUrl(base);
|
||||
noSQL.saveObject(delegate);
|
||||
}
|
||||
}
|
||||
|
|
63
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
Normal file → Executable file
63
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
Normal file → Executable file
|
@ -1,16 +1,5 @@
|
|||
package org.keycloak.models.mongo.keycloak.adapters;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bouncycastle.openssl.PEMWriter;
|
||||
import org.keycloak.PemUtils;
|
||||
import org.keycloak.models.ApplicationModel;
|
||||
|
@ -21,21 +10,31 @@ import org.keycloak.models.RoleModel;
|
|||
import org.keycloak.models.SocialLinkModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.mongo.api.query.NoSQLQueryBuilder;
|
||||
import org.keycloak.models.mongo.keycloak.data.OAuthClientData;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.models.mongo.api.NoSQL;
|
||||
import org.keycloak.models.mongo.api.query.NoSQLQuery;
|
||||
import org.keycloak.models.mongo.api.query.NoSQLQueryBuilder;
|
||||
import org.keycloak.models.mongo.keycloak.credentials.PasswordCredentialHandler;
|
||||
import org.keycloak.models.mongo.keycloak.credentials.TOTPCredentialHandler;
|
||||
import org.keycloak.models.mongo.keycloak.data.ApplicationData;
|
||||
import org.keycloak.models.mongo.keycloak.data.OAuthClientData;
|
||||
import org.keycloak.models.mongo.keycloak.data.RealmData;
|
||||
import org.keycloak.models.mongo.keycloak.data.RequiredCredentialData;
|
||||
import org.keycloak.models.mongo.keycloak.data.RoleData;
|
||||
import org.keycloak.models.mongo.keycloak.data.SocialLinkData;
|
||||
import org.keycloak.models.mongo.keycloak.data.UserData;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.picketlink.idm.credential.Credentials;
|
||||
import org.picketlink.idm.model.sample.User;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
|
@ -596,20 +595,6 @@ public class RealmAdapter implements RealmModel {
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRealmAdmin(UserModel agent) {
|
||||
List<String> realmAdmins = realm.getRealmAdmins();
|
||||
String userId = ((UserAdapter)agent).getUser().getId();
|
||||
return realmAdmins.contains(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRealmAdmin(UserModel agent) {
|
||||
UserData userData = ((UserAdapter)agent).getUser();
|
||||
|
||||
noSQL.pushItemToList(realm, "realmAdmins", userData.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleModel getRoleById(String id) {
|
||||
RoleData role = noSQL.loadObject(RoleData.class, id);
|
||||
|
@ -859,4 +844,24 @@ public class RealmAdapter implements RealmModel {
|
|||
}
|
||||
return userModels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getSmtpConfig() {
|
||||
throw new RuntimeException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSmtpConfig(Map<String, String> smtpConfig) {
|
||||
throw new RuntimeException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getSocialConfig() {
|
||||
throw new RuntimeException("Not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSocialConfig(Map<String, String> socialConfig) {
|
||||
throw new RuntimeException("Not implemented");
|
||||
}
|
||||
}
|
||||
|
|
48
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
Normal file → Executable file
48
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
Normal file → Executable file
|
@ -1,15 +1,15 @@
|
|||
package org.keycloak.models.mongo.keycloak.adapters;
|
||||
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.mongo.api.NoSQL;
|
||||
import org.keycloak.models.mongo.keycloak.data.UserData;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.mongo.api.NoSQL;
|
||||
import org.keycloak.models.mongo.keycloak.data.UserData;
|
||||
|
||||
/**
|
||||
* Wrapper around UserData object, which will persist wrapped object after each set operation (compatibility with picketlink based impl)
|
||||
*
|
||||
|
@ -149,4 +149,44 @@ public class UserAdapter implements UserModel {
|
|||
user.setTotp(totp);
|
||||
noSQL.saveObject(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getWebOrigins() {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWebOrigins(Set<String> webOrigins) {
|
||||
//To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addWebOrigin(String webOrigin) {
|
||||
//To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWebOrigin(String webOrigin) {
|
||||
//To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRedirectUris() {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRedirectUris(Set<String> redirectUris) {
|
||||
//To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRedirectUri(String redirectUri) {
|
||||
//To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRedirectUri(String redirectUri) {
|
||||
//To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
|
8
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/credentials/PasswordCredentialHandler.java
Normal file → Executable file
8
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/credentials/PasswordCredentialHandler.java
Normal file → Executable file
|
@ -1,9 +1,5 @@
|
|||
package org.keycloak.models.mongo.keycloak.credentials;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.keycloak.models.mongo.api.NoSQL;
|
||||
import org.keycloak.models.mongo.api.query.NoSQLQuery;
|
||||
import org.keycloak.models.mongo.keycloak.data.UserData;
|
||||
|
@ -12,6 +8,10 @@ import org.picketlink.idm.credential.Credentials;
|
|||
import org.picketlink.idm.credential.encoder.PasswordEncoder;
|
||||
import org.picketlink.idm.credential.encoder.SHAPasswordEncoder;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Defacto forked from {@link org.picketlink.idm.credential.handler.PasswordCredentialHandler}
|
||||
*
|
||||
|
|
11
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/credentials/TOTPCredentialHandler.java
Normal file → Executable file
11
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/credentials/TOTPCredentialHandler.java
Normal file → Executable file
|
@ -1,8 +1,5 @@
|
|||
package org.keycloak.models.mongo.keycloak.credentials;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.keycloak.models.mongo.api.NoSQL;
|
||||
import org.keycloak.models.mongo.api.query.NoSQLQuery;
|
||||
import org.keycloak.models.mongo.keycloak.data.UserData;
|
||||
|
@ -10,11 +7,11 @@ import org.keycloak.models.mongo.keycloak.data.credentials.OTPData;
|
|||
import org.picketlink.idm.credential.Credentials;
|
||||
import org.picketlink.idm.credential.util.TimeBasedOTP;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.picketlink.common.util.StringUtil.isNullOrEmpty;
|
||||
import static org.picketlink.idm.credential.util.TimeBasedOTP.DEFAULT_ALGORITHM;
|
||||
import static org.picketlink.idm.credential.util.TimeBasedOTP.DEFAULT_DELAY_WINDOW;
|
||||
import static org.picketlink.idm.credential.util.TimeBasedOTP.DEFAULT_INTERVAL_SECONDS;
|
||||
import static org.picketlink.idm.credential.util.TimeBasedOTP.DEFAULT_NUMBER_DIGITS;
|
||||
import static org.picketlink.idm.credential.util.TimeBasedOTP.*;
|
||||
|
||||
/**
|
||||
* Defacto forked from {@link org.picketlink.idm.credential.handler.TOTPCredentialHandler}
|
||||
|
|
4
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/RealmData.java
Normal file → Executable file
4
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/RealmData.java
Normal file → Executable file
|
@ -1,7 +1,5 @@
|
|||
package org.keycloak.models.mongo.keycloak.data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.keycloak.models.mongo.api.NoSQL;
|
||||
import org.keycloak.models.mongo.api.NoSQLCollection;
|
||||
import org.keycloak.models.mongo.api.NoSQLField;
|
||||
|
@ -9,6 +7,8 @@ import org.keycloak.models.mongo.api.NoSQLId;
|
|||
import org.keycloak.models.mongo.api.NoSQLObject;
|
||||
import org.keycloak.models.mongo.api.query.NoSQLQuery;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
4
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/RoleData.java
Normal file → Executable file
4
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/RoleData.java
Normal file → Executable file
|
@ -1,7 +1,5 @@
|
|||
package org.keycloak.models.mongo.keycloak.data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.models.mongo.api.NoSQL;
|
||||
import org.keycloak.models.mongo.api.NoSQLCollection;
|
||||
|
@ -10,6 +8,8 @@ import org.keycloak.models.mongo.api.NoSQLId;
|
|||
import org.keycloak.models.mongo.api.NoSQLObject;
|
||||
import org.keycloak.models.mongo.api.query.NoSQLQuery;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
4
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/UserData.java
Normal file → Executable file
4
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/UserData.java
Normal file → Executable file
|
@ -1,7 +1,5 @@
|
|||
package org.keycloak.models.mongo.keycloak.data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.mongo.api.AbstractAttributedNoSQLObject;
|
||||
|
@ -12,6 +10,8 @@ import org.keycloak.models.mongo.api.NoSQLId;
|
|||
import org.keycloak.models.mongo.api.query.NoSQLQuery;
|
||||
import org.keycloak.models.mongo.keycloak.data.credentials.PasswordData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
4
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/credentials/OTPData.java
Normal file → Executable file
4
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/credentials/OTPData.java
Normal file → Executable file
|
@ -1,11 +1,11 @@
|
|||
package org.keycloak.models.mongo.keycloak.data.credentials;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.keycloak.models.mongo.api.AbstractNoSQLObject;
|
||||
import org.keycloak.models.mongo.api.NoSQLCollection;
|
||||
import org.keycloak.models.mongo.api.NoSQLField;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
4
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/credentials/PasswordData.java
Normal file → Executable file
4
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/data/credentials/PasswordData.java
Normal file → Executable file
|
@ -1,11 +1,11 @@
|
|||
package org.keycloak.models.mongo.keycloak.data.credentials;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.keycloak.models.mongo.api.AbstractNoSQLObject;
|
||||
import org.keycloak.models.mongo.api.NoSQLCollection;
|
||||
import org.keycloak.models.mongo.api.NoSQLField;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
4
model/mongo/src/test/java/org/keycloak/models/mongo/test/Address.java
Normal file → Executable file
4
model/mongo/src/test/java/org/keycloak/models/mongo/test/Address.java
Normal file → Executable file
|
@ -1,10 +1,10 @@
|
|||
package org.keycloak.models.mongo.test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.keycloak.models.mongo.api.AbstractNoSQLObject;
|
||||
import org.keycloak.models.mongo.api.NoSQLField;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
10
model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoDBModelTest.java
Normal file → Executable file
10
model/mongo/src/test/java/org/keycloak/models/mongo/test/MongoDBModelTest.java
Normal file → Executable file
|
@ -1,10 +1,5 @@
|
|||
package org.keycloak.models.mongo.test;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.MongoClient;
|
||||
import org.junit.After;
|
||||
|
@ -15,6 +10,11 @@ import org.keycloak.models.mongo.api.NoSQLObject;
|
|||
import org.keycloak.models.mongo.api.query.NoSQLQuery;
|
||||
import org.keycloak.models.mongo.impl.MongoDBImpl;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
4
model/mongo/src/test/java/org/keycloak/models/mongo/test/Person.java
Normal file → Executable file
4
model/mongo/src/test/java/org/keycloak/models/mongo/test/Person.java
Normal file → Executable file
|
@ -1,12 +1,12 @@
|
|||
package org.keycloak.models.mongo.test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.keycloak.models.mongo.api.AbstractNoSQLObject;
|
||||
import org.keycloak.models.mongo.api.NoSQLCollection;
|
||||
import org.keycloak.models.mongo.api.NoSQLField;
|
||||
import org.keycloak.models.mongo.api.NoSQLId;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
|
|
@ -31,14 +31,4 @@ public class OAuthClientAdapter implements OAuthClientModel {
|
|||
return new UserAdapter(delegate.getOauthAgent(), idm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseUrl() {
|
||||
return delegate.getBaseUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBaseUrl(String base) {
|
||||
delegate.setBaseUrl(base);
|
||||
relationshipManager.update(delegate);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import org.keycloak.models.KeycloakTransaction;
|
|||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.picketlink.mappings.RealmData;
|
||||
import org.keycloak.models.picketlink.relationships.RealmAdminRelationship;
|
||||
import org.keycloak.models.picketlink.relationships.RealmListingRelationship;
|
||||
import org.keycloak.models.utils.KeycloakSessionUtils;
|
||||
import org.picketlink.idm.PartitionManager;
|
||||
|
@ -15,7 +14,6 @@ import org.picketlink.idm.query.RelationshipQuery;
|
|||
import javax.persistence.EntityManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
package org.keycloak.models.picketlink;
|
||||
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.ModelProvider;
|
||||
import org.keycloak.models.picketlink.mappings.ApplicationEntity;
|
||||
import org.keycloak.models.picketlink.mappings.RealmEntity;
|
||||
import org.picketlink.idm.PartitionManager;
|
||||
import org.picketlink.idm.config.IdentityConfigurationBuilder;
|
||||
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.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class PicketlinkModelProvider implements ModelProvider {
|
||||
@Override
|
||||
public KeycloakSessionFactory createFactory() {
|
||||
EntityManagerFactory emf = Persistence.createEntityManagerFactory("picketlink-keycloak-identity-store");
|
||||
return new PicketlinkKeycloakSessionFactory(emf, buildPartitionManager());
|
||||
}
|
||||
|
||||
public static PartitionManager buildPartitionManager() {
|
||||
IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder();
|
||||
|
||||
builder
|
||||
.named("KEYCLOAK_JPA_CONFIG")
|
||||
.stores()
|
||||
.jpa()
|
||||
.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,
|
||||
ApplicationEntity.class
|
||||
)
|
||||
.supportGlobalRelationship(org.picketlink.idm.model.Relationship.class)
|
||||
.addContextInitializer(new JPAContextInitializer(null) {
|
||||
@Override
|
||||
public EntityManager getEntityManager() {
|
||||
return PicketlinkKeycloakSession.currentEntityManager.get();
|
||||
}
|
||||
})
|
||||
.supportAllFeatures();
|
||||
|
||||
DefaultPartitionManager partitionManager = new DefaultPartitionManager(builder.buildAll());
|
||||
return partitionManager;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,11 +2,25 @@ package org.keycloak.models.picketlink;
|
|||
|
||||
import org.bouncycastle.openssl.PEMWriter;
|
||||
import org.keycloak.PemUtils;
|
||||
import org.keycloak.models.*;
|
||||
import org.keycloak.models.picketlink.mappings.RealmData;
|
||||
import org.keycloak.models.ApplicationModel;
|
||||
import org.keycloak.models.IdGenerator;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.OAuthClientModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RequiredCredentialModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.SocialLinkModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.picketlink.mappings.ApplicationData;
|
||||
import org.keycloak.models.picketlink.relationships.*;
|
||||
import org.keycloak.models.picketlink.mappings.RealmData;
|
||||
import org.keycloak.models.picketlink.relationships.ApplicationRelationship;
|
||||
import org.keycloak.models.picketlink.relationships.OAuthClientRelationship;
|
||||
import org.keycloak.models.picketlink.relationships.OAuthClientRequiredCredentialRelationship;
|
||||
import org.keycloak.models.picketlink.relationships.RequiredApplicationCredentialRelationship;
|
||||
import org.keycloak.models.picketlink.relationships.RequiredCredentialRelationship;
|
||||
import org.keycloak.models.picketlink.relationships.ScopeRelationship;
|
||||
import org.keycloak.models.picketlink.relationships.SocialLinkRelationship;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.PartitionManager;
|
||||
import org.picketlink.idm.RelationshipManager;
|
||||
|
@ -601,7 +615,6 @@ public class RealmAdapter implements RealmModel {
|
|||
idm.add(resourceUser);
|
||||
applicationData.setResourceUser(resourceUser);
|
||||
applicationData.setResourceName(name);
|
||||
applicationData.setResourceUser(resourceUser);
|
||||
partitionManager.add(applicationData);
|
||||
ApplicationRelationship resourceRelationship = new ApplicationRelationship();
|
||||
resourceRelationship.setRealm(realm.getName());
|
||||
|
@ -875,23 +888,23 @@ public class RealmAdapter implements RealmModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public HashMap<String, String> getSmtpConfig() {
|
||||
public Map<String, String> getSmtpConfig() {
|
||||
return realm.getSmtpConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSmtpConfig(HashMap<String, String> smtpConfig) {
|
||||
public void setSmtpConfig(Map<String, String> smtpConfig) {
|
||||
realm.setSmtpConfig(smtpConfig);
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<String, String> getSocialConfig() {
|
||||
public Map<String, String> getSocialConfig() {
|
||||
return realm.getSocialConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSocialConfig(HashMap<String, String> socialConfig) {
|
||||
public void setSocialConfig(Map<String, String> socialConfig) {
|
||||
realm.setSocialConfig(socialConfig);
|
||||
updateRealm();
|
||||
}
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
package org.keycloak.models.picketlink;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.model.Attribute;
|
||||
import org.picketlink.idm.model.sample.User;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
|
|
|
@ -3,8 +3,7 @@ package org.keycloak.models.picketlink.mappings;
|
|||
import org.picketlink.idm.model.AbstractPartition;
|
||||
import org.picketlink.idm.model.annotation.AttributeProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -26,8 +25,8 @@ public class RealmData extends AbstractPartition {
|
|||
private String publicKeyPem;
|
||||
private String privateKeyPem;
|
||||
private String[] defaultRoles;
|
||||
private HashMap<String, String> smtpConfig;
|
||||
private HashMap<String, String> socialConfig;
|
||||
private Map<String, String> smtpConfig;
|
||||
private Map<String, String> socialConfig;
|
||||
|
||||
public RealmData() {
|
||||
super(null);
|
||||
|
@ -170,20 +169,20 @@ public class RealmData extends AbstractPartition {
|
|||
}
|
||||
|
||||
@AttributeProperty
|
||||
public HashMap<String, String> getSmtpConfig() {
|
||||
public Map<String, String> getSmtpConfig() {
|
||||
return smtpConfig;
|
||||
}
|
||||
|
||||
public void setSmtpConfig(HashMap<String, String> smtpConfig) {
|
||||
public void setSmtpConfig(Map<String, String> smtpConfig) {
|
||||
this.smtpConfig = smtpConfig;
|
||||
}
|
||||
|
||||
@AttributeProperty
|
||||
public HashMap<String, String> getSocialConfig() {
|
||||
public Map<String, String> getSocialConfig() {
|
||||
return socialConfig;
|
||||
}
|
||||
|
||||
public void setSocialConfig(HashMap<String, String> socialConfig) {
|
||||
public void setSocialConfig(Map<String, String> socialConfig) {
|
||||
this.socialConfig = socialConfig;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,11 @@ 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.*;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Lob;
|
||||
import javax.persistence.OneToOne;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
|
|
@ -3,9 +3,7 @@ package org.keycloak.models.picketlink.relationships;
|
|||
import org.picketlink.idm.model.AbstractAttributedType;
|
||||
import org.picketlink.idm.model.Attribute;
|
||||
import org.picketlink.idm.model.Relationship;
|
||||
import org.picketlink.idm.model.sample.User;
|
||||
import org.picketlink.idm.query.AttributeParameter;
|
||||
import org.picketlink.idm.query.RelationshipQueryParameter;
|
||||
|
||||
/**
|
||||
* Picketlink doesn't allow you to query for all partitions, thus this stupid relationship...
|
||||
|
|
|
@ -37,6 +37,6 @@
|
|||
<module>api</module>
|
||||
<module>picketlink</module>
|
||||
<module>jpa</module>
|
||||
<!--<module>mongo</module>-->
|
||||
<module>mongo</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -9,7 +9,7 @@
|
|||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<resteasy.version>3.0.4.Final</resteasy.version>
|
||||
<resteasy.version>3.0.5.Final</resteasy.version>
|
||||
<undertow.version>1.0.0.Beta12</undertow.version>
|
||||
<picketlink.version>2.5.0.Beta6</picketlink.version>
|
||||
<mongo.driver.version>2.11.2</mongo.driver.version>
|
||||
|
|
|
@ -33,6 +33,12 @@
|
|||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-model-picketlink</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-model-jpa</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--<dependency>
|
||||
|
|
|
@ -21,21 +21,20 @@
|
|||
*/
|
||||
package org.keycloak.services;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.imageio.spi.ServiceRegistry;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.services.resources.flows.FormFlows;
|
||||
import org.keycloak.social.SocialProvider;
|
||||
|
||||
import javax.imageio.spi.ServiceRegistry;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import java.net.URI;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:vrockai@redhat.com">Viliam Rockai</a>
|
||||
*/
|
||||
|
@ -95,7 +94,7 @@ public interface FormService {
|
|||
this.message = message;
|
||||
|
||||
socialProviders = new LinkedList<SocialProvider>();
|
||||
HashMap<String, String> socialConfig = realm.getSocialConfig();
|
||||
Map<String, String> socialConfig = realm.getSocialConfig();
|
||||
if (socialConfig != null) {
|
||||
for (Iterator<SocialProvider> itr = ServiceRegistry.lookupProviders(org.keycloak.social.SocialProvider.class); itr.hasNext(); ) {
|
||||
SocialProvider p = itr.next();
|
||||
|
|
|
@ -21,28 +21,25 @@
|
|||
*/
|
||||
package org.keycloak.services.email;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.jboss.resteasy.logging.Logger;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.services.managers.AccessCodeEntry;
|
||||
import org.keycloak.services.resources.flows.Urls;
|
||||
|
||||
import javax.mail.Message;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.Transport;
|
||||
import javax.mail.internet.AddressException;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.jboss.resteasy.logging.Logger;
|
||||
import org.keycloak.services.managers.AccessCodeEntry;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.services.resources.AccountService;
|
||||
import org.keycloak.services.resources.flows.Urls;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
|
|
|
@ -5,7 +5,12 @@ import org.keycloak.models.KeycloakSession;
|
|||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.KeycloakTransaction;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue