keycloak-uncached

Changes

Details

diff --git a/core/src/main/java/org/keycloak/representations/idm/UserConsentRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/UserConsentRepresentation.java
new file mode 100644
index 0000000..113ba84
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/idm/UserConsentRepresentation.java
@@ -0,0 +1,28 @@
+package org.keycloak.representations.idm;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class UserConsentRepresentation {
+
+    protected List<String> grantedRoles;           // points to roleIds
+    protected List<String> grantedProtocolMappers; // points to protocolMapperIds
+
+    public List<String> getGrantedRoles() {
+        return grantedRoles;
+    }
+
+    public void setGrantedRoles(List<String> grantedRoles) {
+        this.grantedRoles = grantedRoles;
+    }
+
+    public List<String> getGrantedProtocolMappers() {
+        return grantedProtocolMappers;
+    }
+
+    public void setGrantedProtocolMappers(List<String> grantedProtocolMappers) {
+        this.grantedProtocolMappers = grantedProtocolMappers;
+    }
+}
diff --git a/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java
index 94a90d9..b9716d3 100755
--- a/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java
@@ -27,6 +27,7 @@ public class UserRepresentation {
     protected List<FederatedIdentityRepresentation> federatedIdentities;
     protected List<String> realmRoles;
     protected Map<String, List<String>> clientRoles;
+    protected Map<String, UserConsentRepresentation> clientConsents;
 
     @Deprecated
     protected Map<String, List<String>> applicationRoles;
@@ -176,6 +177,14 @@ public class UserRepresentation {
         this.clientRoles = clientRoles;
     }
 
+    public Map<String, UserConsentRepresentation> getClientConsents() {
+        return clientConsents;
+    }
+
+    public void setClientConsents(Map<String, UserConsentRepresentation> clientConsents) {
+        this.clientConsents = clientConsents;
+    }
+
     @Deprecated
     public Map<String, List<String>> getApplicationRoles() {
         return applicationRoles;
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
index c404c3d..bccce2d 100755
--- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
@@ -8,14 +8,15 @@ import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.map.SerializationConfig;
 import org.keycloak.models.ClientModel;
 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;
 import org.keycloak.models.FederatedIdentityModel;
+import org.keycloak.models.UserConsentModel;
 import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.utils.ModelToRepresentation;
-import org.keycloak.representations.idm.ApplicationRepresentation;
 import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
@@ -23,6 +24,7 @@ import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.representations.idm.RolesRepresentation;
 import org.keycloak.representations.idm.ScopeMappingRepresentation;
 import org.keycloak.representations.idm.FederatedIdentityRepresentation;
+import org.keycloak.representations.idm.UserConsentRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 
 import java.io.IOException;
@@ -283,6 +285,35 @@ public class ExportUtils {
         userRep.setCredentials(credReps);
         userRep.setFederationLink(user.getFederationLink());
 
+        // Grants
+        List<UserConsentModel> consents = user.getConsents();
+        Map<String, UserConsentRepresentation> consentReps = new HashMap<String, UserConsentRepresentation>();
+        for (UserConsentModel consent : consents) {
+            String clientId = consent.getClient().getClientId();
+
+            List<String> grantedProtocolMappers = new LinkedList<String>();
+            for (ProtocolMapperModel protocolMapper : consent.getGrantedProtocolMappers()) {
+                grantedProtocolMappers.add(protocolMapper.getId());
+            }
+
+            List<String> grantedRoles = new LinkedList<String>();
+            for (RoleModel role : consent.getGrantedRoles()) {
+                grantedRoles.add(role.getId());
+            }
+
+
+            if (grantedRoles.size() > 0 || grantedProtocolMappers.size() > 0) {
+                UserConsentRepresentation consentRep = new UserConsentRepresentation();
+                if (grantedRoles.size() > 0) consentRep.setGrantedRoles(grantedRoles);
+                if (grantedProtocolMappers.size() > 0) consentRep.setGrantedProtocolMappers(grantedProtocolMappers);
+                consentReps.put(clientId, consentRep);
+            }
+        }
+
+        if (consentReps.size() > 0) {
+            userRep.setClientConsents(consentReps);
+        }
+
         return userRep;
     }
 
diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/AccessBean.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/AccessBean.java
index 959b934..67eb4a6 100644
--- a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/AccessBean.java
+++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/AccessBean.java
@@ -20,7 +20,7 @@ public class AccessBean {
     private List<ClientGrantBean> clientGrants = new LinkedList<ClientGrantBean>();
 
     public AccessBean(RealmModel realm, UserModel user, URI baseUri, String stateChecker) {
-        List<UserConsentModel> grantedConsents = user.getGrantedConsents();
+        List<UserConsentModel> grantedConsents = user.getConsents();
         for (UserConsentModel consent : grantedConsents) {
             ClientModel client = consent.getClient();
 
diff --git a/model/api/src/main/java/org/keycloak/models/UserModel.java b/model/api/src/main/java/org/keycloak/models/UserModel.java
index 09babf8..ed5ae9e 100755
--- a/model/api/src/main/java/org/keycloak/models/UserModel.java
+++ b/model/api/src/main/java/org/keycloak/models/UserModel.java
@@ -75,11 +75,11 @@ public interface UserModel {
     String getFederationLink();
     void setFederationLink(String link);
 
-    void addGrantedConsent(UserConsentModel consent);
-    UserConsentModel getGrantedConsentByClient(String clientId);
-    List<UserConsentModel> getGrantedConsents();
-    void updateGrantedConsent(UserConsentModel consent);
-    boolean revokeGrantedConsentForClient(String clientId);
+    void addConsent(UserConsentModel consent);
+    UserConsentModel getConsentByClient(String clientId);
+    List<UserConsentModel> getConsents();
+    void updateConsent(UserConsentModel consent);
+    boolean revokeConsentForClient(String clientId);
 
     public static enum RequiredAction {
         VERIFY_EMAIL, UPDATE_PROFILE, CONFIGURE_TOTP, UPDATE_PASSWORD
diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
index 6fc3e1e..0312ff4 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -16,6 +16,7 @@ import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserConsentModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserCredentialValueModel;
 import org.keycloak.models.UserFederationProviderModel;
@@ -34,6 +35,7 @@ import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.representations.idm.ScopeMappingRepresentation;
 import org.keycloak.representations.idm.SocialLinkRepresentation;
+import org.keycloak.representations.idm.UserConsentRepresentation;
 import org.keycloak.representations.idm.UserFederationProviderRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.util.UriUtils;
@@ -789,6 +791,35 @@ public class RepresentationToModel {
                 createClientRoleMappings(client, user, entry.getValue());
             }
         }
+        if (userRep.getClientConsents() != null) {
+            for (Map.Entry<String, UserConsentRepresentation> entry : userRep.getClientConsents().entrySet()) {
+                ClientModel client = clientMap.get(entry.getKey());
+                if (client == null) {
+                    throw new RuntimeException("Unable to find client consent mappings for client: " + entry.getKey());
+                }
+
+                UserConsentModel consentModel = new UserConsentModel(newRealm, client.getId());
+
+                UserConsentRepresentation consentRep = entry.getValue();
+                if (consentRep.getGrantedRoles() != null) {
+                    for (String roleId : consentRep.getGrantedRoles()) {
+                        if (newRealm.getRoleById(roleId) == null) {
+                            throw new RuntimeException("Unable to find realm role referenced in consent mappings of user " + user.getUsername() + ". Role ID: " + roleId);
+                        }
+                        consentModel.addGrantedRole(roleId);
+                    }
+                }
+                if (consentRep.getGrantedProtocolMappers() != null) {
+                    for (String mapperId : consentRep.getGrantedProtocolMappers()) {
+                        if (client.getProtocolMapperById(mapperId) == null) {
+                            throw new RuntimeException("Unable to find protocol mapper referenced in consent mappings of user " + user.getUsername() + ". Protocol mapper ID: " + mapperId);
+                        }
+                        consentModel.addGrantedProtocolMapper(mapperId);;
+                    }
+                }
+                user.addConsent(consentModel);
+            }
+        }
         return user;
     }
 
diff --git a/model/api/src/main/java/org/keycloak/models/utils/UserModelDelegate.java b/model/api/src/main/java/org/keycloak/models/utils/UserModelDelegate.java
index cd7aebf..8ac8f5b 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/UserModelDelegate.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/UserModelDelegate.java
@@ -188,27 +188,27 @@ public class UserModelDelegate implements UserModel {
     }
 
     @Override
-    public void addGrantedConsent(UserConsentModel consent) {
-        delegate.addGrantedConsent(consent);
+    public void addConsent(UserConsentModel consent) {
+        delegate.addConsent(consent);
     }
 
     @Override
-    public UserConsentModel getGrantedConsentByClient(String clientId) {
-        return delegate.getGrantedConsentByClient(clientId);
+    public UserConsentModel getConsentByClient(String clientId) {
+        return delegate.getConsentByClient(clientId);
     }
 
     @Override
-    public List<UserConsentModel> getGrantedConsents() {
-        return delegate.getGrantedConsents();
+    public List<UserConsentModel> getConsents() {
+        return delegate.getConsents();
     }
 
     @Override
-    public void updateGrantedConsent(UserConsentModel consent) {
-        delegate.updateGrantedConsent(consent);
+    public void updateConsent(UserConsentModel consent) {
+        delegate.updateConsent(consent);
     }
 
     @Override
-    public boolean revokeGrantedConsentForClient(String clientId) {
-        return delegate.revokeGrantedConsentForClient(clientId);
+    public boolean revokeConsentForClient(String clientId) {
+        return delegate.revokeConsentForClient(clientId);
     }
 }
diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
index 18cc9c8..34ddb06 100755
--- a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
+++ b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
@@ -277,7 +277,8 @@ public class ClientAdapter implements ClientModel {
             throw new RuntimeException("protocol mapper name must be unique per protocol");
         }
         ProtocolMapperEntity entity = new ProtocolMapperEntity();
-        entity.setId(KeycloakModelUtils.generateId());
+        String id = model.getId() != null ? model.getId() : KeycloakModelUtils.generateId();
+        entity.setId(id);
         entity.setProtocol(model.getProtocol());
         entity.setName(model.getName());
         entity.setProtocolMapper(model.getProtocolMapper());
diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java
index b9642db..0937e2c 100755
--- a/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java
+++ b/model/file/src/main/java/org/keycloak/models/file/adapter/UserAdapter.java
@@ -432,29 +432,29 @@ public class UserAdapter implements UserModel, Comparable {
     }
 
     @Override
-    public void addGrantedConsent(UserConsentModel consent) {
+    public void addConsent(UserConsentModel consent) {
         // TODO
     }
 
     @Override
-    public UserConsentModel getGrantedConsentByClient(String clientId) {
+    public UserConsentModel getConsentByClient(String clientId) {
         // TODO
         return null;
     }
 
     @Override
-    public List<UserConsentModel> getGrantedConsents() {
+    public List<UserConsentModel> getConsents() {
         // TODO
         return null;
     }
 
     @Override
-    public void updateGrantedConsent(UserConsentModel consent) {
+    public void updateConsent(UserConsentModel consent) {
         // TODO
     }
 
     @Override
-    public boolean revokeGrantedConsentForClient(String clientId) {
+    public boolean revokeConsentForClient(String clientId) {
         // TODO
         return false;
     }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java
index 16b705b..10336fd 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserAdapter.java
@@ -277,34 +277,34 @@ public class UserAdapter implements UserModel {
     }
 
     @Override
-    public void addGrantedConsent(UserConsentModel consent) {
+    public void addConsent(UserConsentModel consent) {
         getDelegateForUpdate();
-        updated.addGrantedConsent(consent);
+        updated.addConsent(consent);
     }
 
     @Override
-    public UserConsentModel getGrantedConsentByClient(String clientId) {
+    public UserConsentModel getConsentByClient(String clientId) {
         // TODO: caching?
         getDelegateForUpdate();
-        return updated.getGrantedConsentByClient(clientId);
+        return updated.getConsentByClient(clientId);
     }
 
     @Override
-    public List<UserConsentModel> getGrantedConsents() {
+    public List<UserConsentModel> getConsents() {
         // TODO: caching?
         getDelegateForUpdate();
-        return updated.getGrantedConsents();
+        return updated.getConsents();
     }
 
     @Override
-    public void updateGrantedConsent(UserConsentModel consent) {
+    public void updateConsent(UserConsentModel consent) {
         getDelegateForUpdate();
-        updated.updateGrantedConsent(consent);
+        updated.updateConsent(consent);
     }
 
     @Override
-    public boolean revokeGrantedConsentForClient(String clientId) {
+    public boolean revokeConsentForClient(String clientId) {
         getDelegateForUpdate();
-        return updated.revokeGrantedConsentForClient(clientId);
+        return updated.revokeConsentForClient(clientId);
     }
 }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
index 498db9a..f9f62b6 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
@@ -378,7 +378,7 @@ public class ClientAdapter implements ClientModel {
         if (getProtocolMapperByName(model.getProtocol(), model.getName()) != null) {
             throw new RuntimeException("protocol mapper name must be unique per protocol");
         }
-        String id = KeycloakModelUtils.generateId();
+        String id = model.getId() != null ? model.getId() : KeycloakModelUtils.generateId();
         ProtocolMapperEntity entity = new ProtocolMapperEntity();
         entity.setId(id);
         entity.setName(model.getName());
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
index 576801f..737e0e3 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
@@ -480,7 +480,7 @@ public class UserAdapter implements UserModel {
     }
 
     @Override
-    public void addGrantedConsent(UserConsentModel consent) {
+    public void addConsent(UserConsentModel consent) {
         String clientId = consent.getClient().getId();
 
         UserConsentEntity consentEntity = getGrantedConsentEntity(clientId);
@@ -499,13 +499,13 @@ public class UserAdapter implements UserModel {
     }
 
     @Override
-    public UserConsentModel getGrantedConsentByClient(String clientId) {
+    public UserConsentModel getConsentByClient(String clientId) {
         UserConsentEntity entity = getGrantedConsentEntity(clientId);
         return toConsentModel(entity);
     }
 
     @Override
-    public List<UserConsentModel> getGrantedConsents() {
+    public List<UserConsentModel> getConsents() {
         TypedQuery<UserConsentEntity> query = em.createNamedQuery("userConsentsByUser", UserConsentEntity.class);
         query.setParameter("userId", getId());
         List<UserConsentEntity> results = query.getResultList();
@@ -519,7 +519,7 @@ public class UserAdapter implements UserModel {
     }
 
     @Override
-    public void updateGrantedConsent(UserConsentModel consent) {
+    public void updateConsent(UserConsentModel consent) {
         String clientId = consent.getClient().getId();
 
         UserConsentEntity consentEntity = getGrantedConsentEntity(clientId);
@@ -531,7 +531,7 @@ public class UserAdapter implements UserModel {
     }
 
     @Override
-    public boolean revokeGrantedConsentForClient(String clientId) {
+    public boolean revokeConsentForClient(String clientId) {
         UserConsentEntity consentEntity = getGrantedConsentEntity(clientId);
         if (consentEntity == null) return false;
 
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
index 8e07bc9..2cb2c79 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
@@ -305,7 +305,8 @@ public class ClientAdapter extends AbstractMongoAdapter<MongoClientEntity> imple
             throw new RuntimeException("protocol mapper name must be unique per protocol");
         }
         ProtocolMapperEntity entity = new ProtocolMapperEntity();
-        entity.setId(KeycloakModelUtils.generateId());
+        String id = model.getId() != null ? model.getId() : KeycloakModelUtils.generateId();
+        entity.setId(id);
         entity.setProtocol(model.getProtocol());
         entity.setName(model.getName());
         entity.setProtocolMapper(model.getProtocolMapper());
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
index 752f300..b054793 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/UserAdapter.java
@@ -417,7 +417,7 @@ public class UserAdapter extends AbstractMongoAdapter<MongoUserEntity> implement
     }
 
     @Override
-    public void addGrantedConsent(UserConsentModel consent) {
+    public void addConsent(UserConsentModel consent) {
         String clientId = consent.getClient().getId();
         if (getConsentEntityByClientId(clientId) != null) {
             throw new ModelDuplicateException("Consent already exists for client [" + clientId + "] and user [" + user.getId() + "]");
@@ -431,13 +431,13 @@ public class UserAdapter extends AbstractMongoAdapter<MongoUserEntity> implement
     }
 
     @Override
-    public UserConsentModel getGrantedConsentByClient(String clientId) {
+    public UserConsentModel getConsentByClient(String clientId) {
         UserConsentEntity consentEntity = getConsentEntityByClientId(clientId);
         return consentEntity!=null ? toConsentModel(consentEntity) : null;
     }
 
     @Override
-    public List<UserConsentModel> getGrantedConsents() {
+    public List<UserConsentModel> getConsents() {
         List<UserConsentModel> result = new ArrayList<UserConsentModel>();
 
         DBObject query = new QueryBuilder()
@@ -488,7 +488,7 @@ public class UserAdapter extends AbstractMongoAdapter<MongoUserEntity> implement
     }
 
     @Override
-    public void updateGrantedConsent(UserConsentModel consent) {
+    public void updateConsent(UserConsentModel consent) {
         String clientId = consent.getClient().getId();
         MongoUserConsentEntity consentEntity = getConsentEntityByClientId(clientId);
         if (consentEntity == null) {
@@ -500,7 +500,7 @@ public class UserAdapter extends AbstractMongoAdapter<MongoUserEntity> implement
     }
 
     @Override
-    public boolean revokeGrantedConsentForClient(String clientId) {
+    public boolean revokeConsentForClient(String clientId) {
         MongoUserConsentEntity entity = getConsentEntityByClientId(clientId);
         if (entity == null) {
             return false;
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index ee75c43..7647b36 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -420,7 +420,7 @@ public class AuthenticationManager {
         if (client.isConsentRequired()) {
             accessCode.setAction(ClientSessionModel.Action.OAUTH_GRANT);
 
-            UserConsentModel grantedConsent = user.getGrantedConsentByClient(client.getId());
+            UserConsentModel grantedConsent = user.getConsentByClient(client.getId());
 
             List<RoleModel> realmRoles = new LinkedList<RoleModel>();
             MultivaluedMap<String, RoleModel> resourceRoles = new MultivaluedMapImpl<String, RoleModel>();
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index af1c872..3a775e1 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -76,7 +76,6 @@ import javax.ws.rs.core.Variant;
 
 import java.lang.reflect.Method;
 import java.net.URI;
-import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -512,7 +511,7 @@ public class AccountService {
 
         // Revoke grant in UserModel
         UserModel user = auth.getUser();
-        user.revokeGrantedConsentForClient(client.getId());
+        user.revokeConsentForClient(client.getId());
 
         // Logout clientSessions for this user and client
         List<UserSessionModel> userSessions = session.sessions().getUserSessions(realm, user);
diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
index 02ac98e..d4aa8d7 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -609,10 +609,10 @@ public class LoginActionsService {
             return protocol.consentDenied(clientSession);
         }
 
-        UserConsentModel grantedConsent = user.getGrantedConsentByClient(client.getId());
+        UserConsentModel grantedConsent = user.getConsentByClient(client.getId());
         if (grantedConsent == null) {
             grantedConsent = new UserConsentModel(realm, client.getId());
-            user.addGrantedConsent(grantedConsent);
+            user.addConsent(grantedConsent);
         }
         for (String roleId : clientSession.getRoles()) {
             grantedConsent.addGrantedRole(roleId);
@@ -623,7 +623,7 @@ public class LoginActionsService {
                 grantedConsent.addGrantedProtocolMapper(protocolMapper.getId());
             }
         }
-        user.updateGrantedConsent(grantedConsent);
+        user.updateConsent(grantedConsent);
 
         event.success();
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java
index f0fc63b..e56d462 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java
@@ -9,6 +9,7 @@ import org.keycloak.models.RoleModel;
 import org.keycloak.models.utils.ModelToRepresentation;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.ClientRepresentation;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
 import org.keycloak.services.managers.ClientManager;
 
 import java.util.Iterator;
@@ -63,6 +64,9 @@ public class ClientModelTest extends AbstractModelTest {
     public void json() {
         ClientRepresentation representation = ModelToRepresentation.toRepresentation(client);
         representation.setId(null);
+        for (ProtocolMapperRepresentation protocolMapper : representation.getProtocolMappers()) {
+            protocolMapper.setId(null);
+        }
 
         RealmModel realm = realmManager.createRealm("copy");
         ClientModel copy = RepresentationToModel.createClient(session, realm, representation, true);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
index 54f4cbe..5bdc191 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
@@ -14,6 +14,7 @@ import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RequiredCredentialModel;
 import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserConsentModel;
 import org.keycloak.models.UserFederationProvider;
 import org.keycloak.models.UserFederationProviderFactory;
 import org.keycloak.models.UserFederationProviderModel;
@@ -238,6 +239,23 @@ public class ImportTest extends AbstractModelTest {
         String includeInIdToken = gssCredentialMapper.getConfig().get(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN);
         Assert.assertTrue(includeInAccessToken.equalsIgnoreCase("true"));
         Assert.assertTrue(includeInIdToken == null || Boolean.parseBoolean(includeInIdToken) == false);
+
+        // Test user consents
+        admin =  session.users().getUserByUsername("admin", realm);
+        Assert.assertEquals(2, admin.getConsents().size());
+
+        UserConsentModel appAdminConsent = admin.getConsentByClient(application.getId());
+        Assert.assertEquals(2, appAdminConsent.getGrantedRoles().size());
+        Assert.assertTrue(appAdminConsent.getGrantedProtocolMappers() == null || appAdminConsent.getGrantedProtocolMappers().isEmpty());
+        Assert.assertTrue(appAdminConsent.isRoleGranted(realm.getRole("admin")));
+        Assert.assertTrue(appAdminConsent.isRoleGranted(application.getRole("app-admin")));
+
+        UserConsentModel otherAppAdminConsent = admin.getConsentByClient(otherApp.getId());
+        Assert.assertEquals(1, otherAppAdminConsent.getGrantedRoles().size());
+        Assert.assertEquals(1, otherAppAdminConsent.getGrantedProtocolMappers().size());
+        Assert.assertTrue(otherAppAdminConsent.isRoleGranted(realm.getRole("admin")));
+        Assert.assertFalse(otherAppAdminConsent.isRoleGranted(application.getRole("app-admin")));
+        Assert.assertTrue(otherAppAdminConsent.isProtocolMapperGranted(gssCredentialMapper));
     }
 
     @Test
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserConsentModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserConsentModelTest.java
index bdc068b..97cb24b 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserConsentModelTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserConsentModelTest.java
@@ -50,7 +50,7 @@ public class UserConsentModelTest extends AbstractModelTest {
         johnFooGrant.addGrantedRole(realmRole.getId());
         johnFooGrant.addGrantedRole(barClientRole.getId());
         johnFooGrant.addGrantedProtocolMapper(fooMapper.getId());
-        john.addGrantedConsent(johnFooGrant);
+        john.addConsent(johnFooGrant);
 
         UserConsentModel johnBarGrant = new UserConsentModel(realm, barClient.getId());
         johnBarGrant.addGrantedProtocolMapper(barMapper.getId());
@@ -58,17 +58,17 @@ public class UserConsentModelTest extends AbstractModelTest {
 
         // Update should fail as grant doesn't yet exists
         try {
-            john.updateGrantedConsent(johnBarGrant);
+            john.updateConsent(johnBarGrant);
             Assert.fail("Not expected to end here");
         } catch (ModelException expected) {
         }
 
-        john.addGrantedConsent(johnBarGrant);
+        john.addConsent(johnBarGrant);
 
         UserConsentModel maryFooGrant = new UserConsentModel(realm, fooClient.getId());
         maryFooGrant.addGrantedRole(realmRole.getId());
         maryFooGrant.addGrantedProtocolMapper(fooMapper.getId());
-        mary.addGrantedConsent(maryFooGrant);
+        mary.addConsent(maryFooGrant);
 
         commit();
     }
@@ -82,27 +82,27 @@ public class UserConsentModelTest extends AbstractModelTest {
         UserModel john = session.users().getUserByUsername("john", realm);
         UserModel mary = session.users().getUserByUsername("mary", realm);
 
-        UserConsentModel johnFooConsent = john.getGrantedConsentByClient(fooClient.getId());
+        UserConsentModel johnFooConsent = john.getConsentByClient(fooClient.getId());
         Assert.assertEquals(johnFooConsent.getGrantedRoles().size(), 2);
         Assert.assertEquals(johnFooConsent.getGrantedProtocolMappers().size(), 1);
         Assert.assertTrue(isRoleGranted(realm, "realm-role", johnFooConsent));
         Assert.assertTrue(isRoleGranted(barClient, "bar-client-role", johnFooConsent));
         Assert.assertTrue(isMapperGranted(fooClient, "foo", johnFooConsent));
 
-        UserConsentModel johnBarConsent = john.getGrantedConsentByClient(barClient.getId());
+        UserConsentModel johnBarConsent = john.getConsentByClient(barClient.getId());
         Assert.assertEquals(johnBarConsent.getGrantedRoles().size(), 1);
         Assert.assertEquals(johnBarConsent.getGrantedProtocolMappers().size(), 1);
         Assert.assertTrue(isRoleGranted(realm, "realm-role", johnBarConsent));
         Assert.assertTrue(isMapperGranted(barClient, "bar", johnBarConsent));
 
-        UserConsentModel maryConsent = mary.getGrantedConsentByClient(fooClient.getId());
+        UserConsentModel maryConsent = mary.getConsentByClient(fooClient.getId());
         Assert.assertEquals(maryConsent.getGrantedRoles().size(), 1);
         Assert.assertEquals(maryConsent.getGrantedProtocolMappers().size(), 1);
         Assert.assertTrue(isRoleGranted(realm, "realm-role", maryConsent));
         Assert.assertFalse(isRoleGranted(barClient, "bar-client-role", maryConsent));
         Assert.assertTrue(isMapperGranted(fooClient, "foo", maryConsent));
 
-        Assert.assertNull(mary.getGrantedConsentByClient(barClient.getId()));
+        Assert.assertNull(mary.getConsentByClient(barClient.getId()));
     }
 
     @Test
@@ -113,10 +113,10 @@ public class UserConsentModelTest extends AbstractModelTest {
         UserModel john = session.users().getUserByUsername("john", realm);
         UserModel mary = session.users().getUserByUsername("mary", realm);
 
-        List<UserConsentModel> johnConsents = john.getGrantedConsents();
+        List<UserConsentModel> johnConsents = john.getConsents();
         Assert.assertEquals(2, johnConsents.size());
 
-        List<UserConsentModel> maryConsents = mary.getGrantedConsents();
+        List<UserConsentModel> maryConsents = mary.getConsents();
         Assert.assertEquals(1, maryConsents.size());
         UserConsentModel maryConsent = maryConsents.get(0);
         Assert.assertEquals(maryConsent.getClient().getId(), fooClient.getId());
@@ -132,7 +132,7 @@ public class UserConsentModelTest extends AbstractModelTest {
         ClientModel fooClient = realm.getClientByClientId("foo-client");
         UserModel john = session.users().getUserByUsername("john", realm);
 
-        UserConsentModel johnConsent = john.getGrantedConsentByClient(fooClient.getId());
+        UserConsentModel johnConsent = john.getConsentByClient(fooClient.getId());
 
         // Remove foo protocol mapper from johnConsent
         ProtocolMapperModel protMapperModel = fooClient.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "foo");
@@ -145,14 +145,14 @@ public class UserConsentModelTest extends AbstractModelTest {
         RoleModel newRealmRole = realm.addRole("new-realm-role");
         johnConsent.addGrantedRole(newRealmRole.getId());
 
-        john.updateGrantedConsent(johnConsent);
+        john.updateConsent(johnConsent);
 
         commit();
 
         realm = realmManager.getRealm("original");
         fooClient = realm.getClientByClientId("foo-client");
         john = session.users().getUserByUsername("john", realm);
-        johnConsent = john.getGrantedConsentByClient(fooClient.getId());
+        johnConsent = john.getConsentByClient(fooClient.getId());
 
         Assert.assertEquals(johnConsent.getGrantedRoles().size(), 2);
         Assert.assertEquals(johnConsent.getGrantedProtocolMappers().size(), 0);
@@ -167,13 +167,13 @@ public class UserConsentModelTest extends AbstractModelTest {
         ClientModel fooClient = realm.getClientByClientId("foo-client");
         UserModel john = session.users().getUserByUsername("john", realm);
 
-        john.revokeGrantedConsentForClient(fooClient.getId());
+        john.revokeConsentForClient(fooClient.getId());
 
         commit();
 
         realm = realmManager.getRealm("original");
         john = session.users().getUserByUsername("john", realm);
-        Assert.assertNull(john.getGrantedConsentByClient(fooClient.getId()));
+        Assert.assertNull(john.getConsentByClient(fooClient.getId()));
     }
 
     @Test
@@ -196,7 +196,7 @@ public class UserConsentModelTest extends AbstractModelTest {
         realm = realmManager.getRealm("original");
         fooClient = realm.getClientByClientId("foo-client");
         UserModel john = session.users().getUserByUsername("john", realm);
-        UserConsentModel johnConsent = john.getGrantedConsentByClient(fooClient.getId());
+        UserConsentModel johnConsent = john.getConsentByClient(fooClient.getId());
 
         Assert.assertEquals(johnConsent.getGrantedRoles().size(), 2);
         Assert.assertEquals(johnConsent.getGrantedProtocolMappers().size(), 0);
@@ -215,7 +215,7 @@ public class UserConsentModelTest extends AbstractModelTest {
         ClientModel fooClient = realm.getClientByClientId("foo-client");
         ClientModel barClient = realm.getClientByClientId("bar-client");
         UserModel john = session.users().getUserByUsername("john", realm);
-        UserConsentModel johnConsent = john.getGrantedConsentByClient(fooClient.getId());
+        UserConsentModel johnConsent = john.getConsentByClient(fooClient.getId());
 
         Assert.assertEquals(johnConsent.getGrantedRoles().size(), 1);
         Assert.assertEquals(johnConsent.getGrantedProtocolMappers().size(), 1);
@@ -237,13 +237,13 @@ public class UserConsentModelTest extends AbstractModelTest {
 
         UserModel john = session.users().getUserByUsername("john", realm);
 
-        UserConsentModel johnFooConsent = john.getGrantedConsentByClient(fooClient.getId());
+        UserConsentModel johnFooConsent = john.getConsentByClient(fooClient.getId());
         Assert.assertEquals(johnFooConsent.getGrantedRoles().size(), 1);
         Assert.assertEquals(johnFooConsent.getGrantedProtocolMappers().size(), 1);
         Assert.assertTrue(isRoleGranted(realm, "realm-role", johnFooConsent));
         Assert.assertTrue(isMapperGranted(fooClient, "foo", johnFooConsent));
 
-        Assert.assertNull(john.getGrantedConsentByClient(barClient.getId()));
+        Assert.assertNull(john.getConsentByClient(barClient.getId()));
     }
 
     private boolean isRoleGranted(RoleContainerModel roleContainer, String roleName, UserConsentModel consentModel) {
diff --git a/testsuite/integration/src/test/resources/model/testrealm.json b/testsuite/integration/src/test/resources/model/testrealm.json
index 4044399..1c0b7e6 100755
--- a/testsuite/integration/src/test/resources/model/testrealm.json
+++ b/testsuite/integration/src/test/resources/model/testrealm.json
@@ -74,6 +74,15 @@
             "applicationRoles": {
                 "Application": [ "app-admin" ],
                 "OtherApp": [  "otherapp-admin" ]
+            },
+            "clientConsents": {
+                "Application": {
+                    "grantedRoles": [ "456", "789" ]
+                },
+                "OtherApp": {
+                    "grantedProtocolMappers": [ "123" ],
+                    "grantedRoles": [ "456" ]
+                }
             }
         },
         {
@@ -113,6 +122,7 @@
             "enabled": true,
             "protocolMappers" : [
                 {
+                    "id": "123",
                     "name" : "gss delegation credential",
                     "protocol" : "openid-connect",
                     "protocolMapper" : "oidc-usersessionmodel-note-mapper",
@@ -138,12 +148,14 @@
     "roles" : {
         "realm" : [
             {
+                "id":   "456",
                 "name": "admin"
             }
         ],
         "application" : {
             "Application" : [
                 {
+                    "id":   "789",
                     "name": "app-admin"
                 },
                 {