keycloak-uncached

Details

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 72a1e77..0bb71c0 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 de64bf8..8ab450e 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<String> attrsToRemove;
+            Set<String> 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 0000000..100e452
--- /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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+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<RealmRepresentation> 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> response) {
+                invocation.invoke(realm);
+            }
+        }, realm);
+    }
+
+    private void expectNotFound(PermissionsTest.InvocationWithResponse invocation, RealmResource realm) {
+        int statusCode = 0;
+        try {
+            AtomicReference<Response> 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);
+    }
+
+}