Merge pull request #14 from patriot1burke/master
picketlink abstraction
This commit is contained in:
commit
7c9c39c3f8
54 changed files with 1724 additions and 1169 deletions
|
@ -3,40 +3,15 @@ package org.keycloak.example.demo;
|
|||
import org.jboss.resteasy.jwt.JsonSerialization;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RequiredCredentialModel;
|
||||
import org.keycloak.services.models.relationships.RealmAdminRelationship;
|
||||
import org.keycloak.services.models.relationships.RequiredCredentialRelationship;
|
||||
import org.keycloak.services.models.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.relationships.ScopeRelationship;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
import org.keycloak.services.resources.RegistrationService;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.IdentitySessionFactory;
|
||||
import org.picketlink.idm.config.IdentityConfiguration;
|
||||
import org.picketlink.idm.config.IdentityConfigurationBuilder;
|
||||
import org.picketlink.idm.internal.DefaultIdentitySessionFactory;
|
||||
import org.picketlink.idm.jpa.internal.ResourceLocalJpaIdentitySessionHandler;
|
||||
import org.picketlink.idm.jpa.schema.CredentialObject;
|
||||
import org.picketlink.idm.jpa.schema.CredentialObjectAttribute;
|
||||
import org.picketlink.idm.jpa.schema.IdentityObject;
|
||||
import org.picketlink.idm.jpa.schema.IdentityObjectAttribute;
|
||||
import org.picketlink.idm.jpa.schema.PartitionObject;
|
||||
import org.picketlink.idm.jpa.schema.RelationshipIdentityObject;
|
||||
import org.picketlink.idm.jpa.schema.RelationshipObject;
|
||||
import org.picketlink.idm.jpa.schema.RelationshipObjectAttribute;
|
||||
import org.picketlink.idm.model.Realm;
|
||||
import org.picketlink.idm.model.SimpleRole;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Application;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
|
@ -45,7 +20,7 @@ public class DemoApplication extends KeycloakApplication {
|
|||
|
||||
public DemoApplication() {
|
||||
super();
|
||||
IdentitySession session = factory.createIdentitySession();
|
||||
KeycloakSession session = factory.createSession();
|
||||
session.getTransaction().begin();
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
if (realmManager.defaultRealm() == null) {
|
||||
|
@ -55,8 +30,8 @@ public class DemoApplication extends KeycloakApplication {
|
|||
}
|
||||
|
||||
public void install(RealmManager manager) {
|
||||
RealmModel defaultRealm = manager.createRealm(Realm.DEFAULT_REALM, Realm.DEFAULT_REALM);
|
||||
defaultRealm.setName(Realm.DEFAULT_REALM);
|
||||
RealmModel defaultRealm = manager.createRealm(RealmModel.DEFAULT_REALM, RealmModel.DEFAULT_REALM);
|
||||
defaultRealm.setName(RealmModel.DEFAULT_REALM);
|
||||
defaultRealm.setEnabled(true);
|
||||
defaultRealm.setTokenLifespan(300);
|
||||
defaultRealm.setAccessCodeLifespan(60);
|
||||
|
@ -64,7 +39,6 @@ public class DemoApplication extends KeycloakApplication {
|
|||
defaultRealm.setCookieLoginAllowed(true);
|
||||
defaultRealm.setRegistrationAllowed(true);
|
||||
manager.generateRealmKeys(defaultRealm);
|
||||
defaultRealm.updateRealm();
|
||||
defaultRealm.addRequiredCredential(RequiredCredentialModel.PASSWORD);
|
||||
defaultRealm.addRole(RegistrationService.REALM_CREATOR_ROLE);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<%@ page import="org.picketlink.idm.model.*,org.keycloak.services.models.*,org.keycloak.services.resources.*,javax.ws.rs.core.*,java.util.*" language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
<%@ page import="org.keycloak.services.models.*,org.keycloak.services.resources.*,javax.ws.rs.core.*,java.util.*" language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1"%>
|
||||
<%
|
||||
RealmModel realm = (RealmModel)request.getAttribute(RealmModel.class.getName());
|
||||
|
@ -22,9 +22,9 @@
|
|||
<body>
|
||||
|
||||
<%
|
||||
User client = (User)request.getAttribute("client");
|
||||
List<Role> realmRolesRequested = (List<Role>)request.getAttribute("realmRolesRequested");
|
||||
MultivaluedMap<String, Role> resourceRolesRequested = (MultivaluedMap<String, Role>)request.getAttribute("resourceRolesRequested");
|
||||
UserModel client = (UserModel)request.getAttribute("client");
|
||||
List<RoleModel> realmRolesRequested = (List<RoleModel>)request.getAttribute("realmRolesRequested");
|
||||
MultivaluedMap<String, RoleModel> resourceRolesRequested = (MultivaluedMap<String, RoleModel>)request.getAttribute("resourceRolesRequested");
|
||||
%>
|
||||
|
||||
<h1>Grant request for: <%=client.getLoginName()%></h1>
|
||||
|
@ -36,11 +36,11 @@
|
|||
<%
|
||||
if (realmRolesRequested.size() > 0) {
|
||||
%> <ul> <%
|
||||
for (Role role : realmRolesRequested) {
|
||||
for (RoleModel role : realmRolesRequested) {
|
||||
String desc = "Have " + role.getName() + " privileges.";
|
||||
Attribute roleDesc = role.getAttribute("description");
|
||||
String roleDesc = role.getDescription();
|
||||
if (roleDesc != null) {
|
||||
desc = (String)roleDesc.getValue();
|
||||
desc = roleDesc;
|
||||
}
|
||||
%>
|
||||
<li><%=desc%></li>
|
||||
|
@ -49,14 +49,14 @@
|
|||
%> </ul> <%
|
||||
}
|
||||
for (String resource : resourceRolesRequested.keySet()) {
|
||||
List<Role> roles = resourceRolesRequested.get(resource);
|
||||
List<RoleModel> roles = resourceRolesRequested.get(resource);
|
||||
out.println("<i>For application " + resource + ":</i> ");
|
||||
out.println("<ul>");
|
||||
for (Role role : roles) {
|
||||
for (RoleModel role : roles) {
|
||||
String desc = "Have " + role.getName() + " privileges.";
|
||||
Attribute roleDesc = role.getAttribute("description");
|
||||
String roleDesc = role.getDescription();
|
||||
if (roleDesc != null) {
|
||||
desc = (String)roleDesc.getValue();
|
||||
desc = roleDesc;
|
||||
}
|
||||
out.println("<li>" + desc + "</li>");
|
||||
}
|
||||
|
|
|
@ -1,42 +1,42 @@
|
|||
<?xml version="1.0"?>
|
||||
<project>
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0-alpha-1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0-alpha-1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-sdk-html</artifactId>
|
||||
<name>Keycloak HTML SDK</name>
|
||||
<description />
|
||||
<artifactId>keycloak-sdk-html</artifactId>
|
||||
<name>Keycloak HTML SDK</name>
|
||||
<description/>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-social</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>jaxrs-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-social</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>jaxrs-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
66
sdk-html/src/main/resources/META-INF/resources/sdk/login.html
Normal file → Executable file
66
sdk-html/src/main/resources/META-INF/resources/sdk/login.html
Normal file → Executable file
|
@ -1,46 +1,46 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link href="css/bootstrap.css" rel="stylesheet">
|
||||
<link href="css/default.css" rel="stylesheet">
|
||||
<meta charset="utf-8">
|
||||
<link href="css/bootstrap.css" rel="stylesheet">
|
||||
<link href="css/default.css" rel="stylesheet">
|
||||
|
||||
<script src="js/angular.js"></script>
|
||||
<script src="js/angular-resource.js"></script>
|
||||
<script src="js/app.js"></script>
|
||||
<script src="js/angular.js"></script>
|
||||
<script src="js/angular-resource.js"></script>
|
||||
<script src="js/app.js"></script>
|
||||
</head>
|
||||
|
||||
<body class=keycloak-login-page data-ng-app=keycloak>
|
||||
<div id=keycloak-login-container data-ng-controller=GlobalCtrl>
|
||||
<div id=keycloak-login-standard>
|
||||
<h1>Login to {{config.name}}</h1>
|
||||
|
||||
<div class="alert alert-info" data-ng-show="info">{{info}}</div>
|
||||
<div class="alert alert-error" data-ng-show="error">{{error}}</div>
|
||||
<div id=keycloak-login-container data-ng-controller=GlobalCtrl>
|
||||
<div id=keycloak-login-standard>
|
||||
<h1>Login to {{config.name}}</h1>
|
||||
|
||||
<form action="#">
|
||||
<label for=username>Username</label>
|
||||
<input id=username type=text data-ng-model=username required />
|
||||
|
||||
<label for=password>Password</label>
|
||||
<input id=password type=text data-ng-model=password required />
|
||||
|
||||
<div>
|
||||
<button class="btn btn-primary" id=keycloak-login-submit type=submit>Login</button>
|
||||
<a class="btn" href="register.html?application={{config.id}}">Register</a>
|
||||
<a class="btn" href="{{config.callbackUrl}}">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="alert alert-info" data-ng-show="info">{{info}}</div>
|
||||
<div class="alert alert-error" data-ng-show="error">{{error}}</div>
|
||||
|
||||
<div id=keycloak-login-social>
|
||||
<h3>Login with</h3>
|
||||
<form action="#">
|
||||
<label for=username>Username</label>
|
||||
<input id=username type=text data-ng-model=username required/>
|
||||
|
||||
<div data-ng-repeat="p in config.providers">
|
||||
<a href="/keycloak-server/social/api/{{config.id}}/auth/{{p}}"><img data-ng-src="icons/{{p}}.png" /></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<label for=password>Password</label>
|
||||
<input id=password type=text data-ng-model=password required/>
|
||||
|
||||
<div>
|
||||
<button class="btn btn-primary" id=keycloak-login-submit type=submit>Login</button>
|
||||
<a class="btn" href="register.html?application={{config.id}}">Register</a>
|
||||
<a class="btn" href="{{config.callbackUrl}}">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id=keycloak-login-social>
|
||||
<h3>Login with</h3>
|
||||
|
||||
<div data-ng-repeat="p in config.providers">
|
||||
<a href="/keycloak-server/social/api/{{config.id}}/auth/{{p}}"><img data-ng-src="icons/{{p}}.png"/></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
87
sdk-html/src/main/resources/META-INF/resources/sdk/register.html
Normal file → Executable file
87
sdk-html/src/main/resources/META-INF/resources/sdk/register.html
Normal file → Executable file
|
@ -1,57 +1,58 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link href="css/bootstrap.css" rel="stylesheet">
|
||||
<link href="css/default.css" rel="stylesheet">
|
||||
<meta charset="utf-8">
|
||||
<link href="css/bootstrap.css" rel="stylesheet">
|
||||
<link href="css/default.css" rel="stylesheet">
|
||||
|
||||
<script src="js/angular.js"></script>
|
||||
<script src="js/angular-resource.js"></script>
|
||||
<script src="js/app.js"></script>
|
||||
<script src="js/angular.js"></script>
|
||||
<script src="js/angular-resource.js"></script>
|
||||
<script src="js/app.js"></script>
|
||||
</head>
|
||||
|
||||
<body class=keycloak-login-page data-ng-app=keycloak>
|
||||
<div id=keycloak-login-container data-ng-controller=GlobalCtrl>
|
||||
<div id=keycloak-login-standard>
|
||||
<h1>Register with {{config.name}}</h1>
|
||||
|
||||
<div class="alert alert-info" data-ng-show="info">{{info}}</div>
|
||||
<div class="alert alert-error" data-ng-show="error">{{error}}</div>
|
||||
<div id=keycloak-login-container data-ng-controller=GlobalCtrl>
|
||||
<div id=keycloak-login-standard>
|
||||
<h1>Register with {{config.name}}</h1>
|
||||
|
||||
<form action="#">
|
||||
<label for=firstname>Firstname</label>
|
||||
<input id=firstname type=text data-ng-model=firstname />
|
||||
|
||||
<label for=lastname>Lastname</label>
|
||||
<input id=lastname type=text data-ng-model=lastname />
|
||||
|
||||
<label for=email>Email</label>
|
||||
<input id=email type=email data-ng-model=email />
|
||||
<div class="alert alert-info" data-ng-show="info">{{info}}</div>
|
||||
<div class="alert alert-error" data-ng-show="error">{{error}}</div>
|
||||
|
||||
<label for=username>Username</label>
|
||||
<input id=username type=text data-ng-model=username />
|
||||
|
||||
<label for=password>Password</label>
|
||||
<input id=password type=text data-ng-model=password required />
|
||||
|
||||
<label for=password-confirm>Password confirmation</label>
|
||||
<input id=password-confirm type=text data-ng-model=passwordConfirm required pattern="{{password}}" title="Passwords don't match" />
|
||||
|
||||
<div>
|
||||
<button class="btn btn-primary" id=keycloak-login-submit type=submit>Register</button>
|
||||
<a class="btn" href="{{config.callbackUrl}}">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<form action="#">
|
||||
<label for=firstname>Firstname</label>
|
||||
<input id=firstname type=text data-ng-model=firstname/>
|
||||
|
||||
<div id=keycloak-login-social>
|
||||
<h3>Login with</h3>
|
||||
<label for=lastname>Lastname</label>
|
||||
<input id=lastname type=text data-ng-model=lastname/>
|
||||
|
||||
<div data-ng-repeat="p in config.providers">
|
||||
<a href="/social/{{config.id}}/provider/{{p}}"><img data-ng-src="icons/{{p}}.png" /></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<label for=email>Email</label>
|
||||
<input id=email type=email data-ng-model=email/>
|
||||
|
||||
<label for=username>Username</label>
|
||||
<input id=username type=text data-ng-model=username/>
|
||||
|
||||
<label for=password>Password</label>
|
||||
<input id=password type=text data-ng-model=password required/>
|
||||
|
||||
<label for=password-confirm>Password confirmation</label>
|
||||
<input id=password-confirm type=text data-ng-model=passwordConfirm required pattern="{{password}}"
|
||||
title="Passwords don't match"/>
|
||||
|
||||
<div>
|
||||
<button class="btn btn-primary" id=keycloak-login-submit type=submit>Register</button>
|
||||
<a class="btn" href="{{config.callbackUrl}}">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id=keycloak-login-social>
|
||||
<h3>Login with</h3>
|
||||
|
||||
<div data-ng-repeat="p in config.providers">
|
||||
<a href="/social/{{config.id}}/provider/{{p}}"><img data-ng-src="icons/{{p}}.png"/></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,40 +1,40 @@
|
|||
<?xml version="1.0"?>
|
||||
<project>
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0-alpha-1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0-alpha-1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-server</artifactId>
|
||||
<name>Keycloak Server</name>
|
||||
<packaging>war</packaging>
|
||||
<artifactId>keycloak-server</artifactId>
|
||||
<name>Keycloak Server</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<description />
|
||||
<description/>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-sdk-html</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-social</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-ui</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-sdk-html</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-social</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-ui</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>jaxrs-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>jaxrs-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
6
server/src/main/webapp/WEB-INF/web.xml
Normal file → Executable file
6
server/src/main/webapp/WEB-INF/web.xml
Normal file → Executable file
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app 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"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd ">
|
||||
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-app_3_0.xsd ">
|
||||
|
||||
<module-name>keycloak-server</module-name>
|
||||
<module-name>keycloak-server</module-name>
|
||||
|
||||
</web-app>
|
||||
|
|
|
@ -2,8 +2,8 @@ package org.keycloak.services.filters;
|
|||
|
||||
import org.jboss.resteasy.logging.Logger;
|
||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.IdentitySessionFactory;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
|
||||
import javax.ws.rs.container.ContainerRequestContext;
|
||||
import javax.ws.rs.container.ContainerRequestFilter;
|
||||
|
@ -17,24 +17,24 @@ import java.io.IOException;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
@PreMatching
|
||||
public class IdentitySessionFilter implements ContainerRequestFilter, ContainerResponseFilter {
|
||||
protected static final Logger logger = Logger.getLogger(IdentitySessionFilter.class);
|
||||
protected IdentitySessionFactory factory;
|
||||
public class KeycloakSessionFilter implements ContainerRequestFilter, ContainerResponseFilter {
|
||||
protected static final Logger logger = Logger.getLogger(KeycloakSessionFilter.class);
|
||||
protected KeycloakSessionFactory factory;
|
||||
|
||||
public IdentitySessionFilter(IdentitySessionFactory factory) {
|
||||
public KeycloakSessionFilter(KeycloakSessionFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(ContainerRequestContext requestContext) throws IOException {
|
||||
IdentitySession ctx = factory.createIdentitySession();
|
||||
requestContext.setProperty(IdentitySession.class.getName(), ctx);
|
||||
ResteasyProviderFactory.pushContext(IdentitySession.class, ctx);
|
||||
KeycloakSession ctx = factory.createSession();
|
||||
requestContext.setProperty(KeycloakSession.class.getName(), ctx);
|
||||
ResteasyProviderFactory.pushContext(KeycloakSession.class, ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
|
||||
IdentitySession ctx = (IdentitySession)requestContext.getProperty(IdentitySession.class.getName());
|
||||
KeycloakSession ctx = (KeycloakSession)requestContext.getProperty(KeycloakSession.class.getName());
|
||||
if (ctx != null) ctx.close();
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
package org.keycloak.services.managers;
|
||||
|
||||
import org.keycloak.representations.SkeletonKeyToken;
|
||||
import org.picketlink.idm.model.Role;
|
||||
import org.picketlink.idm.model.User;
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
|
||||
import javax.ws.rs.core.MultivaluedHashMap;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
|
@ -22,10 +22,10 @@ public class AccessCodeEntry {
|
|||
|
||||
protected long expiration;
|
||||
protected SkeletonKeyToken token;
|
||||
protected User user;
|
||||
protected User client;
|
||||
protected List<Role> realmRolesRequested = new ArrayList<Role>();
|
||||
MultivaluedMap<String, Role> resourceRolesRequested = new MultivaluedHashMap<String, Role>();
|
||||
protected UserModel user;
|
||||
protected UserModel client;
|
||||
protected List<RoleModel> realmRolesRequested = new ArrayList<RoleModel>();
|
||||
MultivaluedMap<String, RoleModel> resourceRolesRequested = new MultivaluedHashMap<String, RoleModel>();
|
||||
|
||||
public boolean isExpired() {
|
||||
return expiration != 0 && (System.currentTimeMillis() / 1000) > expiration;
|
||||
|
@ -59,27 +59,27 @@ public class AccessCodeEntry {
|
|||
this.token = token;
|
||||
}
|
||||
|
||||
public User getClient() {
|
||||
public UserModel getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public void setClient(User client) {
|
||||
public void setClient(UserModel client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
public UserModel getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
public void setUser(UserModel user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public List<Role> getRealmRolesRequested() {
|
||||
public List<RoleModel> getRealmRolesRequested() {
|
||||
return realmRolesRequested;
|
||||
}
|
||||
|
||||
public MultivaluedMap<String, Role> getResourceRolesRequested() {
|
||||
public MultivaluedMap<String, RoleModel> getResourceRolesRequested() {
|
||||
return resourceRolesRequested;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,12 +9,8 @@ import org.keycloak.representations.SkeletonKeyToken;
|
|||
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RequiredCredentialModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
import org.keycloak.services.resources.RealmsResource;
|
||||
import org.picketlink.idm.credential.Credentials;
|
||||
import org.picketlink.idm.credential.Password;
|
||||
import org.picketlink.idm.credential.TOTPCredentials;
|
||||
import org.picketlink.idm.credential.UsernamePasswordCredentials;
|
||||
import org.picketlink.idm.model.User;
|
||||
|
||||
import javax.ws.rs.NotAuthorizedException;
|
||||
import javax.ws.rs.core.Cookie;
|
||||
|
@ -44,7 +40,7 @@ public class AuthenticationManager {
|
|||
* @return
|
||||
*/
|
||||
public boolean isRealmAdmin(RealmModel realm, HttpHeaders headers) {
|
||||
User user = authenticateBearerToken(realm, headers);
|
||||
UserModel user = authenticateBearerToken(realm, headers);
|
||||
return realm.isRealmAdmin(user);
|
||||
}
|
||||
|
||||
|
@ -60,7 +56,7 @@ public class AuthenticationManager {
|
|||
response.addNewCookie(expireIt);
|
||||
}
|
||||
|
||||
public User authenticateIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
|
||||
public UserModel authenticateIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
|
||||
Cookie cookie = headers.getCookies().get(TokenManager.KEYCLOAK_IDENTITY_COOKIE);
|
||||
if (cookie == null) return null;
|
||||
|
||||
|
@ -72,7 +68,7 @@ public class AuthenticationManager {
|
|||
expireIdentityCookie(realm, uriInfo);
|
||||
return null;
|
||||
}
|
||||
User user = realm.getUser(token.getPrincipal());
|
||||
UserModel user = realm.getUser(token.getPrincipal());
|
||||
if (user == null || !user.isEnabled()) {
|
||||
logger.info("Unknown user in identity cookie");
|
||||
expireIdentityCookie(realm, uriInfo);
|
||||
|
@ -86,7 +82,7 @@ public class AuthenticationManager {
|
|||
return null;
|
||||
}
|
||||
|
||||
public User authenticateBearerToken(RealmModel realm, HttpHeaders headers) {
|
||||
public UserModel authenticateBearerToken(RealmModel realm, HttpHeaders headers) {
|
||||
String tokenString = null;
|
||||
String authHeader = headers.getHeaderString(HttpHeaders.AUTHORIZATION);
|
||||
if (authHeader == null) {
|
||||
|
@ -104,7 +100,7 @@ public class AuthenticationManager {
|
|||
if (!token.isActive()) {
|
||||
throw new NotAuthorizedException("token_expired");
|
||||
}
|
||||
User user = realm.getUser(token.getPrincipal());
|
||||
UserModel user = realm.getUser(token.getPrincipal());
|
||||
if (user == null || !user.isEnabled()) {
|
||||
throw new NotAuthorizedException("invalid_user");
|
||||
}
|
||||
|
@ -115,7 +111,7 @@ public class AuthenticationManager {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean authenticateForm(RealmModel realm, User user, MultivaluedMap<String, String> formData) {
|
||||
public boolean authenticateForm(RealmModel realm, UserModel user, MultivaluedMap<String, String> formData) {
|
||||
String username = user.getLoginName();
|
||||
Set<String> types = new HashSet<String>();
|
||||
|
||||
|
|
|
@ -8,23 +8,16 @@ import org.keycloak.representations.idm.RoleMappingRepresentation;
|
|||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.representations.idm.ScopeMappingRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RequiredCredentialModel;
|
||||
import org.keycloak.services.models.ResourceModel;
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserCredentialModel;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.model.Attribute;
|
||||
import org.picketlink.idm.model.Realm;
|
||||
import org.picketlink.idm.model.Role;
|
||||
import org.picketlink.idm.model.SimpleAgent;
|
||||
import org.picketlink.idm.model.SimpleRole;
|
||||
import org.picketlink.idm.model.SimpleUser;
|
||||
import org.picketlink.idm.model.User;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.Serializable;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
@ -48,22 +41,18 @@ public class RealmManager {
|
|||
return counter.getAndIncrement() + "-" + System.currentTimeMillis();
|
||||
}
|
||||
|
||||
protected IdentitySession identitySession;
|
||||
protected KeycloakSession identitySession;
|
||||
|
||||
public RealmManager(IdentitySession identitySession) {
|
||||
public RealmManager(KeycloakSession identitySession) {
|
||||
this.identitySession = identitySession;
|
||||
}
|
||||
|
||||
public RealmModel defaultRealm() {
|
||||
return getRealm(Realm.DEFAULT_REALM);
|
||||
return getRealm(RealmModel.DEFAULT_REALM);
|
||||
}
|
||||
|
||||
public RealmModel getRealm(String id) {
|
||||
Realm existing = identitySession.findRealm(id);
|
||||
if (existing == null) {
|
||||
return null;
|
||||
}
|
||||
return new RealmModel(existing, identitySession);
|
||||
return identitySession.getRealm(id);
|
||||
}
|
||||
|
||||
public RealmModel createRealm(String name) {
|
||||
|
@ -71,14 +60,11 @@ public class RealmManager {
|
|||
}
|
||||
|
||||
public RealmModel createRealm(String id, String name) {
|
||||
Realm newRealm = identitySession.createRealm(id);
|
||||
IdentityManager idm = identitySession.createIdentityManager(newRealm);
|
||||
SimpleAgent agent = new SimpleAgent(RealmModel.REALM_AGENT_ID);
|
||||
idm.add(agent);
|
||||
RealmModel realm = new RealmModel(newRealm, identitySession);
|
||||
idm.add(new SimpleRole(WILDCARD_ROLE));
|
||||
idm.add(new SimpleRole(RESOURCE_ROLE));
|
||||
idm.add(new SimpleRole(IDENTITY_REQUESTER_ROLE));
|
||||
RealmModel realm =identitySession.createRealm(id, name);
|
||||
realm.setName(name);
|
||||
realm.addRole(WILDCARD_ROLE);
|
||||
realm.addRole(RESOURCE_ROLE);
|
||||
realm.addRole(IDENTITY_REQUESTER_ROLE);
|
||||
return realm;
|
||||
}
|
||||
|
||||
|
@ -91,15 +77,13 @@ public class RealmManager {
|
|||
}
|
||||
realm.setPrivateKey(keyPair.getPrivate());
|
||||
realm.setPublicKey(keyPair.getPublic());
|
||||
realm.updateRealm();
|
||||
}
|
||||
|
||||
public RealmModel importRealm(RealmRepresentation rep, User realmCreator) {
|
||||
public RealmModel importRealm(RealmRepresentation rep, UserModel realmCreator) {
|
||||
verifyRealmRepresentation(rep);
|
||||
RealmModel realm = createRealm(rep.getRealm());
|
||||
importRealm(rep, realm);
|
||||
realm.addRealmAdmin(realmCreator);
|
||||
realm.updateRealm();
|
||||
return realm;
|
||||
}
|
||||
|
||||
|
@ -118,10 +102,7 @@ public class RealmManager {
|
|||
newRealm.setPublicKeyPem(rep.getPublicKey());
|
||||
}
|
||||
|
||||
newRealm.updateRealm();
|
||||
|
||||
|
||||
Map<String, User> userMap = new HashMap<String, User>();
|
||||
Map<String, UserModel> userMap = new HashMap<String, UserModel>();
|
||||
|
||||
for (RequiredCredentialRepresentation requiredCred : rep.getRequiredCredentials()) {
|
||||
RequiredCredentialModel credential = new RequiredCredentialModel();
|
||||
|
@ -132,14 +113,13 @@ public class RealmManager {
|
|||
}
|
||||
|
||||
for (UserRepresentation userRep : rep.getUsers()) {
|
||||
User user = new SimpleUser(userRep.getUsername());
|
||||
UserModel user = newRealm.addUser(userRep.getUsername());
|
||||
user.setEnabled(userRep.isEnabled());
|
||||
if (userRep.getAttributes() != null) {
|
||||
for (Map.Entry<String, String> entry : userRep.getAttributes().entrySet()) {
|
||||
user.setAttribute(new Attribute<String>(entry.getKey(), entry.getValue()));
|
||||
user.setAttribute(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
newRealm.addUser(user);
|
||||
if (userRep.getCredentials() != null) {
|
||||
for (CredentialRepresentation cred : userRep.getCredentials()) {
|
||||
UserCredentialModel credential = new UserCredentialModel();
|
||||
|
@ -153,9 +133,8 @@ public class RealmManager {
|
|||
|
||||
if (rep.getRoles() != null) {
|
||||
for (RoleRepresentation roleRep : rep.getRoles()) {
|
||||
SimpleRole role = new SimpleRole(roleRep.getName());
|
||||
if (roleRep.getDescription() != null) role.setAttribute(new Attribute<String>("description", roleRep.getDescription()));
|
||||
newRealm.addRole(role);
|
||||
RoleModel role = newRealm.addRole(roleRep.getName());
|
||||
if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,12 +144,11 @@ public class RealmManager {
|
|||
|
||||
if (rep.getRoleMappings() != null) {
|
||||
for (RoleMappingRepresentation mapping : rep.getRoleMappings()) {
|
||||
User user = userMap.get(mapping.getUsername());
|
||||
UserModel user = userMap.get(mapping.getUsername());
|
||||
for (String roleString : mapping.getRoles()) {
|
||||
Role role = newRealm.getRole(roleString.trim());
|
||||
RoleModel role = newRealm.getRole(roleString.trim());
|
||||
if (role == null) {
|
||||
role = new SimpleRole(roleString.trim());
|
||||
newRealm.addRole(role);
|
||||
role = newRealm.addRole(roleString.trim());
|
||||
}
|
||||
newRealm.grantRole(user, role);
|
||||
}
|
||||
|
@ -180,12 +158,11 @@ public class RealmManager {
|
|||
if (rep.getScopeMappings() != null) {
|
||||
for (ScopeMappingRepresentation scope : rep.getScopeMappings()) {
|
||||
for (String roleString : scope.getRoles()) {
|
||||
Role role = newRealm.getRole(roleString.trim());
|
||||
RoleModel role = newRealm.getRole(roleString.trim());
|
||||
if (role == null) {
|
||||
role = new SimpleRole(roleString.trim());
|
||||
newRealm.addRole(role);
|
||||
role = newRealm.addRole(roleString.trim());
|
||||
}
|
||||
User user = userMap.get(scope.getUsername());
|
||||
UserModel user = userMap.get(scope.getUsername());
|
||||
newRealm.addScope(user, role.getName());
|
||||
}
|
||||
|
||||
|
@ -193,15 +170,15 @@ public class RealmManager {
|
|||
}
|
||||
}
|
||||
|
||||
protected void createResources(RealmRepresentation rep, RealmModel realm, Map<String, User> userMap) {
|
||||
Role loginRole = realm.getRole(RealmManager.RESOURCE_ROLE);
|
||||
protected void createResources(RealmRepresentation rep, RealmModel realm, Map<String, UserModel> userMap) {
|
||||
RoleModel loginRole = realm.getRole(RealmManager.RESOURCE_ROLE);
|
||||
for (ResourceRepresentation resourceRep : rep.getResources()) {
|
||||
ResourceModel resource = realm.addResource(resourceRep.getName());
|
||||
resource.setManagementUrl(resourceRep.getAdminUrl());
|
||||
resource.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired());
|
||||
resource.updateResource();
|
||||
|
||||
User resourceUser = resource.getResourceUser();
|
||||
UserModel resourceUser = resource.getResourceUser();
|
||||
if (resourceRep.getCredentials() != null) {
|
||||
for (CredentialRepresentation cred : resourceRep.getCredentials()) {
|
||||
UserCredentialModel credential = new UserCredentialModel();
|
||||
|
@ -216,19 +193,17 @@ public class RealmManager {
|
|||
|
||||
if (resourceRep.getRoles() != null) {
|
||||
for (RoleRepresentation roleRep : resourceRep.getRoles()) {
|
||||
SimpleRole role = new SimpleRole(roleRep.getName());
|
||||
if (roleRep.getDescription() != null) role.setAttribute(new Attribute<String>("description", roleRep.getDescription()));
|
||||
resource.addRole(role);
|
||||
RoleModel role = resource.addRole(roleRep.getName());
|
||||
if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
|
||||
}
|
||||
}
|
||||
if (resourceRep.getRoleMappings() != null) {
|
||||
for (RoleMappingRepresentation mapping : resourceRep.getRoleMappings()) {
|
||||
User user = userMap.get(mapping.getUsername());
|
||||
UserModel user = userMap.get(mapping.getUsername());
|
||||
for (String roleString : mapping.getRoles()) {
|
||||
Role role = resource.getRole(roleString.trim());
|
||||
RoleModel role = resource.getRole(roleString.trim());
|
||||
if (role == null) {
|
||||
role = new SimpleRole(roleString.trim());
|
||||
resource.addRole(role);
|
||||
role = resource.addRole(roleString.trim());
|
||||
}
|
||||
realm.grantRole(user, role);
|
||||
}
|
||||
|
@ -236,12 +211,11 @@ public class RealmManager {
|
|||
}
|
||||
if (resourceRep.getScopeMappings() != null) {
|
||||
for (ScopeMappingRepresentation mapping : resourceRep.getScopeMappings()) {
|
||||
User user = userMap.get(mapping.getUsername());
|
||||
UserModel user = userMap.get(mapping.getUsername());
|
||||
for (String roleString : mapping.getRoles()) {
|
||||
Role role = resource.getRole(roleString.trim());
|
||||
RoleModel role = resource.getRole(roleString.trim());
|
||||
if (role == null) {
|
||||
role = new SimpleRole(roleString.trim());
|
||||
resource.addRole(role);
|
||||
role = resource.addRole(roleString.trim());
|
||||
}
|
||||
resource.addScope(user, role.getName());
|
||||
}
|
||||
|
@ -302,5 +276,4 @@ public class RealmManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@ import org.keycloak.representations.SkeletonKeyScope;
|
|||
import org.keycloak.representations.SkeletonKeyToken;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.ResourceModel;
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
import org.keycloak.services.resources.RealmsResource;
|
||||
import org.picketlink.idm.model.Role;
|
||||
import org.picketlink.idm.model.User;
|
||||
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.NewCookie;
|
||||
|
@ -45,21 +45,21 @@ public class TokenManager {
|
|||
return accessCodeMap.remove(key);
|
||||
}
|
||||
|
||||
public NewCookie createLoginCookie(RealmModel realm, User user, UriInfo uriInfo) {
|
||||
public NewCookie createLoginCookie(RealmModel realm, UserModel user, UriInfo uriInfo) {
|
||||
SkeletonKeyToken identityToken = createIdentityToken(realm, user.getLoginName());
|
||||
String encoded = encodeToken(realm, identityToken);
|
||||
URI uri = RealmsResource.realmBaseUrl(uriInfo).build(realm.getId());
|
||||
boolean secureOnly = !realm.isSslNotRequired();
|
||||
NewCookie cookie = new NewCookie(KEYCLOAK_IDENTITY_COOKIE, encoded, uri.getPath(), null, null, realm.getTokenLifespan(), secureOnly, true);
|
||||
NewCookie cookie = new NewCookie(KEYCLOAK_IDENTITY_COOKIE, encoded, uri.getPath(), null, null, NewCookie.DEFAULT_MAX_AGE, secureOnly, true);
|
||||
return cookie;
|
||||
}
|
||||
|
||||
public AccessCodeEntry createAccessCode(String scopeParam, String state, String redirect, RealmModel realm, User client, User user) {
|
||||
public AccessCodeEntry createAccessCode(String scopeParam, String state, String redirect, RealmModel realm, UserModel client, UserModel user) {
|
||||
AccessCodeEntry code = new AccessCodeEntry();
|
||||
SkeletonKeyScope scopeMap = null;
|
||||
if (scopeParam != null) scopeMap = decodeScope(scopeParam);
|
||||
List<Role> realmRolesRequested = code.getRealmRolesRequested();
|
||||
MultivaluedMap<String, Role> resourceRolesRequested = code.getResourceRolesRequested();
|
||||
List<RoleModel> realmRolesRequested = code.getRealmRolesRequested();
|
||||
MultivaluedMap<String, RoleModel> resourceRolesRequested = code.getResourceRolesRequested();
|
||||
Set<String> realmMapping = realm.getRoleMappings(user);
|
||||
|
||||
if (realmMapping != null && realmMapping.size() > 0 && (scopeMap == null || scopeMap.containsKey("realm"))) {
|
||||
|
@ -118,7 +118,7 @@ public class TokenManager {
|
|||
return code;
|
||||
}
|
||||
|
||||
protected SkeletonKeyToken initToken(RealmModel realm, User client, User user) {
|
||||
protected SkeletonKeyToken initToken(RealmModel realm, UserModel client, UserModel user) {
|
||||
SkeletonKeyToken token = new SkeletonKeyToken();
|
||||
token.id(RealmManager.generateId());
|
||||
token.principal(user.getLoginName());
|
||||
|
@ -131,13 +131,13 @@ public class TokenManager {
|
|||
return token;
|
||||
}
|
||||
|
||||
protected void createToken(AccessCodeEntry accessCodeEntry, RealmModel realm, User client, User user) {
|
||||
protected void createToken(AccessCodeEntry accessCodeEntry, RealmModel realm, UserModel client, UserModel user) {
|
||||
|
||||
SkeletonKeyToken token = initToken(realm, client, user);
|
||||
|
||||
if (accessCodeEntry.getRealmRolesRequested().size() > 0) {
|
||||
SkeletonKeyToken.Access access = new SkeletonKeyToken.Access();
|
||||
for (Role role : accessCodeEntry.getRealmRolesRequested()) {
|
||||
for (RoleModel role : accessCodeEntry.getRealmRolesRequested()) {
|
||||
access.addRole(role.getName());
|
||||
}
|
||||
token.setRealmAccess(access);
|
||||
|
@ -148,7 +148,7 @@ public class TokenManager {
|
|||
for (String resourceName : accessCodeEntry.getResourceRolesRequested().keySet()) {
|
||||
ResourceModel resource = resourceMap.get(resourceName);
|
||||
SkeletonKeyToken.Access access = token.addAccess(resourceName).verifyCaller(resource.isSurrogateAuthRequired());
|
||||
for (Role role : accessCodeEntry.getResourceRolesRequested().get(resourceName)) {
|
||||
for (RoleModel role : accessCodeEntry.getResourceRolesRequested().get(resourceName)) {
|
||||
access.addRole(role.getName());
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ public class TokenManager {
|
|||
}
|
||||
|
||||
|
||||
public SkeletonKeyToken createAccessToken(RealmModel realm, User user) {
|
||||
public SkeletonKeyToken createAccessToken(RealmModel realm, UserModel user) {
|
||||
List<ResourceModel> resources = realm.getResources();
|
||||
SkeletonKeyToken token = new SkeletonKeyToken();
|
||||
token.id(RealmManager.generateId());
|
||||
|
|
|
@ -7,5 +7,10 @@ package org.keycloak.services.models;
|
|||
public interface KeycloakSession {
|
||||
KeycloakTransaction getTransaction();
|
||||
|
||||
RealmModel createRealm(String name);
|
||||
RealmModel createRealm(String id, String name);
|
||||
RealmModel getRealm(String id);
|
||||
void deleteRealm(RealmModel realm);
|
||||
|
||||
void close();
|
||||
}
|
||||
|
|
|
@ -5,4 +5,6 @@ package org.keycloak.services.models;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface KeycloakSessionFactory {
|
||||
KeycloakSession createSession();
|
||||
void close();
|
||||
}
|
||||
|
|
|
@ -1,411 +1,101 @@
|
|||
package org.keycloak.services.models;
|
||||
|
||||
import org.bouncycastle.openssl.PEMWriter;
|
||||
import org.jboss.resteasy.security.PemUtils;
|
||||
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.models.relationships.RealmAdminRelationship;
|
||||
import org.keycloak.services.models.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.relationships.RequiredCredentialRelationship;
|
||||
import org.keycloak.services.models.relationships.ScopeRelationship;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.credential.Credentials;
|
||||
import org.picketlink.idm.credential.Password;
|
||||
import org.picketlink.idm.credential.TOTPCredential;
|
||||
import org.picketlink.idm.credential.TOTPCredentials;
|
||||
import org.picketlink.idm.credential.UsernamePasswordCredentials;
|
||||
import org.picketlink.idm.credential.X509CertificateCredentials;
|
||||
import org.picketlink.idm.model.Agent;
|
||||
import org.picketlink.idm.model.Attribute;
|
||||
import org.picketlink.idm.model.Grant;
|
||||
import org.picketlink.idm.model.Realm;
|
||||
import org.picketlink.idm.model.Role;
|
||||
import org.picketlink.idm.model.SimpleRole;
|
||||
import org.picketlink.idm.model.SimpleUser;
|
||||
import org.picketlink.idm.model.Tier;
|
||||
import org.picketlink.idm.model.User;
|
||||
import org.picketlink.idm.query.IdentityQuery;
|
||||
import org.picketlink.idm.query.RelationshipQuery;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Meant to be a per-request object
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class RealmModel {
|
||||
public static final String REALM_AGENT_ID = "_realm_";
|
||||
public static final String REALM_NAME = "name";
|
||||
public static final String REALM_ACCESS_CODE_LIFESPAN = "accessCodeLifespan";
|
||||
public static final String REALM_TOKEN_LIFESPAN = "tokenLifespan";
|
||||
public static final String REALM_PRIVATE_KEY = "privateKey";
|
||||
public static final String REALM_PUBLIC_KEY = "publicKey";
|
||||
public static final String REALM_IS_SSL_NOT_REQUIRED = "isSSLNotRequired";
|
||||
public static final String REALM_IS_COOKIE_LOGIN_ALLOWED = "isCookieLoginAllowed";
|
||||
public static final String REALM_IS_REGISTRATION_ALLOWED = "isRegistrationAllowed";
|
||||
public interface RealmModel {
|
||||
String DEFAULT_REALM = "default";
|
||||
|
||||
protected Realm realm;
|
||||
protected Agent realmAgent;
|
||||
protected IdentitySession identitySession;
|
||||
protected volatile transient PublicKey publicKey;
|
||||
protected volatile transient PrivateKey privateKey;
|
||||
protected IdentityManager idm;
|
||||
String getId();
|
||||
|
||||
public RealmModel(Realm realm, IdentitySession session) {
|
||||
this.realm = realm;
|
||||
this.identitySession = session;
|
||||
realmAgent = getIdm().getAgent(REALM_AGENT_ID);
|
||||
}
|
||||
String getName();
|
||||
|
||||
protected IdentityManager getIdm() {
|
||||
if (idm == null) idm = identitySession.createIdentityManager(realm);
|
||||
return idm;
|
||||
}
|
||||
void setName(String name);
|
||||
|
||||
public void updateRealm() {
|
||||
getIdm().update(realmAgent);
|
||||
}
|
||||
boolean isEnabled();
|
||||
|
||||
public String getId() {
|
||||
return realm.getId();
|
||||
}
|
||||
void setEnabled(boolean enabled);
|
||||
|
||||
public String getName() {
|
||||
return (String) realmAgent.getAttribute(REALM_NAME).getValue();
|
||||
}
|
||||
boolean isSslNotRequired();
|
||||
|
||||
public void setName(String name) {
|
||||
realmAgent.setAttribute(new Attribute<String>(REALM_NAME, name));
|
||||
}
|
||||
void setSslNotRequired(boolean sslNotRequired);
|
||||
|
||||
public boolean isEnabled() {
|
||||
return realmAgent.isEnabled();
|
||||
}
|
||||
boolean isCookieLoginAllowed();
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
realmAgent.setEnabled(enabled);
|
||||
}
|
||||
void setCookieLoginAllowed(boolean cookieLoginAllowed);
|
||||
|
||||
public boolean isSslNotRequired() {
|
||||
return (Boolean) realmAgent.getAttribute(REALM_IS_SSL_NOT_REQUIRED).getValue();
|
||||
}
|
||||
boolean isRegistrationAllowed();
|
||||
|
||||
public void setSslNotRequired(boolean sslNotRequired) {
|
||||
realmAgent.setAttribute(new Attribute<Boolean>(REALM_IS_SSL_NOT_REQUIRED, sslNotRequired));
|
||||
}
|
||||
void setRegistrationAllowed(boolean registrationAllowed);
|
||||
|
||||
public boolean isCookieLoginAllowed() {
|
||||
return (Boolean) realmAgent.getAttribute(REALM_IS_COOKIE_LOGIN_ALLOWED).getValue();
|
||||
}
|
||||
int getTokenLifespan();
|
||||
|
||||
public void setCookieLoginAllowed(boolean cookieLoginAllowed) {
|
||||
realmAgent.setAttribute(new Attribute<Boolean>(REALM_IS_COOKIE_LOGIN_ALLOWED, cookieLoginAllowed));
|
||||
}
|
||||
void setTokenLifespan(int tokenLifespan);
|
||||
|
||||
public boolean isRegistrationAllowed() {
|
||||
return (Boolean) realmAgent.getAttribute(REALM_IS_REGISTRATION_ALLOWED).getValue();
|
||||
}
|
||||
int getAccessCodeLifespan();
|
||||
|
||||
public void setRegistrationAllowed(boolean registrationAllowed) {
|
||||
realmAgent.setAttribute(new Attribute<Boolean>(REALM_IS_REGISTRATION_ALLOWED, registrationAllowed));
|
||||
}
|
||||
void setAccessCodeLifespan(int accessCodeLifespan);
|
||||
|
||||
public int getTokenLifespan() {
|
||||
return (Integer) realmAgent.getAttribute(REALM_TOKEN_LIFESPAN).getValue();
|
||||
}
|
||||
String getPublicKeyPem();
|
||||
|
||||
public void setTokenLifespan(int tokenLifespan) {
|
||||
realmAgent.setAttribute(new Attribute<Integer>(REALM_TOKEN_LIFESPAN, tokenLifespan));
|
||||
}
|
||||
void setPublicKeyPem(String publicKeyPem);
|
||||
|
||||
public int getAccessCodeLifespan() {
|
||||
return (Integer) realmAgent.getAttribute(REALM_ACCESS_CODE_LIFESPAN).getValue();
|
||||
}
|
||||
String getPrivateKeyPem();
|
||||
|
||||
public void setAccessCodeLifespan(int accessCodeLifespan) {
|
||||
realmAgent.setAttribute(new Attribute<Integer>(REALM_ACCESS_CODE_LIFESPAN, accessCodeLifespan));
|
||||
}
|
||||
void setPrivateKeyPem(String privateKeyPem);
|
||||
|
||||
public String getPublicKeyPem() {
|
||||
return (String) realmAgent.getAttribute(REALM_PUBLIC_KEY).getValue();
|
||||
}
|
||||
PublicKey getPublicKey();
|
||||
|
||||
public void setPublicKeyPem(String publicKeyPem) {
|
||||
realmAgent.setAttribute(new Attribute<String>(REALM_PUBLIC_KEY, publicKeyPem));
|
||||
this.publicKey = null;
|
||||
}
|
||||
void setPublicKey(PublicKey publicKey);
|
||||
|
||||
public String getPrivateKeyPem() {
|
||||
return (String) realmAgent.getAttribute(REALM_PRIVATE_KEY).getValue();
|
||||
}
|
||||
PrivateKey getPrivateKey();
|
||||
|
||||
public void setPrivateKeyPem(String privateKeyPem) {
|
||||
realmAgent.setAttribute(new Attribute<String>(REALM_PRIVATE_KEY, privateKeyPem));
|
||||
this.privateKey = null;
|
||||
}
|
||||
void setPrivateKey(PrivateKey privateKey);
|
||||
|
||||
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;
|
||||
}
|
||||
List<RequiredCredentialModel> getRequiredCredentials();
|
||||
|
||||
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));
|
||||
}
|
||||
void addRequiredCredential(RequiredCredentialModel cred);
|
||||
|
||||
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;
|
||||
}
|
||||
boolean validatePassword(UserModel user, String password);
|
||||
|
||||
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));
|
||||
}
|
||||
boolean validateTOTP(UserModel user, String password, String token);
|
||||
|
||||
public List<RequiredCredentialModel> getRequiredCredentials() {
|
||||
IdentityManager idm = getIdm();
|
||||
Agent realmAgent = idm.getAgent(REALM_AGENT_ID);
|
||||
RelationshipQuery<RequiredCredentialRelationship> query = idm.createRelationshipQuery(RequiredCredentialRelationship.class);
|
||||
query.setParameter(RequiredCredentialRelationship.REALM_AGENT, realmAgent);
|
||||
List<RequiredCredentialRelationship> results = query.getResultList();
|
||||
List<RequiredCredentialModel> rtn = new ArrayList<RequiredCredentialModel>();
|
||||
for (RequiredCredentialRelationship relationship : results) {
|
||||
RequiredCredentialModel model = new RequiredCredentialModel();
|
||||
model.setInput(relationship.isInput());
|
||||
model.setSecret(relationship.isSecret());
|
||||
model.setType(relationship.getCredentialType());
|
||||
rtn.add(model);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
void updateCredential(UserModel user, UserCredentialModel cred);
|
||||
|
||||
public void addRequiredCredential(RequiredCredentialModel cred) {
|
||||
IdentityManager idm = getIdm();
|
||||
Agent realmAgent = idm.getAgent(REALM_AGENT_ID);
|
||||
RequiredCredentialRelationship relationship = new RequiredCredentialRelationship();
|
||||
relationship.setCredentialType(cred.getType());
|
||||
relationship.setInput(cred.isInput());
|
||||
relationship.setSecret(cred.isSecret());
|
||||
relationship.setRealmAgent(realmAgent);
|
||||
idm.add(relationship);
|
||||
}
|
||||
UserModel getUser(String name);
|
||||
|
||||
public boolean validatePassword(User user, String password) {
|
||||
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(user.getLoginName(), new Password(password));
|
||||
getIdm().validateCredentials(creds);
|
||||
return creds.getStatus() == Credentials.Status.VALID;
|
||||
}
|
||||
UserModel addUser(String username);
|
||||
|
||||
public boolean validateTOTP(User user, String password, String token) {
|
||||
TOTPCredentials creds = new TOTPCredentials();
|
||||
creds.setToken(token);
|
||||
creds.setUsername(user.getLoginName());
|
||||
creds.setPassword(new Password(password));
|
||||
getIdm().validateCredentials(creds);
|
||||
return creds.getStatus() == Credentials.Status.VALID;
|
||||
}
|
||||
RoleModel getRole(String name);
|
||||
|
||||
public void updateCredential(User user, UserCredentialModel cred) {
|
||||
IdentityManager idm = getIdm();
|
||||
if (cred.getType().equals(RequiredCredentialRepresentation.PASSWORD)) {
|
||||
Password password = new Password(cred.getValue());
|
||||
idm.updateCredential(user, password);
|
||||
} else if (cred.getType().equals(RequiredCredentialRepresentation.TOTP)) {
|
||||
TOTPCredential totp = new TOTPCredential(cred.getValue());
|
||||
idm.updateCredential(user, totp);
|
||||
} else if (cred.getType().equals(RequiredCredentialRepresentation.CLIENT_CERT)) {
|
||||
X509Certificate cert = null;
|
||||
try {
|
||||
cert = org.keycloak.PemUtils.decodeCertificate(cred.getValue());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
X509CertificateCredentials creds = new X509CertificateCredentials(cert);
|
||||
idm.updateCredential(user, creds);
|
||||
}
|
||||
}
|
||||
RoleModel addRole(String name);
|
||||
|
||||
public User getUser(String name) {
|
||||
return getIdm().getUser(name);
|
||||
}
|
||||
List<RoleModel> getRoles();
|
||||
|
||||
public void addUser(User user) {
|
||||
getIdm().add(user);
|
||||
}
|
||||
Map<String, ResourceModel> getResourceMap();
|
||||
|
||||
public Role getRole(String name) {
|
||||
return getIdm().getRole(name);
|
||||
}
|
||||
List<ResourceModel> getResources();
|
||||
|
||||
public Role addRole(String name) {
|
||||
Role role = new SimpleRole(name);
|
||||
getIdm().add(role);
|
||||
return role;
|
||||
}
|
||||
ResourceModel addResource(String name);
|
||||
|
||||
public void addRole(Role role) {
|
||||
getIdm().add(role);
|
||||
}
|
||||
boolean hasRole(UserModel user, RoleModel role);
|
||||
|
||||
public List<Role> getRoles() {
|
||||
IdentityManager idm = getIdm();
|
||||
IdentityQuery<Role> query = idm.createIdentityQuery(Role.class);
|
||||
query.setParameter(Role.PARTITION, realm);
|
||||
return query.getResultList();
|
||||
}
|
||||
void grantRole(UserModel user, RoleModel role);
|
||||
|
||||
Set<String> getRoleMappings(UserModel user);
|
||||
|
||||
/**
|
||||
* Key name, value resource
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<String, ResourceModel> getResourceMap() {
|
||||
Map<String, ResourceModel> resourceMap = new HashMap<String, ResourceModel>();
|
||||
for (ResourceModel resource : getResources()) {
|
||||
resourceMap.put(resource.getName(), resource);
|
||||
}
|
||||
return resourceMap;
|
||||
}
|
||||
void addScope(UserModel agent, String roleName);
|
||||
|
||||
public List<ResourceModel> getResources() {
|
||||
IdentityManager idm = getIdm();
|
||||
RelationshipQuery<ResourceRelationship> query = idm.createRelationshipQuery(ResourceRelationship.class);
|
||||
query.setParameter(ResourceRelationship.REALM_AGENT, realmAgent);
|
||||
List<ResourceRelationship> results = query.getResultList();
|
||||
List<ResourceModel> resources = new ArrayList<ResourceModel>();
|
||||
for (ResourceRelationship relationship : results) {
|
||||
Tier resourceTier = identitySession.findTier(relationship.getResourceId());
|
||||
ResourceModel model = new ResourceModel(resourceTier,relationship, this, identitySession);
|
||||
resources.add(model);
|
||||
}
|
||||
Set<String> getScope(UserModel agent);
|
||||
|
||||
return resources;
|
||||
}
|
||||
boolean isRealmAdmin(UserModel agent);
|
||||
|
||||
public ResourceModel addResource(String name) {
|
||||
Tier newTier = identitySession.createTier(RealmManager.generateId());
|
||||
IdentityManager idm = getIdm();
|
||||
ResourceRelationship relationship = new ResourceRelationship();
|
||||
relationship.setResourceName(name);
|
||||
relationship.setRealmAgent(realmAgent);
|
||||
relationship.setResourceId(newTier.getId());
|
||||
relationship.setManagementUrl(""); // Picketlink doesn't like null attribute values
|
||||
User resourceUser = new SimpleUser(name);
|
||||
idm.add(resourceUser);
|
||||
relationship.setResourceUser(resourceUser);
|
||||
idm.add(relationship);
|
||||
ResourceModel resource = new ResourceModel(newTier, relationship, this, identitySession);
|
||||
resource.addRole(new SimpleRole("*"));
|
||||
resource.addScope(resourceUser, "*");
|
||||
return resource;
|
||||
}
|
||||
|
||||
public boolean hasRole(User user, Role role) {
|
||||
return getIdm().hasRole(user, role);
|
||||
}
|
||||
|
||||
public void grantRole(User user, Role role) {
|
||||
getIdm().grantRole(user, role);
|
||||
}
|
||||
|
||||
public Set<String> getRoleMappings(User user) {
|
||||
RelationshipQuery<Grant> query = getIdm().createRelationshipQuery(Grant.class);
|
||||
query.setParameter(Grant.ASSIGNEE, user);
|
||||
List<Grant> grants = query.getResultList();
|
||||
HashSet<String> set = new HashSet<String>();
|
||||
for (Grant grant : grants) {
|
||||
if (grant.getRole().getPartition().getId().equals(realm.getId())) set.add(grant.getRole().getName());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public void addScope(Agent agent, String roleName) {
|
||||
IdentityManager idm = getIdm();
|
||||
Role role = idm.getRole(roleName);
|
||||
if (role == null) throw new RuntimeException("role not found");
|
||||
ScopeRelationship scope = new ScopeRelationship();
|
||||
scope.setClient(agent);
|
||||
scope.setScope(role);
|
||||
idm.add(scope);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public Set<String> getScope(Agent agent) {
|
||||
RelationshipQuery<ScopeRelationship> query = getIdm().createRelationshipQuery(ScopeRelationship.class);
|
||||
query.setParameter(ScopeRelationship.CLIENT, agent);
|
||||
List<ScopeRelationship> scope = query.getResultList();
|
||||
HashSet<String> set = new HashSet<String>();
|
||||
for (ScopeRelationship rel : scope) {
|
||||
if (rel.getScope().getPartition().getId().equals(realm.getId())) set.add(rel.getScope().getName());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public boolean isRealmAdmin(Agent agent) {
|
||||
IdentityManager idm = new RealmManager(identitySession).defaultRealm().getIdm();
|
||||
RelationshipQuery<RealmAdminRelationship> query = idm.createRelationshipQuery(RealmAdminRelationship.class);
|
||||
query.setParameter(RealmAdminRelationship.REALM, realm.getId());
|
||||
query.setParameter(RealmAdminRelationship.ADMIN, agent);
|
||||
List<RealmAdminRelationship> results = query.getResultList();
|
||||
return results.size() > 0;
|
||||
}
|
||||
|
||||
public void addRealmAdmin(Agent agent) {
|
||||
IdentityManager idm = new RealmManager(identitySession).defaultRealm().getIdm();
|
||||
RealmAdminRelationship relationship = new RealmAdminRelationship();
|
||||
relationship.setAdmin(agent);
|
||||
relationship.setRealm(realm.getId());
|
||||
idm.add(relationship);
|
||||
}
|
||||
void addRealmAdmin(UserModel agent);
|
||||
}
|
||||
|
|
|
@ -1,150 +1,46 @@
|
|||
package org.keycloak.services.models;
|
||||
|
||||
import org.keycloak.services.models.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.relationships.ScopeRelationship;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.model.Agent;
|
||||
import org.picketlink.idm.model.Grant;
|
||||
import org.picketlink.idm.model.Role;
|
||||
import org.picketlink.idm.model.SimpleRole;
|
||||
import org.picketlink.idm.model.Tier;
|
||||
import org.picketlink.idm.model.User;
|
||||
import org.picketlink.idm.query.IdentityQuery;
|
||||
import org.picketlink.idm.query.RelationshipQuery;
|
||||
|
||||
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 ResourceModel {
|
||||
protected Tier tier;
|
||||
protected ResourceRelationship agent;
|
||||
protected RealmModel realm;
|
||||
protected IdentitySession identitySession;
|
||||
protected IdentityManager idm;
|
||||
|
||||
public ResourceModel(Tier tier, ResourceRelationship agent, RealmModel realm, IdentitySession session) {
|
||||
this.tier = tier;
|
||||
this.agent = agent;
|
||||
this.realm = realm;
|
||||
this.identitySession = session;
|
||||
}
|
||||
|
||||
protected IdentityManager getIdm() {
|
||||
if (idm == null) idm = identitySession.createIdentityManager(tier);
|
||||
return idm;
|
||||
}
|
||||
|
||||
public void updateResource() {
|
||||
getIdm().update(agent);
|
||||
}
|
||||
|
||||
public User getResourceUser() {
|
||||
return agent.getResourceUser();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return tier.getId();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return agent.getResourceName();
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
agent.setResourceName(name);
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return agent.getEnabled();
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
agent.setEnabled(enabled);
|
||||
}
|
||||
|
||||
public boolean isSurrogateAuthRequired() {
|
||||
return agent.getSurrogateAuthRequired();
|
||||
}
|
||||
|
||||
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
|
||||
agent.setSurrogateAuthRequired(surrogateAuthRequired);
|
||||
}
|
||||
|
||||
public String getManagementUrl() {
|
||||
return agent.getManagementUrl();
|
||||
}
|
||||
|
||||
public void setManagementUrl(String url) {
|
||||
agent.setManagementUrl(url);
|
||||
}
|
||||
|
||||
public User getUser(String name) {
|
||||
return getIdm().getUser(name);
|
||||
}
|
||||
|
||||
public void addUser(User user) {
|
||||
getIdm().add(user);
|
||||
}
|
||||
|
||||
public Role getRole(String name) {
|
||||
return getIdm().getRole(name);
|
||||
}
|
||||
|
||||
public Role addRole(String name) {
|
||||
Role role = new SimpleRole(name);
|
||||
getIdm().add(role);
|
||||
return role;
|
||||
}
|
||||
|
||||
public void addRole(Role role) {
|
||||
getIdm().add(role);
|
||||
}
|
||||
|
||||
public List<Role> getRoles() {
|
||||
IdentityQuery<Role> query = getIdm().createIdentityQuery(Role.class);
|
||||
query.setParameter(Role.PARTITION, tier);
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
public Set<String> getRoleMappings(User user) {
|
||||
RelationshipQuery<Grant> query = getIdm().createRelationshipQuery(Grant.class);
|
||||
query.setParameter(Grant.ASSIGNEE, user);
|
||||
List<Grant> grants = query.getResultList();
|
||||
HashSet<String> set = new HashSet<String>();
|
||||
for (Grant grant : grants) {
|
||||
if (grant.getRole().getPartition().getId().equals(tier.getId())) set.add(grant.getRole().getName());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public void addScope(Agent agent, String roleName) {
|
||||
IdentityManager idm = getIdm();
|
||||
Role role = idm.getRole(roleName);
|
||||
if (role == null) throw new RuntimeException("role not found");
|
||||
addScope(agent, role);
|
||||
|
||||
}
|
||||
|
||||
public void addScope(Agent agent, Role role) {
|
||||
ScopeRelationship scope = new ScopeRelationship();
|
||||
scope.setClient(agent);
|
||||
scope.setScope(role);
|
||||
}
|
||||
|
||||
public Set<String> getScope(Agent agent) {
|
||||
RelationshipQuery<ScopeRelationship> query = getIdm().createRelationshipQuery(ScopeRelationship.class);
|
||||
query.setParameter(ScopeRelationship.CLIENT, agent);
|
||||
List<ScopeRelationship> scope = query.getResultList();
|
||||
HashSet<String> set = new HashSet<String>();
|
||||
for (ScopeRelationship rel : scope) {
|
||||
if (rel.getScope().getPartition().getId().equals(tier.getId())) set.add(rel.getScope().getName());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
package org.keycloak.services.models;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface ResourceModel {
|
||||
void updateResource();
|
||||
|
||||
UserModel getResourceUser();
|
||||
|
||||
String getId();
|
||||
|
||||
String getName();
|
||||
|
||||
void setName(String name);
|
||||
|
||||
boolean isEnabled();
|
||||
|
||||
void setEnabled(boolean enabled);
|
||||
|
||||
boolean isSurrogateAuthRequired();
|
||||
|
||||
void setSurrogateAuthRequired(boolean surrogateAuthRequired);
|
||||
|
||||
String getManagementUrl();
|
||||
|
||||
void setManagementUrl(String url);
|
||||
|
||||
RoleModel getRole(String name);
|
||||
|
||||
RoleModel addRole(String name);
|
||||
|
||||
List<RoleModel> getRoles();
|
||||
|
||||
Set<String> getRoleMappings(UserModel user);
|
||||
|
||||
void addScope(UserModel agent, String roleName);
|
||||
|
||||
void addScope(UserModel agent, RoleModel role);
|
||||
|
||||
Set<String> getScope(UserModel agent);
|
||||
}
|
||||
|
|
13
services/src/main/java/org/keycloak/services/models/RoleModel.java
Executable file
13
services/src/main/java/org/keycloak/services/models/RoleModel.java
Executable file
|
@ -0,0 +1,13 @@
|
|||
package org.keycloak.services.models;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface RoleModel {
|
||||
String getName();
|
||||
|
||||
String getDescription();
|
||||
|
||||
void setDescription(String description);
|
||||
}
|
23
services/src/main/java/org/keycloak/services/models/UserModel.java
Executable file
23
services/src/main/java/org/keycloak/services/models/UserModel.java
Executable file
|
@ -0,0 +1,23 @@
|
|||
package org.keycloak.services.models;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface UserModel {
|
||||
String getLoginName();
|
||||
|
||||
boolean isEnabled();
|
||||
|
||||
void setEnabled(boolean enabled);
|
||||
|
||||
void setAttribute(String name, String value);
|
||||
|
||||
void removeAttribute(String name);
|
||||
|
||||
String getAttribute(String name);
|
||||
|
||||
Map<String, String> getAttributes();
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package org.keycloak.services.models.picketlink;
|
||||
|
||||
import org.jboss.resteasy.spi.NotImplementedYetException;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.KeycloakTransaction;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.model.Realm;
|
||||
import org.picketlink.idm.model.SimpleAgent;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class PicketlinkKeycloakSession implements KeycloakSession {
|
||||
protected IdentitySession session;
|
||||
|
||||
private static AtomicLong counter = new AtomicLong(1);
|
||||
public static String generateId() {
|
||||
return counter.getAndIncrement() + "-" + System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public PicketlinkKeycloakSession(IdentitySession session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeycloakTransaction getTransaction() {
|
||||
return new PicketlinkKeycloakTransaction(session.getTransaction());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RealmAdapter createRealm(String name) {
|
||||
return createRealm(generateId(), name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RealmAdapter createRealm(String id, String name) {
|
||||
Realm newRealm = session.createRealm(id);
|
||||
IdentityManager idm = session.createIdentityManager(newRealm);
|
||||
SimpleAgent agent = new SimpleAgent(RealmAdapter.REALM_AGENT_ID);
|
||||
idm.add(agent);
|
||||
RealmAdapter realm = new RealmAdapter(newRealm, session);
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RealmAdapter getRealm(String id) {
|
||||
Realm existing = session.findRealm(id);
|
||||
if (existing == null) {
|
||||
return null;
|
||||
}
|
||||
return new RealmAdapter(existing, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRealm(RealmModel realm) {
|
||||
throw new NotImplementedYetException();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
session.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.keycloak.services.models.picketlink;
|
||||
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
import org.picketlink.idm.IdentitySessionFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class PicketlinkKeycloakSessionFactory implements KeycloakSessionFactory {
|
||||
protected IdentitySessionFactory factory;
|
||||
|
||||
public PicketlinkKeycloakSessionFactory(IdentitySessionFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeycloakSession createSession() {
|
||||
return new PicketlinkKeycloakSession(factory.createIdentitySession());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
factory.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package org.keycloak.services.models.picketlink;
|
||||
|
||||
import org.keycloak.services.models.KeycloakTransaction;
|
||||
import org.picketlink.idm.IdentityTransaction;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class PicketlinkKeycloakTransaction implements KeycloakTransaction{
|
||||
protected IdentityTransaction transaction;
|
||||
|
||||
public PicketlinkKeycloakTransaction(IdentityTransaction transaction) {
|
||||
this.transaction = transaction;
|
||||
}
|
||||
|
||||
public void begin() {
|
||||
transaction.begin();
|
||||
}
|
||||
|
||||
public void setRollbackOnly() {
|
||||
transaction.setRollbackOnly();
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return transaction.isActive();
|
||||
}
|
||||
|
||||
public boolean getRollbackOnly() {
|
||||
return transaction.getRollbackOnly();
|
||||
}
|
||||
|
||||
public void commit() {
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
public void rollback() {
|
||||
transaction.rollback();
|
||||
}
|
||||
}
|
479
services/src/main/java/org/keycloak/services/models/picketlink/RealmAdapter.java
Executable file
479
services/src/main/java/org/keycloak/services/models/picketlink/RealmAdapter.java
Executable file
|
@ -0,0 +1,479 @@
|
|||
package org.keycloak.services.models.picketlink;
|
||||
|
||||
import org.bouncycastle.openssl.PEMWriter;
|
||||
import org.jboss.resteasy.security.PemUtils;
|
||||
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RequiredCredentialModel;
|
||||
import org.keycloak.services.models.ResourceModel;
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserCredentialModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
import org.keycloak.services.models.picketlink.relationships.RealmAdminRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.RequiredCredentialRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ScopeRelationship;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.credential.Credentials;
|
||||
import org.picketlink.idm.credential.Password;
|
||||
import org.picketlink.idm.credential.TOTPCredential;
|
||||
import org.picketlink.idm.credential.TOTPCredentials;
|
||||
import org.picketlink.idm.credential.UsernamePasswordCredentials;
|
||||
import org.picketlink.idm.credential.X509CertificateCredentials;
|
||||
import org.picketlink.idm.model.Agent;
|
||||
import org.picketlink.idm.model.Attribute;
|
||||
import org.picketlink.idm.model.Grant;
|
||||
import org.picketlink.idm.model.Realm;
|
||||
import org.picketlink.idm.model.Role;
|
||||
import org.picketlink.idm.model.SimpleRole;
|
||||
import org.picketlink.idm.model.SimpleUser;
|
||||
import org.picketlink.idm.model.Tier;
|
||||
import org.picketlink.idm.model.User;
|
||||
import org.picketlink.idm.query.IdentityQuery;
|
||||
import org.picketlink.idm.query.RelationshipQuery;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Meant to be a per-request object
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class RealmAdapter implements RealmModel {
|
||||
public static final String REALM_AGENT_ID = "_realm_";
|
||||
public static final String REALM_NAME = "name";
|
||||
public static final String REALM_ACCESS_CODE_LIFESPAN = "accessCodeLifespan";
|
||||
public static final String REALM_TOKEN_LIFESPAN = "tokenLifespan";
|
||||
public static final String REALM_PRIVATE_KEY = "privateKey";
|
||||
public static final String REALM_PUBLIC_KEY = "publicKey";
|
||||
public static final String REALM_IS_SSL_NOT_REQUIRED = "isSSLNotRequired";
|
||||
public static final String REALM_IS_COOKIE_LOGIN_ALLOWED = "isCookieLoginAllowed";
|
||||
public static final String REALM_IS_REGISTRATION_ALLOWED = "isRegistrationAllowed";
|
||||
|
||||
protected Realm realm;
|
||||
protected Agent realmAgent;
|
||||
protected IdentitySession identitySession;
|
||||
protected volatile transient PublicKey publicKey;
|
||||
protected volatile transient PrivateKey privateKey;
|
||||
protected IdentityManager idm;
|
||||
|
||||
public RealmAdapter(Realm realm, IdentitySession session) {
|
||||
this.realm = realm;
|
||||
this.identitySession = session;
|
||||
realmAgent = getIdm().getAgent(REALM_AGENT_ID);
|
||||
}
|
||||
|
||||
protected IdentityManager getIdm() {
|
||||
if (idm == null) idm = identitySession.createIdentityManager(realm);
|
||||
return idm;
|
||||
}
|
||||
|
||||
protected void updateRealm() {
|
||||
getIdm().update(realmAgent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return realm.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return (String) realmAgent.getAttribute(REALM_NAME).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
realmAgent.setAttribute(new Attribute<String>(REALM_NAME, name));
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return realmAgent.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
realmAgent.setEnabled(enabled);
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSslNotRequired() {
|
||||
return (Boolean) realmAgent.getAttribute(REALM_IS_SSL_NOT_REQUIRED).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSslNotRequired(boolean sslNotRequired) {
|
||||
realmAgent.setAttribute(new Attribute<Boolean>(REALM_IS_SSL_NOT_REQUIRED, sslNotRequired));
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCookieLoginAllowed() {
|
||||
return (Boolean) realmAgent.getAttribute(REALM_IS_COOKIE_LOGIN_ALLOWED).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCookieLoginAllowed(boolean cookieLoginAllowed) {
|
||||
realmAgent.setAttribute(new Attribute<Boolean>(REALM_IS_COOKIE_LOGIN_ALLOWED, cookieLoginAllowed));
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegistrationAllowed() {
|
||||
return (Boolean) realmAgent.getAttribute(REALM_IS_REGISTRATION_ALLOWED).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRegistrationAllowed(boolean registrationAllowed) {
|
||||
realmAgent.setAttribute(new Attribute<Boolean>(REALM_IS_REGISTRATION_ALLOWED, registrationAllowed));
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTokenLifespan() {
|
||||
return (Integer) realmAgent.getAttribute(REALM_TOKEN_LIFESPAN).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTokenLifespan(int tokenLifespan) {
|
||||
realmAgent.setAttribute(new Attribute<Integer>(REALM_TOKEN_LIFESPAN, tokenLifespan));
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAccessCodeLifespan() {
|
||||
return (Integer) realmAgent.getAttribute(REALM_ACCESS_CODE_LIFESPAN).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccessCodeLifespan(int accessCodeLifespan) {
|
||||
realmAgent.setAttribute(new Attribute<Integer>(REALM_ACCESS_CODE_LIFESPAN, accessCodeLifespan));
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPublicKeyPem() {
|
||||
return (String) realmAgent.getAttribute(REALM_PUBLIC_KEY).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPublicKeyPem(String publicKeyPem) {
|
||||
realmAgent.setAttribute(new Attribute<String>(REALM_PUBLIC_KEY, publicKeyPem));
|
||||
this.publicKey = null;
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrivateKeyPem() {
|
||||
return (String) realmAgent.getAttribute(REALM_PRIVATE_KEY).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrivateKeyPem(String privateKeyPem) {
|
||||
realmAgent.setAttribute(new Attribute<String>(REALM_PRIVATE_KEY, privateKeyPem));
|
||||
this.privateKey = null;
|
||||
updateRealm();
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RequiredCredentialModel> getRequiredCredentials() {
|
||||
IdentityManager idm = getIdm();
|
||||
Agent realmAgent = idm.getAgent(REALM_AGENT_ID);
|
||||
RelationshipQuery<RequiredCredentialRelationship> query = idm.createRelationshipQuery(RequiredCredentialRelationship.class);
|
||||
query.setParameter(RequiredCredentialRelationship.REALM_AGENT, realmAgent);
|
||||
List<RequiredCredentialRelationship> results = query.getResultList();
|
||||
List<RequiredCredentialModel> rtn = new ArrayList<RequiredCredentialModel>();
|
||||
for (RequiredCredentialRelationship relationship : results) {
|
||||
RequiredCredentialModel model = new RequiredCredentialModel();
|
||||
model.setInput(relationship.isInput());
|
||||
model.setSecret(relationship.isSecret());
|
||||
model.setType(relationship.getCredentialType());
|
||||
rtn.add(model);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRequiredCredential(RequiredCredentialModel cred) {
|
||||
IdentityManager idm = getIdm();
|
||||
Agent realmAgent = idm.getAgent(REALM_AGENT_ID);
|
||||
RequiredCredentialRelationship relationship = new RequiredCredentialRelationship();
|
||||
relationship.setCredentialType(cred.getType());
|
||||
relationship.setInput(cred.isInput());
|
||||
relationship.setSecret(cred.isSecret());
|
||||
relationship.setRealmAgent(realmAgent);
|
||||
idm.add(relationship);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validatePassword(UserModel user, String password) {
|
||||
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(user.getLoginName(), new Password(password));
|
||||
getIdm().validateCredentials(creds);
|
||||
return creds.getStatus() == Credentials.Status.VALID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateTOTP(UserModel user, String password, String token) {
|
||||
TOTPCredentials creds = new TOTPCredentials();
|
||||
creds.setToken(token);
|
||||
creds.setUsername(user.getLoginName());
|
||||
creds.setPassword(new Password(password));
|
||||
getIdm().validateCredentials(creds);
|
||||
return creds.getStatus() == Credentials.Status.VALID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCredential(UserModel user, UserCredentialModel cred) {
|
||||
IdentityManager idm = getIdm();
|
||||
if (cred.getType().equals(RequiredCredentialRepresentation.PASSWORD)) {
|
||||
Password password = new Password(cred.getValue());
|
||||
idm.updateCredential(((UserAdapter)user).getUser(), password);
|
||||
} else if (cred.getType().equals(RequiredCredentialRepresentation.TOTP)) {
|
||||
TOTPCredential totp = new TOTPCredential(cred.getValue());
|
||||
idm.updateCredential(((UserAdapter)user).getUser(), totp);
|
||||
} else if (cred.getType().equals(RequiredCredentialRepresentation.CLIENT_CERT)) {
|
||||
X509Certificate cert = null;
|
||||
try {
|
||||
cert = org.keycloak.PemUtils.decodeCertificate(cred.getValue());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
X509CertificateCredentials creds = new X509CertificateCredentials(cert);
|
||||
idm.updateCredential(((UserAdapter)user).getUser(), creds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserAdapter getUser(String name) {
|
||||
User user = getIdm().getUser(name);
|
||||
if (user == null) return null;
|
||||
return new UserAdapter(user, getIdm());
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserAdapter addUser(String username) {
|
||||
User user = getIdm().getUser(username);
|
||||
if (user != null) throw new IllegalStateException("User already exists");
|
||||
user = new SimpleUser(username);
|
||||
getIdm().add(user);
|
||||
return new UserAdapter(user, getIdm());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleAdapter getRole(String name) {
|
||||
Role role = getIdm().getRole(name);
|
||||
if (role == null) return null;
|
||||
return new RoleAdapter(role, getIdm());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleAdapter addRole(String name) {
|
||||
Role role = new SimpleRole(name);
|
||||
getIdm().add(role);
|
||||
return new RoleAdapter(role, getIdm());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoleModel> getRoles() {
|
||||
IdentityManager idm = getIdm();
|
||||
IdentityQuery<Role> query = idm.createIdentityQuery(Role.class);
|
||||
query.setParameter(Role.PARTITION, realm);
|
||||
List<Role> roles = query.getResultList();
|
||||
List<RoleModel> roleModels = new ArrayList<RoleModel>();
|
||||
for (Role role : roles) {
|
||||
roleModels.add(new RoleAdapter(role, idm));
|
||||
}
|
||||
return roleModels;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Key name, value resource
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Map<String, ResourceModel> getResourceMap() {
|
||||
Map<String, ResourceModel> resourceMap = new HashMap<String, ResourceModel>();
|
||||
for (ResourceModel resource : getResources()) {
|
||||
resourceMap.put(resource.getName(), resource);
|
||||
}
|
||||
return resourceMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceModel> getResources() {
|
||||
IdentityManager idm = getIdm();
|
||||
RelationshipQuery<ResourceRelationship> query = idm.createRelationshipQuery(ResourceRelationship.class);
|
||||
query.setParameter(ResourceRelationship.REALM_AGENT, realmAgent);
|
||||
List<ResourceRelationship> results = query.getResultList();
|
||||
List<ResourceModel> resources = new ArrayList<ResourceModel>();
|
||||
for (ResourceRelationship relationship : results) {
|
||||
Tier resourceTier = identitySession.findTier(relationship.getResourceId());
|
||||
ResourceModel model = new ResourceAdapter(resourceTier,relationship, this, identitySession);
|
||||
resources.add(model);
|
||||
}
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceModel addResource(String name) {
|
||||
Tier newTier = identitySession.createTier(RealmManager.generateId());
|
||||
IdentityManager idm = getIdm();
|
||||
ResourceRelationship relationship = new ResourceRelationship();
|
||||
relationship.setResourceName(name);
|
||||
relationship.setRealmAgent(realmAgent);
|
||||
relationship.setResourceId(newTier.getId());
|
||||
relationship.setManagementUrl(""); // Picketlink doesn't like null attribute values
|
||||
User resourceUser = new SimpleUser(name);
|
||||
idm.add(resourceUser);
|
||||
relationship.setResourceUser(resourceUser);
|
||||
idm.add(relationship);
|
||||
ResourceModel resource = new ResourceAdapter(newTier, relationship, this, identitySession);
|
||||
resource.addRole("*");
|
||||
resource.addScope(new UserAdapter(resourceUser, idm), "*");
|
||||
return resource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRole(UserModel user, RoleModel role) {
|
||||
return getIdm().hasRole(((UserAdapter)user).getUser(), ((RoleAdapter)role).getRole());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grantRole(UserModel user, RoleModel role) {
|
||||
getIdm().grantRole(((UserAdapter)user).getUser(), ((RoleAdapter)role).getRole());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRoleMappings(UserModel user) {
|
||||
RelationshipQuery<Grant> query = getIdm().createRelationshipQuery(Grant.class);
|
||||
query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser());
|
||||
List<Grant> grants = query.getResultList();
|
||||
HashSet<String> set = new HashSet<String>();
|
||||
for (Grant grant : grants) {
|
||||
if (grant.getRole().getPartition().getId().equals(realm.getId())) set.add(grant.getRole().getName());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addScope(UserModel agent, String roleName) {
|
||||
IdentityManager idm = getIdm();
|
||||
Role role = idm.getRole(roleName);
|
||||
if (role == null) throw new RuntimeException("role not found");
|
||||
ScopeRelationship scope = new ScopeRelationship();
|
||||
scope.setClient(((UserAdapter)agent).getUser());
|
||||
scope.setScope(role);
|
||||
idm.add(scope);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<String> getScope(UserModel agent) {
|
||||
RelationshipQuery<ScopeRelationship> query = getIdm().createRelationshipQuery(ScopeRelationship.class);
|
||||
query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
|
||||
List<ScopeRelationship> scope = query.getResultList();
|
||||
HashSet<String> set = new HashSet<String>();
|
||||
for (ScopeRelationship rel : scope) {
|
||||
if (rel.getScope().getPartition().getId().equals(realm.getId())) set.add(rel.getScope().getName());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRealmAdmin(UserModel agent) {
|
||||
RealmAdapter realmModel = (RealmAdapter)new RealmManager(new PicketlinkKeycloakSession(identitySession)).defaultRealm();
|
||||
IdentityManager idm = realmModel.getIdm();
|
||||
RelationshipQuery<RealmAdminRelationship> query = idm.createRelationshipQuery(RealmAdminRelationship.class);
|
||||
query.setParameter(RealmAdminRelationship.REALM, realm.getId());
|
||||
query.setParameter(RealmAdminRelationship.ADMIN, ((UserAdapter)agent).getUser());
|
||||
List<RealmAdminRelationship> results = query.getResultList();
|
||||
return results.size() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRealmAdmin(UserModel agent) {
|
||||
RealmAdapter realmModel = (RealmAdapter)new RealmManager(new PicketlinkKeycloakSession(identitySession)).defaultRealm();
|
||||
RealmAdminRelationship relationship = new RealmAdminRelationship();
|
||||
relationship.setAdmin(((UserAdapter)agent).getUser());
|
||||
relationship.setRealm(realm.getId());
|
||||
idm.add(relationship);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
package org.keycloak.services.models.picketlink;
|
||||
|
||||
import org.keycloak.services.models.ResourceModel;
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
import org.keycloak.services.models.picketlink.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ScopeRelationship;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.model.Grant;
|
||||
import org.picketlink.idm.model.Role;
|
||||
import org.picketlink.idm.model.SimpleRole;
|
||||
import org.picketlink.idm.model.Tier;
|
||||
import org.picketlink.idm.query.IdentityQuery;
|
||||
import org.picketlink.idm.query.RelationshipQuery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
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 ResourceAdapter implements ResourceModel {
|
||||
protected Tier tier;
|
||||
protected ResourceRelationship agent;
|
||||
protected RealmAdapter realm;
|
||||
protected IdentitySession identitySession;
|
||||
protected IdentityManager idm;
|
||||
|
||||
public ResourceAdapter(Tier tier, ResourceRelationship agent, RealmAdapter realm, IdentitySession session) {
|
||||
this.tier = tier;
|
||||
this.agent = agent;
|
||||
this.realm = realm;
|
||||
this.identitySession = session;
|
||||
}
|
||||
|
||||
protected IdentityManager getIdm() {
|
||||
if (idm == null) idm = identitySession.createIdentityManager(tier);
|
||||
return idm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateResource() {
|
||||
getIdm().update(agent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserAdapter getResourceUser() {
|
||||
return new UserAdapter(agent.getResourceUser(), realm.getIdm());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return tier.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return agent.getResourceName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
agent.setResourceName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return agent.getEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
agent.setEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSurrogateAuthRequired() {
|
||||
return agent.getSurrogateAuthRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
|
||||
agent.setSurrogateAuthRequired(surrogateAuthRequired);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getManagementUrl() {
|
||||
return agent.getManagementUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setManagementUrl(String url) {
|
||||
agent.setManagementUrl(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleAdapter getRole(String name) {
|
||||
Role role = getIdm().getRole(name);
|
||||
if (role == null) return null;
|
||||
return new RoleAdapter(role, getIdm());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleAdapter addRole(String name) {
|
||||
Role role = new SimpleRole(name);
|
||||
getIdm().add(role);
|
||||
return new RoleAdapter(role, getIdm());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoleModel> getRoles() {
|
||||
IdentityQuery<Role> query = getIdm().createIdentityQuery(Role.class);
|
||||
query.setParameter(Role.PARTITION, tier);
|
||||
List<Role> roles = query.getResultList();
|
||||
List<RoleModel> roleModels = new ArrayList<RoleModel>();
|
||||
for (Role role : roles) {
|
||||
roleModels.add(new RoleAdapter(role, idm));
|
||||
}
|
||||
return roleModels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRoleMappings(UserModel user) {
|
||||
RelationshipQuery<Grant> query = getIdm().createRelationshipQuery(Grant.class);
|
||||
query.setParameter(Grant.ASSIGNEE, ((UserAdapter)user).getUser());
|
||||
List<Grant> grants = query.getResultList();
|
||||
HashSet<String> set = new HashSet<String>();
|
||||
for (Grant grant : grants) {
|
||||
if (grant.getRole().getPartition().getId().equals(tier.getId())) set.add(grant.getRole().getName());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addScope(UserModel agent, String roleName) {
|
||||
IdentityManager idm = getIdm();
|
||||
Role role = idm.getRole(roleName);
|
||||
if (role == null) throw new RuntimeException("role not found");
|
||||
addScope(agent, new RoleAdapter(role, idm));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addScope(UserModel agent, RoleModel role) {
|
||||
ScopeRelationship scope = new ScopeRelationship();
|
||||
scope.setClient(((UserAdapter)agent).getUser());
|
||||
scope.setScope(((RoleAdapter)role).getRole());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getScope(UserModel agent) {
|
||||
RelationshipQuery<ScopeRelationship> query = getIdm().createRelationshipQuery(ScopeRelationship.class);
|
||||
query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
|
||||
List<ScopeRelationship> scope = query.getResultList();
|
||||
HashSet<String> set = new HashSet<String>();
|
||||
for (ScopeRelationship rel : scope) {
|
||||
if (rel.getScope().getPartition().getId().equals(tier.getId())) set.add(rel.getScope().getName());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package org.keycloak.services.models.picketlink;
|
||||
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.model.Attribute;
|
||||
import org.picketlink.idm.model.Role;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class RoleAdapter implements RoleModel {
|
||||
protected Role role;
|
||||
protected IdentityManager idm;
|
||||
|
||||
public RoleAdapter(Role role, IdentityManager idm) {
|
||||
this.role = role;
|
||||
this.idm = idm;
|
||||
}
|
||||
|
||||
protected Role getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return role.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
Attribute<Serializable> description = role.getAttribute("description");
|
||||
if (description == null) return null;
|
||||
return (String) description.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDescription(String description) {
|
||||
if (description == null) {
|
||||
role.removeAttribute("description");
|
||||
} else {
|
||||
role.setAttribute(new Attribute<String>("description", description));
|
||||
}
|
||||
idm.update(role);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package org.keycloak.services.models.picketlink;
|
||||
|
||||
import org.keycloak.services.models.UserModel;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.model.Attribute;
|
||||
import org.picketlink.idm.model.User;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class UserAdapter implements UserModel {
|
||||
protected User user;
|
||||
protected IdentityManager idm;
|
||||
|
||||
public UserAdapter(User user, IdentityManager idm) {
|
||||
this.user = user;
|
||||
this.idm = idm;
|
||||
}
|
||||
|
||||
protected User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLoginName() {
|
||||
return user.getLoginName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return user.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
user.setEnabled(enabled);
|
||||
idm.update(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, String value) {
|
||||
user.setAttribute(new Attribute<String>(name, value));
|
||||
idm.update(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttribute(String name) {
|
||||
user.removeAttribute(name);
|
||||
idm.update(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttribute(String name) {
|
||||
Attribute<String> attribute = user.getAttribute(name);
|
||||
if (attribute == null || attribute.getValue() == null) return null;
|
||||
return attribute.getValue().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAttributes() {
|
||||
Map<String, String> attributes = new HashMap<String, String>();
|
||||
for (Attribute attribute : user.getAttributes()) {
|
||||
if (attribute.getValue() != null) attributes.put(attribute.getName(), attribute.getValue().toString());
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
package org.keycloak.services.models.relationships;
|
||||
package org.keycloak.services.models.picketlink.relationships;
|
||||
|
||||
import org.picketlink.idm.model.AbstractAttributedType;
|
||||
import org.picketlink.idm.model.Agent;
|
||||
import org.picketlink.idm.model.Realm;
|
||||
import org.picketlink.idm.model.Relationship;
|
||||
import org.picketlink.idm.model.annotation.AttributeProperty;
|
||||
import org.picketlink.idm.model.annotation.IdentityProperty;
|
|
@ -1,4 +1,4 @@
|
|||
package org.keycloak.services.models.relationships;
|
||||
package org.keycloak.services.models.picketlink.relationships;
|
||||
|
||||
import org.picketlink.idm.model.AbstractAttributedType;
|
||||
import org.picketlink.idm.model.Agent;
|
|
@ -1,4 +1,4 @@
|
|||
package org.keycloak.services.models.relationships;
|
||||
package org.keycloak.services.models.picketlink.relationships;
|
||||
|
||||
import org.picketlink.idm.model.AbstractAttributedType;
|
||||
import org.picketlink.idm.model.Agent;
|
|
@ -1,4 +1,4 @@
|
|||
package org.keycloak.services.models.relationships;
|
||||
package org.keycloak.services.models.picketlink.relationships;
|
||||
|
||||
import org.picketlink.idm.model.AbstractAttributedType;
|
||||
import org.picketlink.idm.model.Agent;
|
|
@ -1,12 +1,14 @@
|
|||
package org.keycloak.services.resources;
|
||||
|
||||
import org.keycloak.SkeletonKeyContextResolver;
|
||||
import org.keycloak.services.filters.IdentitySessionFilter;
|
||||
import org.keycloak.services.filters.KeycloakSessionFilter;
|
||||
import org.keycloak.services.managers.TokenManager;
|
||||
import org.keycloak.services.models.relationships.RealmAdminRelationship;
|
||||
import org.keycloak.services.models.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.relationships.RequiredCredentialRelationship;
|
||||
import org.keycloak.services.models.relationships.ScopeRelationship;
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
import org.keycloak.services.models.picketlink.PicketlinkKeycloakSessionFactory;
|
||||
import org.keycloak.services.models.picketlink.relationships.RealmAdminRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.RequiredCredentialRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ScopeRelationship;
|
||||
import org.picketlink.idm.IdentitySessionFactory;
|
||||
import org.picketlink.idm.config.IdentityConfiguration;
|
||||
import org.picketlink.idm.config.IdentityConfigurationBuilder;
|
||||
|
@ -34,18 +36,18 @@ public class KeycloakApplication extends Application {
|
|||
protected Set<Object> singletons = new HashSet<Object>();
|
||||
protected Set<Class<?>> classes = new HashSet<Class<?>>();
|
||||
|
||||
protected IdentitySessionFactory factory;
|
||||
protected KeycloakSessionFactory factory;
|
||||
|
||||
public KeycloakApplication() {
|
||||
this.factory = createFactory();
|
||||
IdentitySessionFilter filter = new IdentitySessionFilter(factory);
|
||||
this.factory = new PicketlinkKeycloakSessionFactory(createFactory());
|
||||
KeycloakSessionFilter filter = new KeycloakSessionFilter(factory);
|
||||
singletons.add(new RealmsResource(new TokenManager()));
|
||||
singletons.add(filter);
|
||||
classes.add(SkeletonKeyContextResolver.class);
|
||||
classes.add(RegistrationService.class);
|
||||
}
|
||||
|
||||
public IdentitySessionFactory getFactory() {
|
||||
public KeycloakSessionFactory getFactory() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@ package org.keycloak.services.resources;
|
|||
|
||||
import org.jboss.resteasy.logging.Logger;
|
||||
import org.keycloak.representations.idm.PublishedRealmRepresentation;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
@ -25,7 +25,7 @@ public class RealmSubResource {
|
|||
protected UriInfo uriInfo;
|
||||
|
||||
@Context
|
||||
protected IdentitySession identitySession;
|
||||
protected KeycloakSession identitySession;
|
||||
|
||||
protected RealmModel realm;
|
||||
|
||||
|
|
|
@ -3,13 +3,12 @@ package org.keycloak.services.resources;
|
|||
import org.jboss.resteasy.logging.Logger;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.managers.AuthenticationManager;
|
||||
import org.keycloak.services.managers.TokenManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.managers.TokenManager;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.model.Realm;
|
||||
import org.picketlink.idm.model.Role;
|
||||
import org.picketlink.idm.model.User;
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.NotAuthorizedException;
|
||||
|
@ -40,7 +39,7 @@ public class RealmsResource {
|
|||
protected HttpHeaders headers;
|
||||
|
||||
@Context
|
||||
protected IdentitySession identitySession;
|
||||
protected KeycloakSession identitySession;
|
||||
|
||||
@Context
|
||||
ResourceContext resourceContext;
|
||||
|
@ -92,9 +91,9 @@ public class RealmsResource {
|
|||
RealmModel realm;
|
||||
try {
|
||||
RealmManager realmManager = new RealmManager(identitySession);
|
||||
RealmModel defaultRealm = realmManager.getRealm(Realm.DEFAULT_REALM);
|
||||
User realmCreator = new AuthenticationManager().authenticateBearerToken(defaultRealm, headers);
|
||||
Role creatorRole = defaultRealm.getRole(RegistrationService.REALM_CREATOR_ROLE);
|
||||
RealmModel defaultRealm = realmManager.getRealm(RealmModel.DEFAULT_REALM);
|
||||
UserModel realmCreator = new AuthenticationManager().authenticateBearerToken(defaultRealm, headers);
|
||||
RoleModel creatorRole = defaultRealm.getRole(RegistrationService.REALM_CREATOR_ROLE);
|
||||
if (!defaultRealm.hasRole(realmCreator, creatorRole)) {
|
||||
logger.warn("not a realm creator");
|
||||
throw new NotAuthorizedException("Bearer");
|
||||
|
|
|
@ -4,12 +4,11 @@ import org.jboss.resteasy.logging.Logger;
|
|||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
import org.keycloak.services.models.UserCredentialModel;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.model.Role;
|
||||
import org.picketlink.idm.model.SimpleUser;
|
||||
import org.picketlink.idm.model.User;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.ForbiddenException;
|
||||
|
@ -34,7 +33,7 @@ public class RegistrationService {
|
|||
protected UriInfo uriInfo;
|
||||
|
||||
@Context
|
||||
protected IdentitySession identitySession;
|
||||
protected KeycloakSession identitySession;
|
||||
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
|
@ -49,20 +48,19 @@ public class RegistrationService {
|
|||
if (!defaultRealm.isRegistrationAllowed()) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
User user = defaultRealm.getUser(newUser.getUsername());
|
||||
UserModel user = defaultRealm.getUser(newUser.getUsername());
|
||||
if (user != null) {
|
||||
return Response.status(400).type("text/plain").entity("user exists").build();
|
||||
}
|
||||
|
||||
user = new SimpleUser(newUser.getUsername());
|
||||
defaultRealm.addUser(user);
|
||||
user = defaultRealm.addUser(newUser.getUsername());
|
||||
for (CredentialRepresentation cred : newUser.getCredentials()) {
|
||||
UserCredentialModel credModel = new UserCredentialModel();
|
||||
credModel.setType(cred.getType());
|
||||
credModel.setValue(cred.getValue());
|
||||
defaultRealm.updateCredential(user, credModel);
|
||||
}
|
||||
Role realmCreator = defaultRealm.getRole(REALM_CREATOR_ROLE);
|
||||
RoleModel realmCreator = defaultRealm.getRole(REALM_CREATOR_ROLE);
|
||||
defaultRealm.grantRole(user, realmCreator);
|
||||
identitySession.getTransaction().commit();
|
||||
URI uri = uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(user.getLoginName()).build();
|
||||
|
|
|
@ -15,10 +15,10 @@ import org.keycloak.services.managers.AuthenticationManager;
|
|||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.managers.ResourceAdminManager;
|
||||
import org.keycloak.services.managers.TokenManager;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.model.Role;
|
||||
import org.picketlink.idm.model.User;
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
|
@ -58,7 +58,7 @@ public class TokenService {
|
|||
@Context
|
||||
protected HttpHeaders headers;
|
||||
@Context
|
||||
protected IdentitySession identitySession;
|
||||
protected KeycloakSession identitySession;
|
||||
@Context
|
||||
HttpRequest request;
|
||||
@Context
|
||||
|
@ -125,7 +125,7 @@ public class TokenService {
|
|||
if (!realm.isEnabled()) {
|
||||
throw new NotAuthorizedException("Disabled realm");
|
||||
}
|
||||
User user = realm.getUser(username);
|
||||
UserModel user = realm.getUser(username);
|
||||
if (user == null) {
|
||||
throw new NotAuthorizedException("No user");
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ public class TokenService {
|
|||
if (!realm.isEnabled()) {
|
||||
throw new NotAuthorizedException("Disabled realm");
|
||||
}
|
||||
User user = realm.getUser(username);
|
||||
UserModel user = realm.getUser(username);
|
||||
if (user == null) {
|
||||
throw new NotAuthorizedException("No user");
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ public class TokenService {
|
|||
securityFailureForward("Realm not enabled.");
|
||||
return null;
|
||||
}
|
||||
User client = realm.getUser(clientId);
|
||||
UserModel client = realm.getUser(clientId);
|
||||
if (client == null) {
|
||||
securityFailureForward("Unknown login requester.");
|
||||
return null;
|
||||
|
@ -193,7 +193,7 @@ public class TokenService {
|
|||
return null;
|
||||
}
|
||||
String username = formData.getFirst("username");
|
||||
User user = realm.getUser(username);
|
||||
UserModel user = realm.getUser(username);
|
||||
if (user == null) {
|
||||
logger.error("Incorrect user name.");
|
||||
request.setAttribute("KEYCLOAK_LOGIN_ERROR_MESSAGE", "Incorrect user name.");
|
||||
|
@ -216,9 +216,9 @@ public class TokenService {
|
|||
return processAccessCode(scopeParam, state, redirect, client, user);
|
||||
}
|
||||
|
||||
protected Response processAccessCode(String scopeParam, String state, String redirect, User client, User user) {
|
||||
Role resourceRole = realm.getRole(RealmManager.RESOURCE_ROLE);
|
||||
Role identityRequestRole = realm.getRole(RealmManager.IDENTITY_REQUESTER_ROLE);
|
||||
protected Response processAccessCode(String scopeParam, String state, String redirect, UserModel client, UserModel user) {
|
||||
RoleModel resourceRole = realm.getRole(RealmManager.RESOURCE_ROLE);
|
||||
RoleModel identityRequestRole = realm.getRole(RealmManager.IDENTITY_REQUESTER_ROLE);
|
||||
boolean isResource = realm.hasRole(client, resourceRole);
|
||||
if (!isResource && !realm.hasRole(client, identityRequestRole)) {
|
||||
securityFailureForward("Login requester not allowed to request login.");
|
||||
|
@ -274,7 +274,7 @@ public class TokenService {
|
|||
error.put("error_description", "client_id not specified");
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
|
||||
}
|
||||
User client = realm.getUser(client_id);
|
||||
UserModel client = realm.getUser(client_id);
|
||||
if (client == null) {
|
||||
logger.debug("Could not find user");
|
||||
Map<String, String> error = new HashMap<String, String>();
|
||||
|
@ -332,7 +332,7 @@ public class TokenService {
|
|||
res.put("error_description", "Token expired");
|
||||
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
|
||||
}
|
||||
if (!client.getId().equals(accessCode.getClient().getId())) {
|
||||
if (!client.getLoginName().equals(accessCode.getClient().getLoginName())) {
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put("error", "invalid_grant");
|
||||
res.put("error_description", "Auth error");
|
||||
|
@ -403,7 +403,7 @@ public class TokenService {
|
|||
securityFailureForward("Realm not enabled");
|
||||
return null;
|
||||
}
|
||||
User client = realm.getUser(clientId);
|
||||
UserModel client = realm.getUser(clientId);
|
||||
if (client == null) {
|
||||
securityFailureForward("Unknown login requester.");
|
||||
return null;
|
||||
|
@ -415,8 +415,8 @@ public class TokenService {
|
|||
return null;
|
||||
}
|
||||
|
||||
Role resourceRole = realm.getRole(RealmManager.RESOURCE_ROLE);
|
||||
Role identityRequestRole = realm.getRole(RealmManager.IDENTITY_REQUESTER_ROLE);
|
||||
RoleModel resourceRole = realm.getRole(RealmManager.RESOURCE_ROLE);
|
||||
RoleModel identityRequestRole = realm.getRole(RealmManager.IDENTITY_REQUESTER_ROLE);
|
||||
boolean isResource = realm.hasRole(client, resourceRole);
|
||||
if (!isResource && !realm.hasRole(client, identityRequestRole)) {
|
||||
securityFailureForward("Login requester not allowed to request login.");
|
||||
|
@ -424,7 +424,7 @@ public class TokenService {
|
|||
return null;
|
||||
}
|
||||
|
||||
User user = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
|
||||
UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
|
||||
if (user != null) {
|
||||
logger.info(user.getLoginName() + " already logged in.");
|
||||
return processAccessCode(scopeParam, state, redirect, client, user);
|
||||
|
@ -439,7 +439,7 @@ public class TokenService {
|
|||
public Response logout(@QueryParam("redirect_uri") String redirectUri) {
|
||||
// todo do we care if anybody can trigger this?
|
||||
|
||||
User user = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
|
||||
UserModel user = authManager.authenticateIdentityCookie(realm, uriInfo, headers);
|
||||
if (user != null) {
|
||||
logger.info("Logging out: " + user.getLoginName());
|
||||
authManager.expireIdentityCookie(realm, uriInfo);
|
||||
|
@ -491,7 +491,7 @@ public class TokenService {
|
|||
return location.build();
|
||||
}
|
||||
|
||||
protected void oauthGrantPage(AccessCodeEntry accessCode, User client) {
|
||||
protected void oauthGrantPage(AccessCodeEntry accessCode, UserModel client) {
|
||||
request.setAttribute("realmRolesRequested", accessCode.getRealmRolesRequested());
|
||||
request.setAttribute("resourceRolesRequested", accessCode.getResourceRolesRequested());
|
||||
request.setAttribute("client", client);
|
||||
|
|
|
@ -7,24 +7,22 @@ import org.junit.FixMethodOrder;
|
|||
import org.junit.Test;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
|
||||
import org.keycloak.services.managers.InstallationManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RequiredCredentialModel;
|
||||
import org.keycloak.services.models.RoleModel;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
import org.keycloak.services.models.UserCredentialModel;
|
||||
import org.keycloak.services.models.relationships.RealmAdminRelationship;
|
||||
import org.keycloak.services.models.relationships.RequiredCredentialRelationship;
|
||||
import org.keycloak.services.models.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.relationships.ScopeRelationship;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.keycloak.services.models.picketlink.PicketlinkKeycloakSessionFactory;
|
||||
import org.keycloak.services.models.picketlink.relationships.RealmAdminRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.RequiredCredentialRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ScopeRelationship;
|
||||
import org.picketlink.idm.IdentitySessionFactory;
|
||||
import org.picketlink.idm.IdentityManager;
|
||||
import org.picketlink.idm.config.IdentityConfiguration;
|
||||
import org.picketlink.idm.config.IdentityConfigurationBuilder;
|
||||
import org.picketlink.idm.credential.Credentials;
|
||||
import org.picketlink.idm.credential.Password;
|
||||
import org.picketlink.idm.credential.UsernamePasswordCredentials;
|
||||
import org.picketlink.idm.internal.DefaultIdentitySessionFactory;
|
||||
import org.picketlink.idm.jpa.internal.ResourceLocalJpaIdentitySessionHandler;
|
||||
import org.picketlink.idm.jpa.schema.CredentialObject;
|
||||
|
@ -35,10 +33,6 @@ import org.picketlink.idm.jpa.schema.PartitionObject;
|
|||
import org.picketlink.idm.jpa.schema.RelationshipIdentityObject;
|
||||
import org.picketlink.idm.jpa.schema.RelationshipObject;
|
||||
import org.picketlink.idm.jpa.schema.RelationshipObjectAttribute;
|
||||
import org.picketlink.idm.model.Role;
|
||||
import org.picketlink.idm.model.SimpleRole;
|
||||
import org.picketlink.idm.model.SimpleUser;
|
||||
import org.picketlink.idm.model.User;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -48,16 +42,16 @@ import java.util.List;
|
|||
*/
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class AdapterTest {
|
||||
private IdentitySessionFactory factory;
|
||||
private IdentitySession IdentitySession;
|
||||
private KeycloakSessionFactory factory;
|
||||
private KeycloakSession identitySession;
|
||||
private RealmManager adapter;
|
||||
private RealmModel realmModel;
|
||||
|
||||
@Before
|
||||
public void before() throws Exception {
|
||||
factory = createFactory();
|
||||
IdentitySession = factory.createIdentitySession();
|
||||
adapter = new RealmManager(IdentitySession);
|
||||
factory = new PicketlinkKeycloakSessionFactory(createFactory());
|
||||
identitySession = factory.createSession();
|
||||
adapter = new RealmManager(identitySession);
|
||||
}
|
||||
|
||||
public static IdentitySessionFactory createFactory() {
|
||||
|
@ -86,7 +80,7 @@ public class AdapterTest {
|
|||
|
||||
@After
|
||||
public void after() throws Exception {
|
||||
IdentitySession.close();
|
||||
identitySession.close();
|
||||
factory.close();
|
||||
}
|
||||
|
||||
|
@ -106,7 +100,6 @@ public class AdapterTest {
|
|||
realmModel.setPrivateKeyPem("0234234");
|
||||
realmModel.setPublicKeyPem("0234234");
|
||||
realmModel.setTokenLifespan(1000);
|
||||
realmModel.updateRealm();
|
||||
|
||||
System.out.println(realmModel.getId());
|
||||
realmModel = adapter.getRealm(realmModel.getId());
|
||||
|
@ -147,8 +140,7 @@ public class AdapterTest {
|
|||
@Test
|
||||
public void testCredentialValidation() throws Exception {
|
||||
test1CreateRealm();
|
||||
User user = new SimpleUser("bburke");
|
||||
realmModel.addUser(user);
|
||||
UserModel user = realmModel.addUser("bburke");
|
||||
UserCredentialModel cred = new UserCredentialModel();
|
||||
cred.setType(RequiredCredentialRepresentation.PASSWORD);
|
||||
cred.setValue("geheim");
|
||||
|
@ -159,13 +151,12 @@ public class AdapterTest {
|
|||
@Test
|
||||
public void testRoles() throws Exception {
|
||||
test1CreateRealm();
|
||||
realmModel.addRole(new SimpleRole("admin"));
|
||||
realmModel.addRole(new SimpleRole("user"));
|
||||
List<Role> roles = realmModel.getRoles();
|
||||
realmModel.addRole("admin");
|
||||
realmModel.addRole("user");
|
||||
List<RoleModel> roles = realmModel.getRoles();
|
||||
Assert.assertEquals(5, roles.size());
|
||||
SimpleUser user = new SimpleUser("bburke");
|
||||
realmModel.addUser(user);
|
||||
Role role = realmModel.getRole("user");
|
||||
UserModel user = realmModel.addUser("bburke");
|
||||
RoleModel role = realmModel.getRole("user");
|
||||
realmModel.grantRole(user, role);
|
||||
Assert.assertTrue(realmModel.hasRole(user, role));
|
||||
}
|
||||
|
|
|
@ -8,14 +8,17 @@ import org.junit.Test;
|
|||
import org.junit.runners.MethodSorters;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RequiredCredentialModel;
|
||||
import org.keycloak.services.models.relationships.RealmAdminRelationship;
|
||||
import org.keycloak.services.models.relationships.RequiredCredentialRelationship;
|
||||
import org.keycloak.services.models.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.relationships.ScopeRelationship;
|
||||
import org.keycloak.services.models.UserModel;
|
||||
import org.keycloak.services.models.picketlink.PicketlinkKeycloakSessionFactory;
|
||||
import org.keycloak.services.models.picketlink.relationships.RealmAdminRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.RequiredCredentialRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ResourceRelationship;
|
||||
import org.keycloak.services.models.picketlink.relationships.ScopeRelationship;
|
||||
import org.keycloak.services.resources.RegistrationService;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.IdentitySessionFactory;
|
||||
import org.picketlink.idm.config.IdentityConfiguration;
|
||||
import org.picketlink.idm.config.IdentityConfigurationBuilder;
|
||||
|
@ -30,8 +33,6 @@ import org.picketlink.idm.jpa.schema.RelationshipIdentityObject;
|
|||
import org.picketlink.idm.jpa.schema.RelationshipObject;
|
||||
import org.picketlink.idm.jpa.schema.RelationshipObjectAttribute;
|
||||
import org.picketlink.idm.model.Realm;
|
||||
import org.picketlink.idm.model.SimpleRole;
|
||||
import org.picketlink.idm.model.User;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -41,15 +42,15 @@ import java.util.Set;
|
|||
*/
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class ImportTest {
|
||||
private IdentitySessionFactory factory;
|
||||
private IdentitySession identitySession;
|
||||
private KeycloakSessionFactory factory;
|
||||
private KeycloakSession identitySession;
|
||||
private RealmManager manager;
|
||||
private RealmModel realmModel;
|
||||
|
||||
@Before
|
||||
public void before() throws Exception {
|
||||
factory = createFactory();
|
||||
identitySession = factory.createIdentitySession();
|
||||
factory = new PicketlinkKeycloakSessionFactory(createFactory());
|
||||
identitySession = factory.createSession();
|
||||
manager = new RealmManager(identitySession);
|
||||
}
|
||||
|
||||
|
@ -94,15 +95,14 @@ public class ImportTest {
|
|||
defaultRealm.setCookieLoginAllowed(true);
|
||||
defaultRealm.setRegistrationAllowed(true);
|
||||
manager.generateRealmKeys(defaultRealm);
|
||||
defaultRealm.updateRealm();
|
||||
defaultRealm.addRequiredCredential(RequiredCredentialModel.PASSWORD);
|
||||
defaultRealm.addRole(new SimpleRole(RegistrationService.REALM_CREATOR_ROLE));
|
||||
defaultRealm.addRole(RegistrationService.REALM_CREATOR_ROLE);
|
||||
|
||||
RealmRepresentation rep = KeycloakTestBase.loadJson("testrealm.json");
|
||||
RealmModel realm = manager.createRealm("demo", rep.getRealm());
|
||||
manager.importRealm(rep, realm);
|
||||
|
||||
User user = realm.getUser("loginclient");
|
||||
UserModel user = realm.getUser("loginclient");
|
||||
Assert.assertNotNull(user);
|
||||
Set<String> scopes = realm.getScope(user);
|
||||
System.out.println("Scopes size: " + scopes.size());
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package org.keycloak.services.managers;
|
||||
package org.keycloak.test;
|
||||
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.models.RequiredCredentialModel;
|
||||
import org.keycloak.services.resources.RegistrationService;
|
||||
import org.picketlink.idm.model.Realm;
|
||||
import org.picketlink.idm.model.SimpleRole;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -21,7 +21,6 @@ public class InstallationManager {
|
|||
defaultRealm.setCookieLoginAllowed(true);
|
||||
defaultRealm.setRegistrationAllowed(true);
|
||||
manager.generateRealmKeys(defaultRealm);
|
||||
defaultRealm.updateRealm();
|
||||
defaultRealm.addRequiredCredential(RequiredCredentialModel.PASSWORD);
|
||||
defaultRealm.addRole(RegistrationService.REALM_CREATOR_ROLE);
|
||||
}
|
|
@ -12,8 +12,8 @@ import org.keycloak.representations.idm.RealmRepresentation;
|
|||
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.services.managers.AuthenticationManager;
|
||||
import org.keycloak.services.managers.InstallationManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
import org.picketlink.idm.IdentitySession;
|
||||
import org.picketlink.idm.model.Realm;
|
||||
|
@ -43,7 +43,7 @@ public class RealmCreationTest {
|
|||
deployment.setApplicationClass(KeycloakApplication.class.getName());
|
||||
EmbeddedContainer.start(deployment);
|
||||
KeycloakApplication application = (KeycloakApplication) deployment.getApplication();
|
||||
IdentitySession IdentitySession = application.getFactory().createIdentitySession();
|
||||
KeycloakSession IdentitySession = application.getFactory().createSession();
|
||||
RealmManager manager = new RealmManager(IdentitySession);
|
||||
new InstallationManager().install(manager);
|
||||
client = new ResteasyClientBuilder().build();
|
||||
|
|
|
@ -3,14 +3,12 @@ package org.keycloak.test;
|
|||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.openssl.PEMWriter;
|
||||
import org.jboss.resteasy.security.PemUtils;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Security;
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,14 +27,14 @@
|
|||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jboss.spec.javax.ejb</groupId>
|
||||
<artifactId>jboss-ejb-api_3.2_spec</artifactId>
|
||||
<version>1.0.0.Alpha2</version>
|
||||
<version>1.0.0.Alpha2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.api-client</groupId>
|
||||
<artifactId>google-api-client</artifactId>
|
||||
|
@ -47,11 +47,11 @@
|
|||
<groupId>com.google.apis</groupId>
|
||||
<artifactId>google-api-services-oauth2</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.twitter4j</groupId>
|
||||
<artifactId>twitter4j-core</artifactId>
|
||||
</dependency>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
34
ui/pom.xml
34
ui/pom.xml
|
@ -1,22 +1,22 @@
|
|||
<?xml version="1.0"?>
|
||||
<project>
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0-alpha-1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0-alpha-1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-ui</artifactId>
|
||||
<name>Keycloak UI</name>
|
||||
<description />
|
||||
<artifactId>keycloak-ui</artifactId>
|
||||
<name>Keycloak UI</name>
|
||||
<description/>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>jaxrs-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>jaxrs-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
62
ui/src/main/resources/META-INF/resources/ui/index.html
Normal file → Executable file
62
ui/src/main/resources/META-INF/resources/ui/index.html
Normal file → Executable file
|
@ -2,49 +2,49 @@
|
|||
<html lang="en" data-ng-app="keycloak">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Keycloak</title>
|
||||
<meta charset="utf-8">
|
||||
<title>Keycloak</title>
|
||||
|
||||
<link href="lib/bootstrap/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="lib/bootstrap/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="css/admin.css" rel="stylesheet">
|
||||
<link href="css/admin-responsive.css" rel="stylesheet">
|
||||
<link href="lib/bootstrap/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="lib/bootstrap/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="css/admin.css" rel="stylesheet">
|
||||
<link href="css/admin-responsive.css" rel="stylesheet">
|
||||
|
||||
<link href="css/styles.css" rel="stylesheet">
|
||||
<link href="css/styles.css" rel="stylesheet">
|
||||
|
||||
<script src="lib/jquery/jquery-1.10.2.js"></script>
|
||||
<script src="lib/jquery/jquery-1.10.2.js"></script>
|
||||
|
||||
<script src="lib/angular/angular.js"></script>
|
||||
<script src="lib/angular/angular-resource.js"></script>
|
||||
<script src="lib/angular/ui-bootstrap-tpls-0.4.0.js"></script>
|
||||
<script src="lib/angular/angular.js"></script>
|
||||
<script src="lib/angular/angular-resource.js"></script>
|
||||
<script src="lib/angular/ui-bootstrap-tpls-0.4.0.js"></script>
|
||||
|
||||
<script src="js/app.js"></script>
|
||||
<script src="js/controllers.js"></script>
|
||||
<script src="js/loaders.js"></script>
|
||||
<script src="js/services.js"></script>
|
||||
<script src="js/app.js"></script>
|
||||
<script src="js/controllers.js"></script>
|
||||
<script src="js/loaders.js"></script>
|
||||
<script src="js/services.js"></script>
|
||||
</head>
|
||||
|
||||
<body data-ng-controller="GlobalCtrl">
|
||||
|
||||
<div class="alert-container" data-ng-show="notification" data-ng-click="notification = null">
|
||||
<div class="alert alert-{{notification.type}}">{{notification.message}}</div>
|
||||
<div class="alert-container" data-ng-show="notification" data-ng-click="notification = null">
|
||||
<div class="alert alert-{{notification.type}}">{{notification.message}}</div>
|
||||
</div>
|
||||
|
||||
<div id="wrap">
|
||||
<div data-ng-include data-src="'partials/menu.html'"></div>
|
||||
|
||||
<div data-ng-view id="view" data-ng-hide="httpProviderError"></div>
|
||||
|
||||
<div id="httpProviderError" data-ng-show="httpProviderError">
|
||||
<button class="btn btn-danger" data-ng-click="httpProviderError=null">
|
||||
<strong>Error</strong> {{httpProviderError}}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="wrap">
|
||||
<div data-ng-include data-src="'partials/menu.html'"></div>
|
||||
|
||||
<div data-ng-view id="view" data-ng-hide="httpProviderError"></div>
|
||||
|
||||
<div id="httpProviderError" data-ng-show="httpProviderError">
|
||||
<button class="btn btn-danger" data-ng-click="httpProviderError=null">
|
||||
<strong>Error</strong> {{httpProviderError}}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="loading">
|
||||
<i class="icon-spinner icon-spin"></i> Loading...
|
||||
</div>
|
||||
<div id="loading">
|
||||
<i class="icon-spinner icon-spin"></i> Loading...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
113
ui/src/main/resources/META-INF/resources/ui/partials/application-detail.html
Normal file → Executable file
113
ui/src/main/resources/META-INF/resources/ui/partials/application-detail.html
Normal file → Executable file
|
@ -2,14 +2,17 @@
|
|||
<div class="row">
|
||||
<aside class="span3" data-ng-include data-src="'partials/application-menu.html'"></aside>
|
||||
<div id="actions-bg"></div>
|
||||
|
||||
|
||||
<div id="container-right" class="span9">
|
||||
<h1 data-ng-show="create"><span class="gray">New Application</span></h1>
|
||||
|
||||
<h1 data-ng-hide="create">
|
||||
<span class="gray">{{application.name}}</span> configuration
|
||||
</h1>
|
||||
|
||||
<div data-ng-show="applicationForm.showErrors && applicationForm.$error.required" class="alert alert-error">Please fill in all required fields</div>
|
||||
<div data-ng-show="applicationForm.showErrors && applicationForm.$error.required" class="alert alert-error">
|
||||
Please fill in all required fields
|
||||
</div>
|
||||
<p class="subtitle subtitle-right"><span class="required">*</span> Required fields</p>
|
||||
|
||||
<form class="form-horizontal" name="applicationForm" novalidate>
|
||||
|
@ -17,64 +20,86 @@
|
|||
<legend>Settings</legend>
|
||||
|
||||
<div data-kc-input>
|
||||
<label>Name</label>
|
||||
<input class="input-xlarge" type="text" name="name" data-ng-model="application.name" autofocus required>
|
||||
<label>Name</label>
|
||||
<input class="input-xlarge" type="text" name="name" data-ng-model="application.name" autofocus
|
||||
required>
|
||||
</div>
|
||||
|
||||
<div data-kc-input>
|
||||
<label>Enabled</label>
|
||||
<input class="input-xlarge" type="checkbox" name="enabled" data-ng-model="application.enabled">
|
||||
</div>
|
||||
|
||||
|
||||
<div data-kc-input>
|
||||
<label>Enabled</label>
|
||||
<input class="input-xlarge" type="checkbox" name="enabled" data-ng-model="application.enabled">
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="realm">Realm <span class="required">*</span></label>
|
||||
|
||||
<div class="controls">
|
||||
<select data-ng-model="application.realm" id="realm" name="realm" data-ng-required>
|
||||
<option data-ng-repeat="r in realms" value="{{r.id}}" data-ng-selected="r.id == application.realm">{{r.name}}</option>
|
||||
</select>
|
||||
<select data-ng-model="application.realm" id="realm" name="realm" data-ng-required>
|
||||
<option data-ng-repeat="r in realms" value="{{r.id}}"
|
||||
data-ng-selected="r.id == application.realm">{{r.name}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>Roles</legend>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">Roles</label>
|
||||
<div class="controls">
|
||||
<span class="label" style="margin-right: 1em;" data-ng-repeat="r in (application.roles|orderBy:'toString()')">{{r}} <button data-ng-click="removeRole(r)"><i class="icon-remove icon-white"></i></button></span>
|
||||
|
||||
<div class="input-append">
|
||||
<input class="input-small" type="text" data-ng-model="newRole" placeHolder="Role" data-kc-enter="addRole()" />
|
||||
<button class="btn" type="button" data-ng-click="addRole()">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<legend>Roles</legend>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">Initial Roles</label>
|
||||
<div class="controls">
|
||||
<span class="label" style="margin-right: 1em;" data-ng-repeat="r in (application.initialRoles|orderBy:'toString()')">{{r}} <button data-ng-click="removeInitialRole(r)"><i class="icon-remove icon-white"></i></button></span>
|
||||
|
||||
<div class="input-append">
|
||||
<select style="width: auto;" data-ng-model="newInitialRole" data-ng-click="addInitialRole()">
|
||||
<option data-ng-repeat="r in (application.roles|remove:application.initialRoles|orderBy:'toString()')" value="{{r}}">{{r}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="control-group">
|
||||
<label class="control-label">Roles</label>
|
||||
|
||||
<div class="controls">
|
||||
<span class="label" style="margin-right: 1em;"
|
||||
data-ng-repeat="r in (application.roles|orderBy:'toString()')">{{r}} <button
|
||||
data-ng-click="removeRole(r)"><i class="icon-remove icon-white"></i></button></span>
|
||||
|
||||
<div class="input-append">
|
||||
<input class="input-small" type="text" data-ng-model="newRole" placeHolder="Role"
|
||||
data-kc-enter="addRole()"/>
|
||||
<button class="btn" type="button" data-ng-click="addRole()">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">Initial Roles</label>
|
||||
|
||||
<div class="controls">
|
||||
<span class="label" style="margin-right: 1em;"
|
||||
data-ng-repeat="r in (application.initialRoles|orderBy:'toString()')">{{r}} <button
|
||||
data-ng-click="removeInitialRole(r)"><i class="icon-remove icon-white"></i></button></span>
|
||||
|
||||
<div class="input-append">
|
||||
<select style="width: auto;" data-ng-model="newInitialRole"
|
||||
data-ng-click="addInitialRole()">
|
||||
<option data-ng-repeat="r in (application.roles|remove:application.initialRoles|orderBy:'toString()')"
|
||||
value="{{r}}">{{r}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div class="form-actions" data-ng-show="create">
|
||||
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save</button>
|
||||
<button type="submit" data-ng-click="cancel()" class="btn" data-ng-click="cancel()" data-ng-show="changed">Cancel</button>
|
||||
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save
|
||||
</button>
|
||||
<button type="submit" data-ng-click="cancel()" class="btn" data-ng-click="cancel()"
|
||||
data-ng-show="changed">Cancel
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="form-actions" data-ng-show="!create">
|
||||
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save changes</button>
|
||||
<button type="submit" data-ng-click="reset()" class="btn" data-ng-show="changed">Clear changes</button>
|
||||
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save
|
||||
changes
|
||||
</button>
|
||||
<button type="submit" data-ng-click="reset()" class="btn" data-ng-show="changed">Clear changes
|
||||
</button>
|
||||
<a href="#/applications" data-ng-hide="changed">View applications »</a>
|
||||
<button type="submit" data-ng-click="remove()" class="btn btn-danger" data-ng-hide="changed">Delete</button>
|
||||
<button type="submit" data-ng-click="remove()" class="btn btn-danger" data-ng-hide="changed">
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
6
ui/src/main/resources/META-INF/resources/ui/partials/application-list.html
Normal file → Executable file
6
ui/src/main/resources/META-INF/resources/ui/partials/application-list.html
Normal file → Executable file
|
@ -12,9 +12,9 @@
|
|||
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Application</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Application</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr data-ng-repeat="application in applications">
|
||||
<td><a href="#/applications/{{application.id}}">{{application.name}}</a></td>
|
||||
|
|
8
ui/src/main/resources/META-INF/resources/ui/partials/application-menu.html
Normal file → Executable file
8
ui/src/main/resources/META-INF/resources/ui/partials/application-menu.html
Normal file → Executable file
|
@ -6,10 +6,12 @@
|
|||
</div>
|
||||
<ul>
|
||||
<li data-ng-repeat="a in applications" data-ng-class="path[1] == a.id && 'active'">
|
||||
<a href="#/applications/{{a.id}}">{{a.name}}</a>
|
||||
<a href="#/applications/{{a.id}}">{{a.name}}</a>
|
||||
<ul class="sub-items" data-ng-show="path[1] == a.id">
|
||||
<li data-ng-class="!path[2] && 'active'"><a href="#/applications/{{a.id}}">Configuration</a></li>
|
||||
<li data-ng-class="path[2] == 'roles' && 'active'"><a href="#/applications/{{a.id}}/roles">Role mapping</a></li>
|
||||
<li data-ng-class="!path[2] && 'active'"><a href="#/applications/{{a.id}}">Configuration</a>
|
||||
</li>
|
||||
<li data-ng-class="path[2] == 'roles' && 'active'"><a href="#/applications/{{a.id}}/roles">Role
|
||||
mapping</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
12
ui/src/main/resources/META-INF/resources/ui/partials/menu.html
Normal file → Executable file
12
ui/src/main/resources/META-INF/resources/ui/partials/menu.html
Normal file → Executable file
|
@ -4,9 +4,12 @@
|
|||
<div class="nav-collapse">
|
||||
<nav id="global-nav">
|
||||
<ul class="nav">
|
||||
<li class="divider-vertical-left" data-ng-class="path[0] == '' && 'active'"><a href="#">Home</a></li>
|
||||
<li class="divider-vertical-left" data-ng-class="path[0] == 'applications' && 'active'" data-ng-show="auth.loggedIn"><a href="#/applications">Applications</a></li>
|
||||
<li class="divider-vertical-left" data-ng-class="path[0] == 'realms' && 'active'" data-ng-show="auth.loggedIn"><a href="#/realms">Realms</a></li>
|
||||
<li class="divider-vertical-left" data-ng-class="path[0] == '' && 'active'"><a href="#">Home</a>
|
||||
</li>
|
||||
<li class="divider-vertical-left" data-ng-class="path[0] == 'applications' && 'active'"
|
||||
data-ng-show="auth.loggedIn"><a href="#/applications">Applications</a></li>
|
||||
<li class="divider-vertical-left" data-ng-class="path[0] == 'realms' && 'active'"
|
||||
data-ng-show="auth.loggedIn"><a href="#/realms">Realms</a></li>
|
||||
</ul>
|
||||
<ul class="nav pull-right" data-ng-hide="auth.loggedIn">
|
||||
<li><a href="/ejs-identity/api/login/system">Login</a></li>
|
||||
|
@ -17,7 +20,8 @@
|
|||
class="icon-user icon-gray"></i> {{auth.user.displayName}} <i class="caret"></i></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="" data-ng-click="auth.logout()">Sign Out</a></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
|
|
20
ui/src/main/resources/META-INF/resources/ui/partials/provider/google-help.html
Normal file → Executable file
20
ui/src/main/resources/META-INF/resources/ui/partials/provider/google-help.html
Normal file → Executable file
|
@ -1,12 +1,16 @@
|
|||
<p>
|
||||
Open <a href="https://code.google.com/apis/console/" target="_blank">https://code.google.com/apis/console/</a>. From the
|
||||
Open <a href="https://code.google.com/apis/console/" target="_blank">https://code.google.com/apis/console/</a>. From
|
||||
the
|
||||
drop-down menu select <i>Create</i>.
|
||||
</p>
|
||||
|
||||
<p>Use any name that you'd like, click <i>Create Project</i>, select <i>API Access</i> and click on <i>Create an OAuth 2.0 client ID</i>.</p>
|
||||
<p>Use any name that you'd like, click <i>Create Project</i>, select <i>API Access</i> and click on <i>Create an OAuth
|
||||
2.0 client ID</i>.</p>
|
||||
|
||||
<p>Use any product name you'd like and leave the other fields empty, then click <i>Next</i>. On the next page select <i>Web application</i>
|
||||
as the application type. Click <i>more options</i> next to <i>Your site or hostname</i>. Fill in the form with the following values:</p>
|
||||
<p>Use any product name you'd like and leave the other fields empty, then click <i>Next</i>. On the next page select <i>Web
|
||||
application</i>
|
||||
as the application type. Click <i>more options</i> next to <i>Your site or hostname</i>. Fill in the form with the
|
||||
following values:</p>
|
||||
|
||||
<ul>
|
||||
<li><b>Authorized Redirect URIs:</b> {{callbackUrl}}</li>
|
||||
|
@ -17,14 +21,18 @@
|
|||
<form class="form-horizontal" name="googleHelpForm">
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="providerHelp.key">Client ID </label>
|
||||
|
||||
<div class="controls">
|
||||
<input type="text" class="input-xlarge" id="providerHelp.key" data-ng-model="application.providers[providerHelp.index].key">
|
||||
<input type="text" class="input-xlarge" id="providerHelp.key"
|
||||
data-ng-model="application.providers[providerHelp.index].key">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="providerHelp.secret">Client secret </label>
|
||||
|
||||
<div class="controls">
|
||||
<input type="text" class="input-xlarge" id="providerHelp.secret" data-ng-model="application.providers[providerHelp.index].secret">
|
||||
<input type="text" class="input-xlarge" id="providerHelp.secret"
|
||||
data-ng-model="application.providers[providerHelp.index].secret">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
16
ui/src/main/resources/META-INF/resources/ui/partials/provider/twitter-help.html
Normal file → Executable file
16
ui/src/main/resources/META-INF/resources/ui/partials/provider/twitter-help.html
Normal file → Executable file
|
@ -1,5 +1,6 @@
|
|||
<p>
|
||||
Open <a href="https://dev.twitter.com/apps" target="_blank">https://dev.twitter.com/apps</a>. Click on <i>Create a new
|
||||
Open <a href="https://dev.twitter.com/apps" target="_blank">https://dev.twitter.com/apps</a>. Click on <i>Create a
|
||||
new
|
||||
application</i>.
|
||||
</p>
|
||||
|
||||
|
@ -18,21 +19,26 @@
|
|||
<form class="form-horizontal" name="googleHelpForm">
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="providerHelp.key">Consumer key </label>
|
||||
|
||||
<div class="controls">
|
||||
<input type="text" class="input-xlarge" id="providerHelp.key" data-ng-model="application.providers[providerHelp.index].key">
|
||||
<input type="text" class="input-xlarge" id="providerHelp.key"
|
||||
data-ng-model="application.providers[providerHelp.index].key">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="providerHelp.secret">Consumer secret </label>
|
||||
|
||||
<div class="controls">
|
||||
<input type="text" class="input-xlarge" id="providerHelp.secret" data-ng-model="application.providers[providerHelp.index].secret">
|
||||
<input type="text" class="input-xlarge" id="providerHelp.secret"
|
||||
data-ng-model="application.providers[providerHelp.index].secret">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<p>
|
||||
Now click on <i>Settings</i> and tick the box <i>Allow this application to be used to Sign in with Twitter</i>, and click on <i>Update
|
||||
this Twitter application's settings</i>.
|
||||
Now click on <i>Settings</i> and tick the box <i>Allow this application to be used to Sign in with Twitter</i>, and
|
||||
click on <i>Update
|
||||
this Twitter application's settings</i>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
164
ui/src/main/resources/META-INF/resources/ui/partials/realm-detail.html
Normal file → Executable file
164
ui/src/main/resources/META-INF/resources/ui/partials/realm-detail.html
Normal file → Executable file
|
@ -5,92 +5,118 @@
|
|||
|
||||
<div id="container-right" class="span9">
|
||||
<h1 data-ng-show="create"><span class="gray">New Realm</span></h1>
|
||||
|
||||
<h1 data-ng-hide="create">
|
||||
<span class="gray">{{realm.name}}</span> configuration
|
||||
</h1>
|
||||
|
||||
<div data-ng-show="realmForm.showErrors && realmForm.$error.required" class="alert alert-error">Please fill in all required fields</div>
|
||||
|
||||
<div data-ng-show="realmForm.showErrors && realmForm.$error.required" class="alert alert-error">Please fill
|
||||
in all required fields
|
||||
</div>
|
||||
<p class="subtitle subtitle-right"><span class="required">*</span> Required fields</p>
|
||||
|
||||
<form class="form-horizontal" name="realmForm" novalidate>
|
||||
<fieldset>
|
||||
<legend>Settings</legend>
|
||||
|
||||
<div data-kc-input>
|
||||
<label>Name</label>
|
||||
<input class="input-xlarge" type="text" name="name" data-ng-model="realm.name" autofocus required>
|
||||
</div>
|
||||
|
||||
<div data-kc-input>
|
||||
<label>Enabled</label>
|
||||
<input class="input-xlarge" type="checkbox" name="enabled" data-ng-model="realm.enabled">
|
||||
</div>
|
||||
|
||||
<div data-kc-input>
|
||||
<label>Social login</label>
|
||||
<input class="input-xlarge" type="checkbox" name="social" data-ng-model="realm.social">
|
||||
</div>
|
||||
|
||||
<div data-kc-input>
|
||||
<label>User registration</label>
|
||||
<input class="input-xlarge" type="checkbox" name="social" data-ng-model="realm.userRegistration">
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="realmForm-tokenExpiration" class="control-label">Token expiration</label>
|
||||
<div class="controls">
|
||||
<input class="input-small" type="text" name="tokenExpiration" data-ng-model="realm.tokenExpiration">
|
||||
<select style="width: auto;" name="tokenExpirationUnit" data-ng-model="realm.tokenExpirationUnit">
|
||||
<option value="SECONDS" data-ng-selected="!realm.tokenExpirationUnit">Seconds</option>
|
||||
<option value="MINUTES">Minutes</option>
|
||||
<option value="HOURS">Hours</option>
|
||||
<option value="DAYS">Days</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>Roles</legend>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">Roles</label>
|
||||
<div class="controls">
|
||||
<span class="label" style="margin-right: 1em;" data-ng-repeat="r in (realm.roles|orderBy:'toString()')">{{r}} <button data-ng-click="removeRole(r)"><i class="icon-remove icon-white"></i></button></span>
|
||||
|
||||
<div class="input-append">
|
||||
<input class="input-small" type="text" data-ng-model="newRole" placeHolder="Role" data-kc-enter="addRole()" />
|
||||
<button class="btn" type="button" data-ng-click="addRole()">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">Initial Roles</label>
|
||||
<div class="controls">
|
||||
<span class="label" style="margin-right: 1em;" data-ng-repeat="r in (realm.initialRoles|orderBy:'toString()')">{{r}} <button data-ng-click="removeInitialRole(r)"><i class="icon-remove icon-white"></i></button></span>
|
||||
|
||||
<div class="input-append">
|
||||
<select style="width: auto;" data-ng-model="newInitialRole" data-ng-click="addInitialRole()">
|
||||
<option data-ng-repeat="r in (realm.roles|remove:realm.initialRoles|orderBy:'toString()')" value="{{r}}">{{r}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-kc-input>
|
||||
<label>Name</label>
|
||||
<input class="input-xlarge" type="text" name="name" data-ng-model="realm.name" autofocus
|
||||
required>
|
||||
</div>
|
||||
|
||||
<div data-kc-input>
|
||||
<label>Enabled</label>
|
||||
<input class="input-xlarge" type="checkbox" name="enabled" data-ng-model="realm.enabled">
|
||||
</div>
|
||||
|
||||
<div data-kc-input>
|
||||
<label>Social login</label>
|
||||
<input class="input-xlarge" type="checkbox" name="social" data-ng-model="realm.social">
|
||||
</div>
|
||||
|
||||
<div data-kc-input>
|
||||
<label>User registration</label>
|
||||
<input class="input-xlarge" type="checkbox" name="social"
|
||||
data-ng-model="realm.userRegistration">
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="realmForm-tokenExpiration" class="control-label">Token expiration</label>
|
||||
|
||||
<div class="controls">
|
||||
<input class="input-small" type="text" name="tokenExpiration"
|
||||
data-ng-model="realm.tokenExpiration">
|
||||
<select style="width: auto;" name="tokenExpirationUnit"
|
||||
data-ng-model="realm.tokenExpirationUnit">
|
||||
<option value="SECONDS" data-ng-selected="!realm.tokenExpirationUnit">Seconds</option>
|
||||
<option value="MINUTES">Minutes</option>
|
||||
<option value="HOURS">Hours</option>
|
||||
<option value="DAYS">Days</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>Roles</legend>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">Roles</label>
|
||||
|
||||
<div class="controls">
|
||||
<span class="label" style="margin-right: 1em;"
|
||||
data-ng-repeat="r in (realm.roles|orderBy:'toString()')">{{r}} <button
|
||||
data-ng-click="removeRole(r)"><i class="icon-remove icon-white"></i></button></span>
|
||||
|
||||
<div class="input-append">
|
||||
<input class="input-small" type="text" data-ng-model="newRole" placeHolder="Role"
|
||||
data-kc-enter="addRole()"/>
|
||||
<button class="btn" type="button" data-ng-click="addRole()">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">Initial Roles</label>
|
||||
|
||||
<div class="controls">
|
||||
<span class="label" style="margin-right: 1em;"
|
||||
data-ng-repeat="r in (realm.initialRoles|orderBy:'toString()')">{{r}} <button
|
||||
data-ng-click="removeInitialRole(r)"><i class="icon-remove icon-white"></i></button></span>
|
||||
|
||||
<div class="input-append">
|
||||
<select style="width: auto;" data-ng-model="newInitialRole"
|
||||
data-ng-click="addInitialRole()">
|
||||
<option data-ng-repeat="r in (realm.roles|remove:realm.initialRoles|orderBy:'toString()')"
|
||||
value="{{r}}">{{r}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div class="form-actions" data-ng-show="create">
|
||||
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save</button>
|
||||
<button type="submit" data-ng-click="cancel()" class="btn" data-ng-click="cancel()" data-ng-show="changed">Cancel</button>
|
||||
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save
|
||||
</button>
|
||||
<button type="submit" data-ng-click="cancel()" class="btn" data-ng-click="cancel()"
|
||||
data-ng-show="changed">Cancel
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="form-actions" data-ng-show="!create">
|
||||
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save changes</button>
|
||||
<button type="submit" data-ng-click="reset()" class="btn" data-ng-show="changed">Clear changes</button>
|
||||
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save
|
||||
changes
|
||||
</button>
|
||||
<button type="submit" data-ng-click="reset()" class="btn" data-ng-show="changed">Clear changes
|
||||
</button>
|
||||
<a href="#/realms" data-ng-hide="changed">View realms »</a>
|
||||
<button type="submit" data-ng-click="remove()" class="btn btn-danger" data-ng-hide="changed">Delete</button>
|
||||
<button type="submit" data-ng-click="remove()" class="btn btn-danger" data-ng-hide="changed">
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<div id="container-right-bg"></div>
|
||||
|
|
8
ui/src/main/resources/META-INF/resources/ui/partials/realm-list.html
Normal file → Executable file
8
ui/src/main/resources/META-INF/resources/ui/partials/realm-list.html
Normal file → Executable file
|
@ -5,16 +5,16 @@
|
|||
|
||||
<div id="container-right" class="span9">
|
||||
<a class="btn btn-small pull-right" href="#/create/realm">Add Realm</a>
|
||||
|
||||
|
||||
<h1>
|
||||
<span class="gray">Realms</span>
|
||||
</h1>
|
||||
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Realm</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Realm</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr data-ng-repeat="r in realms">
|
||||
<td><a href="#/realms/{{r.id}}">{{r.name}}</a></td>
|
||||
|
|
6
ui/src/main/resources/META-INF/resources/ui/partials/realm-menu.html
Normal file → Executable file
6
ui/src/main/resources/META-INF/resources/ui/partials/realm-menu.html
Normal file → Executable file
|
@ -9,8 +9,10 @@
|
|||
<a href=#/realms/{{r.id}}>{{r.name}}</a>
|
||||
<ul class="sub-items" data-ng-show="path[1] == r.id">
|
||||
<li data-ng-class="!path[2] && 'active'"><a href="#/realms/{{r.id}}">Configuration</a></li>
|
||||
<li data-ng-class="path[2] == 'users' && 'active'"><a href="#/realms/{{r.id}}/users">Users</a></li>
|
||||
<li data-ng-class="path[2] == 'roles' && 'active'"><a href="#/realms/{{r.id}}/roles">Role mapping</a></li>
|
||||
<li data-ng-class="path[2] == 'users' && 'active'"><a href="#/realms/{{r.id}}/users">Users</a>
|
||||
</li>
|
||||
<li data-ng-class="path[2] == 'roles' && 'active'"><a href="#/realms/{{r.id}}/roles">Role
|
||||
mapping</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
82
ui/src/main/resources/META-INF/resources/ui/partials/role-mapping.html
Normal file → Executable file
82
ui/src/main/resources/META-INF/resources/ui/partials/role-mapping.html
Normal file → Executable file
|
@ -1,46 +1,50 @@
|
|||
<div id="wrapper" class="container">
|
||||
<div class="row">
|
||||
<aside class="span3" data-ng-include data-src="'partials/' + path[0].slice(0, -1) + '-menu.html'"></aside>
|
||||
|
||||
<div id="actions-bg"></div>
|
||||
<div class="row">
|
||||
<aside class="span3" data-ng-include data-src="'partials/' + path[0].slice(0, -1) + '-menu.html'"></aside>
|
||||
|
||||
<div id="container-right" class="span9">
|
||||
<h1>
|
||||
<span class="gray" data-ng-hide="create">{{realm.name}}</span> role mapping
|
||||
</h1>
|
||||
<div id="actions-bg"></div>
|
||||
|
||||
<ul class="nav nav-tabs">
|
||||
<li data-ng-class="path[3] == r && 'active'" data-ng-repeat="r in (realm.roles|orderBy:'toString()')"><a href="#/{{path[0]}}/{{realm.id}}/roles/{{r}}">{{r}}</a></li>
|
||||
</ul>
|
||||
<div id="container-right" class="span9">
|
||||
<h1>
|
||||
<span class="gray" data-ng-hide="create">{{realm.name}}</span> role mapping
|
||||
</h1>
|
||||
|
||||
<div data-ng-show="role">
|
||||
<select style="width: auto;" id="realm" name="realm" data-ng-model="newUser" data-ng-click="addUser(u)">
|
||||
<option data-ng-repeat="u in (allUsers|remove:users:'userId')" value="{{u.userId}}">{{u.userId}}</option>
|
||||
</select>
|
||||
<ul class="nav nav-tabs">
|
||||
<li data-ng-class="path[3] == r && 'active'" data-ng-repeat="r in (realm.roles|orderBy:'toString()')"><a
|
||||
href="#/{{path[0]}}/{{realm.id}}/roles/{{r}}">{{r}}</a></li>
|
||||
</ul>
|
||||
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<th>Firstname</th>
|
||||
<th>Lastname</th>
|
||||
<th>Email</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr data-ng-repeat="user in users">
|
||||
<td>{{user.userId}}</td>
|
||||
<td>{{user.firstName}}</td>
|
||||
<td>{{user.lastName}}</td>
|
||||
<td>{{user.email}}</td>
|
||||
<td><button data-ng-click="removeUser(user.userId)">
|
||||
<i class="icon-remove"></i>
|
||||
</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div data-ng-show="role">
|
||||
<select style="width: auto;" id="realm" name="realm" data-ng-model="newUser" data-ng-click="addUser(u)">
|
||||
<option data-ng-repeat="u in (allUsers|remove:users:'userId')" value="{{u.userId}}">{{u.userId}}
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<div id="container-right-bg"></div>
|
||||
</div>
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<th>Firstname</th>
|
||||
<th>Lastname</th>
|
||||
<th>Email</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr data-ng-repeat="user in users">
|
||||
<td>{{user.userId}}</td>
|
||||
<td>{{user.firstName}}</td>
|
||||
<td>{{user.lastName}}</td>
|
||||
<td>{{user.email}}</td>
|
||||
<td>
|
||||
<button data-ng-click="removeUser(user.userId)">
|
||||
<i class="icon-remove"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="container-right-bg"></div>
|
||||
</div>
|
||||
</div>
|
47
ui/src/main/resources/META-INF/resources/ui/partials/user-detail.html
Normal file → Executable file
47
ui/src/main/resources/META-INF/resources/ui/partials/user-detail.html
Normal file → Executable file
|
@ -5,11 +5,14 @@
|
|||
|
||||
<div id="container-right" class="span9">
|
||||
<h1 data-ng-show="create"><span class="gray">New User</span></h1>
|
||||
|
||||
<h1 data-ng-hide="create">
|
||||
<span class="gray">{{user.userId}}</span> configuration
|
||||
</h1>
|
||||
|
||||
<div data-ng-show="userForm.showErrors && userForm.$error.required" class="alert alert-error">Please fill in all required fields</div>
|
||||
<div data-ng-show="userForm.showErrors && userForm.$error.required" class="alert alert-error">Please fill in
|
||||
all required fields
|
||||
</div>
|
||||
<p class="subtitle subtitle-right"><span class="required">*</span> Required fields</p>
|
||||
|
||||
<form class="form-horizontal" name="userForm" novalidate>
|
||||
|
@ -17,21 +20,26 @@
|
|||
<legend>Details</legend>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="name">Username <span class="required">*</span></label>
|
||||
|
||||
<div class="controls">
|
||||
<input type="text" class="input-xlarge" id="name" name="name" data-ng-model="user.userId" autofocus required data-ng-readonly="!create">
|
||||
<input type="text" class="input-xlarge" id="name" name="name" data-ng-model="user.userId"
|
||||
autofocus required data-ng-readonly="!create">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="email">Email </label>
|
||||
|
||||
<div class="controls">
|
||||
<input type="email" class="input-xlarge" id="email" name="email" data-ng-model="user.email">
|
||||
<span class="help-inline error" data-ng-show="userForm.showErrors && userForm.email.$invalid">Invalid email</span>
|
||||
<span class="help-inline error"
|
||||
data-ng-show="userForm.showErrors && userForm.email.$invalid">Invalid email</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="firstName">Firstname </label>
|
||||
|
||||
<div class="controls">
|
||||
<input type="text" class="input-xlarge" id="firstName" data-ng-model="user.firstName">
|
||||
</div>
|
||||
|
@ -39,6 +47,7 @@
|
|||
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="lastName">Lastname </label>
|
||||
|
||||
<div class="controls">
|
||||
<input type="text" class="input-xlarge" id="lastName" data-ng-model="user.lastName">
|
||||
</div>
|
||||
|
@ -46,8 +55,10 @@
|
|||
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="password">Password <span class="required">*</span></label>
|
||||
|
||||
<div class="controls">
|
||||
<input type="password" class="input-xlarge" id="password" name="password" data-ng-model="user.password" data-ng-required="create">
|
||||
<input type="password" class="input-xlarge" id="password" name="password"
|
||||
data-ng-model="user.password" data-ng-required="create">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
@ -57,10 +68,10 @@
|
|||
|
||||
<table class="table table-striped table-bordered margin-top">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr data-ng-repeat="attribute in user.attributes">
|
||||
<td><input type="text" placeholder="Name" value="{{attribute.name}}" readonly></td>
|
||||
|
@ -70,17 +81,25 @@
|
|||
</fieldset>
|
||||
|
||||
<div class="form-actions" data-ng-show="create">
|
||||
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save</button>
|
||||
<button type="submit" data-ng-click="cancel()" class="btn" data-ng-click="cancel()" data-ng-show="changed">Cancel</button>
|
||||
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save
|
||||
</button>
|
||||
<button type="submit" data-ng-click="cancel()" class="btn" data-ng-click="cancel()"
|
||||
data-ng-show="changed">Cancel
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="form-actions" data-ng-show="!create">
|
||||
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save changes</button>
|
||||
<button type="submit" data-ng-click="reset()" class="btn" data-ng-show="changed">Clear changes</button>
|
||||
<button type="submit" data-ng-click="save()" class="btn btn-primary" data-ng-show="changed">Save
|
||||
changes
|
||||
</button>
|
||||
<button type="submit" data-ng-click="reset()" class="btn" data-ng-show="changed">Clear changes
|
||||
</button>
|
||||
<a href="#/realms/{{realm.id}}/users" data-ng-hide="changed">View users »</a>
|
||||
<button type="submit" data-ng-click="remove()" class="btn btn-danger" data-ng-hide="changed">Delete</button>
|
||||
<button type="submit" data-ng-click="remove()" class="btn btn-danger" data-ng-hide="changed">
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<div id="container-right-bg"></div>
|
||||
|
|
38
ui/src/main/resources/META-INF/resources/ui/partials/user-list.html
Normal file → Executable file
38
ui/src/main/resources/META-INF/resources/ui/partials/user-list.html
Normal file → Executable file
|
@ -6,26 +6,26 @@
|
|||
<div id="container-right" class="span9">
|
||||
<a class="btn btn-small pull-right" href="#/create/user/{{realm.id}}">Add User</a>
|
||||
|
||||
<h1>
|
||||
<span class="gray">{{realm.name}}</span> users
|
||||
</h1>
|
||||
<h1>
|
||||
<span class="gray">{{realm.name}}</span> users
|
||||
</h1>
|
||||
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<th>Firstname</th>
|
||||
<th>Lastname</th>
|
||||
<th>Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr data-ng-repeat="user in users">
|
||||
<td><a href="#/realms/{{realm.id}}/users/{{user.userId}}">{{user.userId}}</a></td>
|
||||
<td>{{user.firstName}}</td>
|
||||
<td>{{user.lastName}}</td>
|
||||
<td>{{user.email}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<th>Firstname</th>
|
||||
<th>Lastname</th>
|
||||
<th>Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr data-ng-repeat="user in users">
|
||||
<td><a href="#/realms/{{realm.id}}/users/{{user.userId}}">{{user.userId}}</a></td>
|
||||
<td>{{user.firstName}}</td>
|
||||
<td>{{user.lastName}}</td>
|
||||
<td>{{user.email}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div id="container-right-bg"></div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue