Merge pull request #571 from patriot1burke/master

federation ui
This commit is contained in:
Bill Burke 2014-07-30 22:53:10 -04:00
commit b960f18f4e
25 changed files with 1110 additions and 427 deletions

View file

@ -702,6 +702,53 @@ module.config([ '$routeProvider', function($routeProvider) {
},
controller : 'RealmSessionStatsCtrl'
})
.when('/realms/:realm/user-federation', {
templateUrl : 'partials/user-federation.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
}
},
controller : 'UserFederationCtrl'
})
.when('/realms/:realm/user-federation/providers/ldap/:provider', {
templateUrl : 'partials/federated-ldap.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
provider : function(UserFederationInstanceLoader) {
return UserFederationInstanceLoader();
}
},
controller : 'LDAPCtrl'
})
.when('/create/user-federation/:realm/providers/ldap', {
templateUrl : 'partials/federated-ldap.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
provider : function() {
return {};
}
},
controller : 'LDAPCtrl'
})
.when('/create/user-federation/:realm/providers/:provider', {
templateUrl : 'partials/federated-ldap.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
provider : function() {
return {
providerName: "@provider"
};
}
},
controller : 'GenericUserFederationCtrl'
})
.when('/logout', {
templateUrl : 'partials/home.html',
controller : 'LogoutCtrl'

View file

@ -331,3 +331,150 @@ module.controller('UserCredentialsCtrl', function($scope, realm, user, User, Use
$scope.userChange = false;
};
});
module.controller('UserFederationCtrl', function($scope, $location, realm, UserFederationProviders, UserFederationInstances, Notifications, Dialog) {
console.log('UserFederationCtrl ++++****');
$scope.realm = realm;
$scope.providers = UserFederationProviders.query({realm: realm.realm});
$scope.addProvider = function(provider) {
console.log('Add provider: ' + provider.name);
$location.url("/create/user-federation/" + realm.realm + "/providers/" + provider.name);
};
$scope.instances = UserFederationInstances.query({realm: realm.realm});
});
module.controller('GenericUserFederationCtrl', function($scope, realm, provider, UserFederationProviders, UserFederationInstances, Notifications, Dialog) {
console.log('GenericUserFederationCtrl');
console.log("provider: " + provider.providerName);
});
module.controller('LDAPCtrl', function($scope, $location, Notifications, Dialog, realm, provider, UserFederationInstances, RealmLDAPConnectionTester) {
console.log('LDAPCtrl');
$scope.provider = angular.copy(provider);
$scope.create = !provider.providerName;
if ($scope.create) {
$scope.provider.providerName = "ldap";
$scope.provider.config = {};
}
$scope.ldapVendors = [
{ "id": "ad", "name": "Active Directory" },
{ "id": "rhds", "name": "Red Hat Directory Server" },
{ "id": "other", "name": "Other" }
];
$scope.usernameLDAPAttributes = [
"uid", "cn", "sAMAccountName"
];
$scope.realm = realm;
$scope.changed = false;
$scope.lastVendor = $scope.provider.config.vendor;
$scope.$watch('realm', function() {
if (!angular.equals($scope.provider, provider)) {
$scope.changed = true;
}
if (!angular.equals($scope.provider.config.vendor, $scope.lastVendor)) {
console.log("LDAP vendor changed");
$scope.lastVendor = $scope.provider.config.vendor;
if ($scope.lastVendor === "ad") {
$scope.provider.config.usernameLDAPAttribute = "cn";
$scope.provider.config.userObjectClasses = "person, organizationalPerson";
} else {
$scope.provider.config.usernameLDAPAttribute = "uid";
$scope.provider.config.userObjectClasses = "inetOrgPerson, organizationalPerson";
}
}
}, true);
$scope.save = function() {
$scope.changed = false;
if ($scope.create) {
UserFederationInstances.save({realm: realm.realm}, $scope.provider, function () {
$scope.changed = false;
$location.url("/realms/" + realm.realm + "/user-federation");
Notifications.success("The provider has been created.");
});
} else {
UserFederationInstances.update({realm: realm.realm,
provider: provider.id
},
$scope.provider, function () {
$scope.changed = false;
$location.url("/realms/" + realm.realm + "/user-federation");
Notifications.success("The provider has been updated.");
});
}
};
$scope.reset = function() {
$scope.provider = angular.copy(provider);
if ($scope.create) {
$scope.provider.providerName = "ldap";
$scope.provider.config = {};
}
$scope.changed = false;
$scope.lastVendor = $scope.provider.config.vendor;
};
$scope.cancel = function() {
$location.url("/realms/" + realm.realm + "/user-federation");
};
$scope.remove = function() {
Dialog.confirmDelete($scope.provider.id, 'provider', function() {
$scope.provider.$remove({
realm : realm.realm,
provider : $scope.provider.id
}, function() {
$location.url("/realms/" + realm.realm + "/user-federation");
Notifications.success("The provider has been deleted.");
});
});
};
var initConnectionTest = function(testAction, ldapConfig) {
return {
action: testAction,
realm: $scope.realm.realm,
connectionUrl: ldapConfig.connectionUrl,
bindDn: ldapConfig.bindDn,
bindCredential: ldapConfig.bindCredential
};
};
$scope.testConnection = function() {
console.log('LDAPCtrl: testConnection');
RealmLDAPConnectionTester.get(initConnectionTest("testConnection", $scope.provider.config), function() {
Notifications.success("LDAP connection successful.");
}, function() {
Notifications.error("Error when trying to connect to LDAP. See server.log for details.");
});
}
$scope.testAuthentication = function() {
console.log('LDAPCtrl: testAuthentication');
RealmLDAPConnectionTester.get(initConnectionTest("testAuthentication", $scope.realm.ldapServer), function() {
Notifications.success("LDAP authentication successful.");
}, function() {
Notifications.error("LDAP authentication failed. See server.log for details");
});
}
});

View file

@ -88,6 +88,16 @@ module.factory('UserLoader', function(Loader, User, $route, $q) {
});
});
module.factory('UserFederationInstanceLoader', function(Loader, UserFederationInstances, $route, $q) {
return Loader.get(UserFederationInstances, function() {
return {
realm : $route.current.params.realm,
provider: $route.current.params.provider
}
});
});
module.factory('UserSessionStatsLoader', function(Loader, UserSessionStats, $route, $q) {
return Loader.get(UserSessionStats, function() {
return {
@ -115,6 +125,9 @@ module.factory('UserSocialLinksLoader', function(Loader, UserSocialLinks, $route
});
});
module.factory('RoleLoader', function(Loader, Role, $route, $q) {
return Loader.get(Role, function() {
return {

View file

@ -199,6 +199,24 @@ module.factory('User', function($resource) {
});
});
module.factory('UserFederationInstances', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/user-federation/instances/:provider', {
realm : '@realm',
provider : '@provider'
}, {
update : {
method : 'PUT'
}
});
});
module.factory('UserFederationProviders', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/user-federation/providers', {
realm : '@realm'
});
});
module.factory('UserSessionStats', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/users/:user/session-stats', {
realm : '@realm',

View file

@ -0,0 +1,16 @@
<div class="bs-sidebar col-sm-3 " data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-sm-9" role="main">
<ul class="nav nav-tabs nav-tabs-pf">
<li><a href="#/realms/{{realm.realm}}/users">User List</a></li>
<li><a href="#/realms/{{realm.realm}}/user-federation">Federation</a></li>
</ul>
<div id="content">
<ol class="breadcrumb">
<li><a href="#/realms/{{realm.realm}}/user-federation">Federation</a></li>
<li class="active">User Federation Provider Configuration</li>
</ol>
<h2 class="pull-left"><span>{{realm.realm}}</span> Provider Settings</h2>
<p class="subtitle"><span class="required">*</span> Required fields</p>
</div>
</div>

View file

@ -0,0 +1,96 @@
<div class="bs-sidebar col-sm-3 " data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-sm-9" role="main">
<ul class="nav nav-tabs nav-tabs-pf">
<li><a href="#/realms/{{realm.realm}}/users">User List</a></li>
<li><a href="#/realms/{{realm.realm}}/user-federation">Federation</a></li>
</ul>
<div id="content">
<ol class="breadcrumb">
<li><a href="#/realms/{{realm.realm}}/user-federation">Federation</a></li>
<li class="active">Ldap Configuration</li>
</ol>
<h2 class="pull-left"><span>{{realm.realm}}</span> Ldap Server Settings</h2>
<p class="subtitle"><span class="required">*</span> Required fields</p>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
<fieldset>
<legend><span class="text">Required Settings</span></legend>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="vendor">Vendor</label>
<div class="col-sm-4">
<div class="select-kc">
<select id="vendor"
ng-model="provider.config.vendor"
ng-options="vendor.id as vendor.name for vendor in ldapVendors">
</select>
</div>
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="usernameLDAPAttribute">Username LDAP attribute </label>
<div class="col-sm-4">
<div class="select-kc">
<select id="usernameLDAPAttribute"
ng-model="provider.config.usernameLDAPAttribute"
ng-options="usernameLDAPAttribute for usernameLDAPAttribute in usernameLDAPAttributes">
</select>
</div>
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="userObjectClasses">User Object Classes </label>
<div class="col-sm-4">
<input class="form-control" id="userObjectClasses" type="text" ng-model="provider.config.userObjectClasses" placeholder="LDAP User Object Classes (div. by comma)">
</div>
</div>
<div class="form-group clearfix">
<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="ldapConnectionUrl" type="text" ng-model="provider.config.connectionUrl" placeholder="LDAP connection URL" required>
</div>
<div class="col-sm-4" data-ng-show="access.manageRealm">
<a class="btn btn-primary" data-ng-click="testConnection()">Test connection</a>
</div>
</div>
<div class="form-group clearfix">
<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="ldapBaseDn" type="text" ng-model="provider.config.baseDn" placeholder="LDAP Base DN" required>
</div>
</div>
<div class="form-group clearfix">
<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="ldapUserDnSuffix" type="text" ng-model="provider.config.userDnSuffix" placeholder="LDAP User DN Suffix" required>
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="ldapBindDn">Bind DN <span class="required">*</span></label>
<div class="col-sm-4">
<input class="form-control" id="ldapBindDn" type="text" ng-model="provider.config.bindDn" placeholder="LDAP Bind DN" required>
</div>
</div>
<div class="form-group clearfix">
<label class="col-sm-2 control-label" for="ldapBindCredential">Bind Credential <span class="required">*</span></label>
<div class="col-sm-4">
<input class="form-control" id="ldapBindCredential" type="text" ng-model="provider.config.bindCredential" placeholder="LDAP Bind Credentials" required>
</div>
<div class="col-sm-4" data-ng-show="access.manageRealm">
<a class="btn btn-primary" data-ng-click="testAuthentication()">Test authentication</a>
</div>
</div>
</fieldset>
<div class="pull-right form-actions" data-ng-show="create && access.manageUsers">
<button kc-cancel data-ng-click="cancel()">Cancel</button>
<button kc-save data-ng-show="changed">Save</button>
</div>
<div class="pull-right form-actions" data-ng-show="!create && access.manageUsers">
<button kc-reset data-ng-show="changed">Clear changes</button>
<button kc-save data-ng-show="changed">Save</button>
<button kc-delete data-ng-click="remove()" data-ng-hide="changed">Delete</button>
</div>
</form>
</div>
</div>

View file

@ -0,0 +1,47 @@
<div class="bs-sidebar col-sm-3 " data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-sm-9" role="main">
<ul class="nav nav-tabs nav-tabs-pf">
<li><a href="#/realms/{{realm.realm}}/users">User List</a></li>
<li class="active"><a href="">Federation</a></li>
</ul>
<div id="content">
<ol class="breadcrumb">
<li><a href="#/realms/{{realm.realm}}">{{realm.realm}}</a></li>
<li class="active">Federation</li>
</ol>
<h2><span>{{realm.realm}}</span> User Federation Providers</h2>
<table class="table table-striped table-bordered">
<thead>
<tr ng-show="providers.length > 0 && access.manageUsers">
<th colspan="3" class="kc-table-actions">
<div class="pull-right">
<div class="select-kc">
<select ng-model="selectedProvider"
ng-options="p.name for p in providers"
data-ng-change="addProvider(selectedProvider); selectedProvider = null">
<option value="" disabled selected>Add provider...</option>
</select>
</div>
</div>
</th>
</tr>
<tr data-ng-show="instances && instances.length > 0">
<th>ID</th>
<th>Provider Name</th>
<th>Priority</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="instance in instances">
<td><a href="#/realms/{{realm.realm}}/user-federation/providers/{{instance.providerName}}/{{instance.id}}">{{instance.id}}</a></td>
<td>{{instance.providerName|capitalize}}</td>
<td>{{instance.priority}}</td>
</tr>
<tr data-ng-show="!instances || instances.length == 0">
<td>No user federation providers configured</td>
</tr>
</tbody>
</table>
</div>
</div>

View file

@ -2,6 +2,7 @@
<div id="content-area" class="col-md-9" role="main">
<ul class="nav nav-tabs nav-tabs-pf">
<li class="active"><a href="">User List</a></li>
<li><a href="#/realms/{{realm.realm}}/user-federation">Federation</a></li>
</ul>
<div id="content">
<ol class="breadcrumb">

View file

@ -3,6 +3,8 @@ package org.keycloak.models;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
@ -14,5 +16,7 @@ public interface KeycloakSessionFactory {
<T extends Provider> ProviderFactory<T> getProviderFactory(Class<T> clazz, String id);
List<ProviderFactory> getProviderFactories(Class<? extends Provider> clazz);
void close();
}

View file

@ -168,6 +168,7 @@ public interface RealmModel extends RoleContainerModel {
List<UserFederationProviderModel> getUserFederationProviders();
UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority);
void updateUserFederationProvider(UserFederationProviderModel provider);
void removeUserFederationProvider(UserFederationProviderModel provider);
void setUserFederationProviders(List<UserFederationProviderModel> providers);

View file

@ -269,4 +269,13 @@ public class ModelToRepresentation {
rep.setNotBefore(model.getNotBefore());
return rep;
}
public static UserFederationProviderRepresentation toRepresentation(UserFederationProviderModel model) {
UserFederationProviderRepresentation rep = new UserFederationProviderRepresentation();
rep.setId(model.getId());
rep.setConfig(model.getConfig());
rep.setProviderName(model.getProviderName());
rep.setPriority(model.getPriority());
return rep;
}
}

View file

@ -630,6 +630,13 @@ public class RealmAdapter implements RealmModel {
}
@Override
public void updateUserFederationProvider(UserFederationProviderModel provider) {
getDelegateForUpdate();
updated.updateUserFederationProvider(provider);
}
@Override
public String getLoginTheme() {
if (updated != null) return updated.getLoginTheme();

View file

@ -769,9 +769,9 @@ public class RealmAdapter implements RealmModel {
@Override
public void removeUserFederationProvider(UserFederationProviderModel provider) {
UserFederationProviderEntity entity = null;
Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
while (it.hasNext()) {
UserFederationProviderEntity entity = it.next();
if (entity.getId().equals(provider.getId())) {
it.remove();
em.remove(entity);
@ -779,6 +779,20 @@ public class RealmAdapter implements RealmModel {
}
}
}
@Override
public void updateUserFederationProvider(UserFederationProviderModel model) {
Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
while (it.hasNext()) {
UserFederationProviderEntity entity = it.next();
if (entity.getId().equals(model.getId())) {
entity.setConfig(model.getConfig());
entity.setPriority(model.getPriority());
entity.setProviderName(model.getProviderName());
entity.setPriority(model.getPriority());
break;
}
}
}
@Override
public void setUserFederationProviders(List<UserFederationProviderModel> providers) {

View file

@ -819,6 +819,20 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
updateRealm();
}
@Override
public void updateUserFederationProvider(UserFederationProviderModel model) {
Iterator<UserFederationProviderEntity> it = realm.getUserFederationProviders().iterator();
while (it.hasNext()) {
UserFederationProviderEntity entity = it.next();
if (entity.getId().equals(model.getId())) {
entity.setProviderName(model.getProviderName());
entity.setConfig(model.getConfig());
entity.setPriority(model.getPriority());
}
}
updateRealm();
}
@Override
public List<UserFederationProviderModel> getUserFederationProviders() {
List<UserFederationProviderEntity> entities = realm.getUserFederationProviders();

View file

@ -10,6 +10,8 @@ import org.keycloak.provider.Spi;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
@ -84,6 +86,16 @@ public class DefaultKeycloakSessionFactory implements KeycloakSessionFactory {
return factoriesMap.get(clazz).get(id);
}
@Override
public List<ProviderFactory> getProviderFactories(Class<? extends Provider> clazz) {
List<ProviderFactory> list = new LinkedList<ProviderFactory>();
if (factoriesMap == null) return list;
Map<String, ProviderFactory> providerFactoryMap = factoriesMap.get(clazz);
if (providerFactoryMap == null) return list;
list.addAll(providerFactoryMap.values());
return list;
}
<T extends Provider> Set<String> getAllProviderIds(Class<T> clazz) {
Set<String> ids = new HashSet<String>();
for (ProviderFactory f : factoriesMap.get(clazz).values()) {

View file

@ -192,6 +192,14 @@ public class RealmAdminResource {
return users;
}
@Path("user-federation")
public UserFederationResource userFederation() {
UserFederationResource fed = new UserFederationResource(realm, auth);
ResteasyProviderFactory.getInstance().injectProperties(fed);
//resourceContext.initResource(fed);
return fed;
}
/**
* Path for managing all realm-level or application-level roles defined in this realm by it's id.
*

View file

@ -0,0 +1,199 @@
package org.keycloak.services.resources.admin;
import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.BadRequestException;
import org.jboss.resteasy.spi.NotFoundException;
import org.keycloak.email.EmailException;
import org.keycloak.email.EmailProvider;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.SocialLinkModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserFederationProvider;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.representations.adapters.action.UserStats;
import org.keycloak.representations.idm.ApplicationMappingsRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.MappingsRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.SocialLinkRepresentation;
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.UserSessionRepresentation;
import org.keycloak.services.managers.AccessCode;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.managers.ResourceAdminManager;
import org.keycloak.services.managers.TokenManager;
import org.keycloak.services.managers.UserManager;
import org.keycloak.services.resources.flows.Flows;
import org.keycloak.services.resources.flows.Urls;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
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;
import java.util.concurrent.TimeUnit;
/**
* Base resource for managing users
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class UserFederationResource {
protected static final Logger logger = Logger.getLogger(UserFederationResource.class);
protected RealmModel realm;
protected RealmAuth auth;
@Context
protected UriInfo uriInfo;
@Context
protected KeycloakSession session;
public UserFederationResource(RealmModel realm, RealmAuth auth) {
this.auth = auth;
this.realm = realm;
auth.init(RealmAuth.Resource.USER);
}
/**
* Get List of available provider factories
*
* @return
*/
@GET
@Path("providers")
@Produces("application/json")
public List<Map<String, String>> getProviders() {
logger.info("get provider list");
auth.requireView();
List<Map<String, String>> providers = new LinkedList<Map<String, String>>();
for (ProviderFactory factory : session.getKeycloakSessionFactory().getProviderFactories(UserFederationProvider.class)) {
Map<String, String> provider = new HashMap<String, String>();
provider.put("name", factory.getId());
providers.add(provider);
}
logger.info("provider list.size() " + providers.size());
return providers;
}
/**
* Create a provider
*
* @param rep
* @return
*/
@POST
@Path("instances")
@Consumes("application/json")
public Response createProvider(UserFederationProviderRepresentation rep) {
logger.info("createProvider");
auth.requireManage();
UserFederationProviderModel model = realm.addUserFederationProvider(rep.getProviderName(), rep.getConfig(), rep.getPriority());
return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
}
/**
* Update a provider
*
* @param id
* @param rep
*/
@PUT
@Path("instances/{id}")
@Consumes("application/json")
public void updateProvider(@PathParam("id") String id, UserFederationProviderRepresentation rep) {
logger.info("updateProvider");
auth.requireManage();
UserFederationProviderModel model = new UserFederationProviderModel(id, rep.getProviderName(), rep.getConfig(), rep.getPriority());
realm.updateUserFederationProvider(model);
}
/**
* get a provider
*
* @param id
*/
@GET
@Path("instances/{id}")
@Consumes("application/json")
public UserFederationProviderRepresentation getProvider(@PathParam("id") String id) {
logger.info("getProvider");
auth.requireView();
for (UserFederationProviderModel model : realm.getUserFederationProviders()) {
if (model.getId().equals(id)) {
return ModelToRepresentation.toRepresentation(model);
}
}
throw new NotFoundException("could not find provider");
}
/**
* Delete a provider
*
* @param id
*/
@DELETE
@Path("instances/{id}")
public void deleteProvider(@PathParam("id") String id) {
logger.info("deleteProvider");
auth.requireManage();
UserFederationProviderModel model = new UserFederationProviderModel(id, null, null, -1);
realm.removeUserFederationProvider(model);
}
/**
* list configured providers
*
* @return
*/
@GET
@Path("instances")
@Produces("application/json")
public List<UserFederationProviderRepresentation> getUserFederationProviders() {
logger.info("getUserFederationProviders");
auth.requireManage();
List<UserFederationProviderRepresentation> reps = new LinkedList<UserFederationProviderRepresentation>();
for (UserFederationProviderModel model : realm.getUserFederationProviders()) {
UserFederationProviderRepresentation rep = ModelToRepresentation.toRepresentation(model);
reps.add(rep);
}
return reps;
}
}

View file

@ -197,13 +197,11 @@
<dependency>
<groupId>org.picketbox</groupId>
<artifactId>picketbox-ldap</artifactId>
<scope>compile</scope>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>org.picketbox</groupId>
<artifactId>picketbox-ldap</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
<build>

View file

@ -104,8 +104,27 @@ public class KeycloakServer {
}
public static void main(String[] args) throws Throwable {
//bootstrapLdap(); Can't seem to get this to work.
bootstrapKeycloakServer(args);
}
private static LDAPEmbeddedServer embeddedServer;
public static void bootstrapLdap() throws Exception {
embeddedServer = new LDAPEmbeddedServer();
embeddedServer.setup();
embeddedServer.importLDIF("ldap/users.ldif");
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
try {
embeddedServer.tearDown();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
}
public static KeycloakServer bootstrapKeycloakServer(String[] args) throws Throwable {
KeycloakServerConfig config = new KeycloakServerConfig();

View file

@ -1,4 +1,4 @@
package org.keycloak.testsuite;
package org.keycloak.testutils;
import org.keycloak.models.LDAPConstants;
import org.keycloak.models.RealmModel;

View file

@ -3,6 +3,7 @@ package org.keycloak.testsuite.forms;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.FixMethodOrder;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
@ -10,8 +11,7 @@ import org.junit.rules.TestRule;
import org.junit.runners.MethodSorters;
import org.keycloak.OAuth2Constants;
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.testsuite.LDAPEmbeddedServer;
import org.keycloak.testutils.LDAPEmbeddedServer;
import org.keycloak.testsuite.LDAPTestUtils;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.LDAPConstants;
@ -32,7 +32,6 @@ import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@ -44,6 +43,8 @@ public class FederationProvidersIntegrationTest {
private static LDAPRule ldapRule = new LDAPRule();
private static Map<String,String> ldapConfig = null;
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
@Override
@ -52,13 +53,15 @@ public class FederationProvidersIntegrationTest {
addUser(manager.getSession(), adminstrationRealm, "mary-admin", "mary@admin.com", "password-admin");
LDAPEmbeddedServer ldapServer = ldapRule.getEmbeddedServer();
Map<String,String> ldapConfig = new HashMap<String,String>();
ldapConfig = new HashMap<String,String>();
ldapConfig.put(LDAPConstants.CONNECTION_URL, ldapServer.getConnectionUrl());
ldapConfig.put(LDAPConstants.BASE_DN, ldapServer.getBaseDn());
ldapConfig.put(LDAPConstants.BIND_DN, ldapServer.getBindDn());
ldapConfig.put(LDAPConstants.BIND_CREDENTIAL, ldapServer.getBindCredential());
ldapConfig.put(LDAPConstants.USER_DN_SUFFIX, ldapServer.getUserDnSuffix());
ldapConfig.put(LDAPConstants.VENDOR, ldapServer.getVendor());
String vendor = ldapServer.getVendor();
ldapConfig.put(LDAPConstants.VENDOR, vendor);
appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0);
@ -111,6 +114,16 @@ public class FederationProvidersIntegrationTest {
return user;
}
@Test
@Ignore
public void runit() throws Exception {
System.out.println("*** ldap config ***");
for (Map.Entry<String, String> entry : ldapConfig.entrySet()) {
System.out.println("key: " + entry.getKey() + " value: " + entry.getValue());
}
Thread.sleep(10000000);
}
@Test
public void loginClassic() {
loginPage.open();

View file

@ -10,7 +10,7 @@ import org.junit.runners.MethodSorters;
import org.keycloak.authentication.AuthProviderConstants;
import org.keycloak.authentication.AuthenticationProviderException;
import org.keycloak.authentication.AuthenticationProviderManager;
import org.keycloak.testsuite.LDAPEmbeddedServer;
import org.keycloak.testutils.LDAPEmbeddedServer;
import org.keycloak.testsuite.LDAPTestUtils;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.AuthenticationProviderModel;

View file

@ -1,7 +1,7 @@
package org.keycloak.testsuite.rule;
import org.junit.rules.ExternalResource;
import org.keycloak.testsuite.LDAPEmbeddedServer;
import org.keycloak.testutils.LDAPEmbeddedServer;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>