Merge pull request #4084 from pedroigor/KEYCLOAK-4755

[KEYCLOAK-4755] - Client UI Tests
This commit is contained in:
Pedro Igor 2017-04-26 13:29:00 -03:00 committed by GitHub
commit b78cc63f0d
27 changed files with 965 additions and 158 deletions

View file

@ -1,6 +1,6 @@
package org.keycloak.authorization.policy.provider.client;
import static org.keycloak.authorization.policy.provider.client.ClientPolicyProviderFactory.getClients;
import java.util.function.Function;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.Policy;
@ -9,24 +9,29 @@ import org.keycloak.authorization.policy.evaluation.EvaluationContext;
import org.keycloak.authorization.policy.provider.PolicyProvider;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
public class ClientPolicyProvider implements PolicyProvider {
private final Function<Policy, ClientPolicyRepresentation> representationFunction;
public ClientPolicyProvider(Function<Policy, ClientPolicyRepresentation> representationFunction) {
this.representationFunction = representationFunction;
}
@Override
public void evaluate(Evaluation evaluation) {
Policy policy = evaluation.getPolicy();
EvaluationContext context = evaluation.getContext();
String[] clients = getClients(policy);
ClientPolicyRepresentation representation = representationFunction.apply(evaluation.getPolicy());
AuthorizationProvider authorizationProvider = evaluation.getAuthorizationProvider();
RealmModel realm = authorizationProvider.getKeycloakSession().getContext().getRealm();
EvaluationContext context = evaluation.getContext();
if (clients.length > 0) {
for (String client : clients) {
ClientModel clientModel = realm.getClientById(client);
if (context.getAttributes().containsValue("kc.client.id", clientModel.getClientId())) {
evaluation.grant();
return;
}
for (String client : representation.getClients()) {
ClientModel clientModel = realm.getClientById(client);
if (context.getAttributes().containsValue("kc.client.id", clientModel.getClientId())) {
evaluation.grant();
return;
}
}
}

View file

@ -2,14 +2,17 @@ package org.keycloak.authorization.policy.provider.client;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.keycloak.Config;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.policy.provider.PolicyProvider;
import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
import org.keycloak.authorization.store.PolicyStore;
import org.keycloak.authorization.store.ResourceServerStore;
@ -17,12 +20,15 @@ import org.keycloak.authorization.store.StoreFactory;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmModel.ClientRemovedEvent;
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.util.JsonSerialization;
public class ClientPolicyProviderFactory implements PolicyProviderFactory {
public class ClientPolicyProviderFactory implements PolicyProviderFactory<ClientPolicyRepresentation> {
private ClientPolicyProvider provider = new ClientPolicyProvider();
private ClientPolicyProvider provider = new ClientPolicyProvider(policy -> toRepresentation(policy, new ClientPolicyRepresentation()));
@Override
public String getName() {
@ -40,8 +46,29 @@ public class ClientPolicyProviderFactory implements PolicyProviderFactory {
}
@Override
public PolicyProviderAdminService getAdminResource(ResourceServer resourceServer, AuthorizationProvider authorization) {
return null;
public ClientPolicyRepresentation toRepresentation(Policy policy, ClientPolicyRepresentation representation) {
representation.setClients(new HashSet<>(Arrays.asList(getClients(policy))));
return representation;
}
@Override
public Class<ClientPolicyRepresentation> getRepresentationType() {
return ClientPolicyRepresentation.class;
}
@Override
public void onCreate(Policy policy, ClientPolicyRepresentation representation, AuthorizationProvider authorization) {
updateClients(policy, representation.getClients(), authorization);
}
@Override
public void onUpdate(Policy policy, ClientPolicyRepresentation representation, AuthorizationProvider authorization) {
updateClients(policy, representation.getClients(), authorization);
}
@Override
public void onImport(Policy policy, PolicyRepresentation representation, AuthorizationProvider authorization) {
updateClients(policy, new HashSet<>(Arrays.asList(getClients(policy))), authorization);
}
@Override
@ -101,7 +128,41 @@ public class ClientPolicyProviderFactory implements PolicyProviderFactory {
return "client";
}
static String[] getClients(Policy policy) {
private void updateClients(Policy policy, Set<String> clients, AuthorizationProvider authorization) {
RealmModel realm = authorization.getKeycloakSession().getContext().getRealm();
if (clients == null || clients.isEmpty()) {
throw new RuntimeException("No client provided.");
}
Set<String> updatedClients = new HashSet<>();
for (String id : clients) {
ClientModel client = realm.getClientByClientId(id);
if (client == null) {
client = realm.getClientById(id);
}
if (client == null) {
throw new RuntimeException("Error while updating policy [" + policy.getName() + "]. Client [" + id + "] could not be found.");
}
updatedClients.add(client.getId());
}
try {
Map<String, String> config = policy.getConfig();
config.put("clients", JsonSerialization.writeValueAsString(updatedClients));
policy.setConfig(config);
} catch (IOException cause) {
throw new RuntimeException("Failed to serialize clients", cause);
}
}
private String[] getClients(Policy policy) {
String clients = policy.getConfig().get("clients");
if (clients != null) {

View file

@ -17,9 +17,9 @@
*/
package org.keycloak.authorization.policy.provider.role;
import static org.keycloak.authorization.policy.provider.role.RolePolicyProviderFactory.getRoles;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.identity.Identity;
@ -29,43 +29,43 @@ import org.keycloak.authorization.policy.provider.PolicyProvider;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public class RolePolicyProvider implements PolicyProvider {
private final Function<Policy, RolePolicyRepresentation> representationFunction;
public RolePolicyProvider(Function<Policy, RolePolicyRepresentation> representationFunction) {
this.representationFunction = representationFunction;
}
@Override
public void evaluate(Evaluation evaluation) {
Policy policy = evaluation.getPolicy();
Map<String, Object>[] roleIds = getRoles(policy);
Set<RolePolicyRepresentation.RoleDefinition> roleIds = representationFunction.apply(policy).getRoles();
AuthorizationProvider authorizationProvider = evaluation.getAuthorizationProvider();
RealmModel realm = authorizationProvider.getKeycloakSession().getContext().getRealm();
Identity identity = evaluation.getContext().getIdentity();
if (roleIds.length > 0) {
Identity identity = evaluation.getContext().getIdentity();
for (RolePolicyRepresentation.RoleDefinition roleDefinition : roleIds) {
RoleModel role = realm.getRoleById(roleDefinition.getId());
for (Map<String, Object> current : roleIds) {
RoleModel role = realm.getRoleById((String) current.get("id"));
if (role != null) {
boolean hasRole = hasRole(identity, role, realm);
if (role != null) {
boolean hasRole = hasRole(identity, role, realm);
if (!hasRole && Boolean.valueOf(isRequired(current))) {
evaluation.deny();
return;
} else if (hasRole) {
evaluation.grant();
}
if (!hasRole && roleDefinition.isRequired()) {
evaluation.deny();
return;
} else if (hasRole) {
evaluation.grant();
}
}
}
}
private boolean isRequired(Map<String, Object> current) {
return (boolean) current.getOrDefault("required", false);
}
private boolean hasRole(Identity identity, RoleModel role, RealmModel realm) {
String roleName = role.getName();
if (role.isClientRole()) {

View file

@ -23,7 +23,6 @@ import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.policy.provider.PolicyProvider;
import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
import org.keycloak.authorization.store.PolicyStore;
import org.keycloak.authorization.store.ResourceServerStore;
@ -53,7 +52,7 @@ import java.util.Set;
*/
public class RolePolicyProviderFactory implements PolicyProviderFactory<RolePolicyRepresentation> {
private RolePolicyProvider provider = new RolePolicyProvider();
private RolePolicyProvider provider = new RolePolicyProvider(policy -> toRepresentation(policy, new RolePolicyRepresentation()));
@Override
public String getName() {
@ -70,20 +69,15 @@ public class RolePolicyProviderFactory implements PolicyProviderFactory<RolePoli
return provider;
}
@Override
public PolicyProviderAdminService getAdminResource(ResourceServer resourceServer, AuthorizationProvider authorization) {
return null;
}
@Override
public PolicyProvider create(KeycloakSession session) {
return new RolePolicyProvider();
return provider;
}
@Override
public RolePolicyRepresentation toRepresentation(Policy policy, RolePolicyRepresentation representation) {
try {
representation.setRoles(JsonSerialization.readValue(policy.getConfig().get("roles"), Set.class));
representation.setRoles(new HashSet<>(Arrays.asList(JsonSerialization.readValue(policy.getConfig().get("roles"), RolePolicyRepresentation.RoleDefinition[].class))));
} catch (IOException cause) {
throw new RuntimeException("Failed to deserialize roles", cause);
}
@ -119,65 +113,63 @@ public class RolePolicyProviderFactory implements PolicyProviderFactory<RolePoli
}
private void updateRoles(Policy policy, AuthorizationProvider authorization, Set<RolePolicyRepresentation.RoleDefinition> roles) {
try {
RealmModel realm = authorization.getRealm();
Set<RolePolicyRepresentation.RoleDefinition> updatedRoles = new HashSet<>();
RealmModel realm = authorization.getRealm();
Set<RolePolicyRepresentation.RoleDefinition> updatedRoles = new HashSet<>();
if (roles != null) {
for (RolePolicyRepresentation.RoleDefinition definition : roles) {
String roleName = definition.getId();
String clientId = null;
int clientIdSeparator = roleName.indexOf("/");
if (roles != null) {
for (RolePolicyRepresentation.RoleDefinition definition : roles) {
String roleName = definition.getId();
String clientId = null;
int clientIdSeparator = roleName.indexOf("/");
if (clientIdSeparator != -1) {
clientId = roleName.substring(0, clientIdSeparator);
roleName = roleName.substring(clientIdSeparator + 1);
}
if (clientIdSeparator != -1) {
clientId = roleName.substring(0, clientIdSeparator);
roleName = roleName.substring(clientIdSeparator + 1);
}
RoleModel role;
RoleModel role;
if (clientId == null) {
role = realm.getRole(roleName);
if (role == null) {
role = realm.getRoleById(roleName);
}
} else {
ClientModel client = realm.getClientByClientId(clientId);
if (client == null) {
throw new RuntimeException("Client with id [" + clientId + "] not found.");
}
role = client.getRole(roleName);
}
// fallback to find any client role with the given name
if (role == null) {
String finalRoleName = roleName;
role = realm.getClients().stream().map(clientModel -> clientModel.getRole(finalRoleName)).filter(roleModel -> roleModel != null)
.findFirst().orElse(null);
}
if (clientId == null) {
role = realm.getRole(roleName);
if (role == null) {
throw new RuntimeException("Error while importing configuration. Role [" + roleName + "] could not be found.");
role = realm.getRoleById(roleName);
}
} else {
ClientModel client = realm.getClientByClientId(clientId);
if (client == null) {
throw new RuntimeException("Client with id [" + clientId + "] not found.");
}
definition.setId(role.getId());
role = client.getRole(roleName);
}
updatedRoles.add(definition);
// fallback to find any client role with the given name
if (role == null) {
String finalRoleName = roleName;
role = realm.getClients().stream().map(clientModel -> clientModel.getRole(finalRoleName)).filter(roleModel -> roleModel != null)
.findFirst().orElse(null);
}
try {
} catch (Exception e) {
throw new RuntimeException("Error while updating policy [" + policy.getName() + "].", e);
if (role == null) {
throw new RuntimeException("Error while updating policy [" + policy.getName() + "]. Role [" + roleName + "] could not be found.");
}
definition.setId(role.getId());
updatedRoles.add(definition);
}
}
try {
Map<String, String> config = policy.getConfig();
config.put("roles", JsonSerialization.writeValueAsString(updatedRoles));
policy.setConfig(config);
} catch (IOException cause) {
throw new RuntimeException("Failed to deserialize roles", cause);
throw new RuntimeException("Failed to serialize roles", cause);
}
}
@ -253,7 +245,7 @@ public class RolePolicyProviderFactory implements PolicyProviderFactory<RolePoli
return "role";
}
static Map<String, Object>[] getRoles(Policy policy) {
private Map<String, Object>[] getRoles(Policy policy) {
String roles = policy.getConfig().get("roles");
if (roles != null) {

View file

@ -17,30 +17,34 @@
*/
package org.keycloak.authorization.policy.provider.user;
import java.util.function.Function;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.policy.evaluation.Evaluation;
import org.keycloak.authorization.policy.evaluation.EvaluationContext;
import org.keycloak.authorization.policy.provider.PolicyProvider;
import static org.keycloak.authorization.policy.provider.user.UserPolicyProviderFactory.getUsers;
import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public class UserPolicyProvider implements PolicyProvider {
private final Function<Policy, UserPolicyRepresentation> representationFunction;
public UserPolicyProvider(Function<Policy, UserPolicyRepresentation> representationFunction) {
this.representationFunction = representationFunction;
}
@Override
public void evaluate(Evaluation evaluation) {
Policy policy = evaluation.getPolicy();
EvaluationContext context = evaluation.getContext();
String[] userIds = getUsers(policy);
UserPolicyRepresentation representation = representationFunction.apply(evaluation.getPolicy());
if (userIds.length > 0) {
for (String userId : userIds) {
if (context.getIdentity().getId().equals(userId)) {
evaluation.grant();
break;
}
for (String userId : representation.getUsers()) {
if (context.getIdentity().getId().equals(userId)) {
evaluation.grant();
break;
}
}
}

View file

@ -24,6 +24,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import org.keycloak.Config;
import org.keycloak.authorization.AuthorizationProvider;
@ -49,7 +50,7 @@ import org.keycloak.util.JsonSerialization;
*/
public class UserPolicyProviderFactory implements PolicyProviderFactory<UserPolicyRepresentation> {
private UserPolicyProvider provider = new UserPolicyProvider();
private UserPolicyProvider provider = new UserPolicyProvider((Function<Policy, UserPolicyRepresentation>) policy -> toRepresentation(policy, new UserPolicyRepresentation()));
@Override
public String getName() {
@ -110,42 +111,40 @@ public class UserPolicyProviderFactory implements PolicyProviderFactory<UserPoli
}
private void updateUsers(Policy policy, AuthorizationProvider authorization, Set<String> users) {
try {
KeycloakSession session = authorization.getKeycloakSession();
RealmModel realm = authorization.getRealm();
UserProvider userProvider = session.users();
Set<String> updatedUsers = new HashSet<>();
KeycloakSession session = authorization.getKeycloakSession();
RealmModel realm = authorization.getRealm();
UserProvider userProvider = session.users();
Set<String> updatedUsers = new HashSet<>();
if (users != null) {
for (String userId : users) {
UserModel user = null;
if (users != null) {
try {
for (String userId : users) {
UserModel user = null;
try {
user = userProvider.getUserByUsername(userId, realm);
} catch (Exception ignore) {
}
if (user == null) {
user = userProvider.getUserById(userId, realm);
}
if (user == null) {
throw new RuntimeException("Error while importing configuration. User [" + userId + "] could not be found.");
}
updatedUsers.add(user.getId());
}
} catch (Exception e) {
throw new RuntimeException("Error while updating policy [" + policy.getName() + "].", e);
user = userProvider.getUserByUsername(userId, realm);
} catch (Exception ignore) {
}
}
if (user == null) {
user = userProvider.getUserById(userId, realm);
}
if (user == null) {
throw new RuntimeException("Error while updating policy [" + policy.getName() + "]. User [" + userId + "] could not be found.");
}
updatedUsers.add(user.getId());
}
}
try {
Map<String, String> config = policy.getConfig();
config.put("users", JsonSerialization.writeValueAsString(updatedUsers));
policy.setConfig(config);
} catch (IOException cause) {
throw new RuntimeException("Failed to deserialize roles", cause);
throw new RuntimeException("Failed to serialize users", cause);
}
}

View file

@ -0,0 +1,49 @@
/*
* 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.representations.idm.authorization;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public class ClientPolicyRepresentation extends AbstractPolicyRepresentation {
private Set<String> clients;
@Override
public String getType() {
return "client";
}
public Set<String> getClients() {
return clients;
}
public void setClients(Set<String> clients) {
this.clients = clients;
}
public void addClient(String... id) {
if (this.clients == null) {
this.clients = new HashSet<>();
}
this.clients.addAll(Arrays.asList(id));
}
}

View file

@ -0,0 +1,50 @@
/*
* 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.admin.client.resource;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public interface ClientPoliciesResource {
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
Response create(ClientPolicyRepresentation representation);
@Path("{id}")
ClientPolicyResource findById(@PathParam("id") String id);
@Path("/search")
@GET
@Produces(MediaType.APPLICATION_JSON)
@NoCache
ClientPolicyRepresentation findByName(@QueryParam("name") String name);
}

View file

@ -0,0 +1,69 @@
/*
* 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.admin.client.resource;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public interface ClientPolicyResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
@NoCache
ClientPolicyRepresentation toRepresentation();
@PUT
@Consumes(MediaType.APPLICATION_JSON)
void update(ClientPolicyRepresentation representation);
@DELETE
void remove();
@Path("/associatedPolicies")
@GET
@Produces(MediaType.APPLICATION_JSON)
@NoCache
List<PolicyRepresentation> associatedPolicies();
@Path("/dependentPolicies")
@GET
@Produces(MediaType.APPLICATION_JSON)
@NoCache
List<PolicyRepresentation> dependentPolicies();
@Path("/resources")
@GET
@Produces("application/json")
@NoCache
List<ResourceRepresentation> resources();
}

View file

@ -70,10 +70,10 @@ public interface PoliciesResource {
PolicyEvaluationResponse evaluate(PolicyEvaluationRequest evaluationRequest);
@Path("role")
RolePoliciesResource roles();
RolePoliciesResource role();
@Path("user")
UserPoliciesResource users();
UserPoliciesResource user();
@Path("js")
JSPoliciesResource js();
@ -86,4 +86,7 @@ public interface PoliciesResource {
@Path("rules")
RulePoliciesResource rule();
@Path("client")
ClientPoliciesResource client();
}

View file

@ -103,7 +103,7 @@ public abstract class AbstractServletAuthzAdapterTest extends AbstractExampleAda
return getClientResource(RESOURCE_SERVER_ID).authorization();
}
private ClientResource getClientResource(String clientId) {
protected ClientResource getClientResource(String clientId) {
ClientsResource clients = this.realmsResouce().realm(REALM_NAME).clients();
ClientRepresentation resourceServer = clients.findByClientId(clientId).get(0);
return clients.get(resourceServer.getId());
@ -199,7 +199,7 @@ public abstract class AbstractServletAuthzAdapterTest extends AbstractExampleAda
assertFalse(policy.getUsers().isEmpty());
getAuthorizationResource().policies().users().create(policy);
getAuthorizationResource().policies().user().create(policy);
}
protected interface ExceptionRunnable {

View file

@ -26,15 +26,19 @@ import java.util.List;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Test;
import org.keycloak.admin.client.resource.ClientsResource;
import org.keycloak.admin.client.resource.ClientPoliciesResource;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.ResourcesResource;
import org.keycloak.admin.client.resource.RolePoliciesResource;
import org.keycloak.admin.client.resource.RoleScopeResource;
import org.keycloak.admin.client.resource.RolesResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.admin.client.resource.UsersResource;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
import org.keycloak.testsuite.util.WaitUtils;
/**
@ -205,4 +209,99 @@ public abstract class AbstractServletAuthzFunctionalAdapterTest extends Abstract
assertTrue(hasText("This is public resource that should be accessible without login."));
});
}
@Test
public void testRequiredRole() throws Exception {
performTests(() -> {
login("jdoe", "jdoe");
navigateToUserPremiumPage();
assertFalse(wasDenied());
RolesResource rolesResource = getClientResource(RESOURCE_SERVER_ID).roles();
rolesResource.create(new RoleRepresentation("required-role", "", false));
RolePolicyRepresentation policy = new RolePolicyRepresentation();
policy.setName("Required Role Policy");
policy.addRole("user_premium", false);
policy.addRole("required-role", false);
RolePoliciesResource rolePolicy = getAuthorizationResource().policies().role();
rolePolicy.create(policy);
policy = rolePolicy.findByName(policy.getName());
updatePermissionPolicies("Premium Resource Permission", policy.getName());
login("jdoe", "jdoe");
navigateToUserPremiumPage();
assertFalse(wasDenied());
policy.getRoles().clear();
policy.addRole("user_premium", false);
policy.addRole("required-role", true);
rolePolicy.findById(policy.getId()).update(policy);
login("jdoe", "jdoe");
navigateToUserPremiumPage();
assertTrue(wasDenied());
UsersResource users = realmsResouce().realm(REALM_NAME).users();
UserRepresentation user = users.search("jdoe").get(0);
RoleScopeResource roleScopeResource = users.get(user.getId()).roles().clientLevel(getClientResource(RESOURCE_SERVER_ID).toRepresentation().getId());
RoleRepresentation requiredRole = rolesResource.get("required-role").toRepresentation();
roleScopeResource.add(Arrays.asList(requiredRole));
login("jdoe", "jdoe");
navigateToUserPremiumPage();
assertFalse(wasDenied());
policy.getRoles().clear();
policy.addRole("user_premium", false);
policy.addRole("required-role", false);
rolePolicy.findById(policy.getId()).update(policy);
login("jdoe", "jdoe");
navigateToUserPremiumPage();
assertFalse(wasDenied());
roleScopeResource.remove(Arrays.asList(requiredRole));
login("jdoe", "jdoe");
navigateToUserPremiumPage();
assertFalse(wasDenied());
});
}
@Test
public void testOnlySpecificClient() throws Exception {
performTests(() -> {
login("jdoe", "jdoe");
assertFalse(wasDenied());
ClientPolicyRepresentation policy = new ClientPolicyRepresentation();
policy.setName("Only Client Policy");
policy.addClient("admin-cli");
ClientPoliciesResource policyResource = getAuthorizationResource().policies().client();
policyResource.create(policy);
policy = policyResource.findByName(policy.getName());
updatePermissionPolicies("Protected Resource Permission", policy.getName());
login("jdoe", "jdoe");
assertTrue(wasDenied());
policy.addClient("servlet-authz-app");
policyResource.findById(policy.getId()).update(policy);
login("jdoe", "jdoe");
assertFalse(wasDenied());
});
}
}

View file

@ -147,7 +147,7 @@ public abstract class AbstractPolicyManagementTest extends AbstractKeycloakTest
representation.setName(name);
representation.addUser(userId);
client.authorization().policies().users().create(representation);
client.authorization().policies().user().create(representation);
}
protected ClientResource getClient() {

View file

@ -0,0 +1,172 @@
/*
* 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.testsuite.admin.client.authorization;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Collections;
import java.util.stream.Collectors;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.Response;
import org.junit.Test;
import org.keycloak.admin.client.resource.AuthorizationResource;
import org.keycloak.admin.client.resource.ClientPoliciesResource;
import org.keycloak.admin.client.resource.ClientPolicyResource;
import org.keycloak.admin.client.resource.PolicyResource;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
import org.keycloak.representations.idm.authorization.DecisionStrategy;
import org.keycloak.representations.idm.authorization.Logic;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.testsuite.util.ClientBuilder;
import org.keycloak.testsuite.util.RealmBuilder;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public class ClientPolicyManagementTest extends AbstractPolicyManagementTest {
@Override
protected RealmBuilder createTestRealm() {
return super.createTestRealm()
.client(ClientBuilder.create().clientId("Client A"))
.client(ClientBuilder.create().clientId("Client B"))
.client(ClientBuilder.create().clientId("Client C"));
}
@Test
public void testCreate() {
AuthorizationResource authorization = getClient().authorization();
ClientPolicyRepresentation representation = new ClientPolicyRepresentation();
representation.setName("Realm Client Policy");
representation.setDescription("description");
representation.setDecisionStrategy(DecisionStrategy.CONSENSUS);
representation.setLogic(Logic.NEGATIVE);
representation.addClient("Client A");
representation.addClient("Client B");
assertCreated(authorization, representation);
}
@Test
public void testUpdate() {
AuthorizationResource authorization = getClient().authorization();
ClientPolicyRepresentation representation = new ClientPolicyRepresentation();
representation.setName("Update Test Client Policy");
representation.setDescription("description");
representation.setDecisionStrategy(DecisionStrategy.CONSENSUS);
representation.setLogic(Logic.NEGATIVE);
representation.addClient("Client A");
representation.addClient("Client B");
representation.addClient("Client C");
assertCreated(authorization, representation);
representation.setName("changed");
representation.setDescription("changed");
representation.setDecisionStrategy(DecisionStrategy.AFFIRMATIVE);
representation.setLogic(Logic.POSITIVE);
representation.setClients(representation.getClients().stream().filter(userName -> !userName.equals("Client A")).collect(Collectors.toSet()));
ClientPoliciesResource policies = authorization.policies().client();
ClientPolicyResource permission = policies.findById(representation.getId());
permission.update(representation);
assertRepresentation(representation, permission);
representation.setClients(representation.getClients().stream().filter(userName -> !userName.equals("Client C")).collect(Collectors.toSet()));
permission.update(representation);
assertRepresentation(representation, permission);
}
@Test
public void testDelete() {
AuthorizationResource authorization = getClient().authorization();
ClientPolicyRepresentation representation = new ClientPolicyRepresentation();
representation.setName("Test Delete Permission");
representation.addClient("Client A");
ClientPoliciesResource policies = authorization.policies().client();
Response response = policies.create(representation);
ClientPolicyRepresentation created = response.readEntity(ClientPolicyRepresentation.class);
policies.findById(created.getId()).remove();
ClientPolicyResource removed = policies.findById(created.getId());
try {
removed.toRepresentation();
fail("Permission not removed");
} catch (NotFoundException ignore) {
}
}
@Test
public void testGenericConfig() {
AuthorizationResource authorization = getClient().authorization();
ClientPolicyRepresentation representation = new ClientPolicyRepresentation();
representation.setName("Test Generic Config Permission");
representation.addClient("Client A");
ClientPoliciesResource policies = authorization.policies().client();
Response response = policies.create(representation);
ClientPolicyRepresentation created = response.readEntity(ClientPolicyRepresentation.class);
PolicyResource policy = authorization.policies().policy(created.getId());
PolicyRepresentation genericConfig = policy.toRepresentation();
assertNotNull(genericConfig.getConfig());
assertNotNull(genericConfig.getConfig().get("clients"));
ClientRepresentation user = getRealm().clients().findByClientId("Client A").get(0);
assertTrue(genericConfig.getConfig().get("clients").contains(user.getId()));
}
private void assertCreated(AuthorizationResource authorization, ClientPolicyRepresentation representation) {
ClientPoliciesResource permissions = authorization.policies().client();
Response response = permissions.create(representation);
ClientPolicyRepresentation created = response.readEntity(ClientPolicyRepresentation.class);
ClientPolicyResource permission = permissions.findById(created.getId());
assertRepresentation(representation, permission);
}
private void assertRepresentation(ClientPolicyRepresentation representation, ClientPolicyResource permission) {
ClientPolicyRepresentation actual = permission.toRepresentation();
assertRepresentation(representation, actual, () -> permission.resources(), () -> Collections.emptyList(), () -> permission.associatedPolicies());
assertEquals(representation.getClients().size(), actual.getClients().size());
assertEquals(0, actual.getClients().stream().filter(clientId -> !representation.getClients().stream()
.filter(userName -> getClientName(clientId).equalsIgnoreCase(userName))
.findFirst().isPresent())
.count());
}
private String getClientName(String id) {
return getRealm().clients().get(id).toRepresentation().getClientId();
}
}

View file

@ -28,6 +28,7 @@ import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import org.keycloak.testsuite.util.UserBuilder;
import org.keycloak.util.JsonSerialization;
/**
@ -43,6 +44,8 @@ public class ImportAuthorizationSettingsTest extends AbstractAuthorizationTest {
RoleRepresentation role = new RoleRepresentation();
role.setName("admin");
clientResource.roles().create(role);
testRealmResource().users().create(UserBuilder.create().username("alice").build());
}
@After
@ -72,6 +75,6 @@ public class ImportAuthorizationSettingsTest extends AbstractAuthorizationTest {
authorizationResource.importSettings(toImport);
assertEquals(13, authorizationResource.policies().policies().size());
assertEquals(15, authorizationResource.policies().policies().size());
}
}

View file

@ -119,7 +119,7 @@ public class RolePolicyManagementTest extends AbstractPolicyManagementTest {
representation.setLogic(Logic.POSITIVE);
representation.setRoles(representation.getRoles().stream().filter(roleDefinition -> !roleDefinition.getId().equals("Resource A")).collect(Collectors.toSet()));
RolePoliciesResource policies = authorization.policies().roles();
RolePoliciesResource policies = authorization.policies().role();
RolePolicyResource permission = policies.findById(representation.getId());
permission.update(representation);
@ -146,7 +146,7 @@ public class RolePolicyManagementTest extends AbstractPolicyManagementTest {
representation.setName("Test Delete Permission");
representation.addRole("Role A", false);
RolePoliciesResource policies = authorization.policies().roles();
RolePoliciesResource policies = authorization.policies().role();
Response response = policies.create(representation);
RolePolicyRepresentation created = response.readEntity(RolePolicyRepresentation.class);
@ -170,7 +170,7 @@ public class RolePolicyManagementTest extends AbstractPolicyManagementTest {
representation.setName("Test Generic Config Permission");
representation.addRole("Role A", false);
RolePoliciesResource policies = authorization.policies().roles();
RolePoliciesResource policies = authorization.policies().role();
Response response = policies.create(representation);
RolePolicyRepresentation created = response.readEntity(RolePolicyRepresentation.class);
@ -186,7 +186,7 @@ public class RolePolicyManagementTest extends AbstractPolicyManagementTest {
}
private void assertCreated(AuthorizationResource authorization, RolePolicyRepresentation representation) {
RolePoliciesResource permissions = authorization.policies().roles();
RolePoliciesResource permissions = authorization.policies().role();
Response response = permissions.create(representation);
RolePolicyRepresentation created = response.readEntity(RolePolicyRepresentation.class);
RolePolicyResource permission = permissions.findById(created.getId());

View file

@ -54,7 +54,7 @@ public class UserPolicyManagementTest extends AbstractPolicyManagementTest {
}
@Test
public void testCreateUserPolicy() {
public void testCreate() {
AuthorizationResource authorization = getClient().authorization();
UserPolicyRepresentation representation = new UserPolicyRepresentation();
@ -89,7 +89,7 @@ public class UserPolicyManagementTest extends AbstractPolicyManagementTest {
representation.setLogic(Logic.POSITIVE);
representation.setUsers(representation.getUsers().stream().filter(userName -> !userName.equals("User A")).collect(Collectors.toSet()));
UserPoliciesResource policies = authorization.policies().users();
UserPoliciesResource policies = authorization.policies().user();
UserPolicyResource permission = policies.findById(representation.getId());
permission.update(representation);
@ -109,7 +109,7 @@ public class UserPolicyManagementTest extends AbstractPolicyManagementTest {
representation.setName("Test Delete Permission");
representation.addUser("User A");
UserPoliciesResource policies = authorization.policies().users();
UserPoliciesResource policies = authorization.policies().user();
Response response = policies.create(representation);
UserPolicyRepresentation created = response.readEntity(UserPolicyRepresentation.class);
@ -133,7 +133,7 @@ public class UserPolicyManagementTest extends AbstractPolicyManagementTest {
representation.setName("Test Generic Config Permission");
representation.addUser("User A");
UserPoliciesResource policies = authorization.policies().users();
UserPoliciesResource policies = authorization.policies().user();
Response response = policies.create(representation);
UserPolicyRepresentation created = response.readEntity(UserPolicyRepresentation.class);
@ -149,7 +149,7 @@ public class UserPolicyManagementTest extends AbstractPolicyManagementTest {
}
private void assertCreated(AuthorizationResource authorization, UserPolicyRepresentation representation) {
UserPoliciesResource permissions = authorization.policies().users();
UserPoliciesResource permissions = authorization.policies().user();
Response response = permissions.create(representation);
UserPolicyRepresentation created = response.readEntity(UserPolicyRepresentation.class);
UserPolicyResource permission = permissions.findById(created.getId());

View file

@ -161,6 +161,20 @@
"config": {
"code": "var context = $evaluation.getContext();\nvar identity = context.getIdentity();\nvar attributes = identity.getAttributes();\nvar email = attributes.getValue('email').asString(0);\n\nif (identity.hasRole('admin') || email.endsWith('@keycloak.org')) {\n $evaluation.grant();\n}"
}
},
{
"name": "Test Client Policy",
"type": "client",
"config": {
"clients": "[\"admin-cli\"]"
}
},
{
"name": "Test User Policy",
"type": "user",
"config": {
"users": "[\"alice\"]"
}
}
],
"scopes": [

View file

@ -0,0 +1,41 @@
/*
* 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.testsuite.console.page.clients.authorization.policy;
import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public class ClientPolicy implements PolicyTypeUI {
@Page
private ClientPolicyForm form;
public ClientPolicyForm form() {
return form;
}
public ClientPolicyRepresentation toRepresentation() {
return form.toRepresentation();
}
public void update(ClientPolicyRepresentation expected) {
form().populate(expected);
}
}

View file

@ -0,0 +1,114 @@
/*
* 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.testsuite.console.page.clients.authorization.policy;
import static org.openqa.selenium.By.tagName;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
import org.keycloak.representations.idm.authorization.Logic;
import org.keycloak.testsuite.console.page.fragment.MultipleStringSelect2;
import org.keycloak.testsuite.page.Form;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.ui.Select;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public class ClientPolicyForm extends Form {
@FindBy(id = "name")
private WebElement name;
@FindBy(id = "description")
private WebElement description;
@FindBy(id = "logic")
private Select logic;
@FindBy(xpath = "//i[contains(@class,'pficon-delete')]")
private WebElement deleteButton;
@FindBy(id = "s2id_clients")
private ClientSelect clientsInput;
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
private WebElement confirmDelete;
public void populate(ClientPolicyRepresentation expected) {
setInputValue(name, expected.getName());
setInputValue(description, expected.getDescription());
logic.selectByValue(expected.getLogic().name());
clientsInput.update(expected.getClients());
save();
}
public void delete() {
deleteButton.click();
confirmDelete.click();
}
public ClientPolicyRepresentation toRepresentation() {
ClientPolicyRepresentation representation = new ClientPolicyRepresentation();
representation.setName(getInputValue(name));
representation.setDescription(getInputValue(description));
representation.setLogic(Logic.valueOf(logic.getFirstSelectedOption().getText().toUpperCase()));
representation.setClients(clientsInput.getSelected());
return representation;
}
public class ClientSelect extends MultipleStringSelect2 {
@Override
protected List<WebElement> getSelectedElements() {
return getRoot().findElements(By.xpath("(//table[@id='selected-clients'])/tbody/tr")).stream()
.filter(webElement -> webElement.findElements(tagName("td")).size() > 1)
.collect(Collectors.toList());
}
@Override
protected BiFunction<WebElement, String, Boolean> deselect() {
return (webElement, name) -> {
List<WebElement> tds = webElement.findElements(tagName("td"));
if (!tds.get(0).getText().isEmpty()) {
if (tds.get(0).getText().equals(name)) {
tds.get(1).findElement(By.tagName("button")).click();
return true;
}
}
return false;
};
}
@Override
protected Function<WebElement, String> representation() {
return webElement -> webElement.findElements(tagName("td")).get(0).getText();
}
}
}

View file

@ -21,6 +21,7 @@ import static org.openqa.selenium.By.tagName;
import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation;
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
@ -62,6 +63,9 @@ public class Policies extends Form {
@Page
private RulePolicy rulePolicy;
@Page
private ClientPolicy clientPolicy;
public PoliciesTable policies() {
return table;
}
@ -95,6 +99,10 @@ public class Policies extends Form {
rulePolicy.form().populate((RulePolicyRepresentation) expected);
rulePolicy.form().save();
return (P) rulePolicy;
} else if ("client".equals(type)) {
clientPolicy.form().populate((ClientPolicyRepresentation) expected);
clientPolicy.form().save();
return (P) clientPolicy;
}
return null;
@ -120,6 +128,8 @@ public class Policies extends Form {
timePolicy.form().populate((TimePolicyRepresentation) representation);
} else if ("rules".equals(type)) {
rulePolicy.form().populate((RulePolicyRepresentation) representation);
} else if ("client".equals(type)) {
clientPolicy.form().populate((ClientPolicyRepresentation) representation);
}
return;
@ -146,6 +156,8 @@ public class Policies extends Form {
return (P) timePolicy;
} else if ("rules".equals(type)) {
return (P) rulePolicy;
} else if ("client".equals(type)) {
return (P) clientPolicy;
}
}
}
@ -173,6 +185,8 @@ public class Policies extends Form {
timePolicy.form().delete();
} else if ("rules".equals(type)) {
rulePolicy.form().delete();
} else if ("client".equals(type)) {
clientPolicy.form().delete();
}
return;

View file

@ -55,7 +55,7 @@ public class AggregatePolicyManagementTest extends AbstractAuthorizationSettings
AuthorizationResource authorization = testRealmResource().clients().get(newClient.getId()).authorization();
PoliciesResource policies = authorization.policies();
RolePoliciesResource roles = policies.roles();
RolePoliciesResource roles = policies.role();
roles.create(policyA);
@ -71,7 +71,7 @@ public class AggregatePolicyManagementTest extends AbstractAuthorizationSettings
policyC.setName("Policy C");
policyC.addUser("test");
policies.users().create(policyC);
policies.user().create(policyC);
}
@Test

View file

@ -0,0 +1,116 @@
/*
* 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.testsuite.console.authorization;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.admin.client.resource.ClientsResource;
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
import org.keycloak.representations.idm.authorization.Logic;
import org.keycloak.testsuite.console.page.clients.authorization.policy.ClientPolicy;
import org.keycloak.testsuite.util.ClientBuilder;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public class ClientPolicyManagementTest extends AbstractAuthorizationSettingsTest {
@Before
public void configureTest() {
super.configureTest();
ClientsResource clients = testRealmResource().clients();
clients.create(ClientBuilder.create().clientId("client a").build());
clients.create(ClientBuilder.create().clientId("client b").build());
clients.create(ClientBuilder.create().clientId("client c").build());
}
@Test
public void testUpdate() throws InterruptedException {
authorizationPage.navigateTo();
ClientPolicyRepresentation expected = new ClientPolicyRepresentation();
expected.setName("Test Client Policy");
expected.setDescription("description");
expected.addClient("client a");
expected.addClient("client b");
expected.addClient("client c");
expected = createPolicy(expected);
String previousName = expected.getName();
expected.setName("Changed Test Client Policy");
expected.setDescription("Changed description");
expected.setLogic(Logic.NEGATIVE);
expected.setClients(expected.getClients().stream().filter(client -> !client.equals("client b")).collect(Collectors.toSet()));
authorizationPage.navigateTo();
authorizationPage.authorizationTabs().policies().update(previousName, expected);
assertAlertSuccess();
authorizationPage.navigateTo();
ClientPolicy actual = authorizationPage.authorizationTabs().policies().name(expected.getName());
assertPolicy(expected, actual);
}
@Test
public void testDeletePolicy() 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().delete(expected.getName());
assertAlertSuccess();
authorizationPage.navigateTo();
assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
}
private ClientPolicyRepresentation createPolicy(ClientPolicyRepresentation expected) {
ClientPolicy policy = authorizationPage.authorizationTabs().policies().create(expected);
assertAlertSuccess();
return assertPolicy(expected, policy);
}
private ClientPolicyRepresentation assertPolicy(ClientPolicyRepresentation expected, ClientPolicy policy) {
ClientPolicyRepresentation actual = policy.toRepresentation();
assertEquals(expected.getName(), actual.getName());
assertEquals(expected.getDescription(), actual.getDescription());
assertEquals(expected.getLogic(), actual.getLogic());
assertNotNull(actual.getClients());
assertEquals(expected.getClients().size(), actual.getClients().size());
assertEquals(0, actual.getClients().stream().filter(actualClient -> !expected.getClients().stream()
.filter(expectedClient -> actualClient.equals(expectedClient))
.findFirst().isPresent())
.count());
return actual;
}
}

View file

@ -56,7 +56,7 @@ public class ResourcePermissionManagementTest extends AbstractAuthorizationSetti
AuthorizationResource authorization = testRealmResource().clients().get(newClient.getId()).authorization();
PoliciesResource policies = authorization.policies();
RolePoliciesResource roles = policies.roles();
RolePoliciesResource roles = policies.role();
roles.create(policyA);
@ -72,7 +72,7 @@ public class ResourcePermissionManagementTest extends AbstractAuthorizationSetti
policyC.setName("Policy C");
policyC.addUser("test");
policies.users().create(policyC);
policies.user().create(policyC);
ResourcesResource resources = authorization.resources();

View file

@ -55,7 +55,7 @@ public class ScopePermissionManagementTest extends AbstractAuthorizationSettings
AuthorizationResource authorization = testRealmResource().clients().get(newClient.getId()).authorization();
PoliciesResource policies = authorization.policies();
RolePoliciesResource roles = policies.roles();
RolePoliciesResource roles = policies.role();
roles.create(policyA);
@ -71,7 +71,7 @@ public class ScopePermissionManagementTest extends AbstractAuthorizationSettings
policyC.setName("Policy C");
policyC.addUser("test");
policies.users().create(policyC);
policies.user().create(policyC);
authorization.scopes().create(new ScopeRepresentation("Scope A"));
authorization.scopes().create(new ScopeRepresentation("Scope B"));

View file

@ -1434,8 +1434,8 @@ module.controller('ResourceServerPolicyClientDetailCtrl', function($scope, $rout
onInitUpdate : function(policy) {
var selectedClients = [];
if (policy.config.clients) {
var clients = eval(policy.config.clients);
if (policy.clients) {
var clients = policy.clients;
for (var i = 0; i < clients.length; i++) {
Client.get({realm: $route.current.params.realm, client: clients[i]}, function(data) {
@ -1461,7 +1461,8 @@ module.controller('ResourceServerPolicyClientDetailCtrl', function($scope, $rout
clients.push($scope.selectedClients[i].id);
}
$scope.policy.config.clients = JSON.stringify(clients);
$scope.policy.clients = clients;
delete $scope.policy.config;
},
onInitCreate : function() {
@ -1481,7 +1482,8 @@ module.controller('ResourceServerPolicyClientDetailCtrl', function($scope, $rout
clients.push($scope.selectedClients[i].id);
}
$scope.policy.config.clients = JSON.stringify(clients);
$scope.policy.clients = clients;
delete $scope.policy.config;
}
}, realm, client, $scope);
});

View file

@ -42,7 +42,7 @@
<div class="form-group clearfix" style="margin-top: -15px;">
<label class="col-md-2 control-label"></label>
<div class="col-sm-3">
<table class="table table-striped table-bordered">
<table class="table table-striped table-bordered" id="selected-clients">
<thead>
<tr data-ng-hide="!selectedClients.length">
<th>{{:: 'clientId' | translate}}</th>
@ -64,10 +64,10 @@
</div>
</div>
<div class="form-group clearfix">
<label class="col-md-2 control-label" for="policy.logic">{{:: 'authz-policy-logic' | translate}}</label>
<label class="col-md-2 control-label" for="logic">{{:: 'authz-policy-logic' | translate}}</label>
<div class="col-sm-1">
<select class="form-control" id="policy.logic"
<select class="form-control" id="logic"
data-ng-model="policy.logic">
<option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option>
<option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option>