remove scope
This commit is contained in:
parent
94528976d4
commit
a994af9010
33 changed files with 612 additions and 188 deletions
|
@ -31,12 +31,15 @@ import org.keycloak.models.ClientModel;
|
|||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.protocol.oidc.utils.AuthorizeClientUtil;
|
||||
import org.keycloak.representations.JsonWebToken;
|
||||
import org.keycloak.services.ErrorResponseException;
|
||||
import org.keycloak.services.clientregistration.policy.RegistrationAuth;
|
||||
import org.keycloak.services.clientregistration.policy.ClientRegistrationPolicyException;
|
||||
import org.keycloak.services.clientregistration.policy.ClientRegistrationPolicyManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.util.TokenUtil;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
@ -231,44 +234,72 @@ public class ClientRegistrationAuth {
|
|||
return initialAccessModel;
|
||||
}
|
||||
|
||||
private boolean hasRole(String... role) {
|
||||
private boolean hasRole(String... roles) {
|
||||
try {
|
||||
Map<String, Object> otherClaims = jwt.getOtherClaims();
|
||||
if (otherClaims != null) {
|
||||
Map<String, Map<String, List<String>>> resourceAccess = (Map<String, Map<String, List<String>>>) jwt.getOtherClaims().get("resource_access");
|
||||
if (resourceAccess == null) {
|
||||
return false;
|
||||
}
|
||||
if (jwt.getIssuedFor().equals(Constants.ADMIN_CLI_CLIENT_ID)
|
||||
|| jwt.getIssuedFor().equals(Constants.ADMIN_CONSOLE_CLIENT_ID)) {
|
||||
return hasRoleInModel(roles);
|
||||
|
||||
List<String> roles = null;
|
||||
|
||||
Map<String, List<String>> map;
|
||||
if (realm.getName().equals(Config.getAdminRealm())) {
|
||||
map = resourceAccess.get(realm.getMasterAdminClient().getClientId());
|
||||
} else {
|
||||
map = resourceAccess.get(Constants.REALM_MANAGEMENT_CLIENT_ID);
|
||||
}
|
||||
|
||||
if (map != null) {
|
||||
roles = map.get("roles");
|
||||
}
|
||||
|
||||
if (roles == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String r : role) {
|
||||
if (roles.contains(r)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return hasRoleInToken(roles);
|
||||
}
|
||||
return false;
|
||||
} catch (Throwable t) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasRoleInModel(String[] roles) {
|
||||
ClientModel roleNamespace;
|
||||
UserModel user = session.users().getUserById(jwt.getSubject(), realm);
|
||||
if (user == null) {
|
||||
return false;
|
||||
}
|
||||
if (realm.getName().equals(Config.getAdminRealm())) {
|
||||
roleNamespace = realm.getMasterAdminClient();
|
||||
} else {
|
||||
roleNamespace = realm.getClientByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID);
|
||||
}
|
||||
for (String role : roles) {
|
||||
RoleModel roleModel = roleNamespace.getRole(role);
|
||||
if (user.hasRole(roleModel)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasRoleInToken(String[] role) {
|
||||
Map<String, Object> otherClaims = jwt.getOtherClaims();
|
||||
if (otherClaims != null) {
|
||||
Map<String, Map<String, List<String>>> resourceAccess = (Map<String, Map<String, List<String>>>) jwt.getOtherClaims().get("resource_access");
|
||||
if (resourceAccess == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<String> roles = null;
|
||||
|
||||
Map<String, List<String>> map;
|
||||
if (realm.getName().equals(Config.getAdminRealm())) {
|
||||
map = resourceAccess.get(realm.getMasterAdminClient().getClientId());
|
||||
} else {
|
||||
map = resourceAccess.get(Constants.REALM_MANAGEMENT_CLIENT_ID);
|
||||
}
|
||||
|
||||
if (map != null) {
|
||||
roles = map.get("roles");
|
||||
}
|
||||
|
||||
if (roles == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String r : role) {
|
||||
if (roles.contains(r)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean authenticateClient(ClientModel client) {
|
||||
if (client == null) {
|
||||
return false;
|
||||
|
|
|
@ -159,7 +159,6 @@ public class RealmManager {
|
|||
ClientModel realmAdminApp = realm.getClientByClientId(realmAdminApplicationClientId);
|
||||
adminRole = realmAdminApp.getRole(AdminRoles.REALM_ADMIN);
|
||||
}
|
||||
adminConsole.addScopeMapping(adminRole);
|
||||
}
|
||||
|
||||
protected void setupAdminConsoleLocaleMapper(RealmModel realm) {
|
||||
|
@ -194,7 +193,6 @@ public class RealmManager {
|
|||
ClientModel realmAdminApp = realm.getClientByClientId(realmAdminApplicationClientId);
|
||||
adminRole = realmAdminApp.getRole(AdminRoles.REALM_ADMIN);
|
||||
}
|
||||
adminCli.addScopeMapping(adminRole);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -834,7 +834,7 @@ public class AuthenticationManagementResource {
|
|||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@NoCache
|
||||
public List<RequiredActionProviderRepresentation> getRequiredActions() {
|
||||
auth.realm().requireViewRealm();
|
||||
auth.requireAnyAdminRole();
|
||||
|
||||
List<RequiredActionProviderRepresentation> list = new LinkedList<>();
|
||||
for (RequiredActionProviderModel model : realm.getRequiredActionProviders()) {
|
||||
|
|
|
@ -140,7 +140,7 @@ public class ClientRoleMappingsResource {
|
|||
|
||||
Set<RoleModel> available = client.getRoles();
|
||||
available = available.stream().filter(r ->
|
||||
canMapRole(r)
|
||||
auth.roles().canMapRole(r)
|
||||
).collect(Collectors.toSet());
|
||||
return getAvailableRoles(user, available);
|
||||
}
|
||||
|
@ -174,23 +174,13 @@ public class ClientRoleMappingsResource {
|
|||
if (roleModel == null || !roleModel.getId().equals(role.getId())) {
|
||||
throw new NotFoundException("Role not found");
|
||||
}
|
||||
checkMapRolePermission(roleModel);
|
||||
auth.roles().requireMapRole(roleModel);
|
||||
user.grantRole(roleModel);
|
||||
}
|
||||
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(roles).success();
|
||||
|
||||
}
|
||||
|
||||
private void checkMapRolePermission(RoleModel roleModel) {
|
||||
if (!canMapRole(roleModel)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canMapRole(RoleModel roleModel) {
|
||||
return auth.roles().canMapRole(roleModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete client-level roles from user role mapping
|
||||
*
|
||||
|
@ -210,7 +200,7 @@ public class ClientRoleMappingsResource {
|
|||
ClientModel client = (ClientModel) roleModel.getContainer();
|
||||
if (!client.getId().equals(this.client.getId())) continue;
|
||||
}
|
||||
checkMapRolePermission(roleModel);
|
||||
auth.roles().requireMapRole(roleModel);
|
||||
user.deleteRoleMapping(roleModel);
|
||||
roles.add(ModelToRepresentation.toRepresentation(roleModel));
|
||||
}
|
||||
|
@ -222,7 +212,7 @@ public class ClientRoleMappingsResource {
|
|||
throw new NotFoundException("Role not found");
|
||||
}
|
||||
|
||||
checkMapRolePermission(roleModel);
|
||||
auth.roles().requireMapRole(roleModel);
|
||||
try {
|
||||
user.deleteRoleMapping(roleModel);
|
||||
} catch (ModelException me) {
|
||||
|
|
|
@ -76,13 +76,20 @@ public class ClientTemplatesResource {
|
|||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@NoCache
|
||||
public List<ClientTemplateRepresentation> getClientTemplates() {
|
||||
auth.clients().requireView();
|
||||
auth.clients().requireListTemplates();
|
||||
|
||||
List<ClientTemplateRepresentation> rep = new ArrayList<>();
|
||||
List<ClientTemplateModel> clientModels = realm.getClientTemplates();
|
||||
|
||||
boolean viewable = auth.clients().canViewTemplates();
|
||||
for (ClientTemplateModel clientModel : clientModels) {
|
||||
rep.add(ModelToRepresentation.toRepresentation(clientModel));
|
||||
if (viewable) rep.add(ModelToRepresentation.toRepresentation(clientModel));
|
||||
else {
|
||||
ClientTemplateRepresentation tempRep = new ClientTemplateRepresentation();
|
||||
tempRep.setName(clientModel.getName());
|
||||
tempRep.setId(clientModel.getId());
|
||||
tempRep.setProtocol(clientModel.getProtocol());
|
||||
}
|
||||
}
|
||||
return rep;
|
||||
}
|
||||
|
|
|
@ -96,18 +96,11 @@ public class RealmsAdminResource {
|
|||
@NoCache
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public List<RealmRepresentation> getRealms() {
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
List<RealmRepresentation> reps = new ArrayList<RealmRepresentation>();
|
||||
if (auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
|
||||
List<RealmModel> realms = session.realms().getRealms();
|
||||
for (RealmModel realm : realms) {
|
||||
addRealmRep(reps, realm, realm.getMasterAdminClient());
|
||||
}
|
||||
} else {
|
||||
ClientModel adminApp = auth.getRealm().getClientByClientId(realmManager.getRealmAdminClientId(auth.getRealm()));
|
||||
addRealmRep(reps, auth.getRealm(), adminApp);
|
||||
List<RealmModel> realms = session.realms().getRealms();
|
||||
for (RealmModel realm : realms) {
|
||||
addRealmRep(reps, realm);
|
||||
}
|
||||
|
||||
if (reps.isEmpty()) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
@ -116,10 +109,10 @@ public class RealmsAdminResource {
|
|||
return reps;
|
||||
}
|
||||
|
||||
protected void addRealmRep(List<RealmRepresentation> reps, RealmModel realm, ClientModel realmManagementClient) {
|
||||
if (auth.hasAppRole(realmManagementClient, AdminRoles.VIEW_REALM)) {
|
||||
protected void addRealmRep(List<RealmRepresentation> reps, RealmModel realm) {
|
||||
if (AdminPermissions.realms(session, auth).canView(realm)) {
|
||||
reps.add(ModelToRepresentation.toRepresentation(realm, false));
|
||||
} else if (auth.hasOneOfAppRole(realmManagementClient, AdminRoles.ALL_REALM_ROLES)) {
|
||||
} else if (AdminPermissions.realms(session, auth).isAdmin(realm)) {
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setRealm(realm.getName());
|
||||
reps.add(rep);
|
||||
|
@ -140,12 +133,7 @@ public class RealmsAdminResource {
|
|||
public Response importRealm(@Context final UriInfo uriInfo, final RealmRepresentation rep) {
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
realmManager.setContextPath(keycloak.getContextPath());
|
||||
if (!auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
if (!auth.hasRealmRole(AdminRoles.CREATE_REALM)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
AdminPermissions.realms(session, auth).requireCreateRealm();
|
||||
|
||||
logger.debugv("importRealm: {0}", rep.getRealm());
|
||||
|
||||
|
|
|
@ -232,7 +232,7 @@ public class RoleMapperResource {
|
|||
if (roleModel == null || !roleModel.getId().equals(role.getId())) {
|
||||
throw new NotFoundException("Role not found");
|
||||
}
|
||||
checkMapRolePermission(roleModel);
|
||||
auth.roles().requireMapRole(roleModel);
|
||||
roleMapper.grantRole(roleModel);
|
||||
}
|
||||
|
||||
|
@ -256,7 +256,7 @@ public class RoleMapperResource {
|
|||
roles = new LinkedList<>();
|
||||
|
||||
for (RoleModel roleModel : roleModels) {
|
||||
checkMapRolePermission(roleModel);
|
||||
auth.roles().requireMapRole(roleModel);
|
||||
roleMapper.deleteRoleMapping(roleModel);
|
||||
roles.add(ModelToRepresentation.toRepresentation(roleModel));
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ public class RoleMapperResource {
|
|||
if (roleModel == null || !roleModel.getId().equals(role.getId())) {
|
||||
throw new NotFoundException("Role not found");
|
||||
}
|
||||
checkMapRolePermission(roleModel);
|
||||
auth.roles().requireMapRole(roleModel);
|
||||
try {
|
||||
roleMapper.deleteRoleMapping(roleModel);
|
||||
} catch (ModelException me) {
|
||||
|
@ -283,12 +283,6 @@ public class RoleMapperResource {
|
|||
|
||||
}
|
||||
|
||||
private void checkMapRolePermission(RoleModel roleModel) {
|
||||
if (!canMapRole(roleModel)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canMapRole(RoleModel roleModel) {
|
||||
return auth.roles().canMapRole(roleModel);
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ public abstract class RoleResource {
|
|||
if (composite == null) {
|
||||
throw new NotFoundException("Could not find composite role");
|
||||
}
|
||||
auth.roles().requireManage(composite);
|
||||
auth.roles().requireMapComposite(composite);
|
||||
role.addCompositeRole(composite);
|
||||
}
|
||||
|
||||
|
|
|
@ -534,7 +534,7 @@ public class UserResource {
|
|||
|
||||
@Path("role-mappings")
|
||||
public RoleMapperResource getRoleMappings() {
|
||||
AdminPermissionEvaluator.RequirePermissionCheck manageCheck = () -> auth.users().requireManage(user);
|
||||
AdminPermissionEvaluator.RequirePermissionCheck manageCheck = () -> auth.users().requireMapRoles(user);
|
||||
AdminPermissionEvaluator.RequirePermissionCheck viewCheck = () -> auth.users().requireView(user);
|
||||
RoleMapperResource resource = new RoleMapperResource(realm, auth, user, adminEvent, manageCheck, viewCheck);
|
||||
ResteasyProviderFactory.getInstance().injectProperties(resource);
|
||||
|
@ -756,13 +756,13 @@ public class UserResource {
|
|||
@Path("groups/{groupId}")
|
||||
@NoCache
|
||||
public void removeMembership(@PathParam("groupId") String groupId) {
|
||||
auth.users().requireManage(user);
|
||||
auth.users().requireManageGroupMembership(user);
|
||||
|
||||
GroupModel group = session.realms().getGroupById(groupId, realm);
|
||||
if (group == null) {
|
||||
throw new NotFoundException("Group not found");
|
||||
}
|
||||
auth.groups().requireManageMembers(group);
|
||||
auth.groups().requireManageMembership(group);
|
||||
|
||||
try {
|
||||
if (user.isMemberOf(group)){
|
||||
|
@ -780,12 +780,12 @@ public class UserResource {
|
|||
@Path("groups/{groupId}")
|
||||
@NoCache
|
||||
public void joinGroup(@PathParam("groupId") String groupId) {
|
||||
auth.users().requireManage(user);
|
||||
auth.users().requireManageGroupMembership(user);
|
||||
GroupModel group = session.realms().getGroupById(groupId, realm);
|
||||
if (group == null) {
|
||||
throw new NotFoundException("Group not found");
|
||||
}
|
||||
//auth.groups().requireManageMembers(group);
|
||||
auth.groups().requireManageMembership(group);
|
||||
if (!user.isMemberOf(group)){
|
||||
user.joinGroup(group);
|
||||
adminEvent.operation(OperationType.CREATE).resource(ResourceType.GROUP_MEMBERSHIP).representation(ModelToRepresentation.toRepresentation(group, true)).resourcePath(uriInfo).success();
|
||||
|
|
|
@ -25,6 +25,8 @@ import org.keycloak.services.resources.admin.AdminAuth;
|
|||
public interface AdminPermissionEvaluator {
|
||||
RealmPermissionEvaluator realm();
|
||||
|
||||
void requireAnyAdminRole();
|
||||
|
||||
AdminAuth adminAuth();
|
||||
|
||||
RolePermissionEvaluator roles();
|
||||
|
|
|
@ -35,6 +35,10 @@ public class AdminPermissions {
|
|||
return new MgmtPermissions(session, realm, adminsRealm, admin);
|
||||
}
|
||||
|
||||
public static RealmsPermissionEvaluator realms(KeycloakSession session, AdminAuth auth) {
|
||||
return new MgmtPermissions(session, auth);
|
||||
}
|
||||
|
||||
public static AdminPermissionManagement management(KeycloakSession session, RealmModel realm) {
|
||||
return new MgmtPermissions(session, realm);
|
||||
}
|
||||
|
|
|
@ -115,16 +115,12 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
|
|||
String managePermissionName = getManagePermissionName(client);
|
||||
Policy managePermission = authz.getStoreFactory().getPolicyStore().findByName(managePermissionName, server.getId());
|
||||
if (managePermission == null) {
|
||||
RoleModel role = root.getRealmManagementClient().getRole(AdminRoles.MANAGE_CLIENTS);
|
||||
Policy manageClientsPolicy = root.roles().rolePolicy(server, role);
|
||||
Helper.addScopePermission(authz, server, managePermissionName, resource, manageScope, manageClientsPolicy);
|
||||
Helper.addEmptyScopePermission(authz, server, managePermissionName, resource, manageScope);
|
||||
}
|
||||
String viewPermissionName = getViewPermissionName(client);
|
||||
Policy viewPermission = authz.getStoreFactory().getPolicyStore().findByName(viewPermissionName, server.getId());
|
||||
if (viewPermission == null) {
|
||||
RoleModel role = root.getRealmManagementClient().getRole(AdminRoles.VIEW_CLIENTS);
|
||||
Policy viewClientsPolicy = root.roles().rolePolicy(server, role);
|
||||
Helper.addScopePermission(authz, server, viewPermissionName, resource, viewScope, viewClientsPolicy);
|
||||
Helper.addEmptyScopePermission(authz, server, viewPermissionName, resource, viewScope);
|
||||
}
|
||||
String mapRolePermissionName = getMapRolesPermissionName(client);
|
||||
Policy mapRolePermission = authz.getStoreFactory().getPolicyStore().findByName(mapRolePermissionName, server.getId());
|
||||
|
@ -216,7 +212,7 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
|
|||
throw new ForbiddenException();
|
||||
}
|
||||
}
|
||||
public boolean canManageClientDefault() {
|
||||
public boolean canManageClientsDefault() {
|
||||
return root.hasOneAdminRole(AdminRoles.MANAGE_CLIENTS);
|
||||
}
|
||||
public boolean canViewClientDefault() {
|
||||
|
@ -225,7 +221,7 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
|
|||
|
||||
@Override
|
||||
public boolean canManage() {
|
||||
return canManageClientDefault();
|
||||
return canManageClientsDefault();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -236,7 +232,7 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
|
|||
}
|
||||
@Override
|
||||
public boolean canView() {
|
||||
return canManageClientDefault() || canViewClientDefault();
|
||||
return canManageClientsDefault() || canViewClientDefault();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -269,25 +265,26 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
|
|||
|
||||
@Override
|
||||
public boolean canManage(ClientModel client) {
|
||||
if (canManageClientsDefault()) return true;
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return canManage();
|
||||
return false;
|
||||
}
|
||||
|
||||
ResourceServer server = resourceServer(client);
|
||||
if (server == null) return canManage();
|
||||
if (server == null) return false;
|
||||
|
||||
Resource resource = authz.getStoreFactory().getResourceStore().findByName(getResourceName(client), server.getId());
|
||||
if (resource == null) return canManage();
|
||||
if (resource == null) return false;
|
||||
|
||||
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getManagePermissionName(client), server.getId());
|
||||
if (policy == null) {
|
||||
return canManage();
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
|
||||
// if no policies attached to permission then just do default behavior
|
||||
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
|
||||
return canManage();
|
||||
return false;
|
||||
}
|
||||
|
||||
Scope scope = manageScope(server);
|
||||
|
@ -303,25 +300,30 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
|
|||
|
||||
@Override
|
||||
public boolean canView(ClientModel client) {
|
||||
return hasView(client) || canManage(client);
|
||||
}
|
||||
|
||||
private boolean hasView(ClientModel client) {
|
||||
if (canView()) return true;
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return canView();
|
||||
return false;
|
||||
}
|
||||
|
||||
ResourceServer server = resourceServer(client);
|
||||
if (server == null) return canView();
|
||||
if (server == null) return false;
|
||||
|
||||
Resource resource = authz.getStoreFactory().getResourceStore().findByName(getResourceName(client), server.getId());
|
||||
if (resource == null) return canView();
|
||||
if (resource == null) return false;
|
||||
|
||||
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getViewPermissionName(client), server.getId());
|
||||
if (policy == null) {
|
||||
return canView();
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
|
||||
// if no policies attached to permission then just do default behavior
|
||||
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
|
||||
return canView();
|
||||
return false;
|
||||
}
|
||||
|
||||
Scope scope = viewScope(server);
|
||||
|
@ -344,7 +346,7 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
|
|||
|
||||
@Override
|
||||
public boolean canManageTemplates() {
|
||||
return canManageClientDefault();
|
||||
return canManageClientsDefault();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -362,7 +364,7 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionMa
|
|||
|
||||
@Override
|
||||
public boolean canManage(ClientTemplateModel template) {
|
||||
return canManageClientDefault();
|
||||
return canManageClientsDefault();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -53,5 +53,9 @@ public interface GroupPermissionEvaluator {
|
|||
|
||||
void requireManageMembers(GroupModel group);
|
||||
|
||||
boolean canManageMembership(GroupModel group);
|
||||
|
||||
void requireManageMembership(GroupModel group);
|
||||
|
||||
Map<String, Boolean> getAccess(GroupModel group);
|
||||
}
|
||||
|
|
|
@ -33,10 +33,14 @@ public interface GroupPermissionManagement {
|
|||
|
||||
Policy viewMembersPermission(GroupModel group);
|
||||
Policy manageMembersPermission(GroupModel group);
|
||||
|
||||
Policy manageMembershipPermission(GroupModel group);
|
||||
|
||||
Policy viewPermission(GroupModel group);
|
||||
Policy managePermission(GroupModel group);
|
||||
|
||||
Resource resource(GroupModel group);
|
||||
|
||||
Map<String, String> getPermissions(GroupModel group);
|
||||
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ import java.util.Set;
|
|||
class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManagement {
|
||||
private static final Logger logger = Logger.getLogger(GroupPermissions.class);
|
||||
public static final String MAP_ROLE_SCOPE = "map-role";
|
||||
public static final String MANAGE_MEMBERSHIP_SCOPE = "manage.membership";
|
||||
public static final String MANAGE_MEMBERS_SCOPE = "manage.members";
|
||||
public static final String VIEW_MEMBERS_SCOPE = "view.members";
|
||||
protected final KeycloakSession session;
|
||||
|
@ -68,6 +69,10 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
|
|||
return "manage.members.permission.group." + group.getId();
|
||||
}
|
||||
|
||||
public static String getManageMembershipPermissionGroup(GroupModel group) {
|
||||
return "manage.membership.permission.group." + group.getId();
|
||||
}
|
||||
|
||||
public static String getGroupSuffix(GroupModel group) {
|
||||
return ModelToRepresentation.buildGroupPath(group).replace('/', '.');
|
||||
}
|
||||
|
@ -88,6 +93,7 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
|
|||
Scope viewScope = root.realmViewScope();
|
||||
Scope manageMembersScope = root.initializeRealmScope(MANAGE_MEMBERS_SCOPE);
|
||||
Scope viewMembersScope = root.initializeRealmScope(VIEW_MEMBERS_SCOPE);
|
||||
Scope manageMembershipScope = root.initializeRealmScope(MANAGE_MEMBERSHIP_SCOPE);
|
||||
|
||||
String groupResourceName = getGroupResourceName(group);
|
||||
Resource groupResource = authz.getStoreFactory().getResourceStore().findByName(groupResourceName, server.getId());
|
||||
|
@ -96,19 +102,19 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
|
|||
Set<Scope> scopeset = new HashSet<>();
|
||||
scopeset.add(manageScope);
|
||||
scopeset.add(viewScope);
|
||||
scopeset.add(manageMembershipScope);
|
||||
scopeset.add(manageMembersScope);
|
||||
groupResource.updateScopes(scopeset);
|
||||
}
|
||||
String managePermissionName = getManagePermissionGroup(group);
|
||||
Policy managePermission = authz.getStoreFactory().getPolicyStore().findByName(managePermissionName, server.getId());
|
||||
if (managePermission == null) {
|
||||
Policy manageUsersPolicy = root.roles().manageUsersPolicy(server);
|
||||
Helper.addScopePermission(authz, server, managePermissionName, groupResource, manageScope, manageUsersPolicy);
|
||||
Helper.addEmptyScopePermission(authz, server, managePermissionName, groupResource, manageScope);
|
||||
}
|
||||
String viewPermissionName = getViewPermissionGroup(group);
|
||||
Policy viewPermission = authz.getStoreFactory().getPolicyStore().findByName(viewPermissionName, server.getId());
|
||||
if (viewPermission == null) {
|
||||
Policy viewUsersPolicy = root.roles().viewUsersPolicy(server);
|
||||
Helper.addScopePermission(authz, server, viewPermissionName, groupResource, viewScope, viewUsersPolicy);
|
||||
Helper.addEmptyScopePermission(authz, server, viewPermissionName, groupResource, viewScope);
|
||||
}
|
||||
String manageMembersPermissionName = getManageMembersPermissionGroup(group);
|
||||
Policy manageMembersPermission = authz.getStoreFactory().getPolicyStore().findByName(manageMembersPermissionName, server.getId());
|
||||
|
@ -120,6 +126,12 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
|
|||
if (viewMembersPermission == null) {
|
||||
Helper.addEmptyScopePermission(authz, server, viewMembersPermissionName, groupResource, viewMembersScope);
|
||||
}
|
||||
String manageMembershipPermissionName = getManageMembershipPermissionGroup(group);
|
||||
Policy manageMembershipPermission = authz.getStoreFactory().getPolicyStore().findByName(manageMembershipPermissionName, server.getId());
|
||||
if (manageMembershipPermission == null) {
|
||||
Helper.addEmptyScopePermission(authz, server, manageMembershipPermissionName, groupResource, manageMembershipScope);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -199,6 +211,14 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
|
|||
return authz.getStoreFactory().getPolicyStore().findByName(manageMembersPermissionName, server.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Policy manageMembershipPermission(GroupModel group) {
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
if (server == null) return null;
|
||||
String manageMembershipPermissionName = getManageMembershipPermissionGroup(group);
|
||||
return authz.getStoreFactory().getPolicyStore().findByName(manageMembershipPermissionName, server.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Policy viewPermission(GroupModel group) {
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
|
@ -231,6 +251,7 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
|
|||
scopes.put(AdminPermissionManagement.MANAGE_SCOPE, managePermission(group).getId());
|
||||
scopes.put(MANAGE_MEMBERS_SCOPE, manageMembersPermission(group).getId());
|
||||
scopes.put(VIEW_MEMBERS_SCOPE, viewMembersPermission(group).getId());
|
||||
scopes.put(MANAGE_MEMBERSHIP_SCOPE, manageMembershipPermission(group).getId());
|
||||
return scopes;
|
||||
}
|
||||
|
||||
|
@ -239,25 +260,26 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
|
|||
|
||||
@Override
|
||||
public boolean canManage(GroupModel group) {
|
||||
if (canManage()) return true;
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return canManage();
|
||||
return false;
|
||||
}
|
||||
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
if (server == null) return canManage();
|
||||
if (server == null) return false;
|
||||
|
||||
Resource resource = authz.getStoreFactory().getResourceStore().findByName(getGroupResourceName(group), server.getId());
|
||||
if (resource == null) return canManage();
|
||||
if (resource == null) return false;
|
||||
|
||||
Policy policy = managePermission(group);
|
||||
if (policy == null) {
|
||||
return canManage();
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
|
||||
// if no policies attached to permission then just do default behavior
|
||||
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
|
||||
return canManage();
|
||||
return false;
|
||||
}
|
||||
|
||||
Scope scope = root.realmManageScope();
|
||||
|
@ -272,25 +294,31 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
|
|||
}
|
||||
@Override
|
||||
public boolean canView(GroupModel group) {
|
||||
return hasView(group) || canManage(group);
|
||||
}
|
||||
|
||||
private boolean hasView(GroupModel group) {
|
||||
if (canView()) return true;
|
||||
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return canView();
|
||||
return false;
|
||||
}
|
||||
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
if (server == null) return canView();
|
||||
if (server == null) return false;
|
||||
|
||||
Resource resource = authz.getStoreFactory().getResourceStore().findByName(getGroupResourceName(group), server.getId());
|
||||
if (resource == null) return canView();
|
||||
if (resource == null) return false;
|
||||
|
||||
Policy policy = viewPermission(group);
|
||||
if (policy == null) {
|
||||
return canView();
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
|
||||
// if no policies attached to permission then abort
|
||||
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
|
||||
return canView();
|
||||
return false;
|
||||
}
|
||||
|
||||
Scope scope = root.realmViewScope();
|
||||
|
@ -335,25 +363,27 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
|
|||
}
|
||||
|
||||
private boolean canViewMembersEvaluation(GroupModel group) {
|
||||
if (root.users().canView()) return true;
|
||||
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return root.users().canView();
|
||||
return false;
|
||||
}
|
||||
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
if (server == null) return root.users().canView();
|
||||
if (server == null) return false;
|
||||
|
||||
Resource resource = authz.getStoreFactory().getResourceStore().findByName(getGroupResourceName(group), server.getId());
|
||||
if (resource == null) return root.users().canView();
|
||||
if (resource == null) return false;
|
||||
|
||||
Policy policy = viewMembersPermission(group);
|
||||
if (policy == null) {
|
||||
return root.users().canView();
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
|
||||
// if no policies attached to permission then just do default behavior
|
||||
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
|
||||
return root.users().canView();
|
||||
return false;
|
||||
}
|
||||
|
||||
Scope scope = authz.getStoreFactory().getScopeStore().findByName(VIEW_MEMBERS_SCOPE, server.getId());
|
||||
|
@ -372,25 +402,27 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
|
|||
|
||||
@Override
|
||||
public boolean canManageMembers(GroupModel group) {
|
||||
if (root.users().canManage()) return true;
|
||||
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return root.users().canManage();
|
||||
return false;
|
||||
}
|
||||
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
if (server == null) return root.users().canManage();
|
||||
if (server == null) return false;
|
||||
|
||||
Resource resource = authz.getStoreFactory().getResourceStore().findByName(getGroupResourceName(group), server.getId());
|
||||
if (resource == null) return root.users().canManage();
|
||||
if (resource == null) return false;
|
||||
|
||||
Policy policy = manageMembersPermission(group);
|
||||
if (policy == null) {
|
||||
return root.users().canManage();
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
|
||||
// if no policies attached to permission then just do default behavior
|
||||
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
|
||||
return root.users().canManage();
|
||||
return false;
|
||||
}
|
||||
|
||||
Scope scope = authz.getStoreFactory().getScopeStore().findByName(MANAGE_MEMBERS_SCOPE, server.getId());
|
||||
|
@ -404,11 +436,48 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canManageMembership(GroupModel group) {
|
||||
if (canManage(group)) return true;
|
||||
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
if (server == null) return false;
|
||||
|
||||
Resource resource = authz.getStoreFactory().getResourceStore().findByName(getGroupResourceName(group), server.getId());
|
||||
if (resource == null) return false;
|
||||
|
||||
Policy policy = manageMembershipPermission(group);
|
||||
if (policy == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
|
||||
// if no policies attached to permission then just do default behavior
|
||||
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Scope scope = authz.getStoreFactory().getScopeStore().findByName(MANAGE_MEMBERSHIP_SCOPE, server.getId());
|
||||
return root.evaluatePermission(resource, scope, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requireManageMembership(GroupModel group) {
|
||||
if (!canManageMembership(group)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getAccess(GroupModel group) {
|
||||
Map<String, Boolean> map = new HashMap<>();
|
||||
map.put("view", canView(group));
|
||||
map.put("manage", canManage(group));
|
||||
map.put("manageMembership", canManageMembership(group));
|
||||
return map;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.keycloak.models.Constants;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.services.ForbiddenException;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
|
@ -51,7 +52,7 @@ import java.util.List;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManagement {
|
||||
class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManagement, RealmsPermissionEvaluator {
|
||||
private static final Logger logger = Logger.getLogger(MgmtPermissions.class);
|
||||
|
||||
protected RealmModel realm;
|
||||
|
@ -85,7 +86,21 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
|
|||
&& !auth.getRealm().equals(new RealmManager(session).getKeycloakAdminstrationRealm())) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
if (auth.getClient().getClientId().equals(Constants.ADMIN_CLI_CLIENT_ID)) {
|
||||
if (auth.getClient().getClientId().equals(Constants.ADMIN_CLI_CLIENT_ID)
|
||||
|| auth.getClient().getClientId().equals(Constants.ADMIN_CONSOLE_CLIENT_ID)) {
|
||||
this.identity = new UserModelIdentity(auth.getRealm(), auth.getUser());
|
||||
|
||||
} else {
|
||||
this.identity = new KeycloakIdentity(auth.getToken(), session);
|
||||
}
|
||||
}
|
||||
MgmtPermissions(KeycloakSession session, AdminAuth auth) {
|
||||
this.session = session;
|
||||
this.auth = auth;
|
||||
this.admin = auth.getUser();
|
||||
this.adminsRealm = auth.getRealm();
|
||||
if (auth.getClient().getClientId().equals(Constants.ADMIN_CLI_CLIENT_ID)
|
||||
|| auth.getClient().getClientId().equals(Constants.ADMIN_CONSOLE_CLIENT_ID)) {
|
||||
this.identity = new UserModelIdentity(auth.getRealm(), auth.getUser());
|
||||
|
||||
} else {
|
||||
|
@ -117,17 +132,36 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
|
|||
|
||||
|
||||
|
||||
@Override
|
||||
public void requireAnyAdminRole() {
|
||||
if (!hasAnyAdminRole()) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasAnyAdminRole() {
|
||||
return hasOneAdminRole(AdminRoles.ALL_REALM_ROLES);
|
||||
}
|
||||
|
||||
public boolean hasAnyAdminRole(RealmModel realm) {
|
||||
return hasOneAdminRole(realm, AdminRoles.ALL_REALM_ROLES);
|
||||
}
|
||||
|
||||
public boolean hasOneAdminRole(String... adminRoles) {
|
||||
String clientId;
|
||||
RealmModel realm = this.realm;
|
||||
return hasOneAdminRole(realm, adminRoles);
|
||||
}
|
||||
|
||||
public boolean hasOneAdminRole(RealmModel realm, String... adminRoles) {
|
||||
String clientId;
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
if (adminsRealm.equals(realmManager.getKeycloakAdminstrationRealm())) {
|
||||
clientId = realm.getMasterAdminClient().getClientId();
|
||||
} else if (adminsRealm.equals(realm)) {
|
||||
clientId = realm.getClientByClientId(realmManager.getRealmAdminClientId(realm)).getClientId();
|
||||
} else {
|
||||
clientId = realm.getClientByClientId(realmManager.getRealmAdminClientId(auth.getRealm())).getClientId();
|
||||
return false;
|
||||
}
|
||||
for (String adminRole : adminRoles) {
|
||||
if (identity.hasClientRole(clientId, adminRole)) return true;
|
||||
|
@ -136,7 +170,6 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
|
|||
}
|
||||
|
||||
|
||||
|
||||
public boolean isAdminSameRealm() {
|
||||
return auth == null || realm.getId().equals(auth.getRealm().getId());
|
||||
}
|
||||
|
@ -274,6 +307,33 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canView(RealmModel realm) {
|
||||
return hasOneAdminRole(realm, AdminRoles.VIEW_REALM, AdminRoles.MANAGE_REALM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdmin(RealmModel realm) {
|
||||
return hasAnyAdminRole(realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreateRealm() {
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
if (!auth.getRealm().equals(realmManager.getKeycloakAdminstrationRealm())) {
|
||||
return false;
|
||||
}
|
||||
return identity.hasRealmRole(AdminRoles.CREATE_REALM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requireCreateRealm() {
|
||||
if (!canCreateRealm()) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -16,12 +16,14 @@
|
|||
*/
|
||||
package org.keycloak.services.resources.admin.permissions;
|
||||
|
||||
import org.keycloak.models.RealmModel;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface RealmPermissionEvaluator {
|
||||
boolean canListRealm();
|
||||
boolean canListRealms();
|
||||
|
||||
void requireViewRealmNameList();
|
||||
|
||||
|
|
|
@ -76,17 +76,18 @@ class RealmPermissions implements RealmPermissionEvaluator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canListRealm() {
|
||||
public boolean canListRealms() {
|
||||
return root.hasAnyAdminRole();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requireViewRealmNameList() {
|
||||
if (!canListRealm()) {
|
||||
if (!canListRealms()) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canManageRealm() {
|
||||
return canManageRealmDefault();
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.keycloak.services.resources.admin.permissions;
|
||||
|
||||
import org.keycloak.models.RealmModel;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface RealmsPermissionEvaluator {
|
||||
boolean canView(RealmModel realm);
|
||||
|
||||
boolean isAdmin(RealmModel realm);
|
||||
|
||||
boolean canCreateRealm();
|
||||
|
||||
void requireCreateRealm();
|
||||
}
|
|
@ -69,10 +69,15 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
|
|||
} else {
|
||||
ResourceServer server = resourceServer(role);
|
||||
if (server == null) return;
|
||||
Policy policy = mapRolePermission(role);
|
||||
if (policy != null) authz.getStoreFactory().getPolicyStore().delete(policy.getId());
|
||||
policy = mapClientScopePermission(role);
|
||||
if (policy != null) authz.getStoreFactory().getPolicyStore().delete(policy.getId());
|
||||
policy = mapCompositePermission(role);
|
||||
if (policy != null) authz.getStoreFactory().getPolicyStore().delete(policy.getId());
|
||||
|
||||
Resource resource = authz.getStoreFactory().getResourceStore().findByName(getRoleResourceName(role), server.getId());
|
||||
if (resource != null) authz.getStoreFactory().getResourceStore().delete(resource.getId());
|
||||
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getMapRolePermissionName(role), server.getId());
|
||||
if (policy != null) authz.getStoreFactory().getPolicyStore().delete(policy.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,20 +145,22 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
|
|||
*/
|
||||
@Override
|
||||
public boolean canMapRole(RoleModel role) {
|
||||
if (root.users().canManageDefault()) return true;
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return root.users().canManageDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (role.getContainer() instanceof ClientModel) {
|
||||
if (root.clients().canMapRoles((ClientModel)role.getContainer())) return true;
|
||||
}
|
||||
if (!isPermissionsEnabled(role)){
|
||||
return root.users().canManageDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
ResourceServer resourceServer = getResourceServer(role);
|
||||
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getMapRolePermissionName(role), resourceServer.getId());
|
||||
if (policy.getAssociatedPolicies().isEmpty()) {
|
||||
return root.users().canManageDefault(); // if no policies applied, just do default
|
||||
return false;
|
||||
}
|
||||
|
||||
Resource roleResource = resource(role);
|
||||
|
@ -216,20 +223,22 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
|
|||
|
||||
@Override
|
||||
public boolean canMapComposite(RoleModel role) {
|
||||
if (canManageDefault(role)) return true;
|
||||
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return canManage(role);
|
||||
return false;
|
||||
}
|
||||
if (role.getContainer() instanceof ClientModel) {
|
||||
if (root.clients().canMapCompositeRoles((ClientModel)role.getContainer())) return true;
|
||||
}
|
||||
if (!isPermissionsEnabled(role)){
|
||||
return canManage(role);
|
||||
return false;
|
||||
}
|
||||
|
||||
ResourceServer resourceServer = getResourceServer(role);
|
||||
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getMapCompositePermissionName(role), resourceServer.getId());
|
||||
if (policy.getAssociatedPolicies().isEmpty()) {
|
||||
return canManage(role);
|
||||
return false;
|
||||
}
|
||||
|
||||
Resource roleResource = resource(role);
|
||||
|
@ -248,20 +257,21 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
|
|||
|
||||
@Override
|
||||
public boolean canMapClientScope(RoleModel role) {
|
||||
if (root.clients().canManageClientsDefault()) return true;
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return root.clients().canManage();
|
||||
return false;
|
||||
}
|
||||
if (role.getContainer() instanceof ClientModel) {
|
||||
if (root.clients().canMapClientScopeRoles((ClientModel)role.getContainer())) return true;
|
||||
}
|
||||
if (!isPermissionsEnabled(role)){
|
||||
return root.clients().canManage();
|
||||
return false;
|
||||
}
|
||||
|
||||
ResourceServer resourceServer = getResourceServer(role);
|
||||
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(getMapClientScopePermissionName(role), resourceServer.getId());
|
||||
if (policy.getAssociatedPolicies().isEmpty()) {
|
||||
return root.clients().canManage();
|
||||
return false;
|
||||
}
|
||||
|
||||
Resource roleResource = resource(role);
|
||||
|
@ -288,6 +298,16 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean canManageDefault(RoleModel role) {
|
||||
if (role.getContainer() instanceof RealmModel) {
|
||||
return root.realm().canManageRealmDefault();
|
||||
} else if (role.getContainer() instanceof ClientModel) {
|
||||
ClientModel client = (ClientModel)role.getContainer();
|
||||
return root.clients().canManageClientsDefault();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requireManage(RoleModel role) {
|
||||
if (!canManage(role)) {
|
||||
|
@ -375,25 +395,15 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme
|
|||
Resource resource = authz.getStoreFactory().getResourceStore().create(getRoleResourceName(role), server, server.getClientId());
|
||||
resource.setType("Role");
|
||||
Scope mapRoleScope = getMapRoleScope(server);
|
||||
Policy policy = manageUsersPolicy(server);
|
||||
Policy mapRolePermission = Helper.addScopePermission(authz, server, getMapRolePermissionName(role), resource, mapRoleScope, policy);
|
||||
Policy mapRolePermission = Helper.addEmptyScopePermission(authz, server, getMapRolePermissionName(role), resource, mapRoleScope);
|
||||
mapRolePermission.setDecisionStrategy(DecisionStrategy.AFFIRMATIVE);
|
||||
|
||||
Scope mapClientScope = getMapClientScope(server);
|
||||
RoleModel mngClients = root.getRealmManagementClient().getRole(AdminRoles.MANAGE_CLIENTS);
|
||||
Policy mngClientsPolicy = rolePolicy(server, mngClients);
|
||||
Policy mapClientScopePermission = Helper.addScopePermission(authz, server, getMapClientScopePermissionName(role), resource, mapClientScope, mngClientsPolicy);
|
||||
Policy mapClientScopePermission = Helper.addEmptyScopePermission(authz, server, getMapClientScopePermissionName(role), resource, mapClientScope);
|
||||
mapClientScopePermission.setDecisionStrategy(DecisionStrategy.AFFIRMATIVE);
|
||||
|
||||
Scope mapCompositeScope = getMapCompositeScope(server);
|
||||
if (role.getContainer() instanceof RealmModel) {
|
||||
RoleModel mngRealm = root.getRealmManagementClient().getRole(AdminRoles.MANAGE_REALM);
|
||||
policy = rolePolicy(server, mngRealm);
|
||||
} else {
|
||||
policy = mngClientsPolicy;
|
||||
|
||||
}
|
||||
Policy mapCompositePermission = Helper.addScopePermission(authz, server, getMapCompositePermissionName(role), resource, mapCompositeScope, policy);
|
||||
Policy mapCompositePermission = Helper.addEmptyScopePermission(authz, server, getMapCompositePermissionName(role), resource, mapCompositeScope);
|
||||
mapCompositePermission.setDecisionStrategy(DecisionStrategy.AFFIRMATIVE);
|
||||
return resource;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.keycloak.services.resources.admin.permissions;
|
||||
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
||||
import java.util.Map;
|
||||
|
@ -25,7 +26,7 @@ import java.util.Map;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface UserPermissionEvaluator {
|
||||
boolean canManage();
|
||||
boolean canManage();
|
||||
|
||||
void requireManage();
|
||||
|
||||
|
@ -51,4 +52,12 @@ public interface UserPermissionEvaluator {
|
|||
void requireImpersonate(UserModel user);
|
||||
|
||||
Map<String, Boolean> getAccess(UserModel user);
|
||||
|
||||
boolean canMapRoles(UserModel user);
|
||||
|
||||
void requireMapRoles(UserModel user);
|
||||
|
||||
boolean canManageGroupMembership(UserModel user);
|
||||
|
||||
void requireManageGroupMembership(UserModel user);
|
||||
}
|
||||
|
|
|
@ -38,4 +38,10 @@ public interface UserPermissionManagement {
|
|||
Policy managePermission();
|
||||
|
||||
Policy viewPermission();
|
||||
|
||||
Policy manageGroupMembershipPermission();
|
||||
|
||||
Policy mapRolesPermission();
|
||||
|
||||
Policy impersonatePermission();
|
||||
}
|
||||
|
|
|
@ -45,6 +45,12 @@ import java.util.Set;
|
|||
*/
|
||||
class UserPermissions implements UserPermissionEvaluator, UserPermissionManagement {
|
||||
private static final Logger logger = Logger.getLogger(UserPermissions.class);
|
||||
public static final String MAP_ROLES_SCOPE="map-roles";
|
||||
public static final String IMPERSONATE_SCOPE="impersonate";
|
||||
public static final String MANAGE_GROUP_MEMBERSHIP_SCOPE="manage-group-membership";
|
||||
public static final String MAP_ROLES_PERMISSION_USERS = "map-roles.permission.users";
|
||||
public static final String IMPERSONATE_PERMISSION_USERS = "impersonate.permission.users";
|
||||
public static final String MANAGE_GROUP_MEMBERSHIP_PERMISSION_USERS = "manage-group-membership.permission.users";
|
||||
public static final String MANAGE_PERMISSION_USERS = "manage.permission.users";
|
||||
public static final String VIEW_PERMISSION_USERS = "view.permission.users";
|
||||
public static final String USERS_RESOURCE = "Users";
|
||||
|
@ -67,6 +73,9 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
|
|||
ResourceServer server = root.realmResourceServer();
|
||||
Scope manageScope = root.realmManageScope();
|
||||
Scope viewScope = root.realmViewScope();
|
||||
Scope mapRolesScope = root.initializeRealmScope(MAP_ROLES_SCOPE);
|
||||
Scope impersonateScope = root.initializeRealmScope(IMPERSONATE_SCOPE);
|
||||
Scope manageGroupMembershipScope = root.initializeRealmScope(MANAGE_GROUP_MEMBERSHIP_SCOPE);
|
||||
|
||||
Resource usersResource = authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
|
||||
if (usersResource == null) {
|
||||
|
@ -74,17 +83,30 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
|
|||
Set<Scope> scopeset = new HashSet<>();
|
||||
scopeset.add(manageScope);
|
||||
scopeset.add(viewScope);
|
||||
scopeset.add(mapRolesScope);
|
||||
scopeset.add(impersonateScope);
|
||||
scopeset.add(manageGroupMembershipScope);
|
||||
usersResource.updateScopes(scopeset);
|
||||
}
|
||||
Policy managePermission = authz.getStoreFactory().getPolicyStore().findByName(MANAGE_PERMISSION_USERS, server.getId());
|
||||
if (managePermission == null) {
|
||||
Policy manageUsersPolicy = root.roles().manageUsersPolicy(server);
|
||||
Helper.addScopePermission(authz, server, MANAGE_PERMISSION_USERS, usersResource, manageScope, manageUsersPolicy);
|
||||
Helper.addEmptyScopePermission(authz, server, MANAGE_PERMISSION_USERS, usersResource, manageScope);
|
||||
}
|
||||
Policy viewPermission = authz.getStoreFactory().getPolicyStore().findByName(VIEW_PERMISSION_USERS, server.getId());
|
||||
if (viewPermission == null) {
|
||||
Policy viewUsersPolicy = root.roles().viewUsersPolicy(server);
|
||||
Helper.addScopePermission(authz, server, VIEW_PERMISSION_USERS, usersResource, viewScope, viewUsersPolicy);
|
||||
Helper.addEmptyScopePermission(authz, server, VIEW_PERMISSION_USERS, usersResource, viewScope);
|
||||
}
|
||||
Policy mapRolesPermission = authz.getStoreFactory().getPolicyStore().findByName(MAP_ROLES_PERMISSION_USERS, server.getId());
|
||||
if (mapRolesPermission == null) {
|
||||
Helper.addEmptyScopePermission(authz, server, MAP_ROLES_PERMISSION_USERS, usersResource, mapRolesScope);
|
||||
}
|
||||
Policy membershipPermission = authz.getStoreFactory().getPolicyStore().findByName(MANAGE_GROUP_MEMBERSHIP_PERMISSION_USERS, server.getId());
|
||||
if (membershipPermission == null) {
|
||||
Helper.addEmptyScopePermission(authz, server, MANAGE_GROUP_MEMBERSHIP_PERMISSION_USERS, usersResource, manageGroupMembershipScope);
|
||||
}
|
||||
Policy impersonatePermission = authz.getStoreFactory().getPolicyStore().findByName(IMPERSONATE_PERMISSION_USERS, server.getId());
|
||||
if (impersonatePermission == null) {
|
||||
Helper.addEmptyScopePermission(authz, server, IMPERSONATE_PERMISSION_USERS, usersResource, impersonateScope);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,6 +115,9 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
|
|||
Map<String, String> scopes = new HashMap<>();
|
||||
scopes.put(AdminPermissionManagement.MANAGE_SCOPE, managePermission().getId());
|
||||
scopes.put(AdminPermissionManagement.VIEW_SCOPE, viewPermission().getId());
|
||||
scopes.put(MAP_ROLES_SCOPE, mapRolesPermission().getId());
|
||||
scopes.put(MANAGE_GROUP_MEMBERSHIP_SCOPE, manageGroupMembershipPermission().getId());
|
||||
scopes.put(IMPERSONATE_SCOPE, impersonatePermission().getId());
|
||||
return scopes;
|
||||
}
|
||||
|
||||
|
@ -117,7 +142,22 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
|
|||
} else {
|
||||
ResourceServer server = authz.getStoreFactory().getResourceServerStore().findByClient(client.getId());
|
||||
if (server == null) return;
|
||||
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(MANAGE_PERMISSION_USERS, server.getId());
|
||||
Policy policy = managePermission();
|
||||
if (policy == null) {
|
||||
authz.getStoreFactory().getPolicyStore().delete(policy.getId());
|
||||
|
||||
}
|
||||
policy = viewPermission();
|
||||
if (policy == null) {
|
||||
authz.getStoreFactory().getPolicyStore().delete(policy.getId());
|
||||
|
||||
}
|
||||
policy = mapRolesPermission();
|
||||
if (policy == null) {
|
||||
authz.getStoreFactory().getPolicyStore().delete(policy.getId());
|
||||
|
||||
}
|
||||
policy = manageGroupMembershipPermission();
|
||||
if (policy == null) {
|
||||
authz.getStoreFactory().getPolicyStore().delete(policy.getId());
|
||||
|
||||
|
@ -153,6 +193,25 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
|
|||
return authz.getStoreFactory().getPolicyStore().findByName(VIEW_PERMISSION_USERS, server.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Policy manageGroupMembershipPermission() {
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
return authz.getStoreFactory().getPolicyStore().findByName(MANAGE_GROUP_MEMBERSHIP_PERMISSION_USERS, server.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Policy mapRolesPermission() {
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
return authz.getStoreFactory().getPolicyStore().findByName(MAP_ROLES_PERMISSION_USERS, server.getId());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Policy impersonatePermission() {
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
return authz.getStoreFactory().getPolicyStore().findByName(IMPERSONATE_PERMISSION_USERS, server.getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -170,25 +229,26 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
|
|||
*/
|
||||
@Override
|
||||
public boolean canManage() {
|
||||
if (canManageDefault()) return true;
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return canManageDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
if (server == null) return canManageDefault();
|
||||
if (server == null) return false;
|
||||
|
||||
Resource resource = authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
|
||||
if (resource == null) return canManageDefault();
|
||||
if (resource == null) return false;
|
||||
|
||||
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(MANAGE_PERMISSION_USERS, server.getId());
|
||||
if (policy == null) {
|
||||
return canManageDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
|
||||
// if no policies attached to permission then just do default behavior
|
||||
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
|
||||
return canManageDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
Scope scope = root.realmManageScope();
|
||||
|
@ -321,14 +381,15 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
|
|||
*/
|
||||
@Override
|
||||
public boolean canView() {
|
||||
if (canViewDefault()) return true;
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return canViewDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
return hasViewPermission() || canManage();
|
||||
}
|
||||
|
||||
public boolean hasViewPermission() {
|
||||
private boolean hasViewPermission() {
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
if (server == null) return canViewDefault();
|
||||
|
||||
|
@ -382,7 +443,32 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
|
|||
|
||||
@Override
|
||||
public boolean canImpersonate(UserModel user) {
|
||||
return root.hasOneAdminRole(ImpersonationConstants.IMPERSONATION_ROLE);
|
||||
if (root.hasOneAdminRole(ImpersonationConstants.IMPERSONATION_ROLE)) return true;
|
||||
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
if (server == null) return false;
|
||||
|
||||
Resource resource = authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
|
||||
if (resource == null) return false;
|
||||
|
||||
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(IMPERSONATE_PERMISSION_USERS, server.getId());
|
||||
if (policy == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
|
||||
// if no policies attached to permission then just do default behavior
|
||||
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Scope scope = root.realmScope(IMPERSONATE_SCOPE);
|
||||
return root.evaluatePermission(resource, scope, server);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -397,9 +483,90 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme
|
|||
Map<String, Boolean> map = new HashMap<>();
|
||||
map.put("view", canView(user));
|
||||
map.put("manage", canManage(user));
|
||||
map.put("mapRoles", canMapRoles(user));
|
||||
map.put("manageGroupMembership", canManageGroupMembership(user));
|
||||
map.put("impersonate", canImpersonate(user));
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMapRoles(UserModel user) {
|
||||
if (canManage(user)) return true;
|
||||
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
if (server == null) return false;
|
||||
|
||||
Resource resource = authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
|
||||
if (resource == null) return false;
|
||||
|
||||
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(MAP_ROLES_PERMISSION_USERS, server.getId());
|
||||
if (policy == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
|
||||
// if no policies attached to permission then just do default behavior
|
||||
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Scope scope = root.realmScope(MAP_ROLES_SCOPE);
|
||||
return root.evaluatePermission(resource, scope, server);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requireMapRoles(UserModel user) {
|
||||
if (!canMapRoles(user)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canManageGroupMembership(UserModel user) {
|
||||
if (canManage(user)) return true;
|
||||
|
||||
if (!root.isAdminSameRealm()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ResourceServer server = root.realmResourceServer();
|
||||
if (server == null) return false;
|
||||
|
||||
Resource resource = authz.getStoreFactory().getResourceStore().findByName(USERS_RESOURCE, server.getId());
|
||||
if (resource == null) return false;
|
||||
|
||||
Policy policy = authz.getStoreFactory().getPolicyStore().findByName(MANAGE_GROUP_MEMBERSHIP_PERMISSION_USERS, server.getId());
|
||||
if (policy == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Policy> associatedPolicies = policy.getAssociatedPolicies();
|
||||
// if no policies attached to permission then just do default behavior
|
||||
if (associatedPolicies == null || associatedPolicies.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Scope scope = root.realmScope(MANAGE_GROUP_MEMBERSHIP_SCOPE);
|
||||
return root.evaluatePermission(resource, scope, server);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requireManageGroupMembership(UserModel user) {
|
||||
if (!canManageGroupMembership(user)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -66,6 +66,43 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
|
|||
testRealmRep.setEnabled(true);
|
||||
testRealms.add(testRealmRep);
|
||||
}
|
||||
public static void setupDemo(KeycloakSession session) {
|
||||
RealmModel realm = session.realms().getRealmByName(TEST);
|
||||
ClientModel client = realm.addClient("sales-pipeline-application");
|
||||
RoleModel clientAdmin = client.addRole("admin");
|
||||
client.addRole("leader-creator");
|
||||
client.addRole("viewLeads");
|
||||
ClientModel client2 = realm.addClient("market-analysis-application");
|
||||
RoleModel client2Admin = client2.addRole("admin");
|
||||
client2.addRole("market-manager");
|
||||
client2.addRole("viewMarkets");
|
||||
GroupModel sales = realm.createGroup("sales");
|
||||
RoleModel salesAppsAdminRole = realm.addRole("sales-apps-admin");
|
||||
salesAppsAdminRole.addCompositeRole(clientAdmin);
|
||||
salesAppsAdminRole.addCompositeRole(client2Admin);
|
||||
|
||||
|
||||
UserModel admin = session.users().addUser(realm, "salesManager");
|
||||
admin.setEnabled(true);
|
||||
session.userCredentialManager().updateCredential(realm, admin, UserCredentialModel.password("password"));
|
||||
admin = session.users().addUser(realm, "sales-group-admin");
|
||||
admin.setEnabled(true);
|
||||
session.userCredentialManager().updateCredential(realm, admin, UserCredentialModel.password("password"));
|
||||
admin = session.users().addUser(realm, "sales-it");
|
||||
admin.setEnabled(true);
|
||||
session.userCredentialManager().updateCredential(realm, admin, UserCredentialModel.password("password"));
|
||||
admin = session.users().addUser(realm, "sales-pipeline-admin");
|
||||
admin.setEnabled(true);
|
||||
session.userCredentialManager().updateCredential(realm, admin, UserCredentialModel.password("password"));
|
||||
|
||||
UserModel user = session.users().addUser(realm, "salesman");
|
||||
user.setEnabled(true);
|
||||
user.joinGroup(sales);
|
||||
|
||||
user = session.users().addUser(realm, "saleswoman");
|
||||
user.setEnabled(true);
|
||||
|
||||
}
|
||||
|
||||
public static void setupPolices(KeycloakSession session) {
|
||||
RealmModel realm = session.realms().getRealmByName(TEST);
|
||||
|
@ -304,9 +341,14 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
|
|||
protected boolean isImportAfterEachMethod() {
|
||||
return true;
|
||||
}
|
||||
//@Test
|
||||
public void testDemo() throws Exception {
|
||||
testingClient.server().run(FineGrainAdminUnitTest::setupDemo);
|
||||
Thread.sleep(1000000000);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
//@Test
|
||||
public void testUI() throws Exception {
|
||||
testingClient.server().run(FineGrainAdminUnitTest::setupPolices);
|
||||
testingClient.server().run(FineGrainAdminUnitTest::setupUsers);
|
||||
|
|
|
@ -717,7 +717,7 @@ public class PermissionsTest extends AbstractKeycloakTest {
|
|||
public void invoke(RealmResource realm) {
|
||||
realm.clientTemplates().findAll();
|
||||
}
|
||||
}, Resource.CLIENT, false);
|
||||
}, Resource.CLIENT, false, true);
|
||||
invoke(new InvocationWithResponse() {
|
||||
public void invoke(RealmResource realm, AtomicReference<Response> response) {
|
||||
ClientTemplateRepresentation template = new ClientTemplateRepresentation();
|
||||
|
|
|
@ -29,7 +29,7 @@ log4j.appender.testsuite.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%C{1}]
|
|||
keycloak.logging.level=info
|
||||
log4j.logger.org.keycloak=${keycloak.logging.level}
|
||||
|
||||
log4j.logger.org.jboss.resteasy.resteasy_jaxrs.i18n=off
|
||||
#log4j.logger.org.jboss.resteasy.resteasy_jaxrs.i18n=off
|
||||
|
||||
#log4j.logger.org.keycloak.keys.DefaultKeyManager=trace
|
||||
#log4j.logger.org.keycloak.services.managers.AuthenticationManager=trace
|
||||
|
@ -62,7 +62,7 @@ log4j.logger.org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory=de
|
|||
|
||||
log4j.logger.org.xnio=off
|
||||
log4j.logger.org.hibernate=off
|
||||
log4j.logger.org.jboss.resteasy=warn
|
||||
log4j.logger.org.jboss.resteasy=info
|
||||
log4j.logger.org.apache.directory.api=warn
|
||||
log4j.logger.org.apache.directory.server.core=warn
|
||||
|
||||
|
|
|
@ -2394,6 +2394,7 @@ module.controller('ClientRolePermissionsCtrl', function($scope, $http, $route, $
|
|||
$scope.permissions = data;
|
||||
});
|
||||
$scope.setEnabled = function() {
|
||||
console.log('perssions enabled: ' + $scope.permissions.enabled);
|
||||
var param = { enabled: $scope.permissions.enabled};
|
||||
$scope.permissions = RoleManagementPermissions.update({realm: realm.realm, role:role.id}, param);
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<kc-tabs-group></kc-tabs-group>
|
||||
|
||||
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageUsers">
|
||||
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!group.access.manage">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -29,7 +29,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="form-group" data-ng-show="access.manageUsers">
|
||||
<div class="form-group" data-ng-show="group.access.manage">
|
||||
<div class="col-md-12">
|
||||
<button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button>
|
||||
<button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div class="form-group" data-ng-show="access.manageUsers">
|
||||
<div class="form-group" data-ng-show="group.access.manage">
|
||||
<div class="col-md-10 col-md-offset-2">
|
||||
<button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button>
|
||||
<button kc-reset data-ng-disabled="!changed" data-ng-click="cancel()">{{:: 'cancel' | translate}}</button>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<kc-tabs-group></kc-tabs-group>
|
||||
|
||||
<form class="form-horizontal" name="realmForm" novalidate>
|
||||
<div class="form-group" kc-read-only="!access.manageUsers">
|
||||
<div class="form-group" kc-read-only="!group.access.manage">
|
||||
<label class="col-md-2 control-label" class="control-label">{{:: 'realm-roles' | translate}}</label>
|
||||
|
||||
<div class="col-md-10">
|
||||
|
@ -54,7 +54,7 @@
|
|||
<span>{{:: 'client-roles' | translate}}</span>
|
||||
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="targetClient" ng-options="a.clientId for a in clients | orderBy:'clientId'" ng-disabled="false"></select>
|
||||
</label>
|
||||
<div class="col-md-10" kc-read-only="!access.manageUsers">
|
||||
<div class="col-md-10" kc-read-only="!group.access.manage">
|
||||
<div class="row" data-ng-hide="targetClient">
|
||||
<div class="col-md-4"><span class="text-muted">{{:: 'select-client-to-view-roles' | translate}}</span></div>
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<kc-tabs-user></kc-tabs-user>
|
||||
|
||||
<form class="form-horizontal" name="realmForm" novalidate>
|
||||
<div class="form-group" kc-read-only="!access.manageUsers">
|
||||
<div class="form-group" kc-read-only="!user.access.mapRoles">
|
||||
<label class="col-md-2 control-label" class="control-label">{{:: 'realm-roles' | translate}}</label>
|
||||
|
||||
<div class="col-md-10">
|
||||
|
@ -54,7 +54,7 @@
|
|||
<span>{{:: 'client-roles' | translate}}</span>
|
||||
<select class="form-control" id="clients" name="clients" ng-change="changeClient()" ng-model="targetClient" ng-options="a.clientId for a in clients | orderBy:'clientId'" ng-disabled="false"></select>
|
||||
</label>
|
||||
<div class="col-md-10" kc-read-only="!access.manageUsers">
|
||||
<div class="col-md-10" kc-read-only="!user.access.mapRoles">
|
||||
<div class="row" data-ng-hide="targetClient">
|
||||
<div class="col-md-4"><span class="text-muted">{{:: 'select-client-to-view-roles' | translate}}</span></div>
|
||||
</div>
|
||||
|
|
|
@ -138,7 +138,7 @@
|
|||
<button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button>
|
||||
</div>
|
||||
|
||||
<div class="col-md-10 col-md-offset-2" data-ng-show="!create && !user.access.manage">
|
||||
<div class="col-md-10 col-md-offset-2" data-ng-show="!create && user.access.manage">
|
||||
<button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button>
|
||||
<button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button>
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<kc-tabs-user></kc-tabs-user>
|
||||
|
||||
<form class="form-horizontal" name="realmForm" novalidate>
|
||||
<div class="form-group" kc-read-only="!access.manageUsers">
|
||||
<div class="form-group" kc-read-only="!user.access.manageGroupMembership">
|
||||
<label class="col-md-1 control-label" class="control-label"></label>
|
||||
|
||||
<div class="col-md-8" >
|
||||
|
@ -21,7 +21,7 @@
|
|||
<label class="control-label">{{:: 'group-membership' | translate}}</label>
|
||||
<kc-tooltip>{{:: 'group-membership.tooltip' | translate}}</kc-tooltip>
|
||||
|
||||
<div class="pull-right" data-ng-show="access.manageUsers">
|
||||
<div class="pull-right" data-ng-show="user.access.manageGroupMembership">
|
||||
<button id="leaveGroups" class="btn btn-default" ng-click="leaveGroup()">{{:: 'leave' | translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -53,7 +53,7 @@
|
|||
<label class="control-label">{{:: 'available-groups' | translate}}</label>
|
||||
<kc-tooltip>{{:: 'membership.available-groups.tooltip' | translate}}</kc-tooltip>
|
||||
|
||||
<div class="pull-right" data-ng-show="access.manageUsers">
|
||||
<div class="pull-right" data-ng-show="user.access.manageGroupMembership">
|
||||
<button id="joinGroup" class="btn btn-default" ng-click="joinGroup()">{{:: 'join' | translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue