diff --git a/docs/documentation/upgrading/topics/changes/changes-26_5_0.adoc b/docs/documentation/upgrading/topics/changes/changes-26_5_0.adoc index dd97da6a99e..adfe7bf73fd 100644 --- a/docs/documentation/upgrading/topics/changes/changes-26_5_0.adoc +++ b/docs/documentation/upgrading/topics/changes/changes-26_5_0.adoc @@ -114,6 +114,10 @@ This adds new indexes on `OFFLINE_CLIENT_SESSION` table to improve performance w If those tables contain more than 300000 entries, {project_name} will skip the index creation by default during the automatic schema migration and instead log the SQL statement on the console during migration to be applied manually after {project_name}'s startup. See the link:{upgradingguide_link}[{upgradingguide_name}] for details on how to configure a different limit. +=== Default authorization policies and resources are no longer auto-created + +When enabling authorization on a new client (creating a Resource Server), Keycloak no longer automatically creates a "Default Resource", a "Default Policy," and a "Default Permission." + // ------------------------ Deprecated features ------------------------ // == Deprecated features diff --git a/js/apps/admin-ui/test/clients/authorization.spec.ts b/js/apps/admin-ui/test/clients/authorization.spec.ts index f5a919eb66c..ba0b28a6fce 100644 --- a/js/apps/admin-ui/test/clients/authorization.spec.ts +++ b/js/apps/admin-ui/test/clients/authorization.spec.ts @@ -14,7 +14,6 @@ import { } from "../utils/table.ts"; import { assertClipboardHasText, - assertDefaultResource, assertDownload, clickAuthenticationSaveButton, clickCopyButton, @@ -69,9 +68,8 @@ test.describe.serial("Client authentication subtab", () => { test("Should create a resource", async ({ page }) => { await goToResourcesSubTab(page); - await assertDefaultResource(page); await createResource(page, { - name: "Resource", + name: "Test Resource", displayName: "The display name", type: "type", uris: ["one", "two"], @@ -83,7 +81,7 @@ test.describe.serial("Client authentication subtab", () => { test("Edit a resource", async ({ page }) => { await goToResourcesSubTab(page); - await clickTableRowItem(page, "Default Resource"); + await clickTableRowItem(page, "Test Resource"); await fillForm(page, { displayName: "updated" }); await clickSaveButton(page); @@ -115,7 +113,7 @@ test.describe.serial("Client authentication subtab", () => { name: "Permission name", description: "Something describing this permission", }); - await selectResource(page, "Default Resource"); + await selectResource(page, "Test Resource"); await clickSaveButton(page); await assertNotificationMessage( @@ -139,7 +137,7 @@ test.describe.serial("Client authentication subtab", () => { test("Should delete a policy", async ({ page }) => { await goToPoliciesSubTab(page); - await deletePolicy(page, "Default Policy"); + await deletePolicy(page, "Regex Policy"); await assertNotificationMessage(page, "The Policy successfully deleted"); }); @@ -175,6 +173,7 @@ test.describe.serial("Client authentication subtab", () => { test.describe .serial("Client authorization tab access for view-realm-authorization", () => { const clientId = `realm-view-authz-client-${crypto.randomUUID()}`; + const resourceName = `test-resource-${crypto.randomUUID()}`; test.beforeAll(async () => { await adminClient.createRealm("realm-view-authz"); @@ -197,6 +196,10 @@ test.describe serviceAccountsEnabled: true, standardFlowEnabled: true, }); + await adminClient.createResource(clientId, { + realm: "realm-view-authz", + name: resourceName, + }); }); test.afterAll(async () => { @@ -219,7 +222,7 @@ test.describe await goToAuthorizationTab(page); await goToResourcesSubTab(page); - await clickTableRowItem(page, "Default Resource"); + await clickTableRowItem(page, resourceName); await page.goBack(); await goToScopesSubTab(page); diff --git a/js/apps/admin-ui/test/clients/authorization.ts b/js/apps/admin-ui/test/clients/authorization.ts index b59f03e9e35..50b60abbf62 100644 --- a/js/apps/admin-ui/test/clients/authorization.ts +++ b/js/apps/admin-ui/test/clients/authorization.ts @@ -21,12 +21,6 @@ export async function clickAuthenticationSaveButton(page: Page) { await page.getByTestId("authenticationSettings-save").click(); } -export async function assertDefaultResource(page: Page) { - await expect(page.getByTestId("name-column-Default Resource")).toHaveText( - "Default Resource", - ); -} - export async function assertResource(page: Page, name: string) { await expect(getRowByCellText(page, name)).toBeVisible(); } @@ -35,7 +29,11 @@ export async function createResource( page: Page, resource: ResourceRepresentation, ) { - await page.getByTestId("createResource").click(); + await page + .locator( + '[data-testid="createResource"], [data-testid="no-resources-empty-action"]', + ) + .click(); await fillForm(page, resource); } @@ -81,7 +79,11 @@ export async function createPolicy( type: string, policy: { [key: string]: string }, ) { - await page.getByTestId("createPolicy").click(); + await page + .locator( + '[data-testid="createPolicy"], [data-testid="no-policies-empty-action"]', + ) + .click(); await page.getByRole("gridcell", { name: type, exact: true }).click(); await fillForm(page, policy); } @@ -106,7 +108,13 @@ export async function createPermission( type: string, permission: PolicyRepresentation, ) { - await page.getByTestId("permissionCreateDropdown").click(); + const dropdown = page.getByTestId("permissionCreateDropdown"); + const hasDropdown = (await dropdown.count()) > 0; + + if (hasDropdown) { + await dropdown.click(); + } + await page.getByTestId(`create-${type}`).click(); await fillForm(page, permission); } diff --git a/js/apps/admin-ui/test/utils/AdminClient.ts b/js/apps/admin-ui/test/utils/AdminClient.ts index 993e799c7c9..c3a5514aaef 100644 --- a/js/apps/admin-ui/test/utils/AdminClient.ts +++ b/js/apps/admin-ui/test/utils/AdminClient.ts @@ -4,6 +4,7 @@ import type ClientScopeRepresentation from "@keycloak/keycloak-admin-client/lib/ import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation.js"; import type OrganizationRepresentation from "@keycloak/keycloak-admin-client/lib/defs/organizationRepresentation.js"; import type PolicyRepresentation from "@keycloak/keycloak-admin-client/lib/defs/policyRepresentation.js"; +import type ResourceRepresentation from "@keycloak/keycloak-admin-client/lib/defs/resourceRepresentation.js"; import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation.js"; import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation.js"; import type { RoleMappingPayload } from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation.js"; @@ -495,6 +496,25 @@ class AdminClient { ); } + async createResource( + clientId: string, + resource: ResourceRepresentation & { realm?: string }, + ) { + await this.#login(); + const { realm = this.#client.realmName, ...payload } = resource; + + const client = (await this.#client.clients.find({ clientId, realm }))[0]; + + if (!client?.id) { + throw new Error(`Client ${clientId} not found in realm ${realm}`); + } + + return await this.#client.clients.createResource( + { id: client.id, realm }, + payload, + ); + } + async findUserByUsername( realm: string, username: string, diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceServerStore.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceServerStore.java index 75f85115f4a..6185abafdc1 100644 --- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceServerStore.java +++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceServerStore.java @@ -65,6 +65,21 @@ public class JPAResourceServerStore implements ResourceServerStore { String id = client.getId(); ResourceServerEntity entity = entityManager.find(ResourceServerEntity.class, id); if (entity == null) return; + + // reordering deletions to avoid FK issues, but it is not a fix, but only a workaround + // proper fix would be to refactor the whole mess with bidirectional relationships with proper cascade-on-delete behavior. + // this method would become just a one-liner entityManager.remove(entity); + { + TypedQuery query = entityManager.createNamedQuery("findPermissionTicketIdByServerId", String.class); + + query.setParameter("serverId", id); + + List result = query.getResultList(); + for (String permissionId : result) { + entityManager.remove(entityManager.getReference(PermissionTicketEntity.class, permissionId)); + } + } + //This didn't work, had to loop through and remove each policy individually //entityManager.createNamedQuery("deletePolicyByResourceServer") // .setParameter("serverId", id).executeUpdate(); @@ -80,17 +95,6 @@ public class JPAResourceServerStore implements ResourceServerStore { } } - { - TypedQuery query = entityManager.createNamedQuery("findPermissionTicketIdByServerId", String.class); - - query.setParameter("serverId", id); - - List result = query.getResultList(); - for (String permissionId : result) { - entityManager.remove(entityManager.getReference(PermissionTicketEntity.class, permissionId)); - } - } - //entityManager.createNamedQuery("deleteResourceByResourceServer") // .setParameter("serverId", id).executeUpdate(); { 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 73ff44fd993..a84645c62ac 100644 --- a/services/src/main/java/org/keycloak/authorization/admin/ResourceServerService.java +++ b/services/src/main/java/org/keycloak/authorization/admin/ResourceServerService.java @@ -19,8 +19,6 @@ package org.keycloak.authorization.admin; import static org.keycloak.models.utils.ModelToRepresentation.toRepresentation; -import java.util.Collections; -import java.util.HashMap; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.GET; @@ -44,11 +42,6 @@ import org.keycloak.models.KeycloakSession; import org.keycloak.models.UserModel; import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.RepresentationToModel; -import org.keycloak.representations.idm.authorization.DecisionStrategy; -import org.keycloak.representations.idm.authorization.Logic; -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.KeycloakOpenAPI; import org.keycloak.services.resources.admin.AdminEventBuilder; @@ -89,7 +82,6 @@ public class ResourceServerService { if (this.resourceServer == null) { this.resourceServer = RepresentationToModel.createResourceServer(client, session, true); - createDefaultPermission(createDefaultResource(), createDefaultPolicy()); audit(ModelToRepresentation.toRepresentation(resourceServer, client), OperationType.CREATE, session.getContext().getUri(), newClient); } @@ -175,53 +167,6 @@ public class ResourceServerService { return new PermissionService(this.resourceServer, this.authorization, this.auth, adminEvent); } - private void createDefaultPermission(ResourceRepresentation resource, PolicyRepresentation policy) { - ResourcePermissionRepresentation defaultPermission = new ResourcePermissionRepresentation(); - - defaultPermission.setName("Default Permission"); - defaultPermission.setDescription("A permission that applies to the default resource type"); - defaultPermission.setDecisionStrategy(DecisionStrategy.UNANIMOUS); - defaultPermission.setLogic(Logic.POSITIVE); - - defaultPermission.setResourceType(resource.getType()); - defaultPermission.addPolicy(policy.getName()); - - getPolicyResource().create(defaultPermission); - } - - private PolicyRepresentation createDefaultPolicy() { - PolicyRepresentation defaultPolicy = new PolicyRepresentation(); - - defaultPolicy.setName("Default Policy"); - defaultPolicy.setDescription("A policy that grants access only for users within this realm"); - defaultPolicy.setType("js"); - defaultPolicy.setDecisionStrategy(DecisionStrategy.AFFIRMATIVE); - defaultPolicy.setLogic(Logic.POSITIVE); - - HashMap defaultPolicyConfig = new HashMap<>(); - - defaultPolicyConfig.put("code", "// by default, grants any permission associated with this policy\n$evaluation.grant();\n"); - - defaultPolicy.setConfig(defaultPolicyConfig); - - session.setAttribute("ALLOW_CREATE_POLICY", true); - - getPolicyResource().create(defaultPolicy); - - return defaultPolicy; - } - - private ResourceRepresentation createDefaultResource() { - ResourceRepresentation defaultResource = new ResourceRepresentation(); - - defaultResource.setName("Default Resource"); - defaultResource.setUris(Collections.singleton("/*")); - defaultResource.setType("urn:" + this.client.getClientId() + ":resources:default"); - - getResourceSetResource().create(defaultResource); - return defaultResource; - } - private void audit(ResourceServerRepresentation rep, OperationType operation, UriInfo uriInfo, boolean newClient) { if (newClient) { adminEvent.resource(ResourceType.AUTHORIZATION_RESOURCE_SERVER).operation(operation).resourcePath(uriInfo, client.getId()) diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthzClientCredentialsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthzClientCredentialsTest.java index 66f85f622cc..c966fbbd5cd 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthzClientCredentialsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthzClientCredentialsTest.java @@ -30,6 +30,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import jakarta.ws.rs.core.Response; import org.junit.Before; import org.junit.Test; import org.keycloak.admin.client.Keycloak; @@ -52,9 +53,12 @@ import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; import org.keycloak.representations.idm.authorization.AuthorizationRequest; import org.keycloak.representations.idm.authorization.AuthorizationResponse; +import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation; +import org.keycloak.representations.idm.authorization.DecisionStrategy; import org.keycloak.representations.idm.authorization.Permission; import org.keycloak.representations.idm.authorization.PermissionRequest; import org.keycloak.representations.idm.authorization.PermissionResponse; +import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation; import org.keycloak.representations.idm.authorization.ResourceRepresentation; import org.keycloak.representations.idm.authorization.ResourceServerRepresentation; import org.keycloak.testsuite.admin.ApiUtil; @@ -70,6 +74,8 @@ import org.keycloak.util.JsonSerialization; */ public class AuthzClientCredentialsTest extends AbstractAuthzTest { + private static final String TEST_RESOURCE = "Test Resource"; + @Override public void addTestRealms(List testRealms) { testRealms.add(configureRealm(RealmBuilder.create().name("authz-client-jwt-test"), ClientBuilder.create() @@ -122,6 +128,39 @@ public class AuthzClientCredentialsTest extends AbstractAuthzTest { settings.setAllowRemoteResourceManagement(true); authorization.update(settings); + + // create authorization model + // create resource + ResourceRepresentation testResource = new ResourceRepresentation(TEST_RESOURCE); + + String resourceId; + try (Response response = authorization.resources().create(testResource)) { + assertEquals(201, response.getStatus()); + testResource = response.readEntity(ResourceRepresentation.class); + resourceId = testResource.getId(); + } + + // create client policy + ClientPolicyRepresentation clientPolicy = new ClientPolicyRepresentation(); + clientPolicy.setName("Policy for " + client.getClientId()); + clientPolicy.addClient(client.getClientId()); + clientPolicy.setDecisionStrategy(DecisionStrategy.AFFIRMATIVE); + + String policyId; + try (Response response = authorization.policies().client().create(clientPolicy)) { + assertEquals(201, response.getStatus()); + policyId = response.readEntity(ClientPolicyRepresentation.class).getId(); + } + + // create permission + ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation(); + permission.setName("Permission for " + TEST_RESOURCE); + permission.addResource(resourceId); + permission.addPolicy(policyId); + + try (Response response = authorization.permissions().resource().create(permission)) { + assertEquals(201, response.getStatus()); + } }); } @@ -133,7 +172,7 @@ public class AuthzClientCredentialsTest extends AbstractAuthzTest { private void testSuccessfulAuthorizationRequest(String config) throws Exception { AuthzClient authzClient = getAuthzClient(config); ProtectionResource protection = authzClient.protection(); - PermissionRequest request = new PermissionRequest("Default Resource"); + PermissionRequest request = new PermissionRequest(TEST_RESOURCE); PermissionResponse ticketResponse = protection.permission().create(request); String ticket = ticketResponse.getTicket(); @@ -151,7 +190,7 @@ public class AuthzClientCredentialsTest extends AbstractAuthzTest { List permissions = new ArrayList<>(authorization.getPermissions()); assertFalse(permissions.isEmpty()); - assertEquals("Default Resource", permissions.get(0).getResourceName()); + assertEquals(TEST_RESOURCE, permissions.get(0).getResourceName()); } @Test @@ -227,13 +266,13 @@ public class AuthzClientCredentialsTest extends AbstractAuthzTest { AuthzClient authzClient = getAuthzClient("default-session-keycloak.json"); ProtectionResource protection = authzClient.protection(); - protection.resource().findByName("Default Resource"); + protection.resource().findByName(TEST_RESOURCE); userSessions = clients.get(clientRepresentation.getId()).getUserSessions(null, null); assertEquals(expectedUserSessionsCount, userSessions.size()); Thread.sleep(2000); protection = authzClient.protection(); - protection.resource().findByName("Default Resource"); + protection.resource().findByName(TEST_RESOURCE); userSessions = clients.get(clientRepresentation.getId()).getUserSessions(null, null); @@ -254,7 +293,7 @@ public class AuthzClientCredentialsTest extends AbstractAuthzTest { AccessToken accessToken = toAccessToken(response.getToken()); assertEquals(1, accessToken.getAuthorization().getPermissions().size()); - assertEquals("Default Resource", accessToken.getAuthorization().getPermissions().iterator().next().getResourceName()); + assertEquals(TEST_RESOURCE, accessToken.getAuthorization().getPermissions().iterator().next().getResourceName()); } @Test @@ -272,7 +311,7 @@ public class AuthzClientCredentialsTest extends AbstractAuthzTest { String sessionState = accessToken.getSessionState(); assertEquals(1, accessToken.getAuthorization().getPermissions().size()); - assertEquals("Default Resource", accessToken.getAuthorization().getPermissions().iterator().next().getResourceName()); + assertEquals(TEST_RESOURCE, accessToken.getAuthorization().getPermissions().iterator().next().getResourceName()); userSessions = clients.get(clientRepresentation.getId()).getUserSessions(null, null); @@ -299,7 +338,7 @@ public class AuthzClientCredentialsTest extends AbstractAuthzTest { AccessToken accessToken = toAccessToken(response.getToken()); assertEquals(1, accessToken.getAuthorization().getPermissions().size()); - assertEquals("Default Resource", accessToken.getAuthorization().getPermissions().iterator().next().getResourceName()); + assertEquals(TEST_RESOURCE, accessToken.getAuthorization().getPermissions().iterator().next().getResourceName()); ProtectionResource protection = authzClient.protection(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java index d87a7d6afb7..7dc3eb2c563 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java @@ -421,9 +421,6 @@ public class EntitlementAPITest extends AbstractAuthzTest { public void testResolveResourcesWithSameUri() throws Exception { ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST); AuthorizationResource authorization = client.authorization(); - List defaultResource = authorization.resources().findByName("Default Resource"); - assertThat(defaultResource.isEmpty(), is(false)); - authorization.resources().resource(defaultResource.get(0).getId()).remove(); JSPolicyRepresentation policy = new JSPolicyRepresentation(); policy.setName(KeycloakModelUtils.generateId()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/PermissionClaimTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/PermissionClaimTest.java index 412fa4ffc47..d7c88d9941a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/PermissionClaimTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/PermissionClaimTest.java @@ -39,7 +39,6 @@ import org.keycloak.admin.client.resource.AuthorizationResource; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.admin.client.resource.ClientsResource; import org.keycloak.admin.client.resource.RealmResource; -import org.keycloak.admin.client.resource.ResourcesResource; import org.keycloak.authorization.client.AuthzClient; import org.keycloak.authorization.client.util.HttpResponseException; import org.keycloak.models.utils.KeycloakModelUtils; @@ -137,11 +136,6 @@ public class PermissionClaimTest extends AbstractAuthzTest { representation.setAuthorizationServicesEnabled(true); client.update(representation); - - ResourcesResource resources = client.authorization().resources(); - List defaultResource = resources.findByName("Default Resource"); - - resources.resource(defaultResource.get(0).getId()).remove(); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/AuthorizationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/AuthorizationTest.java index 575edeb3ea5..3526823d7b9 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/AuthorizationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/AuthorizationTest.java @@ -25,11 +25,9 @@ import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.common.constants.ServiceAccountConstants; import org.keycloak.representations.adapters.config.PolicyEnforcerConfig; import org.keycloak.representations.idm.ClientRepresentation; -import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.authorization.PolicyRepresentation; -import org.keycloak.representations.idm.authorization.ResourceRepresentation; import org.keycloak.representations.idm.authorization.ResourceServerRepresentation; import org.keycloak.representations.idm.authorization.RolePolicyRepresentation; @@ -71,13 +69,8 @@ public class AuthorizationTest extends AbstractAuthorizationTest { clientResource.authorization().policies().role().create(policy); - List defaultResources = clientResource.authorization().resources().resources(); - - assertEquals(1, defaultResources.size()); - - List defaultPolicies = clientResource.authorization().policies().policies(); - - assertEquals(3, defaultPolicies.size()); + List policies = clientResource.authorization().policies().policies(); + assertEquals(1, policies.size()); enableAuthorizationServices(false); enableAuthorizationServices(true); @@ -87,43 +80,13 @@ public class AuthorizationTest extends AbstractAuthorizationTest { assertEquals(PolicyEnforcerConfig.EnforcementMode.ENFORCING.name(), settings.getPolicyEnforcementMode().name()); assertTrue(settings.isAllowRemoteResourceManagement()); assertEquals(resourceServer.getId(), settings.getClientId()); - defaultResources = clientResource.authorization().resources().resources(); - assertEquals(1, defaultResources.size()); - - defaultPolicies = clientResource.authorization().policies().policies(); - - assertEquals(2, defaultPolicies.size()); + policies = clientResource.authorization().policies().policies(); + assertTrue(policies.isEmpty()); serviceAccount = clientResource.getServiceAccountUser(); Assert.assertNotNull(serviceAccount); serviceAccountRoles = realm.users().get(serviceAccount.getId()).roles().clientLevel(resourceServer.getId()).listEffective(); Assert.assertTrue(serviceAccountRoles.stream().anyMatch(roleRepresentation -> "uma_protection".equals(roleRepresentation.getName()))); } - - // KEYCLOAK-6321 - @Test - public void testRemoveDefaultResourceWithAdminEventsEnabled() { - RealmResource realmResource = testRealmResource(); - RealmRepresentation realmRepresentation = realmResource.toRepresentation(); - - realmRepresentation.setAdminEventsEnabled(true); - - realmResource.update(realmRepresentation); - - ClientResource clientResource = getClientResource(); - ClientRepresentation resourceServer = getResourceServer(); - - ResourceServerRepresentation settings = clientResource.authorization().getSettings(); - - assertEquals(PolicyEnforcerConfig.EnforcementMode.ENFORCING.name(), settings.getPolicyEnforcementMode().name()); - assertEquals(resourceServer.getId(), settings.getClientId()); - List defaultResources = clientResource.authorization().resources().resources(); - - assertEquals(1, defaultResources.size()); - - clientResource.authorization().resources().resource(defaultResources.get(0).getId()).remove(); - - assertTrue(clientResource.authorization().resources().resources().isEmpty()); - } -} \ No newline at end of file +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/ExportAuthorizationSettingsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/ExportAuthorizationSettingsTest.java index 5127b6c6d56..071326cf90a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/ExportAuthorizationSettingsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/ExportAuthorizationSettingsTest.java @@ -35,6 +35,10 @@ import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.RoleBuilder; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.notNullValue; + /** * * @author Vlasta Ramik @@ -49,26 +53,34 @@ public class ExportAuthorizationSettingsTest extends AbstractAuthorizationTest { ClientResource clientResource = getClientResource(); AuthorizationResource authorizationResource = clientResource.authorization(); - //get Default Resource - List resources = authorizationResource.resources().findByName("Default Resource"); - Assert.assertTrue(resources.size() == 1); - ResourceRepresentation resource = resources.get(0); - - //get Default Policy - PolicyRepresentation policy = authorizationResource.policies().findByName("Default Policy"); - - //create Resource-based permission and add default policy/resource + ResourceRepresentation resourceRepresentation = new ResourceRepresentation(); + resourceRepresentation.setName("resource-for-export-test"); + try (Response response = authorizationResource.resources().create(resourceRepresentation)) { + Assert.assertEquals(Status.CREATED, response.getStatusInfo()); + } + List resources = authorizationResource.resources().findByName("resource-for-export-test"); + assertThat(resources, hasSize(1)); + String resourceId = resources.get(0).getId();; + + PolicyRepresentation policyRepresentation = new PolicyRepresentation(); + policyRepresentation.setName("policy-for-export-test"); + policyRepresentation.setType("client"); + try (Response response = authorizationResource.policies().create(policyRepresentation)) { + Assert.assertEquals(Status.CREATED, response.getStatusInfo()); + } + PolicyRepresentation policy = authorizationResource.policies().findByName("policy-for-export-test"); + assertThat(policy, notNullValue()); + + //create Resource-based permission and add policy/resource ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation(); permission.setName(permissionName); permission.addPolicy(policy.getId()); - permission.addResource(resource.getId()); - Response create = authorizationResource.permissions().resource().create(permission); - try { + permission.addResource(resourceId); + + try (Response create = authorizationResource.permissions().resource().create(permission)) { Assert.assertEquals(Status.CREATED, create.getStatusInfo()); - } finally { - create.close(); } - + //export authorization settings ResourceServerRepresentation exportSettings = authorizationResource.exportSettings(); @@ -77,8 +89,8 @@ public class ExportAuthorizationSettingsTest extends AbstractAuthorizationTest { for (PolicyRepresentation p : exportSettings.getPolicies()) { if (p.getName().equals(permissionName)) { found = true; - Assert.assertEquals("[\"Default Resource\"]", p.getConfig().get("resources")); - Assert.assertEquals("[\"Default Policy\"]", p.getConfig().get("applyPolicies")); + Assert.assertEquals("[\"resource-for-export-test\"]", p.getConfig().get("resources")); + Assert.assertEquals("[\"policy-for-export-test\"]", p.getConfig().get("applyPolicies")); } } Assert.assertTrue("Permission \"role-based-permission\" was not found.", found); @@ -163,4 +175,4 @@ public class ExportAuthorizationSettingsTest extends AbstractAuthorizationTest { Assert.assertTrue(findByClientId.size() == 1); return findByClientId.get(0); } -} \ No newline at end of file +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/GenericPolicyManagementTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/GenericPolicyManagementTest.java index 747e1625a22..12509628591 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/GenericPolicyManagementTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/GenericPolicyManagementTest.java @@ -70,7 +70,7 @@ public class GenericPolicyManagementTest extends AbstractAuthorizationTest { List policies = getClientResource().authorization().policies().policies(); - assertEquals(6, policies.size()); + assertEquals(4, policies.size()); assertAssociatedPolicy("Test Associated A", newPolicy); assertAssociatedPolicy("Test Associated B", newPolicy);