keycloak-aplcache

Details

diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUser.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUser.java
index ccd6668..b5d962c 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUser.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUser.java
@@ -21,12 +21,15 @@ import org.keycloak.common.util.MultivaluedHashMap;
 import org.keycloak.models.GroupModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserConsentModel;
 import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
 
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -50,6 +53,7 @@ public class CachedUser extends AbstractRevisioned implements InRealm {
     private Set<String> requiredActions = new HashSet<>();
     private Set<String> roleMappings = new HashSet<>();
     private Set<String> groups = new HashSet<>();
+    private Map<String, CachedUserConsent> consents = new HashMap<>(); // Key is client DB Id
 
 
 
@@ -78,6 +82,13 @@ public class CachedUser extends AbstractRevisioned implements InRealm {
                 groups.add(group.getId());
             }
         }
+
+        List<UserConsentModel> consents = user.getConsents();
+        if (consents != null) {
+            for (UserConsentModel consent : consents) {
+                this.consents.put(consent.getClient().getId(), new CachedUserConsent(consent));
+            }
+        }
     }
 
     public String getRealm() {
@@ -143,4 +154,8 @@ public class CachedUser extends AbstractRevisioned implements InRealm {
     public Set<String> getGroups() {
         return groups;
     }
+
+    public Map<String, CachedUserConsent> getConsents() {
+        return consents;
+    }
 }
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUserConsent.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUserConsent.java
new file mode 100644
index 0000000..00022ac
--- /dev/null
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUserConsent.java
@@ -0,0 +1,55 @@
+/*
+ * 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.models.cache.infinispan.entities;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserConsentModel;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class CachedUserConsent {
+
+    private final String clientDbId;
+    private final Set<ProtocolMapperModel> protocolMappers = new HashSet<>();
+    private final Set<String> roleIds = new HashSet<>();
+
+    public CachedUserConsent(UserConsentModel consentModel) {
+        this.clientDbId = consentModel.getClient().getId();
+        this.protocolMappers.addAll(consentModel.getGrantedProtocolMappers());
+        for (RoleModel role : consentModel.getGrantedRoles()) {
+            this.roleIds.add(role.getId());
+        }
+    }
+
+    public String getClientDbId() {
+        return clientDbId;
+    }
+
+    public Set<ProtocolMapperModel> getProtocolMappers() {
+        return protocolMappers;
+    }
+
+    public Set<String> getRoleIds() {
+        return roleIds;
+    }
+}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserAdapter.java
index f628bb5..2b02cee 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserAdapter.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserAdapter.java
@@ -20,6 +20,7 @@ package org.keycloak.models.cache.infinispan;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.GroupModel;
 import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleContainerModel;
 import org.keycloak.models.RoleModel;
@@ -28,10 +29,13 @@ import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.cache.infinispan.entities.CachedUser;
+import org.keycloak.models.cache.infinispan.entities.CachedUserConsent;
 import org.keycloak.models.utils.KeycloakModelUtils;
 
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -392,16 +396,28 @@ public class UserAdapter implements UserModel {
 
     @Override
     public UserConsentModel getConsentByClient(String clientId) {
-        // TODO: caching?
-        getDelegateForUpdate();
-        return updated.getConsentByClient(clientId);
+        if (updated != null) return updated.getConsentByClient(clientId);
+        CachedUserConsent cachedConsent = cached.getConsents().get(clientId);
+        if (cachedConsent == null) {
+            return null;
+        }
+
+        return toConsentModel(cachedConsent);
     }
 
     @Override
     public List<UserConsentModel> getConsents() {
-        // TODO: caching?
-        getDelegateForUpdate();
-        return updated.getConsents();
+        if (updated != null) return updated.getConsents();
+        Collection<CachedUserConsent> cachedConsents = cached.getConsents().values();
+
+        List<UserConsentModel> result = new LinkedList<>();
+        for (CachedUserConsent cachedConsent : cachedConsents) {
+            UserConsentModel consent = toConsentModel(cachedConsent);
+            if (consent != null) {
+                result.add(consent);
+            }
+        }
+        return result;
     }
 
     @Override
@@ -416,6 +432,26 @@ public class UserAdapter implements UserModel {
         return updated.revokeConsentForClient(clientId);
     }
 
+    private UserConsentModel toConsentModel(CachedUserConsent cachedConsent) {
+        ClientModel client = keycloakSession.realms().getClientById(cachedConsent.getClientDbId(), realm);
+        if (client == null) {
+            return null;
+        }
+
+        UserConsentModel consentModel = new UserConsentModel(client);
+
+        for (String roleId : cachedConsent.getRoleIds()) {
+            RoleModel role = keycloakSession.realms().getRoleById(roleId, realm);
+            if (role != null) {
+                consentModel.addGrantedRole(role);
+            }
+        }
+        for (ProtocolMapperModel protocolMapper : cachedConsent.getProtocolMappers()) {
+            consentModel.addGrantedProtocolMapper(protocolMapper);
+        }
+        return consentModel;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;