From 3d46b4c425d39b004566cc78164e1ffbe37d647c Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Fri, 28 Oct 2016 08:43:24 +0200 Subject: [PATCH] KEYCLOAK-3667 --- .../cache/infinispan/UserCacheSession.java | 4 + .../resources/admin/UsersResource.java | 4 +- .../admin/CrossRealmPermissionsTest.java | 155 ++++++++++++++++++ 3 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/CrossRealmPermissionsTest.java diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java index 72a1e77118..0bb71c0b1b 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java @@ -274,6 +274,10 @@ public class UserCacheSession implements UserCache { } protected UserModel validateCache(RealmModel realm, CachedUser cached) { + if (!realm.getId().equals(cached.getRealm())) { + return null; + } + StorageId storageId = new StorageId(cached.getId()); if (!storageId.isLocal()) { ComponentModel component = realm.getComponent(storageId.getProviderId()); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java index de64bf8b67..8ab450e5d3 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java @@ -152,10 +152,10 @@ public class UsersResource { try { UserModel user = session.users().getUserById(id, realm); if (user == null) { - throw new NotFoundException("User not found"); + return Response.status(Status.NOT_FOUND).build(); } - Set attrsToRemove; + Set attrsToRemove; if (rep.getAttributes() != null) { attrsToRemove = new HashSet<>(user.getAttributes().keySet()); attrsToRemove.removeAll(rep.getAttributes().keySet()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/CrossRealmPermissionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/CrossRealmPermissionsTest.java new file mode 100644 index 0000000000..100e452320 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/CrossRealmPermissionsTest.java @@ -0,0 +1,155 @@ +/* + * 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; + +import org.junit.Rule; +import org.junit.Test; +import org.keycloak.admin.client.Keycloak; +import org.keycloak.admin.client.resource.RealmResource; +import org.keycloak.common.util.Time; +import org.keycloak.models.AdminRoles; +import org.keycloak.models.Constants; +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.services.resources.admin.RealmAuth.Resource; +import org.keycloak.testsuite.AbstractKeycloakTest; +import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; +import org.keycloak.testsuite.util.ClientBuilder; +import org.keycloak.testsuite.util.CredentialBuilder; +import org.keycloak.testsuite.util.GreenMailRule; +import org.keycloak.testsuite.util.RealmBuilder; +import org.keycloak.testsuite.util.UserBuilder; + +import javax.ws.rs.ClientErrorException; +import javax.ws.rs.core.Response; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +/** + * @author Stian Thorgersen + */ +public class CrossRealmPermissionsTest extends AbstractKeycloakTest { + + private static final String REALM_NAME = "crossrealm-test"; + private static final String REALM2_NAME = "crossrealm2-test"; + + private RealmResource realm1; + private RealmResource realm2; + + @Rule public GreenMailRule greenMailRule = new GreenMailRule(); + + @Override + public void addTestRealms(List testRealms) { + RealmBuilder builder = RealmBuilder.create().name(REALM_NAME).testMail(); + builder.client(ClientBuilder.create().clientId("test-client").publicClient().directAccessGrants()); + + builder.user(UserBuilder.create() + .username(AdminRoles.REALM_ADMIN) + .role(Constants.REALM_MANAGEMENT_CLIENT_ID, AdminRoles.REALM_ADMIN) + .addPassword("password")); + testRealms.add(builder.build()); + + realm1 = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, AdminRoles.REALM_ADMIN, "password", "test-client", "secret").realm(REALM_NAME); + + builder = RealmBuilder.create().name(REALM2_NAME).testMail(); + builder.client(ClientBuilder.create().clientId("test-client").publicClient().directAccessGrants()); + + builder.user(UserBuilder.create() + .username(AdminRoles.REALM_ADMIN) + .role(Constants.REALM_MANAGEMENT_CLIENT_ID, AdminRoles.REALM_ADMIN) + .addPassword("password")); + + testRealms.add(builder.build()); + + realm2 = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM2_NAME, AdminRoles.REALM_ADMIN, "password", "test-client", "secret").realm(REALM2_NAME); + } + + @Test + public void users() { + UserRepresentation user = UserBuilder.create().username("randomuser-" + Time.currentTimeMillis()).build(); + Response response = realm1.users().create(user); + String userId = ApiUtil.getCreatedId(response); + response.close(); + + realm1.users().get(userId).toRepresentation(); + + expectNotFound(new PermissionsTest.Invocation() { + @Override + public void invoke(RealmResource realm) { + realm.users().get(userId).toRepresentation(); + } + }, realm2); + + expectNotFound(new PermissionsTest.Invocation() { + @Override + public void invoke(RealmResource realm) { + realm.users().get(userId).update(new UserRepresentation()); + } + }, realm2); + + expectNotFound(new PermissionsTest.Invocation() { + @Override + public void invoke(RealmResource realm) { + realm.users().get(userId).remove(); + } + }, realm2); + + expectNotFound(new PermissionsTest.Invocation() { + @Override + public void invoke(RealmResource realm) { + realm.users().get(userId).getUserSessions(); + } + }, realm2); + } + + private void expectNotFound(final PermissionsTest.Invocation invocation, RealmResource realm) { + expectNotFound(new PermissionsTest.InvocationWithResponse() { + public void invoke(RealmResource realm, AtomicReference response) { + invocation.invoke(realm); + } + }, realm); + } + + private void expectNotFound(PermissionsTest.InvocationWithResponse invocation, RealmResource realm) { + int statusCode = 0; + try { + AtomicReference responseReference = new AtomicReference<>(); + invocation.invoke(realm, responseReference); + Response response = responseReference.get(); + if (response != null) { + statusCode = response.getStatus(); + } else { + fail("Expected failure"); + } + } catch (ClientErrorException e) { + statusCode = e.getResponse().getStatus(); + } + + assertEquals(404, statusCode); + } + +}