/* * 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.assertNull; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.function.Supplier; import javax.ws.rs.core.Response; import org.junit.Before; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.admin.client.resource.ClientsResource; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation; import org.keycloak.representations.idm.authorization.PolicyRepresentation; import org.keycloak.representations.idm.authorization.ResourceRepresentation; import org.keycloak.representations.idm.authorization.ScopeRepresentation; import org.keycloak.representations.idm.authorization.UserPolicyRepresentation; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.RealmBuilder; import org.keycloak.testsuite.util.UserBuilder; /** * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> */ public abstract class AbstractPolicyManagementTest extends AbstractKeycloakTest { @Override public void addTestRealms(List<RealmRepresentation> testRealms) { testRealms.add(createTestRealm().build()); } protected RealmBuilder createTestRealm() { return RealmBuilder.create().name("authz-test") .user(UserBuilder.create().username("marta").password("password")) .user(UserBuilder.create().username("kolo").password("password")) .client(ClientBuilder.create().clientId("resource-server-test") .secret("secret") .authorizationServicesEnabled(true) .redirectUris("http://localhost/resource-server-test") .defaultRoles("uma_protection") .directAccessGrants()); } @Before public void configureAuthorization() throws Exception { createResourcesAndScopes(); RealmResource realm = getRealm(); createPolicies(realm, getClient(realm)); } protected void assertRepresentation(AbstractPolicyRepresentation expected, AbstractPolicyRepresentation actual, Supplier<List<ResourceRepresentation>> resources, Supplier<List<ScopeRepresentation>> scopes, Supplier<List<PolicyRepresentation>> policies) { assertNotNull(actual); assertNotNull(actual.getId()); assertEquals(expected.getName(), actual.getName()); assertEquals(expected.getDescription(), actual.getDescription()); assertEquals(expected.getDecisionStrategy(), actual.getDecisionStrategy()); assertEquals(expected.getLogic(), actual.getLogic()); assertNull(actual.getResources()); assertNull(actual.getPolicies()); assertNull(actual.getScopes()); List<PolicyRepresentation> associatedPolicies = policies.get(); if (expected.getPolicies() != null) { assertEquals(expected.getPolicies().size(), associatedPolicies.size()); assertEquals(0, associatedPolicies.stream().map(representation1 -> representation1.getName()).filter(policyName -> !expected.getPolicies().contains(policyName)).count()); } else { assertTrue(associatedPolicies.isEmpty()); } List<ResourceRepresentation> associatedResources = resources.get(); if (expected.getResources() != null) { assertEquals(expected.getResources().size(), associatedResources.size()); assertEquals(0, associatedResources.stream().map(representation1 -> representation1.getName()).filter(resourceName -> !expected.getResources().contains(resourceName)).count()); } else { assertTrue(associatedResources.isEmpty()); } List<ScopeRepresentation> associatedScopes = scopes.get(); if (expected.getScopes() != null) { assertEquals(expected.getScopes().size(), associatedScopes.size()); assertEquals(0, associatedScopes.stream().map(representation1 -> representation1.getName()).filter(scopeName -> !expected.getScopes().contains(scopeName)).count()); } else { assertTrue(associatedScopes.isEmpty()); } expected.setId(actual.getId()); } private void createResourcesAndScopes() throws IOException { Set<ScopeRepresentation> scopes = new HashSet<>(); scopes.add(new ScopeRepresentation("read")); scopes.add(new ScopeRepresentation("write")); scopes.add(new ScopeRepresentation("execute")); List<ResourceRepresentation> resources = new ArrayList<>(); resources.add(new ResourceRepresentation("Resource A", scopes)); resources.add(new ResourceRepresentation("Resource B", scopes)); resources.add(new ResourceRepresentation("Resource C", scopes)); resources.forEach(resource -> { Response response = getClient().authorization().resources().create(resource); response.close(); }); } private void createPolicies(RealmResource realm, ClientResource client) throws IOException { createUserPolicy("Only Marta Policy", realm, client, "marta"); createUserPolicy("Only Kolo Policy", realm, client, "kolo"); } private void createUserPolicy(String name, RealmResource realm, ClientResource client, String username) throws IOException { String userId = realm.users().search(username).stream().map(representation -> representation.getId()).findFirst().orElseThrow(() -> new RuntimeException("Expected user [userId]")); UserPolicyRepresentation representation = new UserPolicyRepresentation(); representation.setName(name); representation.addUser(userId); Response response = client.authorization().policies().user().create(representation); response.close(); } protected ClientResource getClient() { return getClient(getRealm()); } protected ClientResource getClient(RealmResource realm) { ClientsResource clients = realm.clients(); return clients.findByClientId("resource-server-test").stream().map(representation -> clients.get(representation.getId())).findFirst().orElseThrow(() -> new RuntimeException("Expected client [resource-server-test]")); } protected RealmResource getRealm() { try { return adminClient.realm("authz-test"); } catch (Exception cause) { throw new RuntimeException("Failed to create admin client", cause); } } }