keycloak-uncached
Changes
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/ResourceServerManagementTest.java 68(+68 -0)
testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/client-with-authz-settings.json 866(+866 -0)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java 12(+12 -0)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java 12(+12 -0)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resources.java 12(+12 -0)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scopes.java 11(+11 -0)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AggregatePolicyManagementTest.java 16(+16 -0)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ClientPolicyManagementTest.java 18(+17 -1)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/GroupPolicyManagementTest.java 19(+19 -0)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/JSPolicyManagementTest.java 16(+16 -0)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourceManagementTest.java 11(+10 -1)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourcePermissionManagementTest.java 17(+17 -0)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/RolePolicyManagementTest.java 18(+18 -0)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/RulePolicyManagementTest.java 12(+12 -0)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopeManagementTest.java 9(+9 -0)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopePermissionManagementTest.java 17(+17 -0)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/TimePolicyManagementTest.java 27(+27 -0)
Details
diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAPolicyStore.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAPolicyStore.java
index eb350be..1bd41e2 100644
--- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAPolicyStore.java
+++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAPolicyStore.java
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
+import javax.persistence.FlushModeType;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
@@ -34,14 +35,10 @@ import javax.persistence.criteria.Root;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.jpa.entities.PolicyEntity;
-import org.keycloak.authorization.jpa.entities.ResourceServerEntity;
import org.keycloak.authorization.model.Policy;
-import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.store.PolicyStore;
-import org.keycloak.authorization.store.StoreFactory;
import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
/**
@@ -96,8 +93,10 @@ public class JPAPolicyStore implements PolicyStore {
public Policy findByName(String name, String resourceServerId) {
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByName", String.class);
+ query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("serverId", resourceServerId);
query.setParameter("name", name);
+
try {
String id = query.getSingleResult();
return provider.getStoreFactory().getPolicyStore().findById(id, resourceServerId);
@@ -167,6 +166,7 @@ public class JPAPolicyStore implements PolicyStore {
public List<Policy> findByResource(final String resourceId, String resourceServerId) {
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByResource", String.class);
+ query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("resourceId", resourceId);
query.setParameter("serverId", resourceServerId);
@@ -182,6 +182,7 @@ public class JPAPolicyStore implements PolicyStore {
public List<Policy> findByResourceType(final String resourceType, String resourceServerId) {
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByResourceType", String.class);
+ query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("type", resourceType);
query.setParameter("serverId", resourceServerId);
@@ -202,6 +203,7 @@ public class JPAPolicyStore implements PolicyStore {
// Use separate subquery to handle DB2 and MSSSQL
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByScope", String.class);
+ query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("scopeIds", scopeIds);
query.setParameter("serverId", resourceServerId);
@@ -217,6 +219,7 @@ public class JPAPolicyStore implements PolicyStore {
public List<Policy> findByType(String type, String resourceServerId) {
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByType", String.class);
+ query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("serverId", resourceServerId);
query.setParameter("type", type);
@@ -233,6 +236,7 @@ public class JPAPolicyStore implements PolicyStore {
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByDependentPolices", String.class);
+ query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("serverId", resourceServerId);
query.setParameter("policyId", policyId);
diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceStore.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceStore.java
index 8a647d8..7a505ab 100644
--- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceStore.java
+++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceStore.java
@@ -19,13 +19,13 @@ package org.keycloak.authorization.jpa.store;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.jpa.entities.ResourceEntity;
-import org.keycloak.authorization.jpa.entities.ResourceServerEntity;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.store.ResourceStore;
import org.keycloak.models.utils.KeycloakModelUtils;
import javax.persistence.EntityManager;
+import javax.persistence.FlushModeType;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
@@ -34,7 +34,6 @@ import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -62,13 +61,14 @@ public class JPAResourceStore implements ResourceStore {
entity.setOwner(owner);
this.entityManager.persist(entity);
+ this.entityManager.flush();
return new ResourceAdapter(entity, entityManager, provider.getStoreFactory());
}
@Override
public void delete(String id) {
- ResourceEntity resource = entityManager.find(ResourceEntity.class, id);
+ ResourceEntity resource = entityManager.getReference(ResourceEntity.class, id);
if (resource == null) return;
resource.getScopes().clear();
@@ -90,14 +90,18 @@ public class JPAResourceStore implements ResourceStore {
public List<Resource> findByOwner(String ownerId, String resourceServerId) {
TypedQuery<String> query = entityManager.createNamedQuery("findResourceIdByOwner", String.class);
+ query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("owner", ownerId);
query.setParameter("serverId", resourceServerId);
List<String> result = query.getResultList();
List<Resource> list = new LinkedList<>();
+ ResourceStore resourceStore = provider.getStoreFactory().getResourceStore();
+
for (String id : result) {
- list.add(provider.getStoreFactory().getResourceStore().findById(id, resourceServerId));
+ list.add(resourceStore.findById(id, resourceServerId));
}
+
return list;
}
@@ -105,14 +109,18 @@ public class JPAResourceStore implements ResourceStore {
public List<Resource> findByUri(String uri, String resourceServerId) {
TypedQuery<String> query = entityManager.createNamedQuery("findResourceIdByUri", String.class);
+ query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("uri", uri);
query.setParameter("serverId", resourceServerId);
List<String> result = query.getResultList();
List<Resource> list = new LinkedList<>();
+ ResourceStore resourceStore = provider.getStoreFactory().getResourceStore();
+
for (String id : result) {
- list.add(provider.getStoreFactory().getResourceStore().findById(id, resourceServerId));
+ list.add(resourceStore.findById(id, resourceServerId));
}
+
return list;
}
@@ -124,9 +132,12 @@ public class JPAResourceStore implements ResourceStore {
List<String> result = query.getResultList();
List<Resource> list = new LinkedList<>();
+ ResourceStore resourceStore = provider.getStoreFactory().getResourceStore();
+
for (String id : result) {
- list.add(provider.getStoreFactory().getResourceStore().findById(id, resourceServerId));
+ list.add(resourceStore.findById(id, resourceServerId));
}
+
return list;
}
@@ -163,9 +174,12 @@ public class JPAResourceStore implements ResourceStore {
List<String> result = query.getResultList();
List<Resource> list = new LinkedList<>();
+ ResourceStore resourceStore = provider.getStoreFactory().getResourceStore();
+
for (String id : result) {
- list.add(provider.getStoreFactory().getResourceStore().findById(id, resourceServerId));
+ list.add(resourceStore.findById(id, resourceServerId));
}
+
return list;
}
@@ -173,14 +187,18 @@ public class JPAResourceStore implements ResourceStore {
public List<Resource> findByScope(List<String> scopes, String resourceServerId) {
TypedQuery<String> query = entityManager.createNamedQuery("findResourceIdByScope", String.class);
+ query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("scopeIds", scopes);
query.setParameter("serverId", resourceServerId);
List<String> result = query.getResultList();
List<Resource> list = new LinkedList<>();
+ ResourceStore resourceStore = provider.getStoreFactory().getResourceStore();
+
for (String id : result) {
- list.add(provider.getStoreFactory().getResourceStore().findById(id, resourceServerId));
+ list.add(resourceStore.findById(id, resourceServerId));
}
+
return list;
}
@@ -188,8 +206,10 @@ public class JPAResourceStore implements ResourceStore {
public Resource findByName(String name, String resourceServerId) {
TypedQuery<String> query = entityManager.createNamedQuery("findResourceIdByName", String.class);
+ query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("serverId", resourceServerId);
query.setParameter("name", name);
+
try {
String id = query.getSingleResult();
return provider.getStoreFactory().getResourceStore().findById(id, resourceServerId);
@@ -202,14 +222,18 @@ public class JPAResourceStore implements ResourceStore {
public List<Resource> findByType(String type, String resourceServerId) {
TypedQuery<String> query = entityManager.createNamedQuery("findResourceIdByType", String.class);
+ query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("type", type);
query.setParameter("serverId", resourceServerId);
List<String> result = query.getResultList();
List<Resource> list = new LinkedList<>();
+ ResourceStore resourceStore = provider.getStoreFactory().getResourceStore();
+
for (String id : result) {
- list.add(provider.getStoreFactory().getResourceStore().findById(id, resourceServerId));
+ list.add(resourceStore.findById(id, resourceServerId));
}
+
return list;
}
}
diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAScopeStore.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAScopeStore.java
index f8a9350..befde65 100644
--- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAScopeStore.java
+++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAScopeStore.java
@@ -23,6 +23,7 @@ import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
+import javax.persistence.FlushModeType;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
@@ -32,7 +33,6 @@ import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.keycloak.authorization.AuthorizationProvider;
-import org.keycloak.authorization.jpa.entities.ResourceServerEntity;
import org.keycloak.authorization.jpa.entities.ScopeEntity;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.model.Scope;
@@ -61,6 +61,7 @@ public class JPAScopeStore implements ScopeStore {
entity.setResourceServer(ResourceServerAdapter.toEntity(entityManager, resourceServer));
this.entityManager.persist(entity);
+ this.entityManager.flush();
return new ScopeAdapter(entity, entityManager, provider.getStoreFactory());
}
@@ -91,8 +92,10 @@ public class JPAScopeStore implements ScopeStore {
try {
TypedQuery<String> query = entityManager.createNamedQuery("findScopeIdByName", String.class);
+ query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("serverId", resourceServerId);
query.setParameter("name", name);
+
String id = query.getSingleResult();
return provider.getStoreFactory().getScopeStore().findById(id, resourceServerId);
} catch (NoResultException nre) {
@@ -104,6 +107,7 @@ public class JPAScopeStore implements ScopeStore {
public List<Scope> findByResourceServer(final String serverId) {
TypedQuery<String> query = entityManager.createNamedQuery("findScopeIdByResourceServer", String.class);
+ query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("serverId", serverId);
List<String> result = query.getResultList();
diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
index a18c27a..c3a776b 100755
--- a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -1929,24 +1929,21 @@ public class RepresentationToModel {
resourceServer.setPolicyEnforcementMode(rep.getPolicyEnforcementMode());
resourceServer.setAllowRemoteResourceManagement(rep.isAllowRemoteResourceManagement());
- rep.getScopes().forEach(scope -> {
+ for (ScopeRepresentation scope : rep.getScopes()) {
toModel(scope, resourceServer, authorization);
- });
+ }
KeycloakSession session = authorization.getKeycloakSession();
RealmModel realm = authorization.getRealm();
- rep.getResources().forEach(resourceRepresentation -> {
- ResourceOwnerRepresentation owner = resourceRepresentation.getOwner();
+ for (ResourceRepresentation resource : rep.getResources()) {
+ ResourceOwnerRepresentation owner = resource.getOwner();
if (owner == null) {
owner = new ResourceOwnerRepresentation();
- resourceRepresentation.setOwner(owner);
- }
-
- owner.setId(resourceServer.getClientId());
-
- if (owner.getName() != null) {
+ owner.setId(resourceServer.getClientId());
+ resource.setOwner(owner);
+ } else if (owner.getName() != null) {
UserModel user = session.users().getUserByUsername(owner.getName(), realm);
if (user != null) {
@@ -1954,8 +1951,8 @@ public class RepresentationToModel {
}
}
- toModel(resourceRepresentation, resourceServer, authorization);
- });
+ toModel(resource, resourceServer, authorization);
+ }
importPolicies(authorization, resourceServer, rep.getPolicies(), null);
}
@@ -1974,7 +1971,9 @@ public class RepresentationToModel {
PolicyStore policyStore = storeFactory.getPolicyStore();
try {
List<String> policies = (List<String>) JsonSerialization.readValue(applyPolicies, List.class);
- config.put("applyPolicies", JsonSerialization.writeValueAsString(policies.stream().map(policyName -> {
+ Set<String> policyIds = new HashSet<>();
+
+ for (String policyName : policies) {
Policy policy = policyStore.findByName(policyName, resourceServer.getId());
if (policy == null) {
@@ -1988,8 +1987,10 @@ public class RepresentationToModel {
}
}
- return policy.getId();
- }).collect(Collectors.toList())));
+ policyIds.add(policy.getId());
+ }
+
+ config.put("applyPolicies", JsonSerialization.writeValueAsString(policyIds));
} catch (Exception e) {
throw new RuntimeException("Error while importing policy [" + policyRepresentation.getName() + "].", e);
}
@@ -2028,33 +2029,40 @@ public class RepresentationToModel {
if (representation instanceof PolicyRepresentation) {
PolicyRepresentation policy = PolicyRepresentation.class.cast(representation);
- String resourcesConfig = policy.getConfig().get("resources");
- if (resourcesConfig != null) {
- try {
- resources = JsonSerialization.readValue(resourcesConfig, Set.class);
- } catch (IOException e) {
- throw new RuntimeException(e);
+ if (resources == null) {
+ String resourcesConfig = policy.getConfig().get("resources");
+
+ if (resourcesConfig != null) {
+ try {
+ resources = JsonSerialization.readValue(resourcesConfig, Set.class);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
}
- String scopesConfig = policy.getConfig().get("scopes");
+ if (scopes == null) {
+ String scopesConfig = policy.getConfig().get("scopes");
- if (scopesConfig != null) {
- try {
- scopes = JsonSerialization.readValue(scopesConfig, Set.class);
- } catch (IOException e) {
- throw new RuntimeException(e);
+ if (scopesConfig != null) {
+ try {
+ scopes = JsonSerialization.readValue(scopesConfig, Set.class);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
}
- String policiesConfig = policy.getConfig().get("applyPolicies");
+ if (policies == null) {
+ String policiesConfig = policy.getConfig().get("applyPolicies");
- if (policiesConfig != null) {
- try {
- policies = JsonSerialization.readValue(policiesConfig, Set.class);
- } catch (IOException e) {
- throw new RuntimeException(e);
+ if (policiesConfig != null) {
+ try {
+ policies = JsonSerialization.readValue(policiesConfig, Set.class);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
}
diff --git a/services/src/main/java/org/keycloak/authorization/admin/AuthorizationService.java b/services/src/main/java/org/keycloak/authorization/admin/AuthorizationService.java
index 535634b..3d4f163 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/AuthorizationService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/AuthorizationService.java
@@ -35,13 +35,11 @@ public class AuthorizationService {
private final AdminPermissionEvaluator auth;
private final ClientModel client;
- private final KeycloakSession session;
- private final ResourceServer resourceServer;
+ private ResourceServer resourceServer;
private final AuthorizationProvider authorization;
private final AdminEventBuilder adminEvent;
public AuthorizationService(KeycloakSession session, ClientModel client, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
- this.session = session;
this.client = client;
this.authorization = session.getProvider(AuthorizationProvider.class);
this.adminEvent = adminEvent;
@@ -60,7 +58,7 @@ public class AuthorizationService {
public void enable(boolean newClient) {
if (!isEnabled()) {
- resourceServer().create(newClient);
+ this.resourceServer = resourceServer().create(newClient);
}
}
diff --git a/services/src/main/java/org/keycloak/authorization/admin/ResourceServerService.java b/services/src/main/java/org/keycloak/authorization/admin/ResourceServerService.java
index e52da9a..9c7a291 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/ResourceServerService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/ResourceServerService.java
@@ -19,7 +19,6 @@ package org.keycloak.authorization.admin;
import static org.keycloak.models.utils.ModelToRepresentation.toRepresentation;
-import java.io.IOException;
import java.util.HashMap;
import javax.ws.rs.Consumes;
@@ -36,10 +35,6 @@ import javax.ws.rs.core.UriInfo;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.ResourceServer;
-import org.keycloak.authorization.store.PolicyStore;
-import org.keycloak.authorization.store.ResourceStore;
-import org.keycloak.authorization.store.ScopeStore;
-import org.keycloak.authorization.store.StoreFactory;
import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType;
import org.keycloak.exportimport.util.ExportUtils;
@@ -56,8 +51,8 @@ import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
-import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
import org.keycloak.services.resources.admin.AdminEventBuilder;
+import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@@ -83,7 +78,11 @@ public class ResourceServerService {
this.adminEvent = adminEvent;
}
- public void create(boolean newClient) {
+ public ResourceServer create(boolean newClient) {
+ if (resourceServer != null) {
+ throw new IllegalStateException("Resource server already created");
+ }
+
this.auth.realm().requireManageAuthorization();
UserModel serviceAccount = this.session.users().getServiceAccount(client);
@@ -96,6 +95,8 @@ public class ResourceServerService {
createDefaultRoles(serviceAccount);
createDefaultPermission(createDefaultResource(), createDefaultPolicy());
audit(OperationType.CREATE, uriInfo, newClient);
+
+ return resourceServer;
}
@PUT
@@ -111,22 +112,7 @@ public class ResourceServerService {
public void delete() {
this.auth.realm().requireManageAuthorization();
- StoreFactory storeFactory = authorization.getStoreFactory();
- ResourceStore resourceStore = storeFactory.getResourceStore();
- String id = resourceServer.getId();
-
- PolicyStore policyStore = storeFactory.getPolicyStore();
-
- policyStore.findByResourceServer(id).forEach(scope -> policyStore.delete(scope.getId()));
-
- resourceStore.findByResourceServer(id).forEach(resource -> resourceStore.delete(resource.getId()));
-
- ScopeStore scopeStore = storeFactory.getScopeStore();
-
- scopeStore.findByResourceServer(id).forEach(scope -> scopeStore.delete(scope.getId()));
-
- storeFactory.getResourceServerStore().delete(id);
-
+ authorization.getStoreFactory().getResourceServerStore().delete(resourceServer.getId());
audit(OperationType.DELETE, uriInfo, false);
}
@@ -148,7 +134,7 @@ public class ResourceServerService {
@Path("/import")
@POST
@Consumes(MediaType.APPLICATION_JSON)
- public Response importSettings(@Context final UriInfo uriInfo, ResourceServerRepresentation rep) throws IOException {
+ public Response importSettings(@Context final UriInfo uriInfo, ResourceServerRepresentation rep) {
this.auth.realm().requireManageAuthorization();
rep.setClientId(client.getId());
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java
index decb4da..c0ea7df 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java
@@ -33,6 +33,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.idm.ClientRepresentation;
+import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import org.keycloak.services.ErrorResponse;
import org.keycloak.services.ErrorResponseException;
import org.keycloak.services.ForbiddenException;
@@ -188,7 +189,15 @@ public class ClientsResource {
if (Profile.isFeatureEnabled(Profile.Feature.AUTHORIZATION)) {
if (TRUE.equals(rep.getAuthorizationServicesEnabled())) {
- getAuthorizationService(clientModel).enable(true);
+ AuthorizationService authorizationService = getAuthorizationService(clientModel);
+
+ authorizationService.enable(true);
+
+ ResourceServerRepresentation authorizationSettings = rep.getAuthorizationSettings();
+
+ if (authorizationSettings != null) {
+ authorizationService.resourceServer().importSettings(uriInfo, authorizationSettings);
+ }
}
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/ResourceServerManagementTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/ResourceServerManagementTest.java
new file mode 100644
index 0000000..73e1961
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/ResourceServerManagementTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017 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.testsuite.admin.client.authorization;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.keycloak.admin.client.resource.AuthorizationResource;
+import org.keycloak.admin.client.resource.ClientsResource;
+import org.keycloak.representations.idm.ClientRepresentation;
+import org.keycloak.representations.idm.authorization.PolicyEnforcementMode;
+import org.keycloak.util.JsonSerialization;
+
+/**
+ *
+ * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
+ */
+public class ResourceServerManagementTest extends AbstractAuthorizationTest {
+
+ @Test
+ public void testCreateAndDeleteResourceServer() throws Exception {
+ ClientsResource clientsResource = testRealmResource().clients();
+
+ clientsResource.create(JsonSerialization.readValue(getClass().getResourceAsStream("/authorization-test/client-with-authz-settings.json"), ClientRepresentation.class)).close();
+
+ List<ClientRepresentation> clients = clientsResource.findByClientId("authz-client");
+
+ assertFalse(clients.isEmpty());
+
+ String clientId = clients.get(0).getId();
+ AuthorizationResource settings = clientsResource.get(clientId).authorization();
+
+ assertEquals(PolicyEnforcementMode.PERMISSIVE, settings.exportSettings().getPolicyEnforcementMode());
+
+ assertFalse(settings.resources().findByName("Resource 1").isEmpty());
+ assertFalse(settings.resources().findByName("Resource 15").isEmpty());
+ assertFalse(settings.resources().findByName("Resource 20").isEmpty());
+
+ assertNotNull(settings.permissions().resource().findByName("Resource 15 Permission"));
+ assertNotNull(settings.policies().role().findByName("Resource 1 Policy"));
+
+ clientsResource.get(clientId).remove();
+
+ clients = clientsResource.findByClientId("authz-client");
+
+ assertTrue(clients.isEmpty());
+ }
+}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/client-with-authz-settings.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/client-with-authz-settings.json
new file mode 100644
index 0000000..ccc3ccc
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/client-with-authz-settings.json
@@ -0,0 +1,866 @@
+{
+ "clientId": "authz-client",
+ "enabled": true,
+ "publicClient": false,
+ "secret": "secret",
+ "directAccessGrantsEnabled": true,
+ "serviceAccountsEnabled": true,
+ "authorizationServicesEnabled": true,
+ "redirectUris": [
+ "http://localhost/authz-client/*"
+ ],
+ "webOrigins": [
+ "http://localhost"
+ ],
+ "authorizationSettings": {
+ "allowRemoteResourceManagement": true,
+ "policyEnforcementMode": "PERMISSIVE",
+ "resources": [
+ {
+ "name": "Default Resource",
+ "uri": "/*",
+ "type": "urn:authz-client:resources:default"
+ },
+ {
+ "name": "Resource 1",
+ "uri": "/protected/resource/1",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 2",
+ "uri": "/protected/resource/2",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 3",
+ "uri": "/protected/resource/3",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 4",
+ "uri": "/protected/resource/4",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 5",
+ "uri": "/protected/resource/5",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 6",
+ "uri": "/protected/resource/6",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 7",
+ "uri": "/protected/resource/7",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 8",
+ "uri": "/protected/resource/8",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 9",
+ "uri": "/protected/resource/9",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 10",
+ "uri": "/protected/resource/10",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 11",
+ "uri": "/protected/resource/11",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 12",
+ "uri": "/protected/resource/12",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 13",
+ "uri": "/protected/resource/13",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 14",
+ "uri": "/protected/resource/14",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 15",
+ "uri": "/protected/resource/15",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 16",
+ "uri": "/protected/resource/16",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 17",
+ "uri": "/protected/resource/17",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 18",
+ "uri": "/protected/resource/18",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 19",
+ "uri": "/protected/resource/19",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ },
+ {
+ "name": "Resource 20",
+ "uri": "/protected/resource/20",
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ }
+ ],
+ "policies": [
+ {
+ "name": "Default Policy",
+ "description": "A policy that grants access only for users within this realm",
+ "type": "js",
+ "logic": "POSITIVE",
+ "decisionStrategy": "AFFIRMATIVE",
+ "config": {
+ "code": "// by default, grants any permission associated with this policy\n$evaluation.grant();\n"
+ }
+ },
+ {
+ "name": "Resource 1 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 2 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 3 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 4 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 5 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 6 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 7 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 8 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 9 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 10 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 11 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 12 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 13 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 14 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 15 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 16 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 17 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 18 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 19 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Resource 20 Policy",
+ "type": "role",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "roles": "[{\"id\":\"authz-client/uma_protection\",\"required\":false}]"
+ }
+ },
+ {
+ "name": "Default Permission",
+ "description": "A permission that applies to the default resource type",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "defaultResourceType": "urn:authz-client:resources:default",
+ "applyPolicies": "[\"Default Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 1 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 1\"]",
+ "applyPolicies": "[\"Resource 1 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 2 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 2\"]",
+ "applyPolicies": "[\"Resource 2 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 3 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 3\"]",
+ "applyPolicies": "[\"Resource 3 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 4 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 4\"]",
+ "applyPolicies": "[\"Resource 4 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 5 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 5\"]",
+ "applyPolicies": "[\"Resource 5 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 6 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 6\"]",
+ "applyPolicies": "[\"Resource 6 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 7 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 7\"]",
+ "applyPolicies": "[\"Resource 7 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 8 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 8\"]",
+ "applyPolicies": "[\"Resource 8 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 9 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 9\"]",
+ "applyPolicies": "[\"Resource 9 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 10 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 10\"]",
+ "applyPolicies": "[\"Resource 10 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 11 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 11\"]",
+ "applyPolicies": "[\"Resource 11 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 12 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 12\"]",
+ "applyPolicies": "[\"Resource 12 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 13 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 13\"]",
+ "applyPolicies": "[\"Resource 13 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 14 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 14\"]",
+ "applyPolicies": "[\"Resource 14 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 15 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 15\"]",
+ "applyPolicies": "[\"Resource 15 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 16 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 16\"]",
+ "applyPolicies": "[\"Resource 16 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 17 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 17\"]",
+ "applyPolicies": "[\"Resource 17 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 18 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 18\"]",
+ "applyPolicies": "[\"Resource 18 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 19 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 19\"]",
+ "applyPolicies": "[\"Resource 19 Policy\"]"
+ }
+ },
+ {
+ "name": "Resource 20 Permission",
+ "type": "resource",
+ "logic": "POSITIVE",
+ "decisionStrategy": "UNANIMOUS",
+ "config": {
+ "resources": "[\"Resource 20\"]",
+ "applyPolicies": "[\"Resource 20 Policy\"]"
+ }
+ }
+ ],
+ "scopes": [
+ {
+ "name": "Scope B"
+ },
+ {
+ "name": "Scope A"
+ },
+ {
+ "name": "Scope D"
+ },
+ {
+ "name": "Scope C"
+ },
+ {
+ "name": "Scope E"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java
index fee3da3..de9c13c 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java
@@ -27,6 +27,7 @@ import org.keycloak.testsuite.console.page.clients.authorization.policy.PolicyTy
import org.keycloak.testsuite.page.Form;
import org.keycloak.testsuite.util.URLUtils;
import org.keycloak.testsuite.util.WaitUtils;
+import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.ui.Select;
@@ -123,4 +124,15 @@ public class Permissions extends Form {
}
}
}
+
+ public void deleteFromList(String name) {
+ for (WebElement row : permissions().rows()) {
+ PolicyRepresentation actual = permissions().toRepresentation(row);
+ if (actual.getName().equalsIgnoreCase(name)) {
+ row.findElements(tagName("td")).get(4).click();
+ driver.findElement(By.xpath(".//button[text()='Delete']")).click();
+ return;
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java
index 7ac4b52..a42e12e 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java
@@ -32,6 +32,7 @@ import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
import org.keycloak.testsuite.page.Form;
import org.keycloak.testsuite.util.URLUtils;
import org.keycloak.testsuite.util.WaitUtils;
+import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.ui.Select;
@@ -199,4 +200,15 @@ public class Policies extends Form {
}
}
}
+
+ public void deleteFromList(String name) {
+ for (WebElement row : policies().rows()) {
+ PolicyRepresentation actual = policies().toRepresentation(row);
+ if (actual.getName().equalsIgnoreCase(name)) {
+ row.findElements(tagName("td")).get(4).click();
+ driver.findElement(By.xpath(".//button[text()='Delete']")).click();
+ return;
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resources.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resources.java
index 0290bc1..199be95 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resources.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resources.java
@@ -23,6 +23,7 @@ import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.testsuite.page.Form;
import org.keycloak.testsuite.util.URLUtils;
import org.keycloak.testsuite.util.WaitUtils;
+import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@@ -73,6 +74,17 @@ public class Resources extends Form {
}
}
+ public void deleteFromList(String name) {
+ for (WebElement row : resources().rows()) {
+ ResourceRepresentation actual = resources().toRepresentation(row);
+ if (actual.getName().equalsIgnoreCase(name)) {
+ row.findElements(tagName("td")).get(6).click();
+ driver.findElement(By.xpath(".//button[text()='Delete']")).click();
+ return;
+ }
+ }
+ }
+
public Resource name(String name) {
for (WebElement row : resources().rows()) {
ResourceRepresentation actual = resources().toRepresentation(row);
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scopes.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scopes.java
index 4e706e7..3974e35 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scopes.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scopes.java
@@ -22,6 +22,7 @@ import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.testsuite.page.Form;
import org.keycloak.testsuite.util.URLUtils;
+import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@@ -67,4 +68,14 @@ public class Scopes extends Form {
}
}
}
+
+ public void deleteFromList(String name) {
+ for (WebElement row : scopes().rows()) {
+ ScopeRepresentation actual = scopes().toRepresentation(row);
+ if (actual.getName().equalsIgnoreCase(name)) {
+ row.findElements(tagName("td")).get(3).click();
+ driver.findElement(By.xpath(".//button[text()='Delete']")).click();
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AggregatePolicyManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AggregatePolicyManagementTest.java
index f1bba0d..be2a984 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AggregatePolicyManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AggregatePolicyManagementTest.java
@@ -122,6 +122,22 @@ public class AggregatePolicyManagementTest extends AbstractAuthorizationSettings
assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
}
+ @Test
+ public void testDeleteFromList() throws InterruptedException {
+ authorizationPage.navigateTo();
+ AggregatePolicyRepresentation expected = new AggregatePolicyRepresentation();
+
+ expected.setName("Test Delete Aggregate Policy");
+ expected.setDescription("description");
+ expected.addPolicy("Policy C");
+
+ expected = createPolicy(expected);
+ authorizationPage.navigateTo();
+ authorizationPage.authorizationTabs().policies().deleteFromList(expected.getName());
+ authorizationPage.navigateTo();
+ assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
+ }
+
private AggregatePolicyRepresentation createPolicy(AggregatePolicyRepresentation expected) {
AggregatePolicy policy = authorizationPage.authorizationTabs().policies().create(expected);
assertAlertSuccess();
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ClientPolicyManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ClientPolicyManagementTest.java
index 2c95b83..04e9826 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ClientPolicyManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ClientPolicyManagementTest.java
@@ -76,7 +76,7 @@ public class ClientPolicyManagementTest extends AbstractAuthorizationSettingsTes
}
@Test
- public void testDeletePolicy() throws InterruptedException {
+ public void testDelete() throws InterruptedException {
authorizationPage.navigateTo();
ClientPolicyRepresentation expected = new ClientPolicyRepresentation();
@@ -92,6 +92,22 @@ public class ClientPolicyManagementTest extends AbstractAuthorizationSettingsTes
assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
}
+ @Test
+ public void testDeleteFromList() throws InterruptedException {
+ authorizationPage.navigateTo();
+ ClientPolicyRepresentation expected = new ClientPolicyRepresentation();
+
+ expected.setName("Test Client Policy");
+ expected.setDescription("description");
+ expected.addClient("client c");
+
+ expected = createPolicy(expected);
+ authorizationPage.navigateTo();
+ authorizationPage.authorizationTabs().policies().deleteFromList(expected.getName());
+ authorizationPage.navigateTo();
+ assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
+ }
+
private ClientPolicyRepresentation createPolicy(ClientPolicyRepresentation expected) {
ClientPolicy policy = authorizationPage.authorizationTabs().policies().create(expected);
assertAlertSuccess();
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/GroupPolicyManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/GroupPolicyManagementTest.java
index e8b05bf..91c86f9 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/GroupPolicyManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/GroupPolicyManagementTest.java
@@ -135,6 +135,25 @@ public class GroupPolicyManagementTest extends AbstractAuthorizationSettingsTest
assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
}
+ @Test
+ public void testDeleteFromList() throws InterruptedException {
+ authorizationPage.navigateTo();
+ GroupPolicyRepresentation expected = new GroupPolicyRepresentation();
+
+ expected.setName("Test Delete Group Policy");
+ expected.setDescription("description");
+ expected.setGroupsClaim("groups");
+ expected.addGroupPath("/Group A", true);
+ expected.addGroupPath("/Group A/Group B/Group D");
+ expected.addGroupPath("Group F");
+
+ expected = createPolicy(expected);
+ authorizationPage.navigateTo();
+ authorizationPage.authorizationTabs().policies().deleteFromList(expected.getName());
+ authorizationPage.navigateTo();
+ assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
+ }
+
private GroupPolicyRepresentation createPolicy(GroupPolicyRepresentation expected) {
GroupPolicy policy = authorizationPage.authorizationTabs().policies().create(expected);
assertAlertSuccess();
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/JSPolicyManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/JSPolicyManagementTest.java
index 0b9113c..6da809c 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/JSPolicyManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/JSPolicyManagementTest.java
@@ -74,6 +74,22 @@ public class JSPolicyManagementTest extends AbstractAuthorizationSettingsTest {
assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
}
+ @Test
+ public void testDeleteFromList() throws InterruptedException {
+ authorizationPage.navigateTo();
+ JSPolicyRepresentation expected = new JSPolicyRepresentation();
+
+ expected.setName("Test JS Policy");
+ expected.setDescription("description");
+ expected.setCode("$evaluation.deny();");
+
+ expected = createPolicy(expected);
+ authorizationPage.navigateTo();
+ authorizationPage.authorizationTabs().policies().deleteFromList(expected.getName());
+ authorizationPage.navigateTo();
+ assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
+ }
+
private JSPolicyRepresentation createPolicy(JSPolicyRepresentation expected) {
JSPolicy policy = authorizationPage.authorizationTabs().policies().create(expected);
assertAlertSuccess();
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourceManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourceManagementTest.java
index 75a479a..3d29c03 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourceManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourceManagementTest.java
@@ -72,7 +72,7 @@ public class ResourceManagementTest extends AbstractAuthorizationSettingsTest {
}
@Test
- public void testDelete() {
+ public void testDeleteFromDetails() {
ResourceRepresentation expected = createResource();
authorizationPage.navigateTo();
authorizationPage.authorizationTabs().resources().delete(expected.getName());
@@ -80,6 +80,15 @@ public class ResourceManagementTest extends AbstractAuthorizationSettingsTest {
assertNull(authorizationPage.authorizationTabs().resources().resources().findByName(expected.getName()));
}
+ @Test
+ public void testDeleteFromList() {
+ ResourceRepresentation expected = createResource();
+ authorizationPage.navigateTo();
+ authorizationPage.authorizationTabs().resources().deleteFromList(expected.getName());
+ authorizationPage.navigateTo();
+ assertNull(authorizationPage.authorizationTabs().resources().resources().findByName(expected.getName()));
+ }
+
private ResourceRepresentation createResource() {
ResourceRepresentation expected = new ResourceRepresentation();
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourcePermissionManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourcePermissionManagementTest.java
index 4ff011a..f6a967e 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourcePermissionManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourcePermissionManagementTest.java
@@ -165,6 +165,23 @@ public class ResourcePermissionManagementTest extends AbstractAuthorizationSetti
assertNull(authorizationPage.authorizationTabs().permissions().permissions().findByName(expected.getName()));
}
+ @Test
+ public void testDeleteFromList() throws InterruptedException {
+ authorizationPage.navigateTo();
+ ResourcePermissionRepresentation expected = new ResourcePermissionRepresentation();
+
+ expected.setName("Test Delete Resource Permission");
+ expected.setDescription("description");
+ expected.addResource("Resource B");
+ expected.addPolicy("Policy C");
+
+ expected = createPermission(expected);
+ authorizationPage.navigateTo();
+ authorizationPage.authorizationTabs().permissions().deleteFromList(expected.getName());
+ authorizationPage.navigateTo();
+ assertNull(authorizationPage.authorizationTabs().permissions().permissions().findByName(expected.getName()));
+ }
+
private ResourcePermissionRepresentation createPermission(ResourcePermissionRepresentation expected) {
ResourcePermission policy = authorizationPage.authorizationTabs().permissions().create(expected);
assertAlertSuccess();
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/RolePolicyManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/RolePolicyManagementTest.java
index 44e4f70..e8794cc 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/RolePolicyManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/RolePolicyManagementTest.java
@@ -208,6 +208,24 @@ public class RolePolicyManagementTest extends AbstractAuthorizationSettingsTest
assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
}
+ @Test
+ public void testDeleteFromList() throws InterruptedException {
+ authorizationPage.navigateTo();
+ RolePolicyRepresentation expected = new RolePolicyRepresentation();
+
+ expected.setName("Test Delete Role Policy");
+ expected.setDescription("description");
+ expected.addRole("Realm Role A");
+ expected.addRole("Realm Role B");
+ expected.addRole("Realm Role C");
+
+ expected = createPolicy(expected);
+ authorizationPage.navigateTo();
+ authorizationPage.authorizationTabs().policies().deleteFromList(expected.getName());
+ authorizationPage.navigateTo();
+ assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
+ }
+
private RolePolicyRepresentation createPolicy(RolePolicyRepresentation expected) {
RolePolicy policy = authorizationPage.authorizationTabs().policies().create(expected);
assertAlertSuccess();
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/RulePolicyManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/RulePolicyManagementTest.java
index 09fb47a..a1fbb60 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/RulePolicyManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/RulePolicyManagementTest.java
@@ -71,6 +71,18 @@ public class RulePolicyManagementTest extends AbstractAuthorizationSettingsTest
assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
}
+ @Test
+ public void testDeleteFromList() throws InterruptedException {
+ authorizationPage.navigateTo();
+ RulePolicyRepresentation expected =createDefaultRepresentation("Delete Rule Policy");
+
+ expected = createPolicy(expected);
+ authorizationPage.navigateTo();
+ authorizationPage.authorizationTabs().policies().deleteFromList(expected.getName());
+ authorizationPage.navigateTo();
+ assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
+ }
+
private RulePolicyRepresentation createDefaultRepresentation(String name) {
RulePolicyRepresentation expected = new RulePolicyRepresentation();
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopeManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopeManagementTest.java
index 84a5c42..9bd5738 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopeManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopeManagementTest.java
@@ -49,6 +49,15 @@ public class ScopeManagementTest extends AbstractAuthorizationSettingsTest {
assertNull(authorizationPage.authorizationTabs().scopes().scopes().findByName(expected.getName()));
}
+ @Test
+ public void testDeleteFromList() {
+ ScopeRepresentation expected = createScope();
+ authorizationPage.navigateTo();
+ authorizationPage.authorizationTabs().scopes().deleteFromList(expected.getName());
+ authorizationPage.navigateTo();
+ assertNull(authorizationPage.authorizationTabs().scopes().scopes().findByName(expected.getName()));
+ }
+
private ScopeRepresentation createScope() {
ScopeRepresentation expected = new ScopeRepresentation();
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopePermissionManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopePermissionManagementTest.java
index 3dfd0c8..e755335 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopePermissionManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopePermissionManagementTest.java
@@ -166,6 +166,23 @@ public class ScopePermissionManagementTest extends AbstractAuthorizationSettings
assertNull(authorizationPage.authorizationTabs().permissions().permissions().findByName(expected.getName()));
}
+ @Test
+ public void testDeleteFromList() throws InterruptedException {
+ authorizationPage.navigateTo();
+ ScopePermissionRepresentation expected = new ScopePermissionRepresentation();
+
+ expected.setName("Test Delete Scope Permission");
+ expected.setDescription("description");
+ expected.addScope("Scope C");
+ expected.addPolicy("Policy C");
+
+ expected = createPermission(expected);
+ authorizationPage.navigateTo();
+ authorizationPage.authorizationTabs().permissions().deleteFromList(expected.getName());
+ authorizationPage.navigateTo();
+ assertNull(authorizationPage.authorizationTabs().permissions().permissions().findByName(expected.getName()));
+ }
+
private ScopePermissionRepresentation createPermission(ScopePermissionRepresentation expected) {
ScopePermission policy = authorizationPage.authorizationTabs().permissions().create(expected);
assertAlertSuccess();
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/TimePolicyManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/TimePolicyManagementTest.java
index 6242c77..ed0165d 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/TimePolicyManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/TimePolicyManagementTest.java
@@ -109,6 +109,33 @@ public class TimePolicyManagementTest extends AbstractAuthorizationSettingsTest
assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
}
+ @Test
+ public void testDeleteFromList() throws InterruptedException {
+ authorizationPage.navigateTo();
+ TimePolicyRepresentation expected = new TimePolicyRepresentation();
+
+ expected.setName("Test Time Policy");
+ expected.setDescription("description");
+ expected.setNotBefore("2017-01-01 00:00:00");
+ expected.setNotBefore("2018-01-01 00:00:00");
+ expected.setDayMonth("1");
+ expected.setDayMonthEnd("2");
+ expected.setMonth("3");
+ expected.setMonthEnd("4");
+ expected.setYear("5");
+ expected.setYearEnd("6");
+ expected.setHour("7");
+ expected.setHourEnd("8");
+ expected.setMinute("9");
+ expected.setMinuteEnd("10");
+
+ expected = createPolicy(expected);
+ authorizationPage.navigateTo();
+ authorizationPage.authorizationTabs().policies().deleteFromList(expected.getName());
+ authorizationPage.navigateTo();
+ assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
+ }
+
private TimePolicyRepresentation createPolicy(TimePolicyRepresentation expected) {
TimePolicy policy = authorizationPage.authorizationTabs().policies().create(expected);
assertAlertSuccess();
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/UserPolicyManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/UserPolicyManagementTest.java
index ed19bc5..7e8c483 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/UserPolicyManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/UserPolicyManagementTest.java
@@ -76,7 +76,7 @@ public class UserPolicyManagementTest extends AbstractAuthorizationSettingsTest
}
@Test
- public void testDeletePolicy() throws InterruptedException {
+ public void testDelete() throws InterruptedException {
authorizationPage.navigateTo();
UserPolicyRepresentation expected = new UserPolicyRepresentation();
@@ -92,6 +92,22 @@ public class UserPolicyManagementTest extends AbstractAuthorizationSettingsTest
assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
}
+ @Test
+ public void testDeleteFromList() throws InterruptedException {
+ authorizationPage.navigateTo();
+ UserPolicyRepresentation expected = new UserPolicyRepresentation();
+
+ expected.setName("Test User Policy");
+ expected.setDescription("description");
+ expected.addUser("user c");
+
+ expected = createPolicy(expected);
+ authorizationPage.navigateTo();
+ authorizationPage.authorizationTabs().policies().deleteFromList(expected.getName());
+ authorizationPage.navigateTo();
+ assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
+ }
+
private UserPolicyRepresentation createPolicy(UserPolicyRepresentation expected) {
UserPolicy policy = authorizationPage.authorizationTabs().policies().create(expected);
assertAlertSuccess();
diff --git a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
index 134b12a..36ecfaf 100644
--- a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
+++ b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
@@ -79,7 +79,72 @@ module.controller('ResourceServerDetailCtrl', function($scope, $http, $route, $l
});
});
-module.controller('ResourceServerResourceCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerResource, client) {
+var Resources = {
+ delete: function(ResourceServerResource, realm, client, $scope, AuthzDialog, $location, Notifications, $route) {
+ ResourceServerResource.permissions({
+ realm : realm,
+ client : client.id,
+ rsrid : $scope.resource._id
+ }, function (permissions) {
+ var msg = "";
+
+ if (permissions.length > 0 && !$scope.deleteConsent) {
+ msg = "<p>This resource is referenced in some permissions:</p>";
+ msg += "<ul>";
+ for (i = 0; i < permissions.length; i++) {
+ msg+= "<li><strong>" + permissions[i].name + "</strong></li>";
+ }
+ msg += "</ul>";
+ msg += "<p>If you remove this resource, the permissions above will be affected and will not be associated with this resource anymore.</p>";
+ }
+
+ AuthzDialog.confirmDeleteWithMsg($scope.resource.name, "Resource", msg, function() {
+ ResourceServerResource.delete({realm : realm, client : $scope.client.id, rsrid : $scope.resource._id}, null, function() {
+ $location.url("/realms/" + realm + "/clients/" + $scope.client.id + "/authz/resource-server/resource");
+ $route.reload();
+ Notifications.success("The resource has been deleted.");
+ });
+ });
+ });
+ }
+}
+
+var Policies = {
+ delete: function(service, realm, client, $scope, AuthzDialog, $location, Notifications, $route, isPermission) {
+ var msg = "";
+
+ service.dependentPolicies({
+ realm : realm,
+ client : client.id,
+ id : $scope.policy.id
+ }, function (dependentPolicies) {
+ if (dependentPolicies.length > 0 && !$scope.deleteConsent) {
+ msg = "<p>This policy is being used by other policies:</p>";
+ msg += "<ul>";
+ for (i = 0; i < dependentPolicies.length; i++) {
+ msg+= "<li><strong>" + dependentPolicies[i].name + "</strong></li>";
+ }
+ msg += "</ul>";
+ msg += "<p>If you remove this policy, the policies above will be affected and will not be associated with this policy anymore.</p>";
+ }
+
+ AuthzDialog.confirmDeleteWithMsg($scope.policy.name, isPermission ? "Permission" : "Policy", msg, function() {
+ service.delete({realm : realm, client : $scope.client.id, id : $scope.policy.id}, null, function() {
+ if (isPermission) {
+ $location.url("/realms/" + realm + "/clients/" + $scope.client.id + "/authz/resource-server/permission");
+ Notifications.success("The permission has been deleted.");
+ } else {
+ $location.url("/realms/" + realm + "/clients/" + $scope.client.id + "/authz/resource-server/policy");
+ Notifications.success("The policy has been deleted.");
+ }
+ $route.reload();
+ });
+ });
+ });
+ }
+}
+
+module.controller('ResourceServerResourceCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerResource, client, AuthzDialog, Notifications) {
$scope.realm = realm;
$scope.client = client;
@@ -171,6 +236,11 @@ module.controller('ResourceServerResourceCtrl', function($scope, $http, $route,
}
}
};
+
+ $scope.delete = function(resource) {
+ $scope.resource = resource;
+ Resources.delete(ResourceServerResource, $route.current.params.realm, client, $scope, AuthzDialog, $location, Notifications, $route);
+ };
});
module.controller('ResourceServerResourceDetailCtrl', function($scope, $http, $route, $location, realm, ResourceServer, client, ResourceServerResource, ResourceServerScope, AuthzDialog, Notifications) {
@@ -282,30 +352,7 @@ module.controller('ResourceServerResourceDetailCtrl', function($scope, $http, $r
}
$scope.remove = function() {
- ResourceServerResource.permissions({
- realm : $route.current.params.realm,
- client : client.id,
- rsrid : $scope.resource._id
- }, function (permissions) {
- var msg = "";
-
- if (permissions.length > 0 && !$scope.deleteConsent) {
- msg = "<p>This resource is referenced in some policies:</p>";
- msg += "<ul>";
- for (i = 0; i < permissions.length; i++) {
- msg+= "<li><strong>" + permissions[i].name + "</strong></li>";
- }
- msg += "</ul>";
- msg += "<p>If you remove this resource, the policies above will be affected and will not be associated with this resource anymore.</p>";
- }
-
- AuthzDialog.confirmDeleteWithMsg($scope.resource.name, "Resource", msg, function() {
- ResourceServerResource.delete({realm : realm.realm, client : $scope.client.id, rsrid : $scope.resource._id}, null, function() {
- $location.url("/realms/" + realm.realm + "/clients/" + $scope.client.id + "/authz/resource-server/resource");
- Notifications.success("The resource has been deleted.");
- });
- });
- });
+ Resources.delete(ResourceServerResource, $route.current.params.realm, client, $scope, AuthzDialog, $location, Notifications, $route);
}
$scope.reset = function() {
@@ -338,7 +385,37 @@ module.controller('ResourceServerResourceDetailCtrl', function($scope, $http, $r
}
});
-module.controller('ResourceServerScopeCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerScope, client) {
+var Scopes = {
+ delete: function(ResourceServerScope, realm, client, $scope, AuthzDialog, $location, Notifications, $route) {
+ ResourceServerScope.permissions({
+ realm : realm,
+ client : client.id,
+ id : $scope.scope.id
+ }, function (permissions) {
+ var msg = "";
+
+ if (permissions.length > 0 && !$scope.deleteConsent) {
+ msg = "<p>This scope is referenced in some permissions:</p>";
+ msg += "<ul>";
+ for (i = 0; i < permissions.length; i++) {
+ msg+= "<li><strong>" + permissions[i].name + "</strong></li>";
+ }
+ msg += "</ul>";
+ msg += "<p>If you remove this scope, the permissions above will be affected and will not be associated with this scope anymore.</p>";
+ }
+
+ AuthzDialog.confirmDeleteWithMsg($scope.scope.name, "Scope", msg, function() {
+ ResourceServerScope.delete({realm : realm, client : $scope.client.id, id : $scope.scope.id}, null, function() {
+ $location.url("/realms/" + realm + "/clients/" + $scope.client.id + "/authz/resource-server/scope");
+ $route.reload();
+ Notifications.success("The scope has been deleted.");
+ });
+ });
+ });
+ }
+}
+
+module.controller('ResourceServerScopeCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerScope,client, AuthzDialog, Notifications) {
$scope.realm = realm;
$scope.client = client;
@@ -430,6 +507,11 @@ module.controller('ResourceServerScopeCtrl', function($scope, $http, $route, $lo
}
}
};
+
+ $scope.delete = function(scope) {
+ $scope.scope = scope;
+ Scopes.delete(ResourceServerScope, $route.current.params.realm, client, $scope, AuthzDialog, $location, Notifications, $route);
+ };
});
module.controller('ResourceServerScopeDetailCtrl', function($scope, $http, $route, $location, realm, ResourceServer, client, ResourceServerScope, AuthzDialog, Notifications) {
@@ -499,30 +581,7 @@ module.controller('ResourceServerScopeDetailCtrl', function($scope, $http, $rout
}
$scope.remove = function() {
- ResourceServerScope.permissions({
- realm : $route.current.params.realm,
- client : client.id,
- id : $scope.scope.id
- }, function (permissions) {
- var msg = "";
-
- if (permissions.length > 0 && !$scope.deleteConsent) {
- msg = "<p>This scope is referenced in some policies:</p>";
- msg += "<ul>";
- for (i = 0; i < permissions.length; i++) {
- msg+= "<li><strong>" + permissions[i].name + "</strong></li>";
- }
- msg += "</ul>";
- msg += "<p>If you remove this scope, the policies above will be affected and will not be associated with this scope anymore.</p>";
- }
-
- AuthzDialog.confirmDeleteWithMsg($scope.scope.name, "Scope", msg, function() {
- ResourceServerScope.delete({realm : realm.realm, client : $scope.client.id, id : $scope.scope.id}, null, function() {
- $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/scope");
- Notifications.success("The scope has been deleted.");
- });
- });
- });
+ Scopes.delete(ResourceServerScope, $route.current.params.realm, client, $scope, AuthzDialog, $location, Notifications, $route);
}
$scope.reset = function() {
@@ -554,7 +613,7 @@ module.controller('ResourceServerScopeDetailCtrl', function($scope, $http, $rout
}
});
-module.controller('ResourceServerPolicyCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerPolicy, PolicyProvider, client) {
+module.controller('ResourceServerPolicyCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerPolicy, PolicyProvider, client, AuthzDialog, Notifications) {
$scope.realm = realm;
$scope.client = client;
$scope.policyProviders = [];
@@ -650,9 +709,14 @@ module.controller('ResourceServerPolicyCtrl', function($scope, $http, $route, $l
}
}
};
+
+ $scope.delete = function(policy) {
+ $scope.policy = policy;
+ Policies.delete(ResourceServerPolicy, $route.current.params.realm, client, $scope, AuthzDialog, $location, Notifications, $route, false);
+ };
});
-module.controller('ResourceServerPermissionCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerPermission, PolicyProvider, client) {
+module.controller('ResourceServerPermissionCtrl', function($scope, $http, $route, $location, realm, ResourceServer, ResourceServerPermission, PolicyProvider, client, AuthzDialog, Notifications) {
$scope.realm = realm;
$scope.client = client;
$scope.policyProviders = [];
@@ -747,6 +811,11 @@ module.controller('ResourceServerPermissionCtrl', function($scope, $http, $route
}
}
};
+
+ $scope.delete = function(policy) {
+ $scope.policy = policy;
+ Policies.delete(ResourceServerPermission, $route.current.params.realm, client, $scope, AuthzDialog, $location, Notifications, $route, true);
+ };
});
module.controller('ResourceServerPolicyDroolsDetailCtrl', function($scope, $http, $route, realm, client, PolicyController) {
@@ -1137,27 +1206,28 @@ module.controller('ResourceServerPolicyScopeDetailCtrl', function($scope, $route
rsrid: resource[0]._id
}, function (scopes) {
$scope.resourceScopes = scopes;
- ResourceServerPolicy.scopes({
- realm : $route.current.params.realm,
- client : client.id,
- id : policy.id
- }, function(scopes) {
- $scope.selectedScopes = [];
- for (i = 0; i < scopes.length; i++) {
- scopes[i].text = scopes[i].name;
- $scope.selectedScopes.push(scopes[i].id);
- }
- var copy = angular.copy($scope.selectedScopes);
- $scope.$watch('selectedScopes', function() {
- if (!angular.equals($scope.selectedScopes, copy)) {
- $scope.changed = true;
- }
- }, true);
- });
});
});
});
}
+
+ ResourceServerPolicy.scopes({
+ realm : $route.current.params.realm,
+ client : client.id,
+ id : policy.id
+ }, function(scopes) {
+ $scope.selectedScopes = [];
+ for (i = 0; i < scopes.length; i++) {
+ scopes[i].text = scopes[i].name;
+ $scope.selectedScopes.push(scopes[i].id);
+ }
+ var copy = angular.copy($scope.selectedScopes);
+ $scope.$watch('selectedScopes', function() {
+ if (!angular.equals($scope.selectedScopes, copy)) {
+ $scope.changed = true;
+ }
+ }, true);
+ });
} else {
$scope.selectedResource = null;
var copy = angular.copy($scope.selectedResource);
@@ -2098,35 +2168,7 @@ module.service("PolicyController", function($http, $route, $location, ResourceSe
});
$scope.remove = function() {
- var msg = "";
-
- service.dependentPolicies({
- realm : $route.current.params.realm,
- client : client.id,
- id : $scope.policy.id
- }, function (dependentPolicies) {
- if (dependentPolicies.length > 0 && !$scope.deleteConsent) {
- msg = "<p>This policy is being used by other policies:</p>";
- msg += "<ul>";
- for (i = 0; i < dependentPolicies.length; i++) {
- msg+= "<li><strong>" + dependentPolicies[i].name + "</strong></li>";
- }
- msg += "</ul>";
- msg += "<p>If you remove this policy, the policies above will be affected and will not be associated with this policy anymore.</p>";
- }
-
- AuthzDialog.confirmDeleteWithMsg($scope.policy.name, "Policy", msg, function() {
- service.delete({realm : $scope.realm.realm, client : $scope.client.id, id : $scope.policy.id}, null, function() {
- if (delegate.isPermission()) {
- $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/permission");
- Notifications.success("The permission has been deleted.");
- } else {
- $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/authz/resource-server/policy");
- Notifications.success("The policy has been deleted.");
- }
- });
- });
- });
+ Policies.delete(ResourceServerPolicy, $route.current.params.realm, client, $scope, AuthzDialog, $location, Notifications, $route, delegate.isPermission());
}
}
});
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html
index 79cec9a..df4377f 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html
@@ -38,7 +38,6 @@
</div>
<div class="form-group clearfix" data-ng-show="selectedResource">
<label class="col-md-2 control-label" for="resourceScopes">{{:: 'authz-scopes' | translate}} <span class="required">*</span></label>
-
<div class="col-md-6">
<select ui-select2 id="resourceScopes"
data-ng-model="selectedScopes"