brute force merge

This commit is contained in:
Bill Burke 2014-04-02 20:26:33 -04:00
commit 126b444d77
166 changed files with 3640 additions and 854 deletions

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -21,8 +22,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -21,8 +22,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -129,7 +129,7 @@ module.config([ '$routeProvider', function($routeProvider) {
return RealmLoader();
}
},
controller : 'RealmSMTPSettingsCtrl'
controller : 'RealmLdapSettingsCtrl'
})
.when('/create/user/:realm', {
templateUrl : 'partials/user-detail.html',

View file

@ -885,4 +885,33 @@ module.controller('RealmSMTPSettingsCtrl', function($scope, Current, Realm, real
return obj;
}
});
module.controller('RealmLdapSettingsCtrl', function($scope, Realm, realm, $location, Notifications) {
console.log('RealmLdapSettingsCtrl');
$scope.realm = realm;
var oldCopy = angular.copy($scope.realm);
$scope.changed = false;
$scope.$watch('realm', function() {
if (!angular.equals($scope.realm, oldCopy)) {
$scope.changed = true;
}
}, true);
$scope.save = function() {
var realmCopy = angular.copy($scope.realm);
$scope.changed = false;
Realm.update(realmCopy, function () {
$location.url("/realms/" + realm.realm + "/ldap-settings");
Notifications.success("Your changes have been saved to the realm.");
});
};
$scope.reset = function() {
$scope.realm = angular.copy(oldCopy);
$scope.changed = false;
};
});

View file

@ -7,60 +7,39 @@
<li><a href="#/realms/{{realm.realm}}">Settings</a></li>
<li class="active">Ldap Configuration</li>
</ol>
<h2><span>{{realm.realm}}</span> Email Server Settings</h2>
<h2><span>{{realm.realm}}</span> Ldap Server Settings</h2>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
<span class="fieldset-notice"><span class="required">*</span> Required fields</span>
<fieldset>
<legend><span class="text">Required Settings</span></legend>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="smtpHost">Host <span class="required">*</span></label>
<label class="col-sm-2 control-label" for="ldapConnectionUrl">Connection URL <span class="required">*</span></label>
<div class="col-sm-4">
<input class="form-control" id="smtpHost" type="text" ng-model="realm.smtpServer.host" placeholder="SMTP Host" required>
<input class="form-control" id="ldapConnectionUrl" type="text" ng-model="realm.ldapServer.connectionUrl" placeholder="LDAP connection URL" required>
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="smtpPort">Port <span class="required">*</span></label>
<label class="col-sm-2 control-label" for="ldapBaseDn">Base DN <span class="required">*</span></label>
<div class="col-sm-4">
<input class="form-control" id="smtpPort" type="number" ng-model="realm.smtpServer.port" placeholder="SMTP Port (defaults to 25)" required>
<input class="form-control" id="ldapBaseDn" type="text" ng-model="realm.ldapServer.baseDn" placeholder="LDAP Base DN" required>
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="smtpFrom">From <span class="required">*</span></label>
<label class="col-sm-2 control-label" for="ldapUserDnSuffix">User DN Suffix <span class="required">*</span></label>
<div class="col-sm-4">
<input class="form-control" id="smtpFrom" type="email" ng-model="realm.smtpServer.from" placeholder="Sender Email Address" required>
<input class="form-control" id="ldapUserDnSuffix" type="text" ng-model="realm.ldapServer.userDnSuffix" placeholder="LDAP User DN Suffix" required>
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="smtpSSL">Enable SSL</label>
<label class="col-sm-2 control-label" for="ldapBindDn">Bind DN <span class="required">*</span></label>
<div class="col-sm-4">
<input ng-model="realm.smtpServer.ssl" name="smtpSSL" id="smtpSSL" onoffswitch />
<input class="form-control" id="ldapBindDn" type="text" ng-model="realm.ldapServer.bindDn" placeholder="LDAP Bind DN" required>
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="smtpStartTLS">Enable StartTLS</label>
<label class="col-sm-2 control-label" for="ldapBindCredential">Bind Credential <span class="required">*</span></label>
<div class="col-sm-4">
<input ng-model="realm.smtpServer.starttls" name="smtpStartTLS" id="smtpStartTLS" onoffswitch />
</div>
</div>
</fieldset>
<fieldset>
<legend><span class="text">Authentication</span></legend>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="smtpAuth">Enable Authentication</label>
<div class="col-sm-4">
<input ng-model="realm.smtpServer.auth" name="smtpAuth" id="smtpAuth" onoffswitch />
</div>
</div>
<div class="form-group clearfix" data-ng-show="realm.smtpServer.auth">
<label class="col-sm-2 control-label" for="smtpUsername">Username <span class="required" ng-show="realm.smtpServer.auth">*</span></label>
<div class="col-sm-4">
<input class="form-control" id="smtpUsername" type="text" ng-model="realm.smtpServer.user" placeholder="Login Username" ng-disabled="!realm.smtpServer.auth" ng-required="realm.smtpServer.auth">
</div>
</div>
<div class="form-group clearfix" data-ng-show="realm.smtpServer.auth">
<label class="col-sm-2 control-label" for="smtpPassword">Password <span class="required" ng-show="realm.smtpServer.auth">*</span></label>
<div class="col-sm-4">
<input class="form-control" id="smtpPassword" type="password" ng-model="realm.smtpServer.password" placeholder="Login Password" ng-disabled="!realm.smtpServer.auth" ng-required="realm.smtpServer.auth">
<input class="form-control" id="ldapBindCredential" type="text" ng-model="realm.ldapServer.bindCredential" placeholder="LDAP Bind Credentials" required>
</div>
</div>
</fieldset>

View file

@ -1,7 +1,7 @@
<ul data-ng-hide="createRealm">
<li data-ng-show="access.viewRealm" data-ng-class="((!path[2] || path[1] == 'role' || path[2] == 'roles' || path[2] == 'token-settings' ||
path[2] == 'social-settings' || path[2] == 'required-credentials' || path[2] == 'default-roles' || path[2] == 'registration-settings' ||
path[2] == 'keys-settings' || path[2] == 'smtp-settings') && path[3] != 'applications') && 'active'"><a href="#/realms/{{realm.realm}}">Settings</a></li>
path[2] == 'keys-settings' || path[2] == 'smtp-settings' || path[2] == 'ldap-settings') && path[3] != 'applications') && 'active'"><a href="#/realms/{{realm.realm}}">Settings</a></li>
<li data-ng-show="access.viewUsers" data-ng-class="(path[2] == 'users' || path[1] == 'user') && 'active'"><a href="#/realms/{{realm.realm}}/users">Users</a>
</li>
<li data-ng-show="access.viewApplications" data-ng-class="(path[2] == 'applications' || path[1] == 'application' || path[3] == 'applications') && 'active'"><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>

View file

@ -7,4 +7,5 @@
<li ng-class="{active: path[2] == 'token-settings'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li>
<li ng-class="{active: path[2] == 'keys-settings'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li>
<li ng-class="{active: path[2] == 'smtp-settings'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/smtp-settings">Email</a></li>
<li ng-class="{active: path[2] == 'ldap-settings'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/ldap-settings">Ldap</a></li>
</ul>

39
audit/api/pom.xml Executable file
View file

@ -0,0 +1,39 @@
<?xml version="1.0"?>
<project>
<parent>
<artifactId>keycloak-audit-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-beta-1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-audit-api</artifactId>
<name>Keycloak Audit API</name>
<description/>
<dependencies>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View file

@ -0,0 +1,145 @@
package org.keycloak.audit;
import org.jboss.logging.Logger;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.provider.ProviderFactoryLoader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class Audit {
private static final Logger log = Logger.getLogger(Audit.class);
private List<AuditListener> listeners;
private Event event;
public static Audit create(RealmModel realm, String ipAddress) {
ProviderFactoryLoader<AuditListenerFactory> loader = ProviderFactoryLoader.load(AuditListenerFactory.class);
List<AuditListener> listeners = null;
if (realm.getAuditListeners() != null) {
listeners = new LinkedList<AuditListener>();
for (String id : realm.getAuditListeners()) {
listeners.add(loader.find(id).create());
}
}
return new Audit(listeners, new Event()).realm(realm).ipAddress(ipAddress);
}
private Audit(List<AuditListener> listeners, Event event) {
this.listeners = listeners;
this.event = event;
}
public Audit realm(RealmModel realm) {
event.setRealmId(realm.getId());
return this;
}
public Audit realm(String realmId) {
event.setRealmId(realmId);
return this;
}
public Audit client(ClientModel client) {
event.setClientId(client.getClientId());
return this;
}
public Audit client(String clientId) {
event.setClientId(clientId);
return this;
}
public Audit user(UserModel user) {
event.setUserId(user.getId());
return this;
}
public Audit user(String userId) {
event.setUserId(userId);
return this;
}
public Audit ipAddress(String ipAddress) {
event.setIpAddress(ipAddress);
return this;
}
public Audit event(String e) {
event.setEvent(e);
return this;
}
public Audit detail(String key, String value) {
if (value == null || value.equals("")) {
return this;
}
if (event.getDetails() == null) {
event.setDetails(new HashMap<String, String>());
}
event.getDetails().put(key, value);
return this;
}
public Audit removeDetail(String key) {
if (event.getDetails() != null) {
event.getDetails().remove(key);
}
return this;
}
public Event getEvent() {
return event;
}
public void success() {
send();
}
public void error(String error) {
event.setError(error);
send();
}
public Audit clone() {
return new Audit(listeners, event.clone());
}
public Audit reset() {
Event old = event;
event = new Event();
event.setRealmId(old.getRealmId());
event.setIpAddress(old.getIpAddress());
event.setClientId(old.getClientId());
event.setUserId(old.getUserId());
return this;
}
private void send() {
event.setTime(System.currentTimeMillis());
if (listeners != null) {
for (AuditListener l : listeners) {
try {
l.onEvent(event);
} catch (Throwable t) {
log.error("Failed to send event to " + l, t);
}
}
}
}
}

View file

@ -0,0 +1,12 @@
package org.keycloak.audit;
import org.keycloak.provider.Provider;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public interface AuditListener extends Provider {
public void onEvent(Event event);
}

View file

@ -0,0 +1,10 @@
package org.keycloak.audit;
import org.keycloak.provider.ProviderFactory;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public interface AuditListenerFactory extends ProviderFactory<AuditListener> {
}

View file

@ -0,0 +1,14 @@
package org.keycloak.audit;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public interface AuditProvider extends AuditListener {
public EventQuery createQuery();
public void clear();
public void clear(long olderThan);
}

View file

@ -0,0 +1,10 @@
package org.keycloak.audit;
import org.keycloak.provider.ProviderFactory;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public interface AuditProviderFactory extends ProviderFactory<AuditProvider> {
}

View file

@ -0,0 +1,22 @@
package org.keycloak.audit;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public interface Details {
String EMAIL = "email";
String PREVIOUS_EMAIL = "previous_email";
String UPDATED_EMAIL = "updated_email";
String CODE_ID = "code_id";
String REDIRECT_URI = "redirect_uri";
String RESPONSE_TYPE = "response_type";
String AUTH_METHOD = "auth_method";
String REGISTER_METHOD = "register_method";
String USERNAME = "username";
String REMEMBER_ME = "remember_me";
String TOKEN_ID = "token_id";
String REFRESH_TOKEN_ID = "refresh_token_id";
String UPDATED_REFRESH_TOKEN_ID = "updated_refresh_token_id";
}

View file

@ -0,0 +1,36 @@
package org.keycloak.audit;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public interface Errors {
String REALM_DISABLED = "realm_disabled";
String CLIENT_NOT_FOUND = "client_not_found";
String CLIENT_DISABLED = "client_disabled";
String INVALID_CLIENT_CREDENTIALS = "invalid_client_credentials";
String USER_NOT_FOUND = "user_not_found";
String USER_DISABLED = "user_disabled";
String INVALID_USER_CREDENTIALS = "invalid_user_credentials";
String USERNAME_MISSING = "username_missing";
String USERNAME_IN_USE = "username_in_use";
String INVALID_REDIRECT_URI = "invalid_redirect_uri";
String INVALID_CODE = "invalid_code";
String INVALID_TOKEN = "invalid_token";
String INVALID_REGISTRATION = "invalid_registration";
String INVALID_FORM = "invalid_form";
String REGISTRATION_DISABLED = "registration_disabled";
String REJECTED_BY_USER = "rejected_by_user";
String NOT_ALLOWED = "not_allowed";
String SOCIAL_PROVIDER_NOT_FOUND = "social_provider_not_found";
String SOCIAL_ID_IN_USE = "social_id_in_use";
}

View file

@ -0,0 +1,108 @@
package org.keycloak.audit;
import java.util.HashMap;
import java.util.Map;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class Event {
private long time;
private String event;
private String realmId;
private String clientId;
private String userId;
private String ipAddress;
private String error;
private Map<String, String> details;
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
public String getEvent() {
return event;
}
public void setEvent(String event) {
this.event = event;
}
public String getRealmId() {
return realmId;
}
public void setRealmId(String realmId) {
this.realmId = realmId;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getIpAddress() {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public boolean isError() {
return error != null;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public Map<String, String> getDetails() {
return details;
}
public void setDetails(Map<String, String> details) {
this.details = details;
}
public Event clone() {
Event clone = new Event();
clone.time = time;
clone.event = event;
clone.realmId = realmId;
clone.clientId = clientId;
clone.userId = userId;
clone.ipAddress = ipAddress;
clone.error = error;
clone.details = details != null ? new HashMap<String, String>(details) : null;
return clone;
}
}

View file

@ -0,0 +1,24 @@
package org.keycloak.audit;
import java.util.List;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public interface EventQuery {
public EventQuery event(String event);
public EventQuery realm(String realmId);
public EventQuery client(String clientId);
public EventQuery user(String userId);
public EventQuery firstResult(int result);
public EventQuery maxResults(int results);
public List<Event> getResultList();
}

View file

@ -0,0 +1,29 @@
package org.keycloak.audit;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public interface Events {
String LOGIN = "login";
String REGISTER = "register";
String LOGOUT = "logout";
String CODE_TO_TOKEN = "code_to_token";
String REFRESH_TOKEN = "refresh_token";
String SOCIAL_LINK = "social_link";
String REMOVE_SOCIAL_LINK = "remove_social_link";
String UPDATE_EMAIL = "update_email";
String UPDATE_PROFILE = "update_profile";
String UPDATE_PASSWORD = "update_password";
String UPDATE_TOTP = "update_totp";
String VERIFY_EMAIL = "verify_email";
String REMOVE_TOTP = "remove_totp";
String SEND_VERIFY_EMAIL = "send_verify_email";
String SEND_RESET_PASSWORD = "send_reset_password";
}

39
audit/jboss-logging/pom.xml Executable file
View file

@ -0,0 +1,39 @@
<?xml version="1.0"?>
<project>
<parent>
<artifactId>keycloak-audit-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-beta-1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-audit-jboss-logging</artifactId>
<name>Keycloak Audit JBoss Logging Provider</name>
<description/>
<dependencies>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-audit-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View file

@ -0,0 +1,66 @@
package org.keycloak.audit.log;
import org.jboss.logging.Logger;
import org.keycloak.audit.AuditListener;
import org.keycloak.audit.Event;
import java.util.Map;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class JBossLoggingAuditListener implements AuditListener {
private final Logger logger;
public JBossLoggingAuditListener(Logger logger) {
this.logger = logger;
}
@Override
public void onEvent(Event event) {
Logger.Level level = event.isError() ? Logger.Level.WARN : Logger.Level.INFO;
if (logger.isEnabled(level)) {
StringBuilder sb = new StringBuilder();
sb.append("event=");
sb.append(event.getEvent());
sb.append(", realmId=");
sb.append(event.getRealmId());
sb.append(", clientId=");
sb.append(event.getClientId());
sb.append(", userId=");
sb.append(event.getUserId());
sb.append(", ipAddress=");
sb.append(event.getIpAddress());
if (event.isError()) {
sb.append(", error=");
sb.append(event.getError());
}
if (event.getDetails() != null) {
for (Map.Entry<String, String> e : event.getDetails().entrySet()) {
sb.append(", ");
sb.append(e.getKey());
if (e.getValue() == null || e.getValue().indexOf(' ') == -1) {
sb.append("=");
sb.append(e.getValue());
} else {
sb.append("='");
sb.append(e.getValue());
sb.append("'");
}
}
}
logger.log(level, sb.toString());
}
}
@Override
public void close() {
}
}

View file

@ -0,0 +1,34 @@
package org.keycloak.audit.log;
import org.jboss.logging.Logger;
import org.keycloak.audit.AuditListener;
import org.keycloak.audit.AuditListenerFactory;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class JBossLoggingAuditListenerFactory implements AuditListenerFactory {
public static final String ID = "jboss-logging";
private static final Logger logger = Logger.getLogger("org.keycloak.audit");
@Override
public AuditListener create() {
return new JBossLoggingAuditListener(logger);
}
@Override
public void init() {
}
@Override
public void close() {
}
@Override
public String getId() {
return ID;
}
}

View file

@ -0,0 +1 @@
org.keycloak.audit.log.JBossLoggingAuditListenerFactory

61
audit/jpa/pom.xml Executable file
View file

@ -0,0 +1,61 @@
<?xml version="1.0"?>
<project>
<parent>
<artifactId>keycloak-audit-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-beta-1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-audit-jpa</artifactId>
<name>Keycloak Audit JPA Provider</name>
<description/>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-audit-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-audit-tests</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.entitymanager.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</dependency>
</dependencies>
</project>

View file

@ -0,0 +1,103 @@
package org.keycloak.audit.jpa;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
@Entity
public class EventEntity {
@Id
private String id;
private long time;
private String event;
private String realmId;
private String clientId;
private String userId;
private String ipAddress;
private String error;
private String detailsJson;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
public String getEvent() {
return event;
}
public void setEvent(String event) {
this.event = event;
}
public String getRealmId() {
return realmId;
}
public void setRealmId(String realmId) {
this.realmId = realmId;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getIpAddress() {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public String getDetailsJson() {
return detailsJson;
}
public void setDetailsJson(String detailsJson) {
this.detailsJson = detailsJson;
}
}

View file

@ -0,0 +1,99 @@
package org.keycloak.audit.jpa;
import org.json.JSONObject;
import org.keycloak.audit.AuditProvider;
import org.keycloak.audit.Event;
import org.keycloak.audit.EventQuery;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class JpaAuditProvider implements AuditProvider {
private EntityManager em;
private EntityTransaction tx;
public JpaAuditProvider(EntityManager em) {
this.em = em;
}
@Override
public EventQuery createQuery() {
return new JpaEventQuery(em);
}
@Override
public void clear() {
beginTx();
em.createQuery("delete from EventEntity").executeUpdate();
}
@Override
public void clear(long olderThan) {
beginTx();
em.createQuery("delete from EventEntity where time < :time").setParameter("time", olderThan).executeUpdate();
}
@Override
public void onEvent(Event event) {
beginTx();
em.persist(convert(event));
}
@Override
public void close() {
if (tx != null) {
tx.commit();
}
em.close();
}
private void beginTx() {
if (tx == null) {
tx = em.getTransaction();
tx.begin();
}
}
static EventEntity convert(Event o) {
EventEntity e = new EventEntity();
e.setId(UUID.randomUUID().toString());
e.setTime(o.getTime());
e.setEvent(o.getEvent());
e.setRealmId(o.getRealmId());
e.setClientId(o.getClientId());
e.setUserId(o.getUserId());
e.setIpAddress(o.getIpAddress());
e.setError(o.getError());
e.setDetailsJson(new JSONObject(o.getDetails()).toString());
return e;
}
static Event convert(EventEntity o) {
Event e = new Event();
e.setTime(o.getTime());
e.setEvent(o.getEvent());
e.setRealmId(o.getRealmId());
e.setClientId(o.getClientId());
e.setUserId(o.getUserId());
e.setIpAddress(o.getIpAddress());
e.setError(o.getError());
JSONObject object = new JSONObject(o.getDetailsJson());
Map<String, String> details = new HashMap<String, String>();
for (Object k : object.keySet()) {
details.put((String) k, object.getString((String) k));
}
e.setDetails(details);
return e;
}
}

View file

@ -0,0 +1,37 @@
package org.keycloak.audit.jpa;
import org.keycloak.audit.AuditProvider;
import org.keycloak.audit.AuditProviderFactory;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class JpaAuditProviderFactory implements AuditProviderFactory {
public static final String ID = "jpa";
private EntityManagerFactory emf;
@Override
public AuditProvider create() {
return new JpaAuditProvider(emf.createEntityManager());
}
@Override
public void init() {
emf = Persistence.createEntityManagerFactory("jpa-keycloak-audit-store");
}
@Override
public void close() {
emf.close();
}
@Override
public String getId() {
return ID;
}
}

View file

@ -0,0 +1,100 @@
package org.keycloak.audit.jpa;
import org.keycloak.audit.Event;
import org.keycloak.audit.EventQuery;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class JpaEventQuery implements EventQuery {
private final EntityManager em;
private final CriteriaBuilder cb;
private final CriteriaQuery<EventEntity> cq;
private final Root<EventEntity> root;
private final ArrayList<Predicate> predicates;
private Integer firstResult;
private Integer maxResults;
public JpaEventQuery(EntityManager em) {
this.em = em;
cb = em.getCriteriaBuilder();
cq = cb.createQuery(EventEntity.class);
root = cq.from(EventEntity.class);
predicates = new ArrayList<Predicate>(4);
}
@Override
public EventQuery event(String event) {
predicates.add(cb.equal(root.get("event"), event));
return this;
}
@Override
public EventQuery realm(String realmId) {
predicates.add(cb.equal(root.get("realmId"), realmId));
return this;
}
@Override
public EventQuery client(String clientId) {
predicates.add(cb.equal(root.get("clientId"), clientId));
return this;
}
@Override
public EventQuery user(String userId) {
predicates.add(cb.equal(root.get("userId"), userId));
return this;
}
@Override
public EventQuery firstResult(int firstResult) {
this.firstResult = firstResult;
return this;
}
@Override
public EventQuery maxResults(int maxResults) {
this.maxResults = maxResults;
return this;
}
@Override
public List<Event> getResultList() {
if (!predicates.isEmpty()) {
cq.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
}
cq.orderBy(cb.asc(root.get("time")), cb.asc(root.get("id")));
TypedQuery<EventEntity> query = em.createQuery(cq);
if (firstResult != null) {
query.setFirstResult(firstResult);
}
if (maxResults != null) {
query.setMaxResults(maxResults);
}
List<Event> events = new LinkedList<Event>();
for (EventEntity e : query.getResultList()) {
events.add(JpaAuditProvider.convert(e));
}
return events;
}
}

View file

@ -0,0 +1 @@
org.keycloak.audit.jpa.JpaAuditProviderFactory

View file

@ -0,0 +1,15 @@
package org.keycloak.audit.jpa;
import org.keycloak.audit.tests.AbstractAuditProviderTest;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class JpaAuditProviderTest extends AbstractAuditProviderTest {
@Override
protected String getProviderId() {
return JpaAuditProviderFactory.ID;
}
}

View file

@ -0,0 +1,22 @@
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="jpa-keycloak-audit-store" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.keycloak.audit.jpa.EventEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.connection.url" value="jdbc:h2:mem:test"/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
</persistence>

129
audit/mongo/pom.xml Executable file
View file

@ -0,0 +1,129 @@
<?xml version="1.0"?>
<project>
<parent>
<artifactId>keycloak-audit-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-beta-1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-audit-mongo</artifactId>
<name>Keycloak Audit Mongo Provider</name>
<description/>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-audit-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-audit-tests</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</dependency>
</dependencies>
<properties>
<keycloak.audit.mongo.host>localhost</keycloak.audit.mongo.host>
<keycloak.audit.mongo.port>27018</keycloak.audit.mongo.port>
<keycloak.audit.mongo.db>keycloak</keycloak.audit.mongo.db>
<keycloak.audit.mongo.clearOnStartup>true</keycloak.audit.mongo.clearOnStartup>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<!-- Postpone tests to "integration-test" phase, so that we can bootstrap embedded mongo on 27018 before running tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>test</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<systemPropertyVariables>
<keycloak.audit.mongo.host>${keycloak.audit.mongo.host}</keycloak.audit.mongo.host>
<keycloak.audit.mongo.port>${keycloak.audit.mongo.port}</keycloak.audit.mongo.port>
<keycloak.audit.mongo.db>${keycloak.audit.mongo.db}</keycloak.audit.mongo.db>
<keycloak.audit.mongo.clearOnStartup>${keycloak.audit.mongo.clearOnStartup}</keycloak.audit.mongo.clearOnStartup>
</systemPropertyVariables>
<dependenciesToScan>
<dependency>org.keycloak:keycloak-model-tests</dependency>
</dependenciesToScan>
</configuration>
</execution>
<execution>
<id>default-test</id>
<configuration>
<skip>true</skip>
</configuration>
</execution>
</executions>
</plugin>
<!-- Embedded mongo -->
<plugin>
<groupId>com.github.joelittlejohn.embedmongo</groupId>
<artifactId>embedmongo-maven-plugin</artifactId>
<executions>
<execution>
<id>start-mongodb</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
<configuration>
<port>${keycloak.audit.mongo.port}</port>
<logging>file</logging>
<logFile>${project.build.directory}/mongodb.log</logFile>
</configuration>
</execution>
<execution>
<id>stop-mongodb</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,87 @@
package org.keycloak.audit.mongo;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import org.keycloak.audit.AuditProvider;
import org.keycloak.audit.Event;
import org.keycloak.audit.EventQuery;
import java.util.HashMap;
import java.util.Map;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class MongoAuditProvider implements AuditProvider {
private DBCollection audit;
public MongoAuditProvider(DBCollection audit) {
this.audit = audit;
}
@Override
public EventQuery createQuery() {
return new MongoEventQuery(audit);
}
@Override
public void clear() {
audit.remove(new BasicDBObject());
}
@Override
public void clear(long olderThan) {
audit.remove(new BasicDBObject("time", new BasicDBObject("$lt", olderThan)));
}
@Override
public void onEvent(Event event) {
audit.insert(convert(event));
}
@Override
public void close() {
}
static DBObject convert(Event o) {
BasicDBObject e = new BasicDBObject();
e.put("time", o.getTime());
e.put("event", o.getEvent());
e.put("realmId", o.getRealmId());
e.put("clientId", o.getClientId());
e.put("userId", o.getUserId());
e.put("ipAddress", o.getIpAddress());
e.put("error", o.getError());
BasicDBObject details = new BasicDBObject();
for (Map.Entry<String, String> entry : o.getDetails().entrySet()) {
details.put(entry.getKey(), entry.getValue());
}
e.put("details", details);
return e;
}
static Event convert(BasicDBObject o) {
Event e = new Event();
e.setTime(o.getLong("time"));
e.setEvent(o.getString("event"));
e.setRealmId(o.getString("realmId"));
e.setClientId(o.getString("clientId"));
e.setUserId(o.getString("userId"));
e.setIpAddress(o.getString("ipAddress"));
e.setError(o.getString("error"));
BasicDBObject d = (BasicDBObject) o.get("details");
Map<String, String> details = new HashMap<String, String>();
for (Object k : d.keySet()) {
details.put((String) k, d.getString((String) k));
}
e.setDetails(details);
return e;
}
}

View file

@ -0,0 +1,50 @@
package org.keycloak.audit.mongo;
import com.mongodb.DB;
import com.mongodb.MongoClient;
import com.mongodb.WriteConcern;
import org.keycloak.audit.AuditProvider;
import org.keycloak.audit.AuditProviderFactory;
import java.net.UnknownHostException;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class MongoAuditProviderFactory implements AuditProviderFactory {
private static final String MONGO_HOST = "keycloak.audit.mongo.host";
private static final String MONGO_PORT = "keycloak.audit.mongo.port";
private static final String MONGO_DB_NAME = "keycloak.audit.mongo.db";
public static final String ID = "mongo";
private MongoClient client;
private DB db;
@Override
public AuditProvider create() {
return new MongoAuditProvider(db.getCollection("audit"));
}
@Override
public void init() {
try {
client = new MongoClient(System.getProperty(MONGO_HOST, "localhost"), Integer.parseInt(System.getProperty(MONGO_PORT, "27017")));
client.setWriteConcern(WriteConcern.UNACKNOWLEDGED);
db = client.getDB(System.getProperty(MONGO_DB_NAME, "keycloak-audit"));
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
@Override
public void close() {
client.close();
}
@Override
public String getId() {
return ID;
}
}

View file

@ -0,0 +1,81 @@
package org.keycloak.audit.mongo;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import org.keycloak.audit.Event;
import org.keycloak.audit.EventQuery;
import java.util.LinkedList;
import java.util.List;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class MongoEventQuery implements EventQuery {
private Integer firstResult;
private Integer maxResults;
private DBCollection audit;
private final BasicDBObject query;
public MongoEventQuery(DBCollection audit) {
this.audit = audit;
query = new BasicDBObject();
}
@Override
public EventQuery event(String event) {
query.put("event", event);
return this;
}
@Override
public EventQuery realm(String realmId) {
query.put("realmId", realmId);
return this;
}
@Override
public EventQuery client(String clientId) {
query.put("clientId", clientId);
return this;
}
@Override
public EventQuery user(String userId) {
query.put("userId", userId);
return this;
}
@Override
public EventQuery firstResult(int firstResult) {
this.firstResult = firstResult;
return this;
}
@Override
public EventQuery maxResults(int maxResults) {
this.maxResults = maxResults;
return this;
}
@Override
public List<Event> getResultList() {
DBCursor cur = audit.find(query);
if (firstResult != null) {
cur.skip(firstResult);
}
if (maxResults != null) {
cur.limit(maxResults);
}
List<Event> events = new LinkedList<Event>();
while (cur.hasNext()) {
events.add(MongoAuditProvider.convert((BasicDBObject) cur.next()));
}
return events;
}
}

View file

@ -0,0 +1 @@
org.keycloak.audit.mongo.MongoAuditProviderFactory

View file

@ -0,0 +1,15 @@
package org.keycloak.audit.mongo;
import org.keycloak.audit.tests.AbstractAuditProviderTest;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class MongoAuditProviderTest extends AbstractAuditProviderTest {
@Override
protected String getProviderId() {
return MongoAuditProviderFactory.ID;
}
}

25
audit/pom.xml Executable file
View file

@ -0,0 +1,25 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-beta-1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<name>Audit Parent</name>
<description/>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-audit-parent</artifactId>
<packaging>pom</packaging>
<modules>
<module>api</module>
<module>jpa</module>
<module>jboss-logging</module>
<module>mongo</module>
<module>tests</module>
</modules>
</project>

35
audit/tests/pom.xml Executable file
View file

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>keycloak-audit-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>1.0-beta-1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-audit-tests</artifactId>
<name>Keycloak Audit Tests</name>
<description/>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-audit-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View file

@ -0,0 +1,121 @@
package org.keycloak.audit.tests;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.audit.AuditProvider;
import org.keycloak.audit.AuditProviderFactory;
import org.keycloak.audit.Event;
import org.keycloak.provider.ProviderFactoryLoader;
import java.util.HashMap;
import java.util.Map;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public abstract class AbstractAuditProviderTest {
private AuditProviderFactory factory;
private AuditProvider provider;
@Before
public void before() {
ProviderFactoryLoader<AuditProviderFactory> loader = ProviderFactoryLoader.load(AuditProviderFactory.class);
factory = loader.find(getProviderId());
factory.init();
provider = factory.create();
}
protected abstract String getProviderId();
@After
public void after() {
provider.clear();
provider.close();
factory.close();
}
@Test
public void save() {
provider.onEvent(create("event", "realmId", "clientId", "userId", "127.0.0.1", "error"));
}
@Test
public void query() {
provider.onEvent(create("event", "realmId", "clientId", "userId", "127.0.0.1", "error"));
provider.onEvent(create("event2", "realmId", "clientId", "userId", "127.0.0.1", "error"));
provider.onEvent(create("event", "realmId2", "clientId", "userId", "127.0.0.1", "error"));
provider.onEvent(create("event", "realmId", "clientId2", "userId", "127.0.0.1", "error"));
provider.onEvent(create("event", "realmId", "clientId", "userId2", "127.0.0.1", "error"));
provider.close();
provider = factory.create();
Assert.assertEquals(4, provider.createQuery().client("clientId").getResultList().size());
Assert.assertEquals(4, provider.createQuery().realm("realmId").getResultList().size());
Assert.assertEquals(4, provider.createQuery().event("event").getResultList().size());
Assert.assertEquals(4, provider.createQuery().user("userId").getResultList().size());
Assert.assertEquals(1, provider.createQuery().user("userId").event("event2").getResultList().size());
Assert.assertEquals(2, provider.createQuery().maxResults(2).getResultList().size());
Assert.assertEquals(1, provider.createQuery().firstResult(4).getResultList().size());
}
@Test
public void clear() {
provider.onEvent(create(System.currentTimeMillis() - 30000, "event", "realmId", "clientId", "userId", "127.0.0.1", "error"));
provider.onEvent(create(System.currentTimeMillis() - 20000, "event", "realmId", "clientId", "userId", "127.0.0.1", "error"));
provider.onEvent(create(System.currentTimeMillis(), "event", "realmId", "clientId", "userId", "127.0.0.1", "error"));
provider.onEvent(create(System.currentTimeMillis(), "event", "realmId", "clientId", "userId", "127.0.0.1", "error"));
provider.close();
provider = factory.create();
provider.clear();
Assert.assertEquals(0, provider.createQuery().getResultList().size());
}
@Test
public void clearOld() {
provider.onEvent(create(System.currentTimeMillis() - 30000, "event", "realmId", "clientId", "userId", "127.0.0.1", "error"));
provider.onEvent(create(System.currentTimeMillis() - 20000, "event", "realmId", "clientId", "userId", "127.0.0.1", "error"));
provider.onEvent(create(System.currentTimeMillis(), "event", "realmId", "clientId", "userId", "127.0.0.1", "error"));
provider.onEvent(create(System.currentTimeMillis(), "event", "realmId", "clientId", "userId", "127.0.0.1", "error"));
provider.close();
provider = factory.create();
provider.clear(System.currentTimeMillis() - 10000);
Assert.assertEquals(2, provider.createQuery().getResultList().size());
}
private Event create(String event, String realmId, String clientId, String userId, String ipAddress, String error) {
return create(System.currentTimeMillis(), event, realmId, clientId, userId, ipAddress, error);
}
private Event create(long time, String event, String realmId, String clientId, String userId, String ipAddress, String error) {
Event e = new Event();
e.setTime(time);
e.setEvent(event);
e.setRealmId(realmId);
e.setClientId(clientId);
e.setUserId(userId);
e.setIpAddress(ipAddress);
e.setError(error);
Map<String, String> details = new HashMap<String, String>();
details.put("key1", "value1");
details.put("key2", "value2");
e.setDetails(details);
return e;
}
}

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -61,8 +62,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -45,8 +46,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -0,0 +1,10 @@
package org.keycloak.provider;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public interface Provider {
public void close();
}

View file

@ -0,0 +1,16 @@
package org.keycloak.provider;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public interface ProviderFactory<T extends Provider> {
public T create();
public void init();
public void close();
public String getId();
}

View file

@ -0,0 +1,88 @@
package org.keycloak.provider;
import java.util.Iterator;
import java.util.ServiceLoader;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class ProviderFactoryLoader<P extends ProviderFactory> implements Iterable<P> {
private ServiceLoader<P> serviceLoader;
private ProviderFactoryLoader(ServiceLoader<P> serviceLoader) {
this.serviceLoader = serviceLoader;
}
public static <P extends ProviderFactory> ProviderFactoryLoader<P> load(Class<P> service) {
return new ProviderFactoryLoader(ServiceLoader.load(service));
}
public static <P extends ProviderFactory> ProviderFactoryLoader<P> load(Class<P> service, ClassLoader loader) {
return new ProviderFactoryLoader(ServiceLoader.load(service, loader));
}
public P find(String id) {
Iterator<P> itr = iterator();
while (itr.hasNext()) {
P p = itr.next();
if (p.getId() != null && p.getId().equals(id)) {
return p;
}
}
return null;
}
@Override
public Iterator<P> iterator() {
return new ProviderFactoryIterator(serviceLoader.iterator());
}
public void close() {
}
private static class ProviderFactoryIterator<P> implements Iterator<P> {
private Iterator<P> itr;
private P next;
private ProviderFactoryIterator(Iterator<P> itr) {
this.itr = itr;
setNext();
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public P next() {
P n = next;
setNext();
return n;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
private void setNext() {
next = null;
while (itr.hasNext()) {
if (itr.hasNext()) {
P n = itr.next();
if (!System.getProperties().containsKey(n.getClass().getName() + ".disabled")) {
next = n;
return;
}
}
}
}
}
}

View file

@ -1,39 +0,0 @@
package org.keycloak.representations.idm;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AuthenticationMappingRepresentation {
protected String self; // link
protected String username;
protected List<AuthenticationLinkRepresentation> authenticationLinks;
public String getSelf() {
return self;
}
public void setSelf(String self) {
this.self = self;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List<AuthenticationLinkRepresentation> getAuthenticationLinks() {
return authenticationLinks;
}
public void setAuthenticationLinks(List<AuthenticationLinkRepresentation> authenticationLinks) {
this.authenticationLinks = authenticationLinks;
}
}

View file

@ -39,7 +39,6 @@ public class RealmRepresentation {
protected Map<String, List<UserRoleMappingRepresentation>> applicationRoleMappings;
protected Map<String, List<ScopeMappingRepresentation>> applicationScopeMappings;
protected List<SocialMappingRepresentation> socialMappings;
protected List<AuthenticationMappingRepresentation> authenticationMappings;
protected List<ApplicationRepresentation> applications;
protected List<OAuthClientRepresentation> oauthClients;
protected Map<String, String> socialProviders;
@ -181,18 +180,6 @@ public class RealmRepresentation {
return mapping;
}
public List<AuthenticationMappingRepresentation> getAuthenticationMappings() {
return authenticationMappings;
}
public AuthenticationMappingRepresentation authenticationMapping(String username) {
AuthenticationMappingRepresentation mapping = new AuthenticationMappingRepresentation();
mapping.setUsername(username);
if (authenticationMappings == null) authenticationMappings = new ArrayList<AuthenticationMappingRepresentation>();
authenticationMappings.add(mapping);
return mapping;
}
public Set<String> getRequiredCredentials() {
return requiredCredentials;
}

View file

@ -20,6 +20,7 @@ public class UserRepresentation {
protected String firstName;
protected String lastName;
protected String email;
protected AuthenticationLinkRepresentation authenticationLink;
protected Map<String, String> attributes;
protected List<CredentialRepresentation> credentials;
protected List<String> requiredActions;
@ -96,6 +97,14 @@ public class UserRepresentation {
this.emailVerified = emailVerified;
}
public AuthenticationLinkRepresentation getAuthenticationLink() {
return authenticationLink;
}
public void setAuthenticationLink(AuthenticationLinkRepresentation authenticationLink) {
this.authenticationLink = authenticationLink;
}
public Map<String, String> getAttributes() {
return attributes;
}

View file

@ -620,8 +620,6 @@ public class KeycloakUriBuilder {
}
// don't set values if values is null
if (values == null) return this;
// don't set values if values is null
if (values == null) return this;
return queryParam(name, values);
}

View file

@ -1,4 +1,5 @@
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>keycloak-parent</artifactId>

View file

@ -1,4 +1,5 @@
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>keycloak-parent</artifactId>

View file

@ -1,4 +1,5 @@
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>keycloak-parent</artifactId>

View file

@ -1,4 +1,5 @@
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>keycloak-parent</artifactId>

View file

@ -10,7 +10,6 @@
<description/>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak</groupId>
<artifactId>distribution-pom</artifactId>
<packaging>pom</packaging>

View file

@ -1,4 +1,5 @@
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>keycloak-parent</artifactId>

View file

@ -1,4 +1,5 @@
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>keycloak-parent</artifactId>

View file

@ -1,4 +1,5 @@
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>keycloak-parent</artifactId>

View file

@ -1,4 +1,5 @@
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>keycloak-parent</artifactId>

View file

@ -1,4 +1,5 @@
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>keycloak-parent</artifactId>

View file

@ -43,8 +43,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>

View file

@ -33,8 +33,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -67,8 +67,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -78,8 +78,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -10,7 +10,6 @@
<description/>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak</groupId>
<artifactId>demo-pom</artifactId>
<packaging>pom</packaging>

View file

@ -72,8 +72,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -83,8 +83,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -65,8 +65,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -33,8 +33,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -10,7 +10,6 @@
<description/>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak</groupId>
<artifactId>examples-pom</artifactId>
<packaging>pom</packaging>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-forms</artifactId>
<groupId>org.keycloak</groupId>
@ -39,8 +40,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-forms</artifactId>
<groupId>org.keycloak</groupId>
@ -60,8 +61,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-forms</artifactId>
<groupId>org.keycloak</groupId>
@ -44,8 +45,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-forms</artifactId>
<groupId>org.keycloak</groupId>
@ -44,8 +45,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-forms</artifactId>
<groupId>org.keycloak</groupId>
@ -39,8 +40,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-forms</artifactId>
<groupId>org.keycloak</groupId>
@ -65,8 +66,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -58,8 +59,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -24,22 +24,18 @@
<relativePath>../../pom.xml</relativePath>
</parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-as7-subsystem</artifactId>
<version>1.0-beta-1-SNAPSHOT</version>
<name>Keycloak Wildfly Subsystem</name>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -88,8 +89,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -52,8 +53,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -61,8 +62,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -73,8 +74,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -21,8 +22,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -10,7 +10,6 @@
<description/>
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak</groupId>
<artifactId>integration-pom</artifactId>
<packaging>pom</packaging>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -58,8 +59,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -82,8 +83,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -98,8 +99,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -24,22 +24,18 @@
<relativePath>../../pom.xml</relativePath>
</parent>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-wildfly-subsystem</artifactId>
<version>1.0-beta-1-SNAPSHOT</version>
<name>Keycloak Wildfly Subsystem</name>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -40,8 +41,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>

View file

@ -1,5 +1,6 @@
package org.keycloak.models;
import java.util.Collections;
import java.util.Map;
/**
@ -7,6 +8,8 @@ import java.util.Map;
*/
public class AuthenticationProviderModel {
public static final AuthenticationProviderModel DEFAULT_PROVIDER = new AuthenticationProviderModel("model", true, Collections.EMPTY_MAP);
private String providerName;
private boolean passwordUpdateSupported = true;
private Map<String, String> config;

View file

@ -138,11 +138,9 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
boolean removeSocialLink(UserModel user, String socialProvider);
UserModel getUserByAuthenticationLink(AuthenticationLinkModel authenticationLink);
AuthenticationLinkModel getAuthenticationLink(UserModel user);
Set<AuthenticationLinkModel> getAuthenticationLinks(UserModel user);
void addAuthenticationLink(UserModel user, AuthenticationLinkModel authenticationLink);
void setAuthenticationLink(UserModel user, AuthenticationLinkModel authenticationLink);
boolean isSocial();
@ -209,4 +207,8 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
void setNotBefore(int notBefore);
boolean removeRoleById(String id);
Set<String> getAuditListeners();
void setAuditListeners(Set<String> listeners);
}

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
@ -86,8 +87,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>

View file

@ -40,6 +40,8 @@ import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@ -429,7 +431,9 @@ public class RealmAdapter implements RealmModel {
private void removeUser(UserEntity user) {
em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate();
em.createQuery("delete from " + SocialLinkEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate();
em.createQuery("delete from " + AuthenticationLinkEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate();
if (user.getAuthenticationLink() != null) {
em.remove(user.getAuthenticationLink());
}
em.remove(user);
}
@ -648,43 +652,22 @@ public class RealmAdapter implements RealmModel {
}
@Override
public UserModel getUserByAuthenticationLink(AuthenticationLinkModel authenticationLink) {
TypedQuery<UserEntity> query = em.createNamedQuery("findUserByAuthLinkAndRealm", UserEntity.class);
query.setParameter("realm", realm);
query.setParameter("authProvider", authenticationLink.getAuthProvider());
query.setParameter("authUserId", authenticationLink.getAuthUserId());
List<UserEntity> results = query.getResultList();
if (results.isEmpty()) {
return null;
} else if (results.size() > 1) {
throw new IllegalStateException("More results found for authenticationProvider=" + authenticationLink.getAuthProvider() +
", authUserId=" + authenticationLink.getAuthUserId() + ", results=" + results);
} else {
UserEntity user = results.get(0);
return new UserAdapter(user);
}
public AuthenticationLinkModel getAuthenticationLink(UserModel user) {
UserEntity userEntity = ((UserAdapter) user).getUser();
AuthenticationLinkEntity authLinkEntity = userEntity.getAuthenticationLink();
return authLinkEntity == null ? null : new AuthenticationLinkModel(authLinkEntity.getAuthProvider(), authLinkEntity.getAuthUserId());
}
@Override
public Set<AuthenticationLinkModel> getAuthenticationLinks(UserModel user) {
TypedQuery<AuthenticationLinkEntity> query = em.createNamedQuery("findAuthLinkByUser", AuthenticationLinkEntity.class);
query.setParameter("user", ((UserAdapter) user).getUser());
List<AuthenticationLinkEntity> results = query.getResultList();
Set<AuthenticationLinkModel> set = new HashSet<AuthenticationLinkModel>();
for (AuthenticationLinkEntity entity : results) {
set.add(new AuthenticationLinkModel(entity.getAuthProvider(), entity.getAuthUserId()));
}
return set;
}
@Override
public void addAuthenticationLink(UserModel user, AuthenticationLinkModel authenticationLink) {
public void setAuthenticationLink(UserModel user, AuthenticationLinkModel authenticationLink) {
AuthenticationLinkEntity entity = new AuthenticationLinkEntity();
entity.setRealm(realm);
entity.setAuthProvider(authenticationLink.getAuthProvider());
entity.setAuthUserId(authenticationLink.getAuthUserId());
entity.setUser(((UserAdapter) user).getUser());
UserEntity userEntity = ((UserAdapter) user).getUser();
userEntity.setAuthenticationLink(entity);
em.persist(entity);
em.persist(userEntity);
em.flush();
}
@ -850,7 +833,15 @@ public class RealmAdapter implements RealmModel {
@Override
public List<AuthenticationProviderModel> getAuthenticationProviders() {
Collection<AuthenticationProviderEntity> entities = realm.getAuthenticationProviders();
List<AuthenticationProviderEntity> entities = realm.getAuthenticationProviders();
Collections.sort(entities, new Comparator<AuthenticationProviderEntity>() {
@Override
public int compare(AuthenticationProviderEntity o1, AuthenticationProviderEntity o2) {
return o1.getPriority() - o2.getPriority();
}
});
List<AuthenticationProviderModel> result = new ArrayList<AuthenticationProviderModel>();
for (AuthenticationProviderEntity entity : entities) {
result.add(new AuthenticationProviderModel(entity.getProviderName(), entity.isPasswordUpdateSupported(), entity.getConfig()));
@ -862,11 +853,13 @@ public class RealmAdapter implements RealmModel {
@Override
public void setAuthenticationProviders(List<AuthenticationProviderModel> authenticationProviders) {
List<AuthenticationProviderEntity> newEntities = new ArrayList<AuthenticationProviderEntity>();
int counter = 1;
for (AuthenticationProviderModel model : authenticationProviders) {
AuthenticationProviderEntity entity = new AuthenticationProviderEntity();
entity.setProviderName(model.getProviderName());
entity.setPasswordUpdateSupported(model.isPasswordUpdateSupported());
entity.setConfig(model.getConfig());
entity.setPriority(counter++);
newEntities.add(entity);
}
@ -1190,4 +1183,15 @@ public class RealmAdapter implements RealmModel {
realm.setAccountTheme(name);
em.flush();
}
@Override
public Set<String> getAuditListeners() {
return realm.getAuditListeners();
}
@Override
public void setAuditListeners(Set<String> listeners) {
realm.setAuditListeners(listeners);
em.flush();
}
}

View file

@ -6,16 +6,13 @@ import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import org.hibernate.annotations.GenericGenerator;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@NamedQueries({
@NamedQuery(name="findAuthLinkByUser", query="select link from AuthenticationLinkEntity link where link.user = :user"),
@NamedQuery(name="findUserByAuthLinkAndRealm", query="select link.user from AuthenticationLinkEntity link where link.realm = :realm and link.authProvider = :authProvider and link.authUserId = :authUserId")
})
@Entity
public class AuthenticationLinkEntity {
@ -24,12 +21,6 @@ public class AuthenticationLinkEntity {
@GeneratedValue(generator = "keycloak_generator")
private String id;
@ManyToOne
private UserEntity user;
@ManyToOne
protected RealmEntity realm;
protected String authProvider;
protected String authUserId;
@ -41,22 +32,6 @@ public class AuthenticationLinkEntity {
this.id = id;
}
public UserEntity getUser() {
return user;
}
public void setUser(UserEntity user) {
this.user = user;
}
public RealmEntity getRealm() {
return realm;
}
public void setRealm(RealmEntity realm) {
this.realm = realm;
}
public String getAuthProvider() {
return authProvider;
}

View file

@ -25,6 +25,7 @@ public class AuthenticationProviderEntity {
private String providerName;
private boolean passwordUpdateSupported;
private int priority;
@ElementCollection
@MapKeyColumn(name="name")
@ -56,6 +57,14 @@ public class AuthenticationProviderEntity {
this.passwordUpdateSupported = passwordUpdateSupported;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public Map<String, String> getConfig() {
return config;
}

View file

@ -16,7 +16,10 @@ import javax.persistence.OneToMany;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -66,7 +69,7 @@ public class RealmEntity {
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true)
@JoinTable(name="AuthProviders")
Collection<AuthenticationProviderEntity> authenticationProviders = new ArrayList<AuthenticationProviderEntity>();
List<AuthenticationProviderEntity> authenticationProviders = new ArrayList<AuthenticationProviderEntity>();
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
Collection<ApplicationEntity> applications = new ArrayList<ApplicationEntity>();
@ -96,6 +99,9 @@ public class RealmEntity {
@JoinTable(name="RealmDefaultRoles")
Collection<RoleEntity> defaultRoles = new ArrayList<RoleEntity>();
@ElementCollection
protected Set<String> auditListeners= new HashSet<String>();
public String getId() {
return id;
}
@ -240,11 +246,11 @@ public class RealmEntity {
this.requiredCredentials = requiredCredentials;
}
public Collection<AuthenticationProviderEntity> getAuthenticationProviders() {
public List<AuthenticationProviderEntity> getAuthenticationProviders() {
return authenticationProviders;
}
public void setAuthenticationProviders(Collection<AuthenticationProviderEntity> authenticationProviders) {
public void setAuthenticationProviders(List<AuthenticationProviderEntity> authenticationProviders) {
this.authenticationProviders = authenticationProviders;
}
@ -342,5 +348,13 @@ public class RealmEntity {
public void setBruteForceProtected(boolean bruteForceProtected) {
this.bruteForceProtected = bruteForceProtected;
}
public Set<String> getAuditListeners() {
return auditListeners;
}
public void setAuditListeners(Set<String> auditListeners) {
this.auditListeners = auditListeners;
}
}

View file

@ -15,6 +15,8 @@ import javax.persistence.MapKeyColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@ -65,6 +67,9 @@ public class UserEntity {
@OneToMany(cascade = CascadeType.REMOVE, orphanRemoval = true)
protected Collection<CredentialEntity> credentials = new ArrayList<CredentialEntity>();
@OneToOne(cascade = CascadeType.REMOVE, orphanRemoval = true)
protected AuthenticationLinkEntity authenticationLink;
public String getId() {
return id;
}
@ -161,6 +166,14 @@ public class UserEntity {
this.credentials = credentials;
}
public AuthenticationLinkEntity getAuthenticationLink() {
return authenticationLink;
}
public void setAuthenticationLink(AuthenticationLinkEntity authenticationLink) {
this.authenticationLink = authenticationLink;
}
public int getNotBefore() {
return notBefore;
}

View file

@ -75,8 +75,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>

View file

@ -39,6 +39,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -968,41 +969,26 @@ public class RealmAdapter extends AbstractMongoAdapter<RealmEntity> implements R
}
@Override
public UserModel getUserByAuthenticationLink(AuthenticationLinkModel authenticationLink) {
DBObject query = new QueryBuilder()
.and("authenticationLinks.authProvider").is(authenticationLink.getAuthProvider())
.and("authenticationLinks.authUserId").is(authenticationLink.getAuthUserId())
.and("realmId").is(getId())
.get();
UserEntity userEntity = getMongoStore().loadSingleEntity(UserEntity.class, query, invocationContext);
return userEntity==null ? null : new UserAdapter(userEntity, invocationContext);
}
@Override
public Set<AuthenticationLinkModel> getAuthenticationLinks(UserModel user) {
public AuthenticationLinkModel getAuthenticationLink(UserModel user) {
UserEntity userEntity = ((UserAdapter)user).getUser();
List<AuthenticationLinkEntity> linkEntities = userEntity.getAuthenticationLinks();
AuthenticationLinkEntity authLinkEntity = userEntity.getAuthenticationLink();
if (linkEntities == null) {
return Collections.EMPTY_SET;
if (authLinkEntity == null) {
return null;
} else {
return new AuthenticationLinkModel(authLinkEntity.getAuthProvider(), authLinkEntity.getAuthUserId());
}
Set<AuthenticationLinkModel> result = new HashSet<AuthenticationLinkModel>();
for (AuthenticationLinkEntity authLinkEntity : linkEntities) {
AuthenticationLinkModel model = new AuthenticationLinkModel(authLinkEntity.getAuthProvider(), authLinkEntity.getAuthUserId());
result.add(model);
}
return result;
}
@Override
public void addAuthenticationLink(UserModel user, AuthenticationLinkModel authenticationLink) {
public void setAuthenticationLink(UserModel user, AuthenticationLinkModel authenticationLink) {
UserEntity userEntity = ((UserAdapter)user).getUser();
AuthenticationLinkEntity authLinkEntity = new AuthenticationLinkEntity();
authLinkEntity.setAuthProvider(authenticationLink.getAuthProvider());
authLinkEntity.setAuthUserId(authenticationLink.getAuthUserId());
userEntity.setAuthenticationLink(authLinkEntity);
getMongoStore().pushItemToList(userEntity, "authenticationLinks", authLinkEntity, true, invocationContext);
getMongoStore().updateEntity(userEntity, invocationContext);
}
protected void updateRealm() {
@ -1155,6 +1141,20 @@ public class RealmAdapter extends AbstractMongoAdapter<RealmEntity> implements R
updateRealm();
}
@Override
public Set<String> getAuditListeners() {
return realm.getAuditListeners() != null ? new HashSet<String>(realm.getAuditListeners()) : null;
}
@Override
public void setAuditListeners(Set<String> listeners) {
if (listeners != null) {
realm.setAuditListeners(new LinkedList<String>(listeners));
} else {
realm.setAuditListeners(null);
}
}
@Override
public RealmEntity getMongoEntity() {
return realm;

View file

@ -10,8 +10,11 @@ import org.keycloak.models.mongo.api.context.MongoStoreInvocationContext;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -54,6 +57,8 @@ public class RealmEntity extends AbstractMongoIdentifiableEntity implements Mong
private Map<String, String> socialConfig = new HashMap<String, String>();
private Map<String, String> ldapServerConfig;
private List<String> auditListeners = new LinkedList<String>();
@MongoField
public String getName() {
return name;
@ -297,6 +302,15 @@ public class RealmEntity extends AbstractMongoIdentifiableEntity implements Mong
this.ldapServerConfig = ldapServerConfig;
}
@MongoField
public List<String> getAuditListeners() {
return auditListeners;
}
public void setAuditListeners(List<String> auditListeners) {
this.auditListeners = auditListeners;
}
@Override
public void afterRemove(MongoStoreInvocationContext context) {
DBObject query = new QueryBuilder()

View file

@ -38,7 +38,7 @@ public class UserEntity extends AbstractMongoIdentifiableEntity implements Mongo
private List<UserModel.RequiredAction> requiredActions;
private List<CredentialEntity> credentials = new ArrayList<CredentialEntity>();
private List<SocialLinkEntity> socialLinks;
private List<AuthenticationLinkEntity> authenticationLinks;
private AuthenticationLinkEntity authenticationLink;
@MongoField
public String getLoginName() {
@ -168,12 +168,12 @@ public class UserEntity extends AbstractMongoIdentifiableEntity implements Mongo
}
@MongoField
public List<AuthenticationLinkEntity> getAuthenticationLinks() {
return authenticationLinks;
public AuthenticationLinkEntity getAuthenticationLink() {
return authenticationLink;
}
public void setAuthenticationLinks(List<AuthenticationLinkEntity> authenticationLinks) {
this.authenticationLinks = authenticationLinks;
public void setAuthenticationLink(AuthenticationLinkEntity authenticationLink) {
this.authenticationLink = authenticationLink;
}
@MongoField

Some files were not shown because too many files have changed in this diff Show more