keycloak-aplcache
Changes
model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentProtocolMapperEntity.java 4(+3 -1)
model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserConsentProtocolMapperEntity.java 2(+2 -0)
model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserConsentRoleEntity.java 2(+2 -0)
testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProvider.java 4(+3 -1)
testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProviderFactory.java 9(+8 -1)
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 e2fcc83..be3d0ad 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
@@ -54,6 +54,7 @@ import org.keycloak.storage.CacheableStorageProviderModel;
import org.keycloak.storage.StorageId;
import org.keycloak.storage.UserStorageProvider;
import org.keycloak.storage.UserStorageProviderModel;
+import org.keycloak.storage.client.ClientStorageProvider;
import java.util.Calendar;
import java.util.HashMap;
@@ -853,7 +854,7 @@ public class UserCacheSession implements UserCache {
@Override
public void preRemove(RealmModel realm, ComponentModel component) {
- if (!component.getProviderType().equals(UserStorageProvider.class.getName())) return;
+ if (!component.getProviderType().equals(UserStorageProvider.class.getName()) && !component.getProviderType().equals(ClientStorageProvider.class.getName())) return;
addRealmInvalidation(realm.getId()); // easier to just invalidate whole realm
getDelegate().preRemove(realm, component);
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentEntity.java
index a29ab69..9772810 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentEntity.java
@@ -43,11 +43,14 @@ import java.util.Collection;
})
@NamedQueries({
@NamedQuery(name="userConsentByUserAndClient", query="select consent from UserConsentEntity consent where consent.user.id = :userId and consent.clientId = :clientId"),
+ @NamedQuery(name="userConsentByUserAndExternalClient", query="select consent from UserConsentEntity consent where consent.user.id = :userId and consent.clientStorageProvider = :clientStorageProvider and consent.externalClientId = :externalClientId"),
@NamedQuery(name="userConsentsByUser", query="select consent from UserConsentEntity consent where consent.user.id = :userId"),
@NamedQuery(name="deleteUserConsentsByRealm", query="delete from UserConsentEntity consent where consent.user IN (select user from UserEntity user where user.realmId = :realmId)"),
@NamedQuery(name="deleteUserConsentsByRealmAndLink", query="delete from UserConsentEntity consent where consent.user IN (select u from UserEntity u where u.realmId=:realmId and u.federationLink=:link)"),
@NamedQuery(name="deleteUserConsentsByUser", query="delete from UserConsentEntity consent where consent.user = :user"),
@NamedQuery(name="deleteUserConsentsByClient", query="delete from UserConsentEntity consent where consent.clientId = :clientId"),
+ @NamedQuery(name="deleteUserConsentsByExternalClient", query="delete from UserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider and consent.externalClientId = :externalClientId"),
+ @NamedQuery(name="deleteUserConsentsByClientStorageProvider", query="delete from UserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider"),
})
public class UserConsentEntity {
@@ -63,6 +66,12 @@ public class UserConsentEntity {
@Column(name="CLIENT_ID")
protected String clientId;
+ @Column(name="CLIENT_STORAGE_PROVIDER")
+ protected String clientStorageProvider;
+
+ @Column(name="EXTERNAL_CLIENT_ID")
+ protected String externalClientId;
+
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "userConsent")
Collection<UserConsentRoleEntity> grantedRoles = new ArrayList<UserConsentRoleEntity>();
@@ -91,14 +100,6 @@ public class UserConsentEntity {
this.user = user;
}
- public String getClientId() {
- return clientId;
- }
-
- public void setClientId(String clientId) {
- this.clientId = clientId;
- }
-
public Collection<UserConsentRoleEntity> getGrantedRoles() {
return grantedRoles;
}
@@ -131,6 +132,30 @@ public class UserConsentEntity {
this.lastUpdatedDate = lastUpdatedDate;
}
+ public String getClientId() {
+ return clientId;
+ }
+
+ public void setClientId(String clientId) {
+ this.clientId = clientId;
+ }
+
+ public String getClientStorageProvider() {
+ return clientStorageProvider;
+ }
+
+ public void setClientStorageProvider(String clientStorageProvider) {
+ this.clientStorageProvider = clientStorageProvider;
+ }
+
+ public String getExternalClientId() {
+ return externalClientId;
+ }
+
+ public void setExternalClientId(String externalClientId) {
+ this.externalClientId = externalClientId;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentProtocolMapperEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentProtocolMapperEntity.java
index 4c0dd5d..85df759 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentProtocolMapperEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentProtocolMapperEntity.java
@@ -38,7 +38,9 @@ import java.io.Serializable;
@NamedQuery(name="deleteUserConsentProtMappersByUser", query="delete from UserConsentProtocolMapperEntity csm where csm.userConsent IN (select consent from UserConsentEntity consent where consent.user = :user)"),
@NamedQuery(name="deleteUserConsentProtMappersByRealmAndLink", query="delete from UserConsentProtocolMapperEntity csm where csm.userConsent IN (select consent from UserConsentEntity consent where consent.user IN (select u from UserEntity u where u.realmId=:realmId and u.federationLink=:link))"),
@NamedQuery(name="deleteUserConsentProtMappersByProtocolMapper", query="delete from UserConsentProtocolMapperEntity csm where csm.protocolMapperId = :protocolMapperId)"),
- @NamedQuery(name="deleteUserConsentProtMappersByClient", query="delete from UserConsentProtocolMapperEntity csm where csm.userConsent IN (select consent from UserConsentEntity consent where consent.clientId = :clientId))"),
+ @NamedQuery(name="deleteUserConsentProtMappersByClient", query="delete from UserConsentProtocolMapperEntity csm where csm.userConsent IN (select consent from UserConsentEntity consent where consent.clientId = :clientId)"),
+ @NamedQuery(name="deleteUserConsentProtMappersByExternalClient", query="delete from UserConsentProtocolMapperEntity csm where csm.userConsent IN (select consent from UserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider and consent.externalClientId = :externalClientId)"),
+ @NamedQuery(name="deleteUserConsentProtMappersByClientStorageProvider", query="delete from UserConsentProtocolMapperEntity csm where csm.userConsent IN (select consent from UserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider)"),
})
@Entity
@Table(name="USER_CONSENT_PROT_MAPPER")
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentRoleEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentRoleEntity.java
index 95d5f3e..c4818c7 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentRoleEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserConsentRoleEntity.java
@@ -38,6 +38,8 @@ import java.io.Serializable;
@NamedQuery(name="deleteUserConsentRolesByUser", query="delete from UserConsentRoleEntity grantedRole where grantedRole.userConsent IN (select consent from UserConsentEntity consent where consent.user = :user)"),
@NamedQuery(name="deleteUserConsentRolesByRole", query="delete from UserConsentRoleEntity grantedRole where grantedRole.roleId = :roleId)"),
@NamedQuery(name="deleteUserConsentRolesByClient", query="delete from UserConsentRoleEntity grantedRole where grantedRole.userConsent IN (select consent from UserConsentEntity consent where consent.clientId = :clientId)"),
+ @NamedQuery(name="deleteUserConsentRolesByExternalClient", query="delete from UserConsentRoleEntity grantedRole where grantedRole.userConsent IN (select consent from UserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider and consent.externalClientId = :externalClientId)"),
+ @NamedQuery(name="deleteUserConsentRolesByClientStorageProvider", query="delete from UserConsentRoleEntity grantedRole where grantedRole.userConsent IN (select consent from UserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider)"),
})
@Entity
@Table(name="USER_CONSENT_ROLE")
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java
index 08f3164..8eb8102 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java
@@ -45,7 +45,9 @@ import org.keycloak.models.jpa.entities.UserConsentRoleEntity;
import org.keycloak.models.jpa.entities.UserEntity;
import org.keycloak.models.utils.DefaultRoles;
import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.storage.StorageId;
import org.keycloak.storage.UserStorageProvider;
+import org.keycloak.storage.client.ClientStorageProvider;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
@@ -194,7 +196,14 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
consentEntity = new UserConsentEntity();
consentEntity.setId(KeycloakModelUtils.generateId());
consentEntity.setUser(em.getReference(UserEntity.class, userId));
- consentEntity.setClientId(clientId);
+ StorageId clientStorageId = new StorageId(clientId);
+ if (clientStorageId.isLocal()) {
+ consentEntity.setClientId(clientId);
+ } else {
+ consentEntity.setClientStorageProvider(clientStorageId.getProviderId());
+ consentEntity.setExternalClientId(clientStorageId.getExternalId());
+ }
+
consentEntity.setCreatedDate(currentTime);
consentEntity.setLastUpdatedDate(currentTime);
em.persist(consentEntity);
@@ -246,9 +255,16 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
private UserConsentEntity getGrantedConsentEntity(String userId, String clientId) {
- TypedQuery<UserConsentEntity> query = em.createNamedQuery("userConsentByUserAndClient", UserConsentEntity.class);
+ StorageId clientStorageId = new StorageId(clientId);
+ String queryName = clientStorageId.isLocal() ? "userConsentByUserAndClient" : "userConsentByUserAndExternalClient";
+ TypedQuery<UserConsentEntity> query = em.createNamedQuery(queryName, UserConsentEntity.class);
query.setParameter("userId", userId);
- query.setParameter("clientId", clientId);
+ if (clientStorageId.isLocal()) {
+ query.setParameter("clientId", clientId);
+ } else {
+ query.setParameter("clientStorageProvider", clientStorageId.getProviderId());
+ query.setParameter("externalClientId", clientStorageId.getExternalId());
+ }
List<UserConsentEntity> results = query.getResultList();
if (results.size() > 1) {
throw new ModelException("More results found for user [" + userId + "] and client [" + clientId + "]");
@@ -257,6 +273,7 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
} else {
return null;
}
+
}
private UserConsentModel toConsentModel(RealmModel realm, UserConsentEntity entity) {
@@ -264,9 +281,16 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
return null;
}
- ClientModel client = realm.getClientById(entity.getClientId());
+ StorageId clientStorageId = null;
+ if ( entity.getClientId() == null) {
+ clientStorageId = new StorageId(entity.getClientStorageProvider(), entity.getExternalClientId());
+ } else {
+ clientStorageId = new StorageId(entity.getClientId());
+ }
+
+ ClientModel client = realm.getClientById(clientStorageId.getId());
if (client == null) {
- throw new ModelException("Client with id " + entity.getClientId() + " is not available");
+ throw new ModelException("Client with id " + clientStorageId.getId() + " is not available");
}
UserConsentModel model = new UserConsentModel(client);
model.setCreatedDate(entity.getCreatedDate());
@@ -472,9 +496,32 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
@Override
public void preRemove(RealmModel realm, ClientModel client) {
- em.createNamedQuery("deleteUserConsentProtMappersByClient").setParameter("clientId", client.getId()).executeUpdate();
- em.createNamedQuery("deleteUserConsentRolesByClient").setParameter("clientId", client.getId()).executeUpdate();
- em.createNamedQuery("deleteUserConsentsByClient").setParameter("clientId", client.getId()).executeUpdate();
+ StorageId clientStorageId = new StorageId(client.getId());
+ if (clientStorageId.isLocal()) {
+ em.createNamedQuery("deleteUserConsentProtMappersByClient")
+ .setParameter("clientId", client.getId())
+ .executeUpdate();
+ em.createNamedQuery("deleteUserConsentRolesByClient")
+ .setParameter("clientId", client.getId())
+ .executeUpdate();
+ em.createNamedQuery("deleteUserConsentsByClient")
+ .setParameter("clientId", client.getId())
+ .executeUpdate();
+ } else {
+ em.createNamedQuery("deleteUserConsentProtMappersByExternalClient")
+ .setParameter("clientStorageProvider", clientStorageId.getProviderId())
+ .setParameter("externalClientId",clientStorageId.getExternalId())
+ .executeUpdate();
+ em.createNamedQuery("deleteUserConsentRolesByExternalClient")
+ .setParameter("clientStorageProvider", clientStorageId.getProviderId())
+ .setParameter("externalClientId", clientStorageId.getExternalId())
+ .executeUpdate();
+ em.createNamedQuery("deleteUserConsentsByExternalClient")
+ .setParameter("clientStorageProvider", clientStorageId.getProviderId())
+ .setParameter("externalClientId", clientStorageId.getExternalId())
+ .executeUpdate();
+
+ }
}
@Override
@@ -806,8 +853,24 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
@Override
public void preRemove(RealmModel realm, ComponentModel component) {
- if (!component.getProviderType().equals(UserStorageProvider.class.getName())) return;
- removeImportedUsers(realm, component.getId());
+ if (component.getProviderType().equals(UserStorageProvider.class.getName())) {
+ removeImportedUsers(realm, component.getId());
+ }
+ if (component.getProviderType().equals(ClientStorageProvider.class.getName())) {
+ removeConsentByClientStorageProvider(realm, component.getId());
+ }
+ }
+
+ protected void removeConsentByClientStorageProvider(RealmModel realm, String providerId) {
+ em.createNamedQuery("deleteUserConsentProtMappersByClientStorageProvider")
+ .setParameter("clientStorageProvider", providerId)
+ .executeUpdate();
+ em.createNamedQuery("deleteUserConsentRolesByClientStorageProvider")
+ .setParameter("clientStorageProvider", providerId)
+ .executeUpdate();
+ em.createNamedQuery("deleteUserConsentsByClientStorageProvider")
+ .setParameter("clientStorageProvider", providerId)
+ .executeUpdate();
}
diff --git a/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserConsentEntity.java b/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserConsentEntity.java
index 225e80b..c2eac0b 100755
--- a/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserConsentEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserConsentEntity.java
@@ -40,11 +40,14 @@ import java.util.Collection;
})
@NamedQueries({
@NamedQuery(name="userFederatedConsentByUserAndClient", query="select consent from FederatedUserConsentEntity consent where consent.userId = :userId and consent.clientId = :clientId"),
+ @NamedQuery(name="userFederatedConsentByUserAndExternalClient", query="select consent from FederatedUserConsentEntity consent where consent.userId = :userId and consent.clientStorageProvider = :clientStorageProvider and consent.externalClientId = :externalClientId"),
@NamedQuery(name="userFederatedConsentsByUser", query="select consent from FederatedUserConsentEntity consent where consent.userId = :userId"),
@NamedQuery(name="deleteFederatedUserConsentsByRealm", query="delete from FederatedUserConsentEntity consent where consent.realmId=:realmId"),
@NamedQuery(name="deleteFederatedUserConsentsByStorageProvider", query="delete from FederatedUserConsentEntity e where e.storageProviderId=:storageProviderId"),
@NamedQuery(name="deleteFederatedUserConsentsByUser", query="delete from FederatedUserConsentEntity consent where consent.userId = :userId and consent.realmId = :realmId"),
@NamedQuery(name="deleteFederatedUserConsentsByClient", query="delete from FederatedUserConsentEntity consent where consent.clientId = :clientId"),
+ @NamedQuery(name="deleteFederatedUserConsentsByExternalClient", query="delete from FederatedUserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider and consent.externalClientId = :externalClientId"),
+ @NamedQuery(name="deleteFederatedUserConsentsByClientStorageProvider", query="delete from FederatedUserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider"),
})
public class FederatedUserConsentEntity {
@@ -65,6 +68,12 @@ public class FederatedUserConsentEntity {
@Column(name="CLIENT_ID")
protected String clientId;
+ @Column(name="CLIENT_STORAGE_PROVIDER")
+ protected String clientStorageProvider;
+
+ @Column(name="EXTERNAL_CLIENT_ID")
+ protected String externalClientId;
+
@Column(name = "CREATED_DATE")
private Long createdDate;
@@ -119,6 +128,22 @@ public class FederatedUserConsentEntity {
this.clientId = clientId;
}
+ public String getClientStorageProvider() {
+ return clientStorageProvider;
+ }
+
+ public void setClientStorageProvider(String clientStorageProvider) {
+ this.clientStorageProvider = clientStorageProvider;
+ }
+
+ public String getExternalClientId() {
+ return externalClientId;
+ }
+
+ public void setExternalClientId(String externalClientId) {
+ this.externalClientId = externalClientId;
+ }
+
public Collection<FederatedUserConsentRoleEntity> getGrantedRoles() {
return grantedRoles;
}
diff --git a/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserConsentProtocolMapperEntity.java b/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserConsentProtocolMapperEntity.java
index f7da2cc..a9de2c6 100755
--- a/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserConsentProtocolMapperEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserConsentProtocolMapperEntity.java
@@ -39,6 +39,8 @@ import java.io.Serializable;
@NamedQuery(name="deleteFederatedUserConsentProtMappersByStorageProvider", query="delete from FederatedUserConsentProtocolMapperEntity csm where csm.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.storageProviderId = :storageProviderId)"),
@NamedQuery(name="deleteFederatedUserConsentProtMappersByProtocolMapper", query="delete from FederatedUserConsentProtocolMapperEntity csm where csm.protocolMapperId = :protocolMapperId"),
@NamedQuery(name="deleteFederatedUserConsentProtMappersByClient", query="delete from FederatedUserConsentProtocolMapperEntity csm where csm.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.clientId = :clientId)"),
+ @NamedQuery(name="deleteFederatedUserConsentProtMappersByExternalClient", query="delete from FederatedUserConsentProtocolMapperEntity csm where csm.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider and consent.externalClientId = :externalClientId)"),
+ @NamedQuery(name="deleteFederatedUserConsentProtMappersByClientStorageProvider", query="delete from FederatedUserConsentProtocolMapperEntity csm where csm.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider)"),
})
@Entity
@Table(name="FED_USER_CONSENT_PROT_MAPPER")
diff --git a/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserConsentRoleEntity.java b/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserConsentRoleEntity.java
index d74865d..0e0551d 100755
--- a/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserConsentRoleEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/storage/jpa/entity/FederatedUserConsentRoleEntity.java
@@ -38,6 +38,8 @@ import java.io.Serializable;
@NamedQuery(name="deleteFederatedUserConsentRolesByStorageProvider", query="delete from FederatedUserConsentRoleEntity grantedRole where grantedRole.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.storageProviderId = :storageProviderId)"),
@NamedQuery(name="deleteFederatedUserConsentRolesByRole", query="delete from FederatedUserConsentRoleEntity grantedRole where grantedRole.roleId = :roleId"),
@NamedQuery(name="deleteFederatedUserConsentRolesByClient", query="delete from FederatedUserConsentRoleEntity grantedRole where grantedRole.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.clientId = :clientId)"),
+ @NamedQuery(name="deleteFederatedUserConsentRolesByExternalClient", query="delete from FederatedUserConsentRoleEntity grantedRole where grantedRole.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider and consent.externalClientId = :externalClientId)"),
+ @NamedQuery(name="deleteFederatedUserConsentRolesByClientStorageProvider", query="delete from FederatedUserConsentRoleEntity grantedRole where grantedRole.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider)"),
})
@Entity
@Table(name="FED_USER_CONSENT_ROLE")
diff --git a/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java b/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java
index f6de431..7474155 100644
--- a/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/storage/jpa/JpaUserFederatedStorageProvider.java
@@ -32,9 +32,11 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserConsentModel;
import org.keycloak.models.UserModel;
+import org.keycloak.models.jpa.entities.UserConsentEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.storage.StorageId;
import org.keycloak.storage.UserStorageProvider;
+import org.keycloak.storage.client.ClientStorageProvider;
import org.keycloak.storage.federated.UserFederatedStorageProvider;
import org.keycloak.storage.jpa.entity.BrokerLinkEntity;
import org.keycloak.storage.jpa.entity.FederatedUser;
@@ -257,7 +259,13 @@ public class JpaUserFederatedStorageProvider implements
consentEntity = new FederatedUserConsentEntity();
consentEntity.setId(KeycloakModelUtils.generateId());
consentEntity.setUserId(userId);
- consentEntity.setClientId(clientId);
+ StorageId clientStorageId = new StorageId(clientId);
+ if (clientStorageId.isLocal()) {
+ consentEntity.setClientId(clientId);
+ } else {
+ consentEntity.setClientStorageProvider(clientStorageId.getProviderId());
+ consentEntity.setExternalClientId(clientStorageId.getExternalId());
+ }
consentEntity.setRealmId(realm.getId());
consentEntity.setStorageProviderId(new StorageId(userId).getProviderId());
long currentTime = Time.currentTimeMillis();
@@ -315,9 +323,16 @@ public class JpaUserFederatedStorageProvider implements
}
private FederatedUserConsentEntity getGrantedConsentEntity(String userId, String clientId) {
- TypedQuery<FederatedUserConsentEntity> query = em.createNamedQuery("userFederatedConsentByUserAndClient", FederatedUserConsentEntity.class);
+ StorageId clientStorageId = new StorageId(clientId);
+ String queryName = clientStorageId.isLocal() ? "userFederatedConsentByUserAndClient" : "userFederatedConsentByUserAndExternalClient";
+ TypedQuery<FederatedUserConsentEntity> query = em.createNamedQuery(queryName, FederatedUserConsentEntity.class);
query.setParameter("userId", userId);
- query.setParameter("clientId", clientId);
+ if (clientStorageId.isLocal()) {
+ query.setParameter("clientId", clientId);
+ } else {
+ query.setParameter("clientStorageProvider", clientStorageId.getProviderId());
+ query.setParameter("externalClientId", clientStorageId.getExternalId());
+ }
List<FederatedUserConsentEntity> results = query.getResultList();
if (results.size() > 1) {
throw new ModelException("More results found for user [" + userId + "] and client [" + clientId + "]");
@@ -334,10 +349,14 @@ public class JpaUserFederatedStorageProvider implements
return null;
}
- ClientModel client = realm.getClientById(entity.getClientId());
- if (client == null) {
- throw new ModelException("Client with id " + entity.getClientId() + " is not available");
+ StorageId clientStorageId = null;
+ if ( entity.getClientId() == null) {
+ clientStorageId = new StorageId(entity.getClientStorageProvider(), entity.getExternalClientId());
+ } else {
+ clientStorageId = new StorageId(entity.getClientId());
}
+
+ ClientModel client = realm.getClientById(clientStorageId.getId());
UserConsentModel model = new UserConsentModel(client);
model.setCreatedDate(entity.getCreatedDate());
model.setLastUpdatedDate(entity.getLastUpdatedDate());
@@ -822,9 +841,26 @@ public class JpaUserFederatedStorageProvider implements
@Override
public void preRemove(RealmModel realm, ClientModel client) {
- em.createNamedQuery("deleteFederatedUserConsentProtMappersByClient").setParameter("clientId", client.getId()).executeUpdate();
- em.createNamedQuery("deleteFederatedUserConsentRolesByClient").setParameter("clientId", client.getId()).executeUpdate();
- em.createNamedQuery("deleteFederatedUserConsentsByClient").setParameter("clientId", client.getId()).executeUpdate();
+ StorageId clientStorageId = new StorageId(client.getId());
+ if (clientStorageId.isLocal()) {
+ em.createNamedQuery("deleteFederatedUserConsentProtMappersByClient").setParameter("clientId", client.getId()).executeUpdate();
+ em.createNamedQuery("deleteFederatedUserConsentRolesByClient").setParameter("clientId", client.getId()).executeUpdate();
+ em.createNamedQuery("deleteFederatedUserConsentsByClient").setParameter("clientId", client.getId()).executeUpdate();
+ } else {
+ em.createNamedQuery("deleteFederatedUserConsentProtMappersByExternalClient")
+ .setParameter("clientStorageProvider", clientStorageId.getProviderId())
+ .setParameter("externalClientId",clientStorageId.getExternalId())
+ .executeUpdate();
+ em.createNamedQuery("deleteFederatedUserConsentRolesByExternalClient")
+ .setParameter("clientStorageProvider", clientStorageId.getProviderId())
+ .setParameter("externalClientId",clientStorageId.getExternalId())
+ .executeUpdate();
+ em.createNamedQuery("deleteFederatedUserConsentsByExternalClient")
+ .setParameter("clientStorageProvider", clientStorageId.getProviderId())
+ .setParameter("externalClientId",clientStorageId.getExternalId())
+ .executeUpdate();
+
+ }
}
@Override
@@ -885,41 +921,53 @@ public class JpaUserFederatedStorageProvider implements
@Override
public void preRemove(RealmModel realm, ComponentModel model) {
- if (!model.getProviderType().equals(UserStorageProvider.class.getName())) return;
+ if (model.getProviderType().equals(UserStorageProvider.class.getName())) {
+
+ em.createNamedQuery("deleteBrokerLinkByStorageProvider")
+ .setParameter("storageProviderId", model.getId())
+ .executeUpdate();
+ em.createNamedQuery("deleteFederatedAttributesByStorageProvider")
+ .setParameter("storageProviderId", model.getId())
+ .executeUpdate();
+ em.createNamedQuery("deleteFederatedUserConsentProtMappersByStorageProvider")
+ .setParameter("storageProviderId", model.getId())
+ .executeUpdate();
+ em.createNamedQuery("deleteFederatedUserRoleMappingsByStorageProvider")
+ .setParameter("storageProviderId", model.getId())
+ .executeUpdate();
+ em.createNamedQuery("deleteFederatedUserConsentsByStorageProvider")
+ .setParameter("storageProviderId", model.getId())
+ .executeUpdate();
+ em.createNamedQuery("deleteFederatedCredentialAttributeByStorageProvider")
+ .setParameter("storageProviderId", model.getId())
+ .executeUpdate();
+ em.createNamedQuery("deleteFederatedUserCredentialsByStorageProvider")
+ .setParameter("storageProviderId", model.getId())
+ .executeUpdate();
+ em.createNamedQuery("deleteFederatedUserGroupMembershipByStorageProvider")
+ .setParameter("storageProviderId", model.getId())
+ .executeUpdate();
+ em.createNamedQuery("deleteFederatedUserRequiredActionsByStorageProvider")
+ .setParameter("storageProviderId", model.getId())
+ .executeUpdate();
+ em.createNamedQuery("deleteFederatedUserRoleMappingsByStorageProvider")
+ .setParameter("storageProviderId", model.getId())
+ .executeUpdate();
+ em.createNamedQuery("deleteFederatedUsersByStorageProvider")
+ .setParameter("storageProviderId", model.getId())
+ .executeUpdate();
+ } else if (model.getProviderType().equals(ClientStorageProvider.class.getName())) {
+ em.createNamedQuery("deleteFederatedUserConsentProtMappersByClientStorageProvider")
+ .setParameter("clientStorageProvider", model.getId())
+ .executeUpdate();
+ em.createNamedQuery("deleteFederatedUserConsentRolesByClientStorageProvider")
+ .setParameter("clientStorageProvider", model.getId())
+ .executeUpdate();
+ em.createNamedQuery("deleteFederatedUserConsentsByClientStorageProvider")
+ .setParameter("clientStorageProvider", model.getId())
+ .executeUpdate();
- em.createNamedQuery("deleteBrokerLinkByStorageProvider")
- .setParameter("storageProviderId", model.getId())
- .executeUpdate();
- em.createNamedQuery("deleteFederatedAttributesByStorageProvider")
- .setParameter("storageProviderId", model.getId())
- .executeUpdate();
- em.createNamedQuery("deleteFederatedUserConsentProtMappersByStorageProvider")
- .setParameter("storageProviderId", model.getId())
- .executeUpdate();
- em.createNamedQuery("deleteFederatedUserRoleMappingsByStorageProvider")
- .setParameter("storageProviderId", model.getId())
- .executeUpdate();
- em.createNamedQuery("deleteFederatedUserConsentsByStorageProvider")
- .setParameter("storageProviderId", model.getId())
- .executeUpdate();
- em.createNamedQuery("deleteFederatedCredentialAttributeByStorageProvider")
- .setParameter("storageProviderId", model.getId())
- .executeUpdate();
- em.createNamedQuery("deleteFederatedUserCredentialsByStorageProvider")
- .setParameter("storageProviderId", model.getId())
- .executeUpdate();
- em.createNamedQuery("deleteFederatedUserGroupMembershipByStorageProvider")
- .setParameter("storageProviderId", model.getId())
- .executeUpdate();
- em.createNamedQuery("deleteFederatedUserRequiredActionsByStorageProvider")
- .setParameter("storageProviderId", model.getId())
- .executeUpdate();
- em.createNamedQuery("deleteFederatedUserRoleMappingsByStorageProvider")
- .setParameter("storageProviderId", model.getId())
- .executeUpdate();
- em.createNamedQuery("deleteFederatedUsersByStorageProvider")
- .setParameter("storageProviderId", model.getId())
- .executeUpdate();
+ }
}
}
diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-4.0.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-4.0.0.xml
index 859f2a7..09a1d80 100644
--- a/model/jpa/src/main/resources/META-INF/jpa-changelog-4.0.0.xml
+++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-4.0.0.xml
@@ -41,8 +41,32 @@
<!-- Modify USER_CONSENT -->
<dropUniqueConstraint constraintName="UK_JKUWUVD56ONTGSUHOGM8UEWRT" tableName="USER_CONSENT"/>
- <modifyDataType tableName="USER_CONSENT" columnName="CLIENT_ID" newDataType="VARCHAR(255)"/>
- <addUniqueConstraint columnNames="CLIENT_ID, USER_ID" constraintName="UK_JKUWUVD56ONTGSUHOGM8UEWRT" tableName="USER_CONSENT"/>
+ <dropNotNullConstraint tableName="USER_CONSENT" columnName="CLIENT_ID" columnDataType="VARCHAR(36)"/>
+ <addColumn tableName="USER_CONSENT">
+ <column name="CLIENT_STORAGE_PROVIDER" type="VARCHAR(36)">
+ <constraints nullable="true"/>
+ </column>
+ <column name="EXTERNAL_CLIENT_ID" type="VARCHAR(255)">
+ <constraints nullable="true"/>
+ </column>
+ </addColumn>
+ <addUniqueConstraint columnNames="CLIENT_ID, CLIENT_STORAGE_PROVIDER, EXTERNAL_CLIENT_ID, USER_ID" constraintName="UK_JKUWUVD56ONTGSUHOGM8UEWRT" tableName="USER_CONSENT"/>
+
+ <!-- FED_USER_CONSENT -->
+ <addColumn tableName="FED_USER_CONSENT">
+ <column name="CLIENT_STORAGE_PROVIDER" type="VARCHAR(36)">
+ <constraints nullable="true"/>
+ </column>
+ <column name="EXTERNAL_CLIENT_ID" type="VARCHAR(255)">
+ <constraints nullable="true"/>
+ </column>
+ </addColumn>
+ <dropNotNullConstraint tableName="FED_USER_CONSENT" columnName="CLIENT_ID" columnDataType="VARCHAR(36)"/>
+ <createIndex tableName="FED_USER_CONSENT" indexName="IDX_FU_CNSNT_EXT">
+ <column name="USER_ID" type="VARCHAR(255)" />
+ <column name="CLIENT_STORAGE_PROVIDER" type="VARCHAR(36)" />
+ <column name="EXTERNAL_CLIENT_ID" type="VARCHAR(255)" />
+ </createIndex>
<!-- Modify CLIENT_NODE_REGISTRATIONS -->
<dropForeignKeyConstraint constraintName="FK4129723BA992F594" baseTableName="CLIENT"/>
@@ -53,12 +77,5 @@
<modifyDataType tableName="OFFLINE_CLIENT_SESSION" columnName="CLIENT_ID" newDataType="VARCHAR(255)"/>
<addPrimaryKey columnNames="USER_SESSION_ID,CLIENT_ID, OFFLINE_FLAG" constraintName="CONSTRAINT_OFFL_CL_SES_PK3" tableName="OFFLINE_CLIENT_SESSION"/>
- <!-- FED_USER_CONSENT -->
- <dropIndex tableName="FED_USER_CONSENT" indexName="IDX_FU_CONSENT"/>
- <modifyDataType tableName="FED_USER_CONSENT" columnName="CLIENT_ID" newDataType="VARCHAR(255)"/>
- <createIndex tableName="FED_USER_CONSENT" indexName="IDX_FU_CONSENT">
- <column name="USER_ID" type="VARCHAR(255)" />
- <column name="CLIENT_ID" type="VARCHAR(36)" />
- </createIndex>
- </changeSet>
+ </changeSet>
</databaseChangeLog>
diff --git a/services/src/main/java/org/keycloak/storage/UserStorageManager.java b/services/src/main/java/org/keycloak/storage/UserStorageManager.java
index 16d14e0..4801553 100755
--- a/services/src/main/java/org/keycloak/storage/UserStorageManager.java
+++ b/services/src/main/java/org/keycloak/storage/UserStorageManager.java
@@ -40,6 +40,7 @@ import org.keycloak.models.cache.UserCache;
import org.keycloak.models.utils.ComponentUtil;
import org.keycloak.models.utils.ReadOnlyUserModelDelegate;
import org.keycloak.services.managers.UserStorageSyncManager;
+import org.keycloak.storage.client.ClientStorageProvider;
import org.keycloak.storage.federated.UserFederatedStorageProvider;
import org.keycloak.storage.user.ImportedUserValidation;
import org.keycloak.storage.user.UserBulkUpdateProvider;
@@ -696,6 +697,11 @@ public class UserStorageManager implements UserProvider, OnUserCache, OnCreateCo
@Override
public void preRemove(RealmModel realm, ComponentModel component) {
+ if (component.getProviderType().equals(ClientStorageProvider.class.getName())) {
+ localStorage().preRemove(realm, component);
+ if (getFederatedStorage() != null) getFederatedStorage().preRemove(realm, component);
+ return;
+ }
if (!component.getProviderType().equals(UserStorageProvider.class.getName())) return;
localStorage().preRemove(realm, component);
if (getFederatedStorage() != null) getFederatedStorage().preRemove(realm, component);
diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProvider.java
index e56c864..672cb1e 100644
--- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProvider.java
+++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProvider.java
@@ -42,12 +42,14 @@ public class HardcodedClientStorageProvider implements ClientStorageProvider, Cl
protected ClientStorageProviderModel component;
protected String clientId;
protected String redirectUri;
+ protected boolean consent;
public HardcodedClientStorageProvider(KeycloakSession session, ClientStorageProviderModel component) {
this.session = session;
this.component = component;
this.clientId = component.getConfig().getFirst(HardcodedClientStorageProviderFactory.CLIENT_ID);
this.redirectUri = component.getConfig().getFirst(HardcodedClientStorageProviderFactory.REDIRECT_URI);
+ this.consent = "true".equals(component.getConfig().getFirst(HardcodedClientStorageProviderFactory.CONSENT));
}
@Override
@@ -189,7 +191,7 @@ public class HardcodedClientStorageProvider implements ClientStorageProvider, Cl
@Override
public boolean isConsentRequired() {
- return false;
+ return consent;
}
@Override
diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProviderFactory.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProviderFactory.java
index 6b2e480..67fcc0e 100644
--- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProviderFactory.java
+++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProviderFactory.java
@@ -48,6 +48,7 @@ public class HardcodedClientStorageProviderFactory implements ClientStorageProvi
public static final String CLIENT_ID = "client_id";
public static final String REDIRECT_URI = "redirect_uri";
+ public static final String CONSENT = "consent";
static {
CONFIG_PROPERTIES = ProviderConfigurationBuilder.create()
@@ -58,11 +59,17 @@ public class HardcodedClientStorageProviderFactory implements ClientStorageProvi
.defaultValue("hardcoded-client")
.add()
.property().name(REDIRECT_URI)
- .type(ProviderConfigProperty.BOOLEAN_TYPE)
+ .type(ProviderConfigProperty.STRING_TYPE)
.label("Redirect Uri")
.helpText("Valid redirect uri. Only one allowed")
.defaultValue("http://localhost:8180/*")
.add()
+ .property().name(CONSENT)
+ .type(ProviderConfigProperty.BOOLEAN_TYPE)
+ .label("Consent Required")
+ .helpText("Is consent required")
+ .defaultValue("false")
+ .add()
.build();
}
diff --git a/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/UserConsentModelTest.java b/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/UserConsentModelTest.java
index 9fe49f2..ced16a0 100644
--- a/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/UserConsentModelTest.java
+++ b/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/UserConsentModelTest.java
@@ -20,6 +20,7 @@ package org.keycloak.testsuite.model;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.keycloak.component.ComponentModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.ModelException;
import org.keycloak.models.ProtocolMapperModel;
@@ -30,6 +31,8 @@ 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.client.ClientStorageProviderModel;
+import org.keycloak.testsuite.federation.HardcodedClientStorageProviderFactory;
import java.util.List;
@@ -38,6 +41,8 @@ import java.util.List;
*/
public class UserConsentModelTest extends AbstractModelTest {
+ private ComponentModel clientStorageComponent;
+
@Before
public void setupEnv() {
RealmModel realm = realmManager.createRealm("original");
@@ -87,6 +92,22 @@ public class UserConsentModelTest extends AbstractModelTest {
maryFooGrant.addGrantedProtocolMapper(fooMapper);
realmManager.getSession().users().addConsent(realm, mary.getId(), maryFooGrant);
+ ClientStorageProviderModel clientStorage = new ClientStorageProviderModel();
+ clientStorage.setProviderId(HardcodedClientStorageProviderFactory.PROVIDER_ID);
+ clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.CLIENT_ID, "hardcoded-client");
+ clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.REDIRECT_URI, "http://localhost:8081/*");
+ clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.CONSENT, "true");
+ clientStorage.setParentId(realm.getId());
+ clientStorageComponent = realm.addComponentModel(clientStorage);
+
+ ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
+
+ Assert.assertNotNull(hardcodedClient);
+
+ UserConsentModel maryHardcodedGrant = new UserConsentModel(hardcodedClient);
+ realmManager.getSession().users().addConsent(realm, mary.getId(), maryHardcodedGrant);
+
+
commit();
}
@@ -125,7 +146,15 @@ public class UserConsentModelTest extends AbstractModelTest {
Assert.assertNotNull("Created Date should be set", maryConsent.getCreatedDate());
Assert.assertNotNull("Last Updated Date should be set", maryConsent.getLastUpdatedDate());
+ ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
+ UserConsentModel maryHardcodedConsent = realmManager.getSession().users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId());
+ Assert.assertEquals(maryHardcodedConsent.getGrantedRoles().size(), 0);
+ Assert.assertEquals(maryHardcodedConsent.getGrantedProtocolMappers().size(), 0);
+ Assert.assertNotNull("Created Date should be set", maryHardcodedConsent.getCreatedDate());
+ Assert.assertNotNull("Last Updated Date should be set", maryHardcodedConsent.getLastUpdatedDate());
+
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, mary.getId(), barClient.getId()));
+ Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), hardcodedClient.getId()));
}
@Test
@@ -139,14 +168,26 @@ public class UserConsentModelTest extends AbstractModelTest {
List<UserConsentModel> johnConsents = realmManager.getSession().users().getConsents(realm, john.getId());
Assert.assertEquals(2, johnConsents.size());
+ ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
+
List<UserConsentModel> maryConsents = realmManager.getSession().users().getConsents(realm, mary.getId());
- Assert.assertEquals(1, maryConsents.size());
+ Assert.assertEquals(2, maryConsents.size());
UserConsentModel maryConsent = maryConsents.get(0);
+ UserConsentModel maryHardcodedConsent = maryConsents.get(1);
+ if (maryConsents.get(0).getClient().getId().equals(hardcodedClient.getId())) {
+ maryConsent = maryConsents.get(1);
+ maryHardcodedConsent = 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));
+
+ Assert.assertEquals(maryHardcodedConsent.getClient().getId(), hardcodedClient.getId());
+ Assert.assertEquals(maryHardcodedConsent.getGrantedRoles().size(), 0);
+ Assert.assertEquals(maryHardcodedConsent.getGrantedProtocolMappers().size(), 0);
}
@Test
@@ -190,14 +231,19 @@ public class UserConsentModelTest extends AbstractModelTest {
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);
realmManager.getSession().users().revokeConsentForClient(realm, john.getId(), fooClient.getId());
+ ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
+ realmManager.getSession().users().revokeConsentForClient(realm, mary.getId(), hardcodedClient.getId());
commit();
realm = realmManager.getRealm("original");
john = session.users().getUserByUsername("john", realm);
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId()));
+ mary = session.users().getUserByUsername("mary", realm);
+ Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId()));
}
@Test
@@ -206,6 +252,8 @@ public class UserConsentModelTest extends AbstractModelTest {
RealmModel realm = realmManager.getRealm("original");
UserModel john = session.users().getUserByUsername("john", realm);
session.users().removeUser(realm, john);
+ UserModel mary = session.users().getUserByUsername("mary", realm);
+ session.users().removeUser(realm, mary);
}
@Test
@@ -270,6 +318,24 @@ public class UserConsentModelTest extends AbstractModelTest {
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), barClient.getId()));
}
+ @Test
+ public void deleteClientStorageTest() {
+ RealmModel realm = realmManager.getRealm("original");
+ realm.removeComponent(clientStorageComponent);
+ commit();
+
+
+
+ realm = realmManager.getRealm("original");
+ ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
+ Assert.assertNull(hardcodedClient);
+
+ UserModel mary = session.users().getUserByUsername("mary", realm);
+
+ List<UserConsentModel> maryConsents = realmManager.getSession().users().getConsents(realm, mary.getId());
+ Assert.assertEquals(1, maryConsents.size());
+ }
+
private boolean isRoleGranted(RoleContainerModel roleContainer, String roleName, UserConsentModel consentModel) {
RoleModel role = roleContainer.getRole(roleName);
return consentModel.isRoleGranted(role);
diff --git a/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/UserConsentWithUserStorageModelTest.java b/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/UserConsentWithUserStorageModelTest.java
index 6fd18bf..04b5cde 100644
--- a/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/UserConsentWithUserStorageModelTest.java
+++ b/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/UserConsentWithUserStorageModelTest.java
@@ -20,6 +20,7 @@ package org.keycloak.testsuite.model;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.keycloak.component.ComponentModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.ModelException;
import org.keycloak.models.ProtocolMapperModel;
@@ -31,6 +32,8 @@ 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.storage.client.ClientStorageProviderModel;
+import org.keycloak.testsuite.federation.HardcodedClientStorageProviderFactory;
import org.keycloak.testsuite.federation.storage.UserMapStorageFactory;
import org.keycloak.testsuite.federation.storage.UserPropertyFileStorageFactory;
@@ -41,6 +44,8 @@ import java.util.List;
*/
public class UserConsentWithUserStorageModelTest extends AbstractModelTest {
+ private ComponentModel clientStorageComponent;
+
@Before
public void setupEnv() {
RealmModel realm = realmManager.createRealm("original");
@@ -97,6 +102,22 @@ public class UserConsentWithUserStorageModelTest extends AbstractModelTest {
maryFooGrant.addGrantedProtocolMapper(fooMapper);
realmManager.getSession().users().addConsent(realm, mary.getId(), maryFooGrant);
+ ClientStorageProviderModel clientStorage = new ClientStorageProviderModel();
+ clientStorage.setProviderId(HardcodedClientStorageProviderFactory.PROVIDER_ID);
+ clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.CLIENT_ID, "hardcoded-client");
+ clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.REDIRECT_URI, "http://localhost:8081/*");
+ clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.CONSENT, "true");
+ clientStorage.setParentId(realm.getId());
+ clientStorageComponent = realm.addComponentModel(clientStorage);
+
+ ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
+
+ Assert.assertNotNull(hardcodedClient);
+
+ UserConsentModel maryHardcodedGrant = new UserConsentModel(hardcodedClient);
+ realmManager.getSession().users().addConsent(realm, mary.getId(), maryHardcodedGrant);
+
+
commit();
}
@@ -135,7 +156,15 @@ public class UserConsentWithUserStorageModelTest extends AbstractModelTest {
Assert.assertNotNull("Created Date should be set", maryConsent.getCreatedDate());
Assert.assertNotNull("Last Updated Date should be set", maryConsent.getLastUpdatedDate());
+ ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
+ UserConsentModel maryHardcodedConsent = realmManager.getSession().users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId());
+ Assert.assertEquals(maryHardcodedConsent.getGrantedRoles().size(), 0);
+ Assert.assertEquals(maryHardcodedConsent.getGrantedProtocolMappers().size(), 0);
+ Assert.assertNotNull("Created Date should be set", maryHardcodedConsent.getCreatedDate());
+ Assert.assertNotNull("Last Updated Date should be set", maryHardcodedConsent.getLastUpdatedDate());
+
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, mary.getId(), barClient.getId()));
+ Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), hardcodedClient.getId()));
}
@Test
@@ -149,14 +178,26 @@ public class UserConsentWithUserStorageModelTest extends AbstractModelTest {
List<UserConsentModel> johnConsents = realmManager.getSession().users().getConsents(realm, john.getId());
Assert.assertEquals(2, johnConsents.size());
+ ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
+
List<UserConsentModel> maryConsents = realmManager.getSession().users().getConsents(realm, mary.getId());
- Assert.assertEquals(1, maryConsents.size());
+ Assert.assertEquals(2, maryConsents.size());
UserConsentModel maryConsent = maryConsents.get(0);
+ UserConsentModel maryHardcodedConsent = maryConsents.get(1);
+ if (maryConsents.get(0).getClient().getId().equals(hardcodedClient.getId())) {
+ maryConsent = maryConsents.get(1);
+ maryHardcodedConsent = 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));
+
+ Assert.assertEquals(maryHardcodedConsent.getClient().getId(), hardcodedClient.getId());
+ Assert.assertEquals(maryHardcodedConsent.getGrantedRoles().size(), 0);
+ Assert.assertEquals(maryHardcodedConsent.getGrantedProtocolMappers().size(), 0);
}
@Test
@@ -200,14 +241,19 @@ public class UserConsentWithUserStorageModelTest extends AbstractModelTest {
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);
realmManager.getSession().users().revokeConsentForClient(realm, john.getId(), fooClient.getId());
+ ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
+ realmManager.getSession().users().revokeConsentForClient(realm, mary.getId(), hardcodedClient.getId());
commit();
realm = realmManager.getRealm("original");
john = session.users().getUserByUsername("john", realm);
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId()));
+ mary = session.users().getUserByUsername("mary", realm);
+ Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId()));
}
@Test
@@ -216,6 +262,8 @@ public class UserConsentWithUserStorageModelTest extends AbstractModelTest {
RealmModel realm = realmManager.getRealm("original");
UserModel john = session.users().getUserByUsername("john", realm);
session.users().removeUser(realm, john);
+ UserModel mary = session.users().getUserByUsername("mary", realm);
+ session.users().removeUser(realm, mary);
}
@Test
@@ -280,6 +328,24 @@ public class UserConsentWithUserStorageModelTest extends AbstractModelTest {
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), barClient.getId()));
}
+ @Test
+ public void deleteClientStorageTest() {
+ RealmModel realm = realmManager.getRealm("original");
+ realm.removeComponent(clientStorageComponent);
+ commit();
+
+
+
+ realm = realmManager.getRealm("original");
+ ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
+ Assert.assertNull(hardcodedClient);
+
+ UserModel mary = session.users().getUserByUsername("mary", realm);
+
+ List<UserConsentModel> maryConsents = realmManager.getSession().users().getConsents(realm, mary.getId());
+ Assert.assertEquals(1, maryConsents.size());
+ }
+
private boolean isRoleGranted(RoleContainerModel roleContainer, String roleName, UserConsentModel consentModel) {
RoleModel role = roleContainer.getRole(roleName);
return consentModel.isRoleGranted(role);