diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserConsentWithUserStorageModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserConsentWithUserStorageModelTest.java
new file mode 100644
index 0000000..6fd18bf
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserConsentWithUserStorageModelTest.java
@@ -0,0 +1,292 @@
+/*
+ * 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.model;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.ModelException;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleContainerModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserConsentModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.protocol.oidc.OIDCLoginProtocol;
+import org.keycloak.protocol.oidc.mappers.UserPropertyMapper;
+import org.keycloak.storage.UserStorageProviderModel;
+import org.keycloak.testsuite.federation.storage.UserMapStorageFactory;
+import org.keycloak.testsuite.federation.storage.UserPropertyFileStorageFactory;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class UserConsentWithUserStorageModelTest extends AbstractModelTest {
+
+ @Before
+ public void setupEnv() {
+ RealmModel realm = realmManager.createRealm("original");
+
+ UserStorageProviderModel model = new UserStorageProviderModel();
+ model.setName("memory");
+ model.setPriority(0);
+ model.setProviderId(UserMapStorageFactory.PROVIDER_ID);
+ model.setParentId(realm.getId());
+ realm.addComponentModel(model);
+
+ ClientModel fooClient = realm.addClient("foo-client");
+ ClientModel barClient = realm.addClient("bar-client");
+
+ RoleModel realmRole = realm.addRole("realm-role");
+ RoleModel barClientRole = barClient.addRole("bar-client-role");
+
+ ProtocolMapperModel fooMapper = new ProtocolMapperModel();
+ fooMapper.setName("foo");
+ fooMapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
+ fooMapper.setProtocolMapper(UserPropertyMapper.PROVIDER_ID);
+ fooMapper = fooClient.addProtocolMapper(fooMapper);
+
+ ProtocolMapperModel barMapper = new ProtocolMapperModel();
+ barMapper.setName("bar");
+ barMapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
+ barMapper.setProtocolMapper(UserPropertyMapper.PROVIDER_ID);
+ barMapper = barClient.addProtocolMapper(barMapper);
+
+ UserModel john = session.users().addUser(realm, "john");
+ UserModel mary = session.users().addUser(realm, "mary");
+
+ UserConsentModel johnFooGrant = new UserConsentModel(fooClient);
+ johnFooGrant.addGrantedRole(realmRole);
+ johnFooGrant.addGrantedRole(barClientRole);
+ johnFooGrant.addGrantedProtocolMapper(fooMapper);
+ realmManager.getSession().users().addConsent(realm, john.getId(), johnFooGrant);
+
+ UserConsentModel johnBarGrant = new UserConsentModel(barClient);
+ johnBarGrant.addGrantedProtocolMapper(barMapper);
+ johnBarGrant.addGrantedRole(realmRole);
+
+ // Update should fail as grant doesn't yet exists
+ try {
+ realmManager.getSession().users().updateConsent(realm, john.getId(), johnBarGrant);
+ Assert.fail("Not expected to end here");
+ } catch (ModelException expected) {
+ }
+
+ realmManager.getSession().users().addConsent(realm, john.getId(), johnBarGrant);
+
+ UserConsentModel maryFooGrant = new UserConsentModel(fooClient);
+ maryFooGrant.addGrantedRole(realmRole);
+ maryFooGrant.addGrantedProtocolMapper(fooMapper);
+ realmManager.getSession().users().addConsent(realm, mary.getId(), maryFooGrant);
+
+ commit();
+ }
+
+ @Test
+ public void basicConsentTest() {
+ RealmModel realm = realmManager.getRealm("original");
+ ClientModel fooClient = realm.getClientByClientId("foo-client");
+ ClientModel barClient = realm.getClientByClientId("bar-client");
+
+ UserModel john = session.users().getUserByUsername("john", realm);
+ UserModel mary = session.users().getUserByUsername("mary", realm);
+
+ UserConsentModel johnFooConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), 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));
+ Assert.assertNotNull("Created Date should be set", johnFooConsent.getCreatedDate());
+ Assert.assertNotNull("Last Updated Date should be set", johnFooConsent.getLastUpdatedDate());
+
+ UserConsentModel johnBarConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), 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));
+ Assert.assertNotNull("Created Date should be set", johnBarConsent.getCreatedDate());
+ Assert.assertNotNull("Last Updated Date should be set", johnBarConsent.getLastUpdatedDate());
+
+ UserConsentModel maryConsent = realmManager.getSession().users().getConsentByClient(realm, mary.getId(), 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.assertNotNull("Created Date should be set", maryConsent.getCreatedDate());
+ Assert.assertNotNull("Last Updated Date should be set", maryConsent.getLastUpdatedDate());
+
+ Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, mary.getId(), barClient.getId()));
+ }
+
+ @Test
+ public void getAllConsentTest() {
+ RealmModel realm = realmManager.getRealm("original");
+ ClientModel fooClient = realm.getClientByClientId("foo-client");
+
+ UserModel john = session.users().getUserByUsername("john", realm);
+ UserModel mary = session.users().getUserByUsername("mary", realm);
+
+ List<UserConsentModel> johnConsents = realmManager.getSession().users().getConsents(realm, john.getId());
+ Assert.assertEquals(2, johnConsents.size());
+
+ List<UserConsentModel> maryConsents = realmManager.getSession().users().getConsents(realm, mary.getId());
+ Assert.assertEquals(1, maryConsents.size());
+ UserConsentModel maryConsent = maryConsents.get(0);
+ Assert.assertEquals(maryConsent.getClient().getId(), fooClient.getId());
+ Assert.assertEquals(maryConsent.getGrantedRoles().size(), 1);
+ Assert.assertEquals(maryConsent.getGrantedProtocolMappers().size(), 1);
+ Assert.assertTrue(isRoleGranted(realm, "realm-role", maryConsent));
+ Assert.assertTrue(isMapperGranted(fooClient, "foo", maryConsent));
+ }
+
+ @Test
+ public void updateWithRoleRemovalTest() {
+ RealmModel realm = realmManager.getRealm("original");
+ ClientModel fooClient = realm.getClientByClientId("foo-client");
+ UserModel john = session.users().getUserByUsername("john", realm);
+
+ UserConsentModel johnConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
+
+ // Remove foo protocol mapper from johnConsent
+ ProtocolMapperModel protMapperModel = fooClient.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "foo");
+ johnConsent.getGrantedProtocolMappers().remove(protMapperModel);
+
+ // Remove realm-role and add new-realm-role to johnConsent
+ RoleModel realmRole = realm.getRole("realm-role");
+ johnConsent.getGrantedRoles().remove(realmRole);
+
+ RoleModel newRealmRole = realm.addRole("new-realm-role");
+ johnConsent.addGrantedRole(newRealmRole);
+
+ realmManager.getSession().users().updateConsent(realm, john.getId(), johnConsent);
+
+ commit();
+
+ realm = realmManager.getRealm("original");
+ fooClient = realm.getClientByClientId("foo-client");
+ john = session.users().getUserByUsername("john", realm);
+ johnConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
+
+ Assert.assertEquals(johnConsent.getGrantedRoles().size(), 2);
+ Assert.assertEquals(johnConsent.getGrantedProtocolMappers().size(), 0);
+ Assert.assertFalse(isRoleGranted(realm, "realm-role", johnConsent));
+ Assert.assertTrue(isRoleGranted(realm, "new-realm-role", johnConsent));
+ Assert.assertFalse(isMapperGranted(fooClient, "foo", johnConsent));
+ Assert.assertTrue("Created date should be less than last updated date", johnConsent.getCreatedDate() < johnConsent.getLastUpdatedDate());
+ }
+
+ @Test
+ public void revokeTest() {
+ RealmModel realm = realmManager.getRealm("original");
+ ClientModel fooClient = realm.getClientByClientId("foo-client");
+ UserModel john = session.users().getUserByUsername("john", realm);
+
+ realmManager.getSession().users().revokeConsentForClient(realm, john.getId(), fooClient.getId());
+
+ commit();
+
+ realm = realmManager.getRealm("original");
+ john = session.users().getUserByUsername("john", realm);
+ Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId()));
+ }
+
+ @Test
+ public void deleteUserTest() {
+ // Validate user deleted without any referential constraint errors
+ RealmModel realm = realmManager.getRealm("original");
+ UserModel john = session.users().getUserByUsername("john", realm);
+ session.users().removeUser(realm, john);
+ }
+
+ @Test
+ public void deleteProtocolMapperTest() {
+ RealmModel realm = realmManager.getRealm("original");
+ ClientModel fooClient = realm.getClientByClientId("foo-client");
+ ProtocolMapperModel fooMapper = fooClient.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "foo");
+ fooClient.removeProtocolMapper(fooMapper);
+
+ commit();
+
+ realm = realmManager.getRealm("original");
+ fooClient = realm.getClientByClientId("foo-client");
+ UserModel john = session.users().getUserByUsername("john", realm);
+ UserConsentModel johnConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
+
+ Assert.assertEquals(johnConsent.getGrantedRoles().size(), 2);
+ Assert.assertEquals(johnConsent.getGrantedProtocolMappers().size(), 0);
+ Assert.assertFalse(johnConsent.isProtocolMapperGranted(fooMapper));
+ }
+
+ @Test
+ public void deleteRoleTest() {
+ RealmModel realm = realmManager.getRealm("original");
+ RoleModel realmRole = realm.getRole("realm-role");
+ realm.removeRole(realmRole);
+
+ commit();
+
+ realm = realmManager.getRealm("original");
+ ClientModel fooClient = realm.getClientByClientId("foo-client");
+ ClientModel barClient = realm.getClientByClientId("bar-client");
+ UserModel john = session.users().getUserByUsername("john", realm);
+ UserConsentModel johnConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
+
+ Assert.assertEquals(johnConsent.getGrantedRoles().size(), 1);
+ Assert.assertEquals(johnConsent.getGrantedProtocolMappers().size(), 1);
+ Assert.assertFalse(johnConsent.isRoleGranted(realmRole));
+ Assert.assertTrue(isRoleGranted(barClient, "bar-client-role", johnConsent));
+ }
+
+ @Test
+ public void deleteClientTest() {
+ RealmModel realm = realmManager.getRealm("original");
+ ClientModel barClient = realm.getClientByClientId("bar-client");
+ realm.removeClient(barClient.getId());
+
+ commit();
+
+ realm = realmManager.getRealm("original");
+ ClientModel fooClient = realm.getClientByClientId("foo-client");
+ Assert.assertNull(realm.getClientByClientId("bar-client"));
+
+ UserModel john = session.users().getUserByUsername("john", realm);
+
+ UserConsentModel johnFooConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), 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(realmManager.getSession().users().getConsentByClient(realm, john.getId(), barClient.getId()));
+ }
+
+ private boolean isRoleGranted(RoleContainerModel roleContainer, String roleName, UserConsentModel consentModel) {
+ RoleModel role = roleContainer.getRole(roleName);
+ return consentModel.isRoleGranted(role);
+ }
+
+ private boolean isMapperGranted(ClientModel client, String protocolMapperName, UserConsentModel consentModel) {
+ ProtocolMapperModel protocolMapper = client.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, protocolMapperName);
+ return consentModel.isProtocolMapperGranted(protocolMapper);
+ }
+}