Merge pull request #58 from patriot1burke/master

scope mapping, oauth client
This commit is contained in:
Bill Burke 2013-10-09 14:32:54 -07:00
commit 8fd70dc51a
37 changed files with 1010 additions and 337 deletions

View file

@ -1,57 +0,0 @@
package org.keycloak.representations.idm;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class AllRoleMappingsRepresentation {
protected String realmId;
protected String realmName;
protected String username;
protected List<RoleRepresentation> realmMappings;
protected Map<String, ApplicationRoleMappingsRepresentation> applicationMappings;
public String getRealmId() {
return realmId;
}
public void setRealmId(String realmId) {
this.realmId = realmId;
}
public String getRealmName() {
return realmName;
}
public void setRealmName(String realmName) {
this.realmName = realmName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List<RoleRepresentation> getRealmMappings() {
return realmMappings;
}
public void setRealmMappings(List<RoleRepresentation> realmMappings) {
this.realmMappings = realmMappings;
}
public Map<String,ApplicationRoleMappingsRepresentation> getApplicationMappings() {
return applicationMappings;
}
public void setApplicationMappings(Map<String, ApplicationRoleMappingsRepresentation> applicationMappings) {
this.applicationMappings = applicationMappings;
}
}

View file

@ -6,10 +6,9 @@ import java.util.List;
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $ * @version $Revision: 1 $
*/ */
public class ApplicationRoleMappingsRepresentation { public class ApplicationMappingsRepresentation {
protected String applicationId; protected String applicationId;
protected String application; protected String application;
protected String username;
protected List<RoleRepresentation> mappings; protected List<RoleRepresentation> mappings;
@ -29,14 +28,6 @@ public class ApplicationRoleMappingsRepresentation {
this.application = application; this.application = application;
} }
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List<RoleRepresentation> getMappings() { public List<RoleRepresentation> getMappings() {
return mappings; return mappings;
} }

View file

@ -18,7 +18,7 @@ public class ApplicationRepresentation {
protected boolean enabled; protected boolean enabled;
protected List<CredentialRepresentation> credentials; protected List<CredentialRepresentation> credentials;
protected List<RoleRepresentation> roles; protected List<RoleRepresentation> roles;
protected List<RoleMappingRepresentation> roleMappings; protected List<UserRoleMappingRepresentation> roleMappings;
protected List<ScopeMappingRepresentation> scopeMappings; protected List<ScopeMappingRepresentation> scopeMappings;
public String getSelf() { public String getSelf() {
@ -82,14 +82,14 @@ public class ApplicationRepresentation {
return this; return this;
} }
public List<RoleMappingRepresentation> getRoleMappings() { public List<UserRoleMappingRepresentation> getRoleMappings() {
return roleMappings; return roleMappings;
} }
public RoleMappingRepresentation roleMapping(String username) { public UserRoleMappingRepresentation roleMapping(String username) {
RoleMappingRepresentation mapping = new RoleMappingRepresentation(); UserRoleMappingRepresentation mapping = new UserRoleMappingRepresentation();
mapping.setUsername(username); mapping.setUsername(username);
if (roleMappings == null) roleMappings = new ArrayList<RoleMappingRepresentation>(); if (roleMappings == null) roleMappings = new ArrayList<UserRoleMappingRepresentation>();
roleMappings.add(mapping); roleMappings.add(mapping);
return mapping; return mapping;
} }

View file

@ -0,0 +1,29 @@
package org.keycloak.representations.idm;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class MappingsRepresentation {
protected List<RoleRepresentation> realmMappings;
protected Map<String, ApplicationMappingsRepresentation> applicationMappings;
public List<RoleRepresentation> getRealmMappings() {
return realmMappings;
}
public void setRealmMappings(List<RoleRepresentation> realmMappings) {
this.realmMappings = realmMappings;
}
public Map<String,ApplicationMappingsRepresentation> getApplicationMappings() {
return applicationMappings;
}
public void setApplicationMappings(Map<String, ApplicationMappingsRepresentation> applicationMappings) {
this.applicationMappings = applicationMappings;
}
}

View file

@ -0,0 +1,60 @@
package org.keycloak.representations.idm;
import java.util.ArrayList;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class OAuthClientRepresentation {
protected String id;
protected String name;
protected String baseUrl;
protected boolean enabled;
protected List<ScopeMappingRepresentation> scopeMappings;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public List<ScopeMappingRepresentation> getScopeMappings() {
return scopeMappings;
}
public ScopeMappingRepresentation scopeMapping(String username) {
ScopeMappingRepresentation mapping = new ScopeMappingRepresentation();
mapping.setUsername(username);
if (scopeMappings == null) scopeMappings = new ArrayList<ScopeMappingRepresentation>();
scopeMappings.add(mapping);
return mapping;
}
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
}

View file

@ -31,7 +31,7 @@ public class RealmRepresentation {
protected Set<String> requiredApplicationCredentials; protected Set<String> requiredApplicationCredentials;
protected Set<String> requiredOAuthClientCredentials; protected Set<String> requiredOAuthClientCredentials;
protected List<UserRepresentation> users; protected List<UserRepresentation> users;
protected List<RoleMappingRepresentation> roleMappings; protected List<UserRoleMappingRepresentation> roleMappings;
protected List<ScopeMappingRepresentation> scopeMappings; protected List<ScopeMappingRepresentation> scopeMappings;
protected List<SocialMappingRepresentation> socialMappings; protected List<SocialMappingRepresentation> socialMappings;
protected List<ApplicationRepresentation> applications; protected List<ApplicationRepresentation> applications;
@ -125,14 +125,14 @@ public class RealmRepresentation {
this.tokenLifespan = tokenLifespan; this.tokenLifespan = tokenLifespan;
} }
public List<RoleMappingRepresentation> getRoleMappings() { public List<UserRoleMappingRepresentation> getRoleMappings() {
return roleMappings; return roleMappings;
} }
public RoleMappingRepresentation roleMapping(String username) { public UserRoleMappingRepresentation roleMapping(String username) {
RoleMappingRepresentation mapping = new RoleMappingRepresentation(); UserRoleMappingRepresentation mapping = new UserRoleMappingRepresentation();
mapping.setUsername(username); mapping.setUsername(username);
if (roleMappings == null) roleMappings = new ArrayList<RoleMappingRepresentation>(); if (roleMappings == null) roleMappings = new ArrayList<UserRoleMappingRepresentation>();
roleMappings.add(mapping); roleMappings.add(mapping);
return mapping; return mapping;
} }

View file

@ -1,47 +0,0 @@
package org.keycloak.representations.idm;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class RealmRoleMappingsRepresentation {
protected String realmId;
protected String realm;
protected String username;
protected List<RoleRepresentation> mappings;
public String getRealmId() {
return realmId;
}
public void setRealmId(String realmId) {
this.realmId = realmId;
}
public String getRealm() {
return realm;
}
public void setRealm(String realm) {
this.realm = realm;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List<RoleRepresentation> getMappings() {
return mappings;
}
public void setMappings(List<RoleRepresentation> mappings) {
this.mappings = mappings;
}
}

View file

@ -7,7 +7,7 @@ import java.util.Set;
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $ * @version $Revision: 1 $
*/ */
public class RoleMappingRepresentation { public class UserRoleMappingRepresentation {
protected String self; // link protected String self; // link
protected String username; protected String username;
protected Set<String> roles; protected Set<String> roles;
@ -36,7 +36,7 @@ public class RoleMappingRepresentation {
this.roles = roles; this.roles = roles;
} }
public RoleMappingRepresentation role(String role) { public UserRoleMappingRepresentation role(String role) {
if (this.roles == null) this.roles = new HashSet<String>(); if (this.roles == null) this.roles = new HashSet<String>();
this.roles.add(role); this.roles.add(role);
return this; return this;

View file

@ -181,6 +181,23 @@ module.config([ '$routeProvider', function($routeProvider) {
} }
}, },
controller : 'ApplicationRoleListCtrl' controller : 'ApplicationRoleListCtrl'
}).when('/realms/:realm/applications/:application/scope-mappings', {
templateUrl : 'partials/application-scope-mappings.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
},
applications : function(ApplicationListLoader) {
return ApplicationListLoader();
},
roles : function(RoleListLoader) {
return RoleListLoader();
}
},
controller : 'ApplicationScopeMappingCtrl'
}) })

View file

@ -2,9 +2,6 @@
var module = angular.module('keycloak.controllers', [ 'keycloak.services' ]); var module = angular.module('keycloak.controllers', [ 'keycloak.services' ]);
var realmslist = {};
module.controller('GlobalCtrl', function($scope, $http, Auth, Current, $location, Notifications) { module.controller('GlobalCtrl', function($scope, $http, Auth, Current, $location, Notifications) {
$scope.addMessage = function() { $scope.addMessage = function() {
Notifications.success("test"); Notifications.success("test");
@ -463,6 +460,74 @@ module.controller('RoleListCtrl', function($scope, $location, realm, roles) {
}); });
}); });
module.controller('RoleDetailCtrl', function($scope, realm, role, Role, $location, Dialog, Notifications) {
$scope.realm = realm;
$scope.role = angular.copy(role);
$scope.create = !role.name;
$scope.changed = $scope.create;
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
$scope.$watch('role', function() {
if (!angular.equals($scope.role, role)) {
$scope.changed = true;
}
}, true);
$scope.save = function() {
if ($scope.create) {
Role.save({
realm: realm.id
}, $scope.role, function (data, headers) {
$scope.changed = false;
role = angular.copy($scope.role);
var l = headers().location;
var id = l.substring(l.lastIndexOf("/") + 1);
$location.url("/realms/" + realm.id + "/roles/" + id);
Notifications.success("Created role");
});
} else {
Role.update({
realm : realm.id,
roleId : role.id
}, $scope.role, function() {
$scope.changed = false;
role = angular.copy($scope.role);
Notifications.success("Saved changes to role");
});
}
};
$scope.reset = function() {
$scope.role = angular.copy(role);
$scope.changed = false;
$scope.roleForm.showErrors = false;
};
$scope.cancel = function() {
$location.url("/realms/" + realm.id + "/roles");
};
$scope.remove = function() {
Dialog.confirmDelete($scope.role.name, 'role', function() {
$scope.role.$remove({
realm : realm.id,
role : $scope.role.name
}, function() {
$location.url("/realms/" + realm.id + "/roles");
Notifications.success("Deleted role");
});
});
};
});
module.controller('ApplicationRoleListCtrl', function($scope, $location, realm, application, roles) { module.controller('ApplicationRoleListCtrl', function($scope, $location, realm, application, roles) {
$scope.realm = realm; $scope.realm = realm;
$scope.roles = roles; $scope.roles = roles;
@ -775,3 +840,121 @@ module.controller('RoleMappingCtrl', function($scope, realm, User, users, role,
} }
} }
}); });
module.controller('ApplicationScopeMappingCtrl', function($scope, $http, realm, application, roles, applications, ApplicationRealmScopeMapping, ApplicationApplicationScopeMapping, ApplicationRole) {
$scope.realm = realm;
$scope.application = application;
$scope.realmRoles = angular.copy(roles);
$scope.selectedRealmRoles = [];
$scope.selectedRealmMappings = [];
$scope.realmMappings = [];
$scope.applications = applications;
$scope.applicationRoles = [];
$scope.selectedApplicationRoles = [];
$scope.selectedApplicationMappings = [];
$scope.applicationMappings = [];
$scope.realmMappings = ApplicationRealmScopeMapping.query({realm : realm.id, application : application.id}, function(){
for (var i = 0; i < $scope.realmMappings.length; i++) {
var role = $scope.realmMappings[i];
for (var j = 0; j < $scope.realmRoles.length; j++) {
var realmRole = $scope.realmRoles[j];
if (realmRole.id == role.id) {
var idx = $scope.realmRoles.indexOf(realmRole);
if (idx != -1) {
$scope.realmRoles.splice(idx, 1);
break;
}
}
}
}
});
$scope.addRealmRole = function() {
$http.post('/auth-server/rest/saas/admin/realms/' + realm.id + '/applications/' + application.id + '/scope-mappings/realm',
$scope.selectedRealmRoles).success(function() {
for (var i = 0; i < $scope.selectedRealmRoles.length; i++) {
var role = $scope.selectedRealmRoles[i];
var idx = $scope.realmRoles.indexOf($scope.selectedRealmRoles[i]);
if (idx != -1) {
$scope.realmRoles.splice(idx, 1);
$scope.realmMappings.push(role);
}
}
$scope.selectRealmRoles = [];
});
};
$scope.deleteRealmRole = function() {
$http.delete('/auth-server/rest/saas/admin/realms/' + realm.id + '/applications/' + application.id + '/scope-mappings/realm',
{data : $scope.selectedRealmMappings, headers : {"content-type" : "application/json"}}).success(function() {
for (var i = 0; i < $scope.selectedRealmMappings.length; i++) {
var role = $scope.selectedRealmMappings[i];
var idx = $scope.realmMappings.indexOf($scope.selectedRealmMappings[i]);
if (idx != -1) {
$scope.realmMappings.splice(idx, 1);
$scope.realmRoles.push(role);
}
}
$scope.selectedRealmMappings = [];
});
};
$scope.addApplicationRole = function() {
$http.post('/auth-server/rest/saas/admin/realms/' + realm.id + '/applications/' + application.id + '/scope-mappings/applications/' + $scope.targetApp.id,
$scope.selectedApplicationRoles).success(function() {
for (var i = 0; i < $scope.selectedApplicationRoles.length; i++) {
var role = $scope.selectedApplicationRoles[i];
var idx = $scope.applicationRoles.indexOf($scope.selectedApplicationRoles[i]);
if (idx != -1) {
$scope.applicationRoles.splice(idx, 1);
$scope.applicationMappings.push(role);
}
}
$scope.selectedApplicationRoles = [];
});
};
$scope.deleteApplicationRole = function() {
$http.delete('/auth-server/rest/saas/admin/realms/' + realm.id + '/applications/' + application.id + '/scope-mappings/applications/' + $scope.targetApp.id,
{data : $scope.selectedApplicationMappings, headers : {"content-type" : "application/json"}}).success(function() {
for (var i = 0; i < $scope.selectedApplicationMappings.length; i++) {
var role = $scope.selectedApplicationMappings[i];
var idx = $scope.applicationMappings.indexOf($scope.selectedApplicationMappings[i]);
if (idx != -1) {
$scope.applicationMappings.splice(idx, 1);
$scope.applicationRoles.push(role);
}
}
$scope.selectedApplicationMappings = [];
});
};
$scope.changeApplication = function() {
$scope.applicationRoles = ApplicationRole.query({realm : realm.id, application : $scope.targetApp.id}, function() {
$scope.applicationMappings = ApplicationApplicationScopeMapping.query({realm : realm.id, application : application.id, targetApp : $scope.targetApp.id}, function(){
for (var i = 0; i < $scope.applicationMappings.length; i++) {
var role = $scope.applicationMappings[i];
for (var j = 0; j < $scope.applicationRoles.length; j++) {
var realmRole = $scope.applicationRoles[j];
if (realmRole.id == role.id) {
var idx = $scope.applicationRoles.indexOf(realmRole);
if (idx != -1) {
$scope.applicationRoles.splice(idx, 1);
break;
}
}
}
}
});
}
);
};
});

View file

@ -111,8 +111,6 @@ module.factory('RealmRoleMapping', function($resource) {
}); });
}); });
module.factory('ApplicationRoleMapping', function($resource) { module.factory('ApplicationRoleMapping', function($resource) {
return $resource('/auth-server/rest/saas/admin/realms/:realm/users/:userId/role-mappings/applications/:application', { return $resource('/auth-server/rest/saas/admin/realms/:realm/users/:userId/role-mappings/applications/:application', {
realm : '@realm', realm : '@realm',
@ -121,6 +119,21 @@ module.factory('ApplicationRoleMapping', function($resource) {
}); });
}); });
module.factory('ApplicationRealmScopeMapping', function($resource) {
return $resource('/auth-server/rest/saas/admin/realms/:realm/applications/:application/scope-mappings/realm', {
realm : '@realm',
application : '@application'
});
});
module.factory('ApplicationApplicationScopeMapping', function($resource) {
return $resource('/auth-server/rest/saas/admin/realms/:realm/applications/:application/scope-mappings/applications/:targetApp', {
realm : '@realm',
application : '@application',
targetApp : '@targetApp'
});
});
module.factory('RealmRoles', function($resource) { module.factory('RealmRoles', function($resource) {

View file

@ -10,7 +10,7 @@
<li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li> <li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li>
<li><a href="#">Installation</a></li> <li><a href="#">Installation</a></li>
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li> <li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li>
<li><a href="#">Scope</a></li> <li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/scope-mappings">Scope</a></li>
<li><a href="#">Sessions</a></li> <li><a href="#">Sessions</a></li>
</ul> </ul>
</div> </div>

View file

@ -10,7 +10,7 @@
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li> <li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li>
<li><a href="#">Installation</a></li> <li><a href="#">Installation</a></li>
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li> <li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li>
<li><a href="#">Scope</a></li> <li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/scope-mappings">Scope</a></li>
<li><a href="#">Sessions</a></li> <li><a href="#">Sessions</a></li>
</ul> </ul>
</div> </div>

View file

@ -0,0 +1,73 @@
<div id="wrapper" class="container">
<div class="row">
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
<div id="content-area" class="col-md-9" role="main">
<div class="top-nav">
<ul class="rcue-tabs">
<li><a href="#/create/application/{{realm.id}}">New Application</a></li>
<li><a href="#/realms/{{realm.id}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}">Settings</a></li>
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/credentials">Credentials</a></li>
<li><a href="#">Installation</a></li>
<li><a href="#/realms/{{realm.id}}/applications/{{application.id}}/roles">Roles</a></li>
<li class="active"><a href="#/realms/{{realm.id}}/applications/{{application.id}}/scope-mappings">Scope</a></li>
<li><a href="#">Sessions</a></li>
</ul>
</div>
<div id="content">
<h2 class="pull-left">Application Scope Mappings for <span>{{application.name}}</span></h2>
<p class="subtitle"></p>
<form name="realmForm" novalidate>
<fieldset>
<legend uncollapsed><span class="text">Realm Scope</span> </legend>
<div class="form-group">
<div class="controls">
<select multiple size="5"
ng-multiple="true"
ng-model="selectedRealmRoles"
ng-options="r.name for r in realmRoles">
</select>
<button type="submit" ng-click="addRealmRole()">---&gt;</button>
<button type="submit" ng-click="deleteRealmRole()">&lt;---</button>
<select multiple size=5
ng-multiple="true"
ng-model="selectedRealmMappings"
ng-options="r.name for r in realmMappings">
</select>
</div>
</div>
</fieldset>
<fieldset ng-show="applications.length > 0">
<legend collapsed><span class="text">Application Scope</span> </legend>
<div class="form-group input-select">
<label for="applications">Application: </label>
<div class="input-group">
<div class="select-rcue">
<select id="applications" name="applications" ng-change="changeApplication()" ng-model="targetApp" ng-options="a.name for a in applications">
</select>
</div>
</div>
</div>
<div class="form-group" ng-show="application">
<div class="controls">
<select multiple size="5"
ng-multiple="true"
ng-model="selectedApplicationRoles"
ng-options="r.name for r in applicationRoles">
</select>
<button type="submit" ng-click="addApplicationRole()">---&gt;</button>
<button type="submit" ng-click="deleteApplicationRole()">&lt;---</button>
<select multiple size=5
ng-multiple="true"
ng-model="selectedApplicationMappings"
ng-options="r.name for r in applicationMappings">
</select>
</div>
</div>
</fieldset>
</form>
</div>
</div>
<div id="container-right-bg"></div>
</div>
</div>

View file

@ -7,7 +7,7 @@ import java.util.Set;
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $ * @version $Revision: 1 $
*/ */
public interface ApplicationModel { public interface ApplicationModel extends RoleContainerModel, RoleMapperModel, ScopeMapperModel {
void updateApplication(); void updateApplication();
UserModel getApplicationUser(); UserModel getApplicationUser();
@ -34,25 +34,4 @@ public interface ApplicationModel {
void setBaseUrl(String url); void setBaseUrl(String url);
RoleModel getRole(String name);
RoleModel addRole(String name);
List<RoleModel> getRoles();
Set<String> getRoleMappingValues(UserModel user);
void addScopeMapping(UserModel agent, String roleName);
void addScopeMapping(UserModel agent, RoleModel role);
Set<String> getScopeMapping(UserModel agent);
List<RoleModel> getRoleMappings(UserModel user);
void deleteRoleMapping(UserModel user, RoleModel role);
RoleModel getRoleById(String id);
void grantRole(UserModel user, RoleModel role);
} }

View file

@ -10,7 +10,7 @@ import java.util.Set;
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $ * @version $Revision: 1 $
*/ */
public interface RealmModel { public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMapperModel {
String DEFAULT_REALM = "default"; String DEFAULT_REALM = "default";
String getId(); String getId();
@ -85,12 +85,6 @@ public interface RealmModel {
UserModel addUser(String username); UserModel addUser(String username);
RoleModel getRole(String name);
RoleModel addRole(String name);
List<RoleModel> getRoles();
List<RoleModel> getDefaultRoles(); List<RoleModel> getDefaultRoles();
void addDefaultRole(String name); void addDefaultRole(String name);
@ -103,30 +97,16 @@ public interface RealmModel {
ApplicationModel addApplication(String name); ApplicationModel addApplication(String name);
boolean hasRole(UserModel user, RoleModel role);
void grantRole(UserModel user, RoleModel role);
Set<String> getRoleMappingValues(UserModel user);
void addScopeMapping(UserModel agent, String roleName);
Set<String> getScopeMapping(UserModel agent);
boolean isRealmAdmin(UserModel agent); boolean isRealmAdmin(UserModel agent);
void addRealmAdmin(UserModel agent); void addRealmAdmin(UserModel agent);
RoleModel getRoleById(String id);
List<RequiredCredentialModel> getRequiredApplicationCredentials(); List<RequiredCredentialModel> getRequiredApplicationCredentials();
List<RequiredCredentialModel> getRequiredOAuthClientCredentials(); List<RequiredCredentialModel> getRequiredOAuthClientCredentials();
boolean hasRole(UserModel user, String role);
ApplicationModel getApplicationById(String id); ApplicationModel getApplicationById(String id);
void addRequiredOAuthClientCredential(String type); void addRequiredOAuthClientCredential(String type);
@ -157,11 +137,9 @@ public interface RealmModel {
List<UserModel> searchForUserByAttributes(Map<String, String> attributes); List<UserModel> searchForUserByAttributes(Map<String, String> attributes);
List<RoleModel> getRoleMappings(UserModel user);
void deleteRoleMapping(UserModel user, RoleModel role);
OAuthClientModel addOAuthClient(String name); OAuthClientModel addOAuthClient(String name);
OAuthClientModel getOAuthClient(String name); OAuthClientModel getOAuthClient(String name);
List<OAuthClientModel> getOAuthClients();
} }

View file

@ -0,0 +1,17 @@
package org.keycloak.models;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public interface RoleContainerModel {
RoleModel getRole(String name);
RoleModel addRole(String name);
List<RoleModel> getRoles();
RoleModel getRoleById(String id);
}

View file

@ -0,0 +1,22 @@
package org.keycloak.models;
import java.util.List;
import java.util.Set;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public interface RoleMapperModel {
boolean hasRole(UserModel user, RoleModel role);
void grantRole(UserModel user, RoleModel role);
Set<String> getRoleMappingValues(UserModel user);
List<RoleModel> getRoleMappings(UserModel user);
void deleteRoleMapping(UserModel user, RoleModel role);
boolean hasRole(UserModel user, String role);
}

View file

@ -0,0 +1,20 @@
package org.keycloak.models;
import java.util.List;
import java.util.Set;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public interface ScopeMapperModel {
void addScopeMapping(UserModel agent, String roleName);
Set<String> getScopeMappingValues(UserModel agent);
List<RoleModel> getScopeMappings(UserModel agent);
void addScopeMapping(UserModel agent, RoleModel role);
void deleteScopeMapping(UserModel user, RoleModel role);
}

View file

@ -134,7 +134,16 @@ public class ApplicationAdapter implements ApplicationModel {
SampleModel.grantRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole()); SampleModel.grantRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole());
} }
@Override
public boolean hasRole(UserModel user, RoleModel role) {
return SampleModel.hasRole(getRelationshipManager(), ((UserAdapter) user).getUser(), ((RoleAdapter) role).getRole());
}
@Override
public boolean hasRole(UserModel user, String role) {
RoleModel roleModel = getRole(role);
return hasRole(user, roleModel);
}
@Override @Override
public RoleAdapter addRole(String name) { public RoleAdapter addRole(String name) {
@ -190,9 +199,6 @@ public class ApplicationAdapter implements ApplicationModel {
} }
} }
@Override @Override
public void addScopeMapping(UserModel agent, String roleName) { public void addScopeMapping(UserModel agent, String roleName) {
IdentityManager idm = getIdm(); IdentityManager idm = getIdm();
@ -211,7 +217,19 @@ public class ApplicationAdapter implements ApplicationModel {
} }
@Override @Override
public Set<String> getScopeMapping(UserModel agent) { public void deleteScopeMapping(UserModel user, RoleModel role) {
RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)user).getUser());
query.setParameter(ScopeRelationship.SCOPE, ((RoleAdapter)role).getRole());
List<ScopeRelationship> grants = query.getResultList();
for (ScopeRelationship grant : grants) {
getRelationshipManager().remove(grant);
}
}
@Override
public Set<String> getScopeMappingValues(UserModel agent) {
RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class); RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser()); query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
List<ScopeRelationship> scope = query.getResultList(); List<ScopeRelationship> scope = query.getResultList();
@ -221,4 +239,17 @@ public class ApplicationAdapter implements ApplicationModel {
} }
return set; return set;
} }
@Override
public List<RoleModel> getScopeMappings(UserModel agent) {
RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
List<ScopeRelationship> scope = query.getResultList();
List<RoleModel> roles = new ArrayList<RoleModel>();
for (ScopeRelationship rel : scope) {
if (rel.getScope().getPartition().getId().equals(applicationData.getId())) roles.add(new RoleAdapter(rel.getScope(), getIdm()));
}
return roles;
}
} }

View file

@ -665,7 +665,6 @@ public class RealmAdapter implements RealmModel {
return set; return set;
} }
@Override @Override
public void addScopeMapping(UserModel agent, String roleName) { public void addScopeMapping(UserModel agent, String roleName) {
IdentityManager idm = getIdm(); IdentityManager idm = getIdm();
@ -677,6 +676,25 @@ public class RealmAdapter implements RealmModel {
getRelationshipManager().add(scope); getRelationshipManager().add(scope);
} }
@Override
public void addScopeMapping(UserModel agent, RoleModel role) {
ScopeRelationship scope = new ScopeRelationship();
scope.setClient(((UserAdapter)agent).getUser());
scope.setScope(((RoleAdapter)role).getRole());
getRelationshipManager().add(scope);
}
@Override
public void deleteScopeMapping(UserModel user, RoleModel role) {
RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)user).getUser());
query.setParameter(ScopeRelationship.SCOPE, ((RoleAdapter)role).getRole());
List<ScopeRelationship> grants = query.getResultList();
for (ScopeRelationship grant : grants) {
getRelationshipManager().remove(grant);
}
}
@Override @Override
public OAuthClientModel addOAuthClient(String name) { public OAuthClientModel addOAuthClient(String name) {
User client = new User(name); User client = new User(name);
@ -699,9 +717,32 @@ public class RealmAdapter implements RealmModel {
return new OAuthClientAdapter(results.get(0), getIdm(), getRelationshipManager()); return new OAuthClientAdapter(results.get(0), getIdm(), getRelationshipManager());
} }
@Override
public List<OAuthClientModel> getOAuthClients() {
RelationshipQuery<OAuthClientRelationship> query = getRelationshipManager().createRelationshipQuery(OAuthClientRelationship.class);
query.setParameter(OAuthClientRelationship.REALM, realm.getName());
List<OAuthClientRelationship> results = query.getResultList();
List<OAuthClientModel> list = new ArrayList<OAuthClientModel>();
for (OAuthClientRelationship rel : results) {
list.add(new OAuthClientAdapter(rel, getIdm(), getRelationshipManager()));
}
return list;
}
@Override @Override
public Set<String> getScopeMapping(UserModel agent) { public List<RoleModel> getScopeMappings(UserModel agent) {
RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
List<ScopeRelationship> scope = query.getResultList();
List<RoleModel> roles = new ArrayList<RoleModel>();
for (ScopeRelationship rel : scope) {
if (rel.getScope().getPartition().getId().equals(realm.getId())) roles.add(new RoleAdapter(rel.getScope(), getIdm()));
}
return roles;
}
@Override
public Set<String> getScopeMappingValues(UserModel agent) {
RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class); RelationshipQuery<ScopeRelationship> query = getRelationshipManager().createRelationshipQuery(ScopeRelationship.class);
query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser()); query.setParameter(ScopeRelationship.CLIENT, ((UserAdapter)agent).getUser());
List<ScopeRelationship> scope = query.getResultList(); List<ScopeRelationship> scope = query.getResultList();

View file

@ -21,6 +21,15 @@ public class ScopeRelationship extends AbstractAttributedType implements Relatio
} }
}; };
public static final RelationshipQueryParameter SCOPE = new RelationshipQueryParameter() {
@Override
public String getName() {
return "scope";
}
};
protected User client; protected User client;
protected Role scope; protected Role scope;

View file

@ -42,7 +42,7 @@ public class ApplicationManager {
} }
} }
if (resourceRep.getRoleMappings() != null) { if (resourceRep.getRoleMappings() != null) {
for (RoleMappingRepresentation mapping : resourceRep.getRoleMappings()) { for (UserRoleMappingRepresentation mapping : resourceRep.getRoleMappings()) {
UserModel user = realm.getUser(mapping.getUsername()); UserModel user = realm.getUser(mapping.getUsername());
for (String roleString : mapping.getRoles()) { for (String roleString : mapping.getRoles()) {
RoleModel role = applicationModel.getRole(roleString.trim()); RoleModel role = applicationModel.getRole(roleString.trim());

View file

@ -3,6 +3,7 @@ package org.keycloak.services.managers;
import org.keycloak.models.OAuthClientModel; import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.representations.idm.OAuthClientRepresentation;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -15,10 +16,30 @@ public class OAuthClientManager {
this.realm = realm; this.realm = realm;
} }
public OAuthClientModel createOAuthClient(String name) { public OAuthClientModel create(String name) {
OAuthClientModel model = realm.addOAuthClient(name); OAuthClientModel model = realm.addOAuthClient(name);
RoleModel role = realm.getRole(RealmManager.IDENTITY_REQUESTER_ROLE); RoleModel role = realm.getRole(RealmManager.IDENTITY_REQUESTER_ROLE);
realm.grantRole(model.getOAuthAgent(), role); realm.grantRole(model.getOAuthAgent(), role);
return model; return model;
} }
public OAuthClientModel create(OAuthClientRepresentation rep) {
OAuthClientModel model = create(rep.getName());
model.setBaseUrl(rep.getBaseUrl());
model.getOAuthAgent().setEnabled(rep.isEnabled());
return model;
}
public void update(OAuthClientRepresentation rep, OAuthClientModel model) {
model.setBaseUrl(rep.getBaseUrl());
}
public static OAuthClientRepresentation toRepresentation(OAuthClientModel model) {
OAuthClientRepresentation rep = new OAuthClientRepresentation();
rep.setId(model.getId());
rep.setBaseUrl(model.getBaseUrl());
rep.setName(model.getOAuthAgent().getLoginName());
rep.setEnabled(model.getOAuthAgent().isEnabled());
return rep;
}
} }

View file

@ -183,7 +183,7 @@ public class RealmManager {
} }
if (rep.getRoleMappings() != null) { if (rep.getRoleMappings() != null) {
for (RoleMappingRepresentation mapping : rep.getRoleMappings()) { for (UserRoleMappingRepresentation mapping : rep.getRoleMappings()) {
UserModel user = userMap.get(mapping.getUsername()); UserModel user = userMap.get(mapping.getUsername());
for (String roleString : mapping.getRoles()) { for (String roleString : mapping.getRoles()) {
RoleModel role = newRealm.getRole(roleString.trim()); RoleModel role = newRealm.getRole(roleString.trim());

View file

@ -50,7 +50,7 @@ public class TokenManager {
Set<String> realmMapping = realm.getRoleMappingValues(user); Set<String> realmMapping = realm.getRoleMappingValues(user);
if (realmMapping != null && realmMapping.size() > 0 && (scopeMap == null || scopeMap.containsKey("realm"))) { if (realmMapping != null && realmMapping.size() > 0 && (scopeMap == null || scopeMap.containsKey("realm"))) {
Set<String> scope = realm.getScopeMapping(client); Set<String> scope = realm.getScopeMappingValues(client);
if (scope.size() > 0) { if (scope.size() > 0) {
Set<String> scopeRequest = null; Set<String> scopeRequest = null;
if (scopeMap != null) { if (scopeMap != null) {
@ -69,7 +69,7 @@ public class TokenManager {
for (ApplicationModel resource : realm.getApplications()) { for (ApplicationModel resource : realm.getApplications()) {
Set<String> mapping = resource.getRoleMappingValues(user); Set<String> mapping = resource.getRoleMappingValues(user);
if (mapping != null && mapping.size() > 0 && (scopeMap == null || scopeMap.containsKey(resource.getName()))) { if (mapping != null && mapping.size() > 0 && (scopeMap == null || scopeMap.containsKey(resource.getName()))) {
Set<String> scope = resource.getScopeMapping(client); Set<String> scope = resource.getScopeMappingValues(client);
if (scope.size() > 0) { if (scope.size() > 0) {
Set<String> scopeRequest = null; Set<String> scopeRequest = null;
if (scopeMap != null) { if (scopeMap != null) {

View file

@ -3,9 +3,7 @@ package org.keycloak.services.resources.admin;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.logging.Logger; import org.jboss.resteasy.logging.Logger;
import org.keycloak.models.*; import org.keycloak.models.*;
import org.keycloak.representations.idm.ApplicationRepresentation; import org.keycloak.representations.idm.*;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.services.managers.ApplicationManager; import org.keycloak.services.managers.ApplicationManager;
import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.RealmManager;
@ -15,25 +13,25 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $ * @version $Revision: 1 $
*/ */
public class ApplicationResource { public class ApplicationResource extends RoleContainerResource {
protected static final Logger logger = Logger.getLogger(RealmAdminResource.class); protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
protected UserModel admin;
protected RealmModel realm; protected RealmModel realm;
protected ApplicationModel application; protected ApplicationModel application;
@Context
protected KeycloakSession session; protected KeycloakSession session;
public ApplicationResource(UserModel admin, RealmModel realm, ApplicationModel applicationModel) { public ApplicationResource(RealmModel realm, ApplicationModel applicationModel, KeycloakSession session) {
this.admin = admin; super(applicationModel);
this.realm = realm; this.realm = realm;
this.application = applicationModel; this.application = applicationModel;
this.session = session;
} }
@PUT @PUT
@ -52,59 +50,6 @@ public class ApplicationResource {
return applicationManager.toRepresentation(application); return applicationManager.toRepresentation(application);
} }
@Path("roles")
@GET
@NoCache
@Produces("application/json")
public List<RoleRepresentation> getRoles() {
List<RoleModel> roleModels = application.getRoles();
List<RoleRepresentation> roles = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : roleModels) {
roles.add(RealmManager.toRepresentation(roleModel));
}
return roles;
}
@Path("roles/{id}")
@GET
@NoCache
@Produces("application/json")
public RoleRepresentation getRole(final @PathParam("id") String id) {
RoleModel roleModel = application.getRoleById(id);
if (roleModel == null) {
throw new NotFoundException();
}
return RealmManager.toRepresentation(roleModel);
}
@Path("roles/{id}")
@PUT
@Consumes("application/json")
public void updateRole(final @PathParam("id") String id, final RoleRepresentation rep) {
RoleModel role = application.getRoleById(id);
if (role == null) {
throw new NotFoundException();
}
role.setName(rep.getName());
role.setDescription(rep.getDescription());
}
@Path("roles")
@POST
@Consumes("application/json")
public Response createRole(final @Context UriInfo uriInfo, final RoleRepresentation rep) {
if (application.getRole(rep.getName()) != null) { // no duplicates
throw new InternalServerErrorException(); // todo appropriate status here.
}
RoleModel role = application.addRole(rep.getName());
if (role == null) {
throw new NotFoundException();
}
role.setDescription(rep.getDescription());
return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getId()).build()).build();
}
@Path("credentials") @Path("credentials")
@PUT @PUT
@Consumes("application/json") @Consumes("application/json")
@ -116,7 +61,12 @@ public class ApplicationResource {
UserCredentialModel cred = RealmManager.fromRepresentation(rep); UserCredentialModel cred = RealmManager.fromRepresentation(rep);
realm.updateCredential(application.getApplicationUser(), cred); realm.updateCredential(application.getApplicationUser(), cred);
} }
} }
@Path("scope-mappings")
public ScopeMappedResource getScopeMappedResource() {
return new ScopeMappedResource(realm, application.getApplicationUser(), session);
}
} }

View file

@ -25,7 +25,6 @@ import java.util.List;
*/ */
public class ApplicationsResource { public class ApplicationsResource {
protected static final Logger logger = Logger.getLogger(RealmAdminResource.class); protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
protected UserModel admin;
protected RealmModel realm; protected RealmModel realm;
@Context @Context
@ -34,15 +33,14 @@ public class ApplicationsResource {
@Context @Context
protected KeycloakSession session; protected KeycloakSession session;
public ApplicationsResource(UserModel admin, RealmModel realm) { public ApplicationsResource(RealmModel realm) {
this.admin = admin;
this.realm = realm; this.realm = realm;
} }
@GET @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@NoCache @NoCache
public List<ApplicationRepresentation> getResources() { public List<ApplicationRepresentation> getApplications() {
List<ApplicationRepresentation> rep = new ArrayList<ApplicationRepresentation>(); List<ApplicationRepresentation> rep = new ArrayList<ApplicationRepresentation>();
List<ApplicationModel> applicationModels = realm.getApplications(); List<ApplicationModel> applicationModels = realm.getApplications();
ApplicationManager resourceManager = new ApplicationManager(new RealmManager(session)); ApplicationManager resourceManager = new ApplicationManager(new RealmManager(session));
@ -54,19 +52,19 @@ public class ApplicationsResource {
@POST @POST
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public Response createResource(final @Context UriInfo uriInfo, final ApplicationRepresentation rep) { public Response createApplication(final @Context UriInfo uriInfo, final ApplicationRepresentation rep) {
ApplicationManager resourceManager = new ApplicationManager(new RealmManager(session)); ApplicationManager resourceManager = new ApplicationManager(new RealmManager(session));
ApplicationModel applicationModel = resourceManager.createApplication(realm, rep); ApplicationModel applicationModel = resourceManager.createApplication(realm, rep);
return Response.created(uriInfo.getAbsolutePathBuilder().path(applicationModel.getId()).build()).build(); return Response.created(uriInfo.getAbsolutePathBuilder().path(applicationModel.getId()).build()).build();
} }
@Path("{id}") @Path("{id}")
public ApplicationResource getResource(final @PathParam("id") String id) { public ApplicationResource getApplication(final @PathParam("id") String id) {
ApplicationModel applicationModel = realm.getApplicationById(id); ApplicationModel applicationModel = realm.getApplicationById(id);
if (applicationModel == null) { if (applicationModel == null) {
throw new NotFoundException(); throw new NotFoundException();
} }
ApplicationResource applicationResource = new ApplicationResource(admin, realm, applicationModel); ApplicationResource applicationResource = new ApplicationResource(realm, applicationModel, session);
resourceContext.initResource(applicationResource); resourceContext.initResource(applicationResource);
return applicationResource; return applicationResource;
} }

View file

@ -0,0 +1,68 @@
package org.keycloak.services.resources.admin;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.logging.Logger;
import org.keycloak.models.*;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.OAuthClientRepresentation;
import org.keycloak.services.managers.ApplicationManager;
import org.keycloak.services.managers.OAuthClientManager;
import org.keycloak.services.managers.RealmManager;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class OAuthClientResource {
protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
protected RealmModel realm;
protected OAuthClientModel oauthClient;
protected KeycloakSession session;
public OAuthClientResource(RealmModel realm, OAuthClientModel oauthClient, KeycloakSession session) {
this.realm = realm;
this.oauthClient = oauthClient;
this.session = session;
}
@PUT
@Consumes(MediaType.APPLICATION_JSON)
public void update(final OAuthClientRepresentation rep) {
OAuthClientManager manager = new OAuthClientManager(realm);
manager.update(rep, oauthClient);
}
@GET
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public OAuthClientRepresentation getApplication() {
OAuthClientManager manager = new OAuthClientManager(realm);
return OAuthClientManager.toRepresentation(oauthClient);
}
@Path("credentials")
@PUT
@Consumes("application/json")
public void updateCredentials(List<CredentialRepresentation> credentials) {
logger.info("updateCredentials");
if (credentials == null) return;
for (CredentialRepresentation rep : credentials) {
UserCredentialModel cred = RealmManager.fromRepresentation(rep);
realm.updateCredential(oauthClient.getOAuthAgent(), cred);
}
}
@Path("scope-mappings")
public ScopeMappedResource getScopeMappedResource() {
return new ScopeMappedResource(realm, oauthClient.getOAuthAgent(), session);
}
}

View file

@ -0,0 +1,69 @@
package org.keycloak.services.resources.admin;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.logging.Logger;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.OAuthClientRepresentation;
import org.keycloak.services.managers.ApplicationManager;
import org.keycloak.services.managers.OAuthClientManager;
import org.keycloak.services.managers.RealmManager;
import javax.ws.rs.*;
import javax.ws.rs.container.ResourceContext;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.util.ArrayList;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class OAuthClientsResource {
protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
protected RealmModel realm;
protected KeycloakSession session;
public OAuthClientsResource(RealmModel realm, KeycloakSession session) {
this.realm = realm;
this.session = session;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public List<OAuthClientRepresentation> getOAuthClients() {
List<OAuthClientRepresentation> rep = new ArrayList<OAuthClientRepresentation>();
List<OAuthClientModel> oauthModels = realm.getOAuthClients();
for (OAuthClientModel oauth : oauthModels) {
rep.add(OAuthClientManager.toRepresentation(oauth));
}
return rep;
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response createOAuthClient(final @Context UriInfo uriInfo, final OAuthClientRepresentation rep) {
OAuthClientManager resourceManager = new OAuthClientManager(realm);
OAuthClientModel oauth = resourceManager.create(rep);
return Response.created(uriInfo.getAbsolutePathBuilder().path(oauth.getOAuthAgent().getLoginName()).build()).build();
}
@Path("{id}")
public OAuthClientResource getOAuthClient(final @PathParam("id") String id) {
OAuthClientModel oauth = realm.getOAuthClient(id);
if (oauth == null) {
throw new NotFoundException();
}
OAuthClientResource oAuthClientResource = new OAuthClientResource(realm, oauth, session);
return oAuthClientResource;
}
}

View file

@ -2,13 +2,10 @@ package org.keycloak.services.resources.admin;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.logging.Logger; import org.jboss.resteasy.logging.Logger;
import org.keycloak.models.*;
import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.RealmManager;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import javax.ws.rs.*; import javax.ws.rs.*;
import javax.ws.rs.container.ResourceContext; import javax.ws.rs.container.ResourceContext;
@ -22,7 +19,7 @@ import java.util.List;
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $ * @version $Revision: 1 $
*/ */
public class RealmAdminResource { public class RealmAdminResource extends RoleContainerResource {
protected static final Logger logger = Logger.getLogger(RealmAdminResource.class); protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
protected UserModel admin; protected UserModel admin;
protected RealmModel realm; protected RealmModel realm;
@ -34,22 +31,29 @@ public class RealmAdminResource {
protected KeycloakSession session; protected KeycloakSession session;
public RealmAdminResource(UserModel admin, RealmModel realm) { public RealmAdminResource(UserModel admin, RealmModel realm) {
super(realm);
this.admin = admin; this.admin = admin;
this.realm = realm; this.realm = realm;
} }
@Path("applications") @Path("applications")
public ApplicationsResource getResources() { public ApplicationsResource getApplications() {
ApplicationsResource applicationsResource = new ApplicationsResource(admin, realm); ApplicationsResource applicationsResource = new ApplicationsResource(realm);
resourceContext.initResource(applicationsResource); resourceContext.initResource(applicationsResource);
return applicationsResource; return applicationsResource;
} }
@Path("oauth-clients")
public OAuthClientsResource getOAuthClients() {
OAuthClientsResource oauth = new OAuthClientsResource(realm, session);
return oauth;
}
@GET @GET
@NoCache @NoCache
@Produces("application/json") @Produces("application/json")
public RealmRepresentation getRealm() { public RealmRepresentation getRealm() {
return new RealmManager(session).toRepresentation(realm); return RealmManager.toRepresentation(realm);
} }
@ -60,62 +64,6 @@ public class RealmAdminResource {
new RealmManager(session).updateRealm(rep, realm); new RealmManager(session).updateRealm(rep, realm);
} }
@Path("roles")
@GET
@NoCache
@Produces("application/json")
public List<RoleRepresentation> getRoles() {
List<RoleModel> roleModels = realm.getRoles();
List<RoleRepresentation> roles = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : roleModels) {
RoleRepresentation role = new RoleRepresentation(roleModel.getName(), roleModel.getDescription());
role.setId(roleModel.getId());
roles.add(role);
}
return roles;
}
@Path("roles/{id}")
@GET
@NoCache
@Produces("application/json")
public RoleRepresentation getRole(final @PathParam("id") String id) {
RoleModel roleModel = realm.getRoleById(id);
if (roleModel == null) {
throw new NotFoundException();
}
RoleRepresentation rep = new RoleRepresentation(roleModel.getName(), roleModel.getDescription());
rep.setId(roleModel.getId());
return rep;
}
@Path("roles/{id}")
@PUT
@Consumes("application/json")
public void updateRole(final @PathParam("id") String id, final RoleRepresentation rep) {
RoleModel role = realm.getRoleById(id);
if (role == null) {
throw new NotFoundException();
}
role.setName(rep.getName());
role.setDescription(rep.getDescription());
}
@Path("roles")
@POST
@Consumes("application/json")
public Response createRole(final @Context UriInfo uriInfo, final RoleRepresentation rep) {
if (realm.getRole(rep.getName()) != null) {
throw new InternalServerErrorException(); // todo appropriate status here.
}
RoleModel role = realm.addRole(rep.getName());
if (role == null) {
throw new NotFoundException();
}
role.setDescription(rep.getDescription());
return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getId()).build()).build();
}
@Path("users") @Path("users")
public UsersResource users() { public UsersResource users() {

View file

@ -0,0 +1,81 @@
package org.keycloak.services.resources.admin;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.representations.idm.RoleRepresentation;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.util.ArrayList;
import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class RoleContainerResource {
protected RoleContainerModel roleContainer;
public RoleContainerResource(RoleContainerModel roleContainer) {
this.roleContainer = roleContainer;
}
@Path("roles")
@GET
@NoCache
@Produces("application/json")
public List<RoleRepresentation> getRoles() {
List<RoleModel> roleModels = roleContainer.getRoles();
List<RoleRepresentation> roles = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : roleModels) {
RoleRepresentation role = new RoleRepresentation(roleModel.getName(), roleModel.getDescription());
role.setId(roleModel.getId());
roles.add(role);
}
return roles;
}
@Path("roles/{id}")
@GET
@NoCache
@Produces("application/json")
public RoleRepresentation getRole(final @PathParam("id") String id) {
RoleModel roleModel = roleContainer.getRoleById(id);
if (roleModel == null) {
throw new NotFoundException();
}
RoleRepresentation rep = new RoleRepresentation(roleModel.getName(), roleModel.getDescription());
rep.setId(roleModel.getId());
return rep;
}
@Path("roles/{id}")
@PUT
@Consumes("application/json")
public void updateRole(final @PathParam("id") String id, final RoleRepresentation rep) {
RoleModel role = roleContainer.getRoleById(id);
if (role == null) {
throw new NotFoundException();
}
role.setName(rep.getName());
role.setDescription(rep.getDescription());
}
@Path("roles")
@POST
@Consumes("application/json")
public Response createRole(final @Context UriInfo uriInfo, final RoleRepresentation rep) {
if (roleContainer.getRole(rep.getName()) != null) {
throw new InternalServerErrorException(); // todo appropriate status here.
}
RoleModel role = roleContainer.addRole(rep.getName());
if (role == null) {
throw new NotFoundException();
}
role.setDescription(rep.getDescription());
return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getId()).build()).build();
}
}

View file

@ -0,0 +1,182 @@
package org.keycloak.services.resources.admin;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.keycloak.models.*;
import org.keycloak.representations.idm.ApplicationMappingsRepresentation;
import org.keycloak.representations.idm.MappingsRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.services.managers.RealmManager;
import javax.ws.rs.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ScopeMappedResource {
protected RealmModel realm;
protected UserModel agent;
protected KeycloakSession session;
public ScopeMappedResource(RealmModel realm, UserModel account, KeycloakSession session) {
this.realm = realm;
this.agent = account;
this.session = session;
}
@GET
@Produces("application/json")
@NoCache
public MappingsRepresentation getScopeMappings() {
MappingsRepresentation all = new MappingsRepresentation();
List<RoleModel> realmMappings = realm.getScopeMappings(agent);
RealmManager manager = new RealmManager(session);
if (realmMappings.size() > 0) {
List<RoleRepresentation> realmRep = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : realmMappings) {
realmRep.add(manager.toRepresentation(roleModel));
}
all.setRealmMappings(realmRep);
}
List<ApplicationModel> applications = realm.getApplications();
if (applications.size() > 0) {
Map<String, ApplicationMappingsRepresentation> appMappings = new HashMap<String, ApplicationMappingsRepresentation>();
for (ApplicationModel app : applications) {
List<RoleModel> roleMappings = app.getScopeMappings(agent);
if (roleMappings.size() > 0) {
ApplicationMappingsRepresentation mappings = new ApplicationMappingsRepresentation();
mappings.setApplicationId(app.getId());
mappings.setApplication(app.getName());
List<RoleRepresentation> roles = new ArrayList<RoleRepresentation>();
mappings.setMappings(roles);
for (RoleModel role : roleMappings) {
roles.add(manager.toRepresentation(role));
}
appMappings.put(app.getName(), mappings);
all.setApplicationMappings(appMappings);
}
}
}
return all;
}
@Path("realm")
@GET
@Produces("application/json")
@NoCache
public List<RoleRepresentation> getRealmScopeMappings() {
List<RoleModel> realmMappings = realm.getScopeMappings(agent);
List<RoleRepresentation> realmMappingsRep = new ArrayList<RoleRepresentation>();
RealmManager manager = new RealmManager(session);
for (RoleModel roleModel : realmMappings) {
realmMappingsRep.add(manager.toRepresentation(roleModel));
}
return realmMappingsRep;
}
@Path("realm")
@POST
@Consumes("application/json")
public void addRealmScopeMappings(List<RoleRepresentation> roles) {
for (RoleRepresentation role : roles) {
RoleModel roleModel = realm.getRoleById(role.getId());
if (roleModel == null) {
throw new NotFoundException();
}
realm.addScopeMapping(agent, roleModel);
}
}
@Path("realm")
@DELETE
@Consumes("application/json")
public void deleteRealmScopeMappings(List<RoleRepresentation> roles) {
if (roles == null) {
List<RoleModel> roleModels = realm.getScopeMappings(agent);
for (RoleModel roleModel : roleModels) {
realm.deleteScopeMapping(agent, roleModel);
}
} else {
for (RoleRepresentation role : roles) {
RoleModel roleModel = realm.getRoleById(role.getId());
if (roleModel == null) {
throw new NotFoundException();
}
realm.deleteScopeMapping(agent, roleModel);
}
}
}
@Path("applications/{appId}")
@GET
@Produces("application/json")
@NoCache
public List<RoleRepresentation> getApplicationScopeMappings(@PathParam("appId") String appId) {
ApplicationModel app = realm.getApplicationById(appId);
if (app == null) {
throw new NotFoundException();
}
List<RoleModel> mappings = app.getScopeMappings(agent);
List<RoleRepresentation> mapRep = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : mappings) {
mapRep.add(RealmManager.toRepresentation(roleModel));
}
return mapRep;
}
@Path("applications/{appId}")
@POST
@Consumes("application/json")
public void addApplicationScopeMapping(@PathParam("appId") String appId, List<RoleRepresentation> roles) {
ApplicationModel app = realm.getApplicationById(appId);
if (app == null) {
throw new NotFoundException();
}
for (RoleRepresentation role : roles) {
RoleModel roleModel = app.getRoleById(role.getId());
if (roleModel == null) {
throw new NotFoundException();
}
app.addScopeMapping(agent, roleModel);
}
}
@Path("applications/{appId}")
@DELETE
@Consumes("application/json")
public void deleteApplicationRoleMapping(@PathParam("appId") String appId, List<RoleRepresentation> roles) {
ApplicationModel app = realm.getApplicationById(appId);
if (app == null) {
throw new NotFoundException();
}
if (roles == null) {
List<RoleModel> roleModels = app.getScopeMappings(agent);
for (RoleModel roleModel : roleModels) {
app.deleteScopeMapping(agent, roleModel);
}
} else {
for (RoleRepresentation role : roles) {
RoleModel roleModel = app.getRoleById(role.getId());
if (roleModel == null) {
throw new NotFoundException();
}
app.deleteScopeMapping(agent, roleModel);
}
}
}}

View file

@ -127,16 +127,13 @@ public class UsersResource {
@GET @GET
@Produces("application/json") @Produces("application/json")
@NoCache @NoCache
public AllRoleMappingsRepresentation getRoleMappings(@PathParam("username") String username) { public MappingsRepresentation getRoleMappings(@PathParam("username") String username) {
UserModel user = realm.getUser(username); UserModel user = realm.getUser(username);
if (user == null) { if (user == null) {
throw new NotFoundException(); throw new NotFoundException();
} }
AllRoleMappingsRepresentation all = new AllRoleMappingsRepresentation(); MappingsRepresentation all = new MappingsRepresentation();
all.setRealmId(realm.getId());
all.setRealmName(realm.getName());
all.setUsername(username);
List<RoleModel> realmMappings = realm.getRoleMappings(user); List<RoleModel> realmMappings = realm.getRoleMappings(user);
RealmManager manager = new RealmManager(session); RealmManager manager = new RealmManager(session);
if (realmMappings.size() > 0) { if (realmMappings.size() > 0) {
@ -149,12 +146,11 @@ public class UsersResource {
List<ApplicationModel> applications = realm.getApplications(); List<ApplicationModel> applications = realm.getApplications();
if (applications.size() > 0) { if (applications.size() > 0) {
Map<String, ApplicationRoleMappingsRepresentation> appMappings = new HashMap<String, ApplicationRoleMappingsRepresentation>(); Map<String, ApplicationMappingsRepresentation> appMappings = new HashMap<String, ApplicationMappingsRepresentation>();
for (ApplicationModel application : applications) { for (ApplicationModel application : applications) {
List<RoleModel> roleMappings = application.getRoleMappings(user); List<RoleModel> roleMappings = application.getRoleMappings(user);
if (roleMappings.size() > 0) { if (roleMappings.size() > 0) {
ApplicationRoleMappingsRepresentation mappings = new ApplicationRoleMappingsRepresentation(); ApplicationMappingsRepresentation mappings = new ApplicationMappingsRepresentation();
mappings.setUsername(user.getLoginName());
mappings.setApplicationId(application.getId()); mappings.setApplicationId(application.getId());
mappings.setApplication(application.getName()); mappings.setApplication(application.getName());
List<RoleRepresentation> roles = new ArrayList<RoleRepresentation>(); List<RoleRepresentation> roles = new ArrayList<RoleRepresentation>();
@ -180,7 +176,6 @@ public class UsersResource {
throw new NotFoundException(); throw new NotFoundException();
} }
RealmRoleMappingsRepresentation rep = new RealmRoleMappingsRepresentation();
List<RoleModel> realmMappings = realm.getRoleMappings(user); List<RoleModel> realmMappings = realm.getRoleMappings(user);
List<RoleRepresentation> realmMappingsRep = new ArrayList<RoleRepresentation>(); List<RoleRepresentation> realmMappingsRep = new ArrayList<RoleRepresentation>();
RealmManager manager = new RealmManager(session); RealmManager manager = new RealmManager(session);

View file

@ -134,7 +134,7 @@ public class AdapterTest {
public void testOAuthClient() throws Exception { public void testOAuthClient() throws Exception {
test1CreateRealm(); test1CreateRealm();
OAuthClientModel oauth = new OAuthClientManager(realmModel).createOAuthClient("oauth-client"); OAuthClientModel oauth = new OAuthClientManager(realmModel).create("oauth-client");
oauth.setBaseUrl("/foo/bar"); oauth.setBaseUrl("/foo/bar");
oauth = realmModel.getOAuthClient("oauth-client"); oauth = realmModel.getOAuthClient("oauth-client");
Assert.assertEquals("/foo/bar", oauth.getBaseUrl()); Assert.assertEquals("/foo/bar", oauth.getBaseUrl());

View file

@ -86,7 +86,7 @@ public class ImportTest {
UserModel user = realm.getUser("loginclient"); UserModel user = realm.getUser("loginclient");
Assert.assertNotNull(user); Assert.assertNotNull(user);
Set<String> scopes = realm.getScopeMapping(user); Set<String> scopes = realm.getScopeMappingValues(user);
System.out.println("Scopes size: " + scopes.size()); System.out.println("Scopes size: " + scopes.size());
Assert.assertTrue(scopes.contains("*")); Assert.assertTrue(scopes.contains("*"));
Assert.assertEquals(0, realm.getSocialLinks(user).size()); Assert.assertEquals(0, realm.getSocialLinks(user).size());
@ -101,7 +101,7 @@ public class ImportTest {
UserModel oauthClient = realm.getUser("oauthclient"); UserModel oauthClient = realm.getUser("oauthclient");
Assert.assertNotNull(application); Assert.assertNotNull(application);
Assert.assertNotNull(oauthClient); Assert.assertNotNull(oauthClient);
Set<String> appScopes = application.getScopeMapping(oauthClient); Set<String> appScopes = application.getScopeMappingValues(oauthClient);
Assert.assertTrue(appScopes.contains("user")); Assert.assertTrue(appScopes.contains("user"));
// Test social linking // Test social linking

View file

@ -37,11 +37,13 @@
<artifactId>keycloak-services</artifactId> <artifactId>keycloak-services</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<!--
<dependency> <dependency>
<groupId>org.keycloak</groupId> <groupId>org.keycloak</groupId>
<artifactId>keycloak-server</artifactId> <artifactId>keycloak-server</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
-->
<dependency> <dependency>
<groupId>org.keycloak</groupId> <groupId>org.keycloak</groupId>
<artifactId>keycloak-social-core</artifactId> <artifactId>keycloak-social-core</artifactId>