brute force merge
This commit is contained in:
commit
126b444d77
166 changed files with 3640 additions and 854 deletions
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -129,7 +129,7 @@ module.config([ '$routeProvider', function($routeProvider) {
|
|||
return RealmLoader();
|
||||
}
|
||||
},
|
||||
controller : 'RealmSMTPSettingsCtrl'
|
||||
controller : 'RealmLdapSettingsCtrl'
|
||||
})
|
||||
.when('/create/user/:realm', {
|
||||
templateUrl : 'partials/user-detail.html',
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
});
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
39
audit/api/pom.xml
Executable 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>
|
145
audit/api/src/main/java/org/keycloak/audit/Audit.java
Normal file
145
audit/api/src/main/java/org/keycloak/audit/Audit.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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> {
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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> {
|
||||
|
||||
}
|
22
audit/api/src/main/java/org/keycloak/audit/Details.java
Normal file
22
audit/api/src/main/java/org/keycloak/audit/Details.java
Normal 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";
|
||||
|
||||
}
|
36
audit/api/src/main/java/org/keycloak/audit/Errors.java
Normal file
36
audit/api/src/main/java/org/keycloak/audit/Errors.java
Normal 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";
|
||||
|
||||
}
|
108
audit/api/src/main/java/org/keycloak/audit/Event.java
Normal file
108
audit/api/src/main/java/org/keycloak/audit/Event.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
24
audit/api/src/main/java/org/keycloak/audit/EventQuery.java
Normal file
24
audit/api/src/main/java/org/keycloak/audit/EventQuery.java
Normal 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();
|
||||
|
||||
}
|
29
audit/api/src/main/java/org/keycloak/audit/Events.java
Normal file
29
audit/api/src/main/java/org/keycloak/audit/Events.java
Normal 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
39
audit/jboss-logging/pom.xml
Executable 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>
|
|
@ -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() {
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
org.keycloak.audit.log.JBossLoggingAuditListenerFactory
|
61
audit/jpa/pom.xml
Executable file
61
audit/jpa/pom.xml
Executable 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>
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
org.keycloak.audit.jpa.JpaAuditProviderFactory
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
22
audit/jpa/src/src/test/resources/META-INF/persistence.xml
Executable file
22
audit/jpa/src/src/test/resources/META-INF/persistence.xml
Executable 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
129
audit/mongo/pom.xml
Executable 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>
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
org.keycloak.audit.mongo.MongoAuditProviderFactory
|
|
@ -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
25
audit/pom.xml
Executable 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
35
audit/tests/pom.xml
Executable 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>
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
10
core/src/main/java/org/keycloak/provider/Provider.java
Normal file
10
core/src/main/java/org/keycloak/provider/Provider.java
Normal 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();
|
||||
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
<description/>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>distribution-pom</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
<description/>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>demo-pom</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
4
examples/demo-template/third-party/pom.xml
vendored
4
examples/demo-template/third-party/pom.xml
vendored
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
<description/>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>examples-pom</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
<description/>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>integration-pom</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue