parent
6963364514
commit
0ceaed0e2e
13 changed files with 490 additions and 86 deletions
|
@ -0,0 +1,169 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.keycloak.models.light;
|
||||||
|
|
||||||
|
import org.keycloak.common.util.Time;
|
||||||
|
import org.keycloak.models.ClientModel;
|
||||||
|
import org.keycloak.models.ClientScopeModel;
|
||||||
|
import org.keycloak.models.ModelException;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserConsentModel;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author hmlnarik
|
||||||
|
*/
|
||||||
|
class LightweightConsentEntity {
|
||||||
|
|
||||||
|
private String clientId;
|
||||||
|
private Long createdDate;
|
||||||
|
private Set<String> grantedClientScopesIds;
|
||||||
|
private Long lastUpdatedDate;
|
||||||
|
|
||||||
|
public static LightweightConsentEntity fromModel(UserConsentModel model) {
|
||||||
|
long currentTime = Time.currentTimeMillis();
|
||||||
|
|
||||||
|
LightweightConsentEntity consentEntity = new LightweightConsentEntity();
|
||||||
|
consentEntity.setClientId(model.getClient().getId());
|
||||||
|
consentEntity.setCreatedDate(currentTime);
|
||||||
|
consentEntity.setLastUpdatedDate(currentTime);
|
||||||
|
|
||||||
|
model.getGrantedClientScopes()
|
||||||
|
.stream()
|
||||||
|
.map(ClientScopeModel::getId)
|
||||||
|
.forEach(consentEntity::addGrantedClientScopesId);
|
||||||
|
|
||||||
|
return consentEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UserConsentModel toModel(RealmModel realm, LightweightConsentEntity entity) {
|
||||||
|
if (entity == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientModel client = realm.getClientById(entity.getClientId());
|
||||||
|
if (client == null) {
|
||||||
|
throw new ModelException("Client with id " + entity.getClientId() + " is not available");
|
||||||
|
}
|
||||||
|
UserConsentModel model = new UserConsentModel(client);
|
||||||
|
model.setCreatedDate(entity.getCreatedDate());
|
||||||
|
model.setLastUpdatedDate(entity.getLastUpdatedDate());
|
||||||
|
|
||||||
|
Set<String> grantedClientScopesIds = entity.getGrantedClientScopesIds();
|
||||||
|
|
||||||
|
if (grantedClientScopesIds != null && !grantedClientScopesIds.isEmpty()) {
|
||||||
|
grantedClientScopesIds.stream()
|
||||||
|
.map(scopeId -> KeycloakModelUtils.findClientScopeById(realm, client, scopeId))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.forEach(model::addGrantedClientScope);
|
||||||
|
}
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(clientId, grantedClientScopesIds, lastUpdatedDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final LightweightConsentEntity other = (LightweightConsentEntity) obj;
|
||||||
|
return Objects.equals(this.clientId, other.clientId)
|
||||||
|
&& Objects.equals(this.lastUpdatedDate, other.lastUpdatedDate)
|
||||||
|
&& Objects.equals(this.grantedClientScopesIds, other.grantedClientScopesIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("%s@%08x", "LightweightConsentEntity", System.identityHashCode(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientId() {
|
||||||
|
return clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientId(String clientId) {
|
||||||
|
this.clientId = clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getCreatedDate() {
|
||||||
|
return createdDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreatedDate(Long createdDate) {
|
||||||
|
this.createdDate = createdDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getGrantedClientScopesIds() {
|
||||||
|
return grantedClientScopesIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeGrantedClientScopesId(String clientScopeId) {
|
||||||
|
if (grantedClientScopesIds == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (grantedClientScopesIds.remove(clientScopeId)) {
|
||||||
|
this.lastUpdatedDate = Time.currentTimeMillis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGrantedClientScopesIds(Set<String> clientScopeIds) {
|
||||||
|
clientScopeIds = clientScopeIds == null ? null : new HashSet<>(clientScopeIds);
|
||||||
|
if (clientScopeIds != null) {
|
||||||
|
clientScopeIds.removeIf(Objects::isNull);
|
||||||
|
if (clientScopeIds.isEmpty()) {
|
||||||
|
clientScopeIds = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grantedClientScopesIds = clientScopeIds;
|
||||||
|
this.lastUpdatedDate = Time.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addGrantedClientScopesId(String clientScopeId) {
|
||||||
|
if (clientScopeId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (grantedClientScopesIds == null) {
|
||||||
|
grantedClientScopesIds = new HashSet<>();
|
||||||
|
}
|
||||||
|
grantedClientScopesIds.add(clientScopeId);
|
||||||
|
this.lastUpdatedDate = Time.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getLastUpdatedDate() {
|
||||||
|
return lastUpdatedDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastUpdatedDate(Long lastUpdatedDate) {
|
||||||
|
this.lastUpdatedDate = lastUpdatedDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -19,11 +19,14 @@ package org.keycloak.models.light;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
import org.keycloak.common.Profile.Feature;
|
import org.keycloak.common.Profile.Feature;
|
||||||
import org.keycloak.common.util.Base64;
|
import org.keycloak.common.util.Base64;
|
||||||
|
import org.keycloak.models.ClientScopeModel;
|
||||||
import org.keycloak.models.GroupModel;
|
import org.keycloak.models.GroupModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.ModelException;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.SubjectCredentialManager;
|
import org.keycloak.models.SubjectCredentialManager;
|
||||||
|
import org.keycloak.models.UserConsentModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserModel.RequiredAction;
|
import org.keycloak.models.UserModel.RequiredAction;
|
||||||
import org.keycloak.storage.adapter.AbstractInMemoryUserAdapter;
|
import org.keycloak.storage.adapter.AbstractInMemoryUserAdapter;
|
||||||
|
@ -33,10 +36,13 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
|
||||||
import com.fasterxml.jackson.annotation.JsonIncludeProperties;
|
import com.fasterxml.jackson.annotation.JsonIncludeProperties;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Level;
|
import java.util.stream.Collectors;
|
||||||
import java.util.logging.Logger;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -52,6 +58,7 @@ import java.util.logging.Logger;
|
||||||
"attributes",
|
"attributes",
|
||||||
"requiredActions",
|
"requiredActions",
|
||||||
"federationLink",
|
"federationLink",
|
||||||
|
"consents",
|
||||||
"serviceAccountClientLink",
|
"serviceAccountClientLink",
|
||||||
"readonly"
|
"readonly"
|
||||||
})
|
})
|
||||||
|
@ -62,6 +69,8 @@ public class LightweightUserAdapter extends AbstractInMemoryUserAdapter {
|
||||||
|
|
||||||
public static final String ID_PREFIX = "lightweight-";
|
public static final String ID_PREFIX = "lightweight-";
|
||||||
|
|
||||||
|
private final Set<LightweightConsentEntity> consents = new HashSet<>();
|
||||||
|
|
||||||
public static boolean isLightweightUser(UserModel user) {
|
public static boolean isLightweightUser(UserModel user) {
|
||||||
return Profile.isFeatureEnabled(Feature.TRANSIENT_USERS) && user instanceof LightweightUserAdapter;
|
return Profile.isFeatureEnabled(Feature.TRANSIENT_USERS) && user instanceof LightweightUserAdapter;
|
||||||
}
|
}
|
||||||
|
@ -116,115 +125,115 @@ public class LightweightUserAdapter extends AbstractInMemoryUserAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteRoleMapping(RoleModel role) {
|
public void deleteRoleMapping(RoleModel role) {
|
||||||
super.deleteRoleMapping(role); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.deleteRoleMapping(role);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void grantRole(RoleModel role) {
|
public void grantRole(RoleModel role) {
|
||||||
super.grantRole(role); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.grantRole(role);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setServiceAccountClientLink(String clientInternalId) {
|
public void setServiceAccountClientLink(String clientInternalId) {
|
||||||
super.setServiceAccountClientLink(clientInternalId); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.setServiceAccountClientLink(clientInternalId);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFederationLink(String link) {
|
public void setFederationLink(String link) {
|
||||||
super.setFederationLink(link); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.setFederationLink(link);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void leaveGroup(GroupModel group) {
|
public void leaveGroup(GroupModel group) {
|
||||||
super.leaveGroup(group); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.leaveGroup(group);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void joinGroup(GroupModel group) {
|
public void joinGroup(GroupModel group) {
|
||||||
super.joinGroup(group); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.joinGroup(group);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEmailVerified(boolean verified) {
|
public void setEmailVerified(boolean verified) {
|
||||||
super.setEmailVerified(verified); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.setEmailVerified(verified);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeRequiredAction(RequiredAction action) {
|
public void removeRequiredAction(RequiredAction action) {
|
||||||
super.removeRequiredAction(action); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.removeRequiredAction(action);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addRequiredAction(RequiredAction action) {
|
public void addRequiredAction(RequiredAction action) {
|
||||||
super.addRequiredAction(action); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.addRequiredAction(action);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeRequiredAction(String action) {
|
public void removeRequiredAction(String action) {
|
||||||
super.removeRequiredAction(action); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.removeRequiredAction(action);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addRequiredAction(String action) {
|
public void addRequiredAction(String action) {
|
||||||
super.addRequiredAction(action); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.addRequiredAction(action);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeAttribute(String name) {
|
public void removeAttribute(String name) {
|
||||||
super.removeAttribute(name); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.removeAttribute(name);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAttribute(String name, List<String> values) {
|
public void setAttribute(String name, List<String> values) {
|
||||||
super.setAttribute(name, values); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.setAttribute(name, values);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSingleAttribute(String name, String value) {
|
public void setSingleAttribute(String name, String value) {
|
||||||
super.setSingleAttribute(name, value); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.setSingleAttribute(name, value);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEnabled(boolean enabled) {
|
public void setEnabled(boolean enabled) {
|
||||||
super.setEnabled(enabled); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.setEnabled(enabled);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCreatedTimestamp(Long timestamp) {
|
public void setCreatedTimestamp(Long timestamp) {
|
||||||
super.setCreatedTimestamp(timestamp); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.setCreatedTimestamp(timestamp);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setReadonly(boolean flag) {
|
public void setReadonly(boolean flag) {
|
||||||
super.setReadonly(flag); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.setReadonly(flag);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addDefaults() {
|
public void addDefaults() {
|
||||||
super.addDefaults(); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.addDefaults();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUsername(String username) {
|
public void setUsername(String username) {
|
||||||
super.setUsername(username); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/OverriddenMethodBody
|
super.setUsername(username);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,4 +245,56 @@ public class LightweightUserAdapter extends AbstractInMemoryUserAdapter {
|
||||||
updateHandler.accept(this);
|
updateHandler.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addConsent(UserConsentModel consent) {
|
||||||
|
if (consent != null) {
|
||||||
|
consents.add(LightweightConsentEntity.fromModel(consent));
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserConsentModel getConsentByClient(String clientInternalId) {
|
||||||
|
return LightweightConsentEntity.toModel(realm, getConsentEntityByClient(clientInternalId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean revokeConsentForClient(String clientInternalId) {
|
||||||
|
if (clientInternalId != null) {
|
||||||
|
final boolean res = consents.removeIf(lce -> clientInternalId.equals(lce.getClientId()));
|
||||||
|
if (res) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateConsent(UserConsentModel consent) {
|
||||||
|
if (consent == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String clientId = consent.getClient() == null
|
||||||
|
? null
|
||||||
|
: consent.getClient().getId();
|
||||||
|
LightweightConsentEntity userConsentEntity = getConsentEntityByClient(clientId);
|
||||||
|
|
||||||
|
userConsentEntity.setGrantedClientScopesIds(
|
||||||
|
consent.getGrantedClientScopes().stream()
|
||||||
|
.map(ClientScopeModel::getId)
|
||||||
|
.collect(Collectors.toSet())
|
||||||
|
);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
LightweightConsentEntity getConsentEntityByClient(String clientId) {
|
||||||
|
return consents.stream().filter(lce -> Objects.equals(clientId, lce.getClientId()))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream<UserConsentModel> getConsentsStream() {
|
||||||
|
return consents.stream()
|
||||||
|
.map(lce -> LightweightConsentEntity.toModel(realm, lce));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,7 @@ import org.keycloak.services.ErrorResponseException;
|
||||||
import org.keycloak.services.Urls;
|
import org.keycloak.services.Urls;
|
||||||
import org.keycloak.services.managers.AuthenticationManager;
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.managers.AuthenticationSessionManager;
|
import org.keycloak.services.managers.AuthenticationSessionManager;
|
||||||
|
import org.keycloak.services.managers.UserConsentManager;
|
||||||
import org.keycloak.services.managers.UserSessionCrossDCManager;
|
import org.keycloak.services.managers.UserSessionCrossDCManager;
|
||||||
import org.keycloak.services.managers.UserSessionManager;
|
import org.keycloak.services.managers.UserSessionManager;
|
||||||
import org.keycloak.services.resources.IdentityBrokerService;
|
import org.keycloak.services.resources.IdentityBrokerService;
|
||||||
|
@ -744,7 +745,7 @@ public class TokenManager {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
UserConsentModel grantedConsent = session.users().getConsentByClient(client.getRealm(), user.getId(), client.getId());
|
UserConsentModel grantedConsent = UserConsentManager.getConsentByClient(session, client.getRealm(), user, client.getId());
|
||||||
|
|
||||||
return requestedClientScopes
|
return requestedClientScopes
|
||||||
.filter(ClientScopeModel::isDisplayOnConsentScreen)
|
.filter(ClientScopeModel::isDisplayOnConsentScreen)
|
||||||
|
|
|
@ -51,6 +51,7 @@ import org.keycloak.services.CorsErrorResponseException;
|
||||||
import org.keycloak.services.clientpolicy.ClientPolicyException;
|
import org.keycloak.services.clientpolicy.ClientPolicyException;
|
||||||
import org.keycloak.services.clientpolicy.context.TokenRevokeContext;
|
import org.keycloak.services.clientpolicy.context.TokenRevokeContext;
|
||||||
import org.keycloak.services.clientpolicy.context.TokenRevokeResponseContext;
|
import org.keycloak.services.clientpolicy.context.TokenRevokeResponseContext;
|
||||||
|
import org.keycloak.services.managers.UserConsentManager;
|
||||||
import org.keycloak.services.managers.UserSessionCrossDCManager;
|
import org.keycloak.services.managers.UserSessionCrossDCManager;
|
||||||
import org.keycloak.services.managers.UserSessionManager;
|
import org.keycloak.services.managers.UserSessionManager;
|
||||||
import org.keycloak.services.resources.Cors;
|
import org.keycloak.services.resources.Cors;
|
||||||
|
@ -241,7 +242,7 @@ public class TokenRevocationEndpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void revokeClient() {
|
private void revokeClient() {
|
||||||
session.users().revokeConsentForClient(realm, user.getId(), client.getId());
|
UserConsentManager.revokeConsentForClient(session, realm, user, client.getId());
|
||||||
if (TokenUtil.TOKEN_TYPE_OFFLINE.equals(token.getType())) {
|
if (TokenUtil.TOKEN_TYPE_OFFLINE.equals(token.getType())) {
|
||||||
new UserSessionManager(session).revokeOfflineToken(user, client);
|
new UserSessionManager(session).revokeOfflineToken(user, client);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ import org.keycloak.services.ErrorResponseException;
|
||||||
import org.keycloak.services.Urls;
|
import org.keycloak.services.Urls;
|
||||||
import org.keycloak.services.clientpolicy.ClientPolicyException;
|
import org.keycloak.services.clientpolicy.ClientPolicyException;
|
||||||
import org.keycloak.services.managers.AuthenticationManager;
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
|
import org.keycloak.services.managers.UserConsentManager;
|
||||||
import org.keycloak.services.resources.Cors;
|
import org.keycloak.services.resources.Cors;
|
||||||
import org.keycloak.services.util.DefaultClientSessionContext;
|
import org.keycloak.services.util.DefaultClientSessionContext;
|
||||||
import org.keycloak.sessions.AuthenticationSessionModel;
|
import org.keycloak.sessions.AuthenticationSessionModel;
|
||||||
|
@ -268,10 +269,10 @@ public class CibaGrantType {
|
||||||
}
|
}
|
||||||
|
|
||||||
// authorization (consent)
|
// authorization (consent)
|
||||||
UserConsentModel grantedConsent = session.users().getConsentByClient(realm, user.getId(), client.getId());
|
UserConsentModel grantedConsent = UserConsentManager.getConsentByClient(session, realm, user, client.getId());
|
||||||
if (grantedConsent == null) {
|
if (grantedConsent == null) {
|
||||||
grantedConsent = new UserConsentModel(client);
|
grantedConsent = new UserConsentModel(client);
|
||||||
session.users().addConsent(realm, user.getId(), grantedConsent);
|
UserConsentManager.addConsent(session, realm, user, grantedConsent);
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
grantedConsent.getGrantedClientScopes().forEach(i->logger.tracef("CIBA Grant :: Consent granted. %s", i.getName()));
|
grantedConsent.getGrantedClientScopes().forEach(i->logger.tracef("CIBA Grant :: Consent granted. %s", i.getName()));
|
||||||
}
|
}
|
||||||
|
@ -288,7 +289,7 @@ public class CibaGrantType {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateConsentRequired) {
|
if (updateConsentRequired) {
|
||||||
session.users().updateConsent(realm, user.getId(), grantedConsent);
|
UserConsentManager.updateConsent(session, realm, user, grantedConsent);
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
grantedConsent.getGrantedClientScopes().forEach(i->logger.tracef("CIBA Grant :: Consent updated. %s", i.getName()));
|
grantedConsent.getGrantedClientScopes().forEach(i->logger.tracef("CIBA Grant :: Consent updated. %s", i.getName()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1150,7 +1150,7 @@ public class AuthenticationManager {
|
||||||
final UserModel user = authSession.getAuthenticatedUser();
|
final UserModel user = authSession.getAuthenticatedUser();
|
||||||
final ClientModel client = authSession.getClient();
|
final ClientModel client = authSession.getClient();
|
||||||
|
|
||||||
return session.users().getConsentByClient(realm, user.getId(), client.getId());
|
return UserConsentManager.getConsentByClient(session, realm, user, client.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,13 @@ package org.keycloak.services.managers;
|
||||||
|
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.ModelException;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserConsentModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.models.light.LightweightUserAdapter;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import static org.keycloak.models.light.LightweightUserAdapter.isLightweightUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
@ -38,7 +43,7 @@ public class UserConsentManager {
|
||||||
*/
|
*/
|
||||||
public static boolean revokeConsentToClient(KeycloakSession session, ClientModel client, UserModel user) {
|
public static boolean revokeConsentToClient(KeycloakSession session, ClientModel client, UserModel user) {
|
||||||
RealmModel realm = session.getContext().getRealm();
|
RealmModel realm = session.getContext().getRealm();
|
||||||
boolean revokedConsent = session.users().revokeConsentForClient(realm, user.getId(), client.getId());
|
boolean revokedConsent = revokeConsentForClient(session, realm, user, client.getId());
|
||||||
boolean revokedOfflineToken = new UserSessionManager(session).revokeOfflineToken(user, client);
|
boolean revokedOfflineToken = new UserSessionManager(session).revokeOfflineToken(user, client);
|
||||||
|
|
||||||
if (revokedConsent) {
|
if (revokedConsent) {
|
||||||
|
@ -48,4 +53,95 @@ public class UserConsentManager {
|
||||||
|
|
||||||
return revokedConsent || revokedOfflineToken;
|
return revokedConsent || revokedOfflineToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add user consent for the user.
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param user user. Must not be {@code null}
|
||||||
|
* @param consent all details corresponding to the granted consent
|
||||||
|
*
|
||||||
|
* @throws ModelException If there is no user with userId
|
||||||
|
*/
|
||||||
|
public static void addConsent(KeycloakSession session, RealmModel realm, UserModel user, UserConsentModel consent) {
|
||||||
|
if (isLightweightUser(user)) {
|
||||||
|
LightweightUserAdapter lua = (LightweightUserAdapter) user;
|
||||||
|
lua.addConsent(consent);
|
||||||
|
} else {
|
||||||
|
session.users().addConsent(realm, user.getId(), consent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns UserConsentModel given by a user for the client with clientInternalId
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param user user. Must not be {@code null}
|
||||||
|
* @param clientInternalId id of the client
|
||||||
|
* @return consent given by the user to the client or {@code null} if no consent or user exists
|
||||||
|
*
|
||||||
|
* @throws ModelException when there are more consents fulfilling specified parameters
|
||||||
|
*/
|
||||||
|
public static UserConsentModel getConsentByClient(KeycloakSession session, RealmModel realm, UserModel user, String clientInternalId) {
|
||||||
|
if (isLightweightUser(user)) {
|
||||||
|
LightweightUserAdapter lua = (LightweightUserAdapter) user;
|
||||||
|
return lua.getConsentByClient(clientInternalId);
|
||||||
|
} else {
|
||||||
|
return session.users().getConsentByClient(realm, user.getId(), clientInternalId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains the consents associated with the user
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm.
|
||||||
|
* @param user user. Must not be {@code null}
|
||||||
|
* @return a non-null {@link Stream} of consents associated with the user.
|
||||||
|
*/
|
||||||
|
public static Stream<UserConsentModel> getConsentsStream(KeycloakSession session, RealmModel realm, UserModel user) {
|
||||||
|
if (isLightweightUser(user)) {
|
||||||
|
LightweightUserAdapter lua = (LightweightUserAdapter) user;
|
||||||
|
return lua.getConsentsStream();
|
||||||
|
} else {
|
||||||
|
return session.users().getConsentsStream(realm, user.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update client scopes in the stored user consent
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param user user. Must not be {@code null}
|
||||||
|
* @param consent new details of the user consent
|
||||||
|
*
|
||||||
|
* @throws ModelException when consent doesn't exist for the userId
|
||||||
|
*/
|
||||||
|
public static void updateConsent(KeycloakSession session, RealmModel realm, UserModel user, UserConsentModel consent) {
|
||||||
|
if (isLightweightUser(user)) {
|
||||||
|
LightweightUserAdapter lua = (LightweightUserAdapter) user;
|
||||||
|
lua.updateConsent(consent);
|
||||||
|
} else {
|
||||||
|
session.users().updateConsent(realm, user.getId(), consent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a user consent given by the user and client id
|
||||||
|
*
|
||||||
|
* @param realm a reference to the realm
|
||||||
|
* @param user user. Must not be {@code null}
|
||||||
|
* @param clientInternalId id of the client
|
||||||
|
* @return {@code true} if the consent was removed, {@code false} otherwise
|
||||||
|
*
|
||||||
|
* TODO: Make this method return Boolean so that store can return "I don't know" answer, this can be used for example in async stores
|
||||||
|
*/
|
||||||
|
public static boolean revokeConsentForClient(KeycloakSession session, RealmModel realm, UserModel user, String clientInternalId) {
|
||||||
|
if (isLightweightUser(user)) {
|
||||||
|
LightweightUserAdapter lua = (LightweightUserAdapter) user;
|
||||||
|
return lua.revokeConsentForClient(clientInternalId);
|
||||||
|
} else {
|
||||||
|
return session.users().revokeConsentForClient(realm, user.getId(), clientInternalId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,7 @@ import org.keycloak.services.Urls;
|
||||||
import org.keycloak.services.managers.AuthenticationManager;
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.managers.AuthenticationSessionManager;
|
import org.keycloak.services.managers.AuthenticationSessionManager;
|
||||||
import org.keycloak.services.managers.ClientSessionCode;
|
import org.keycloak.services.managers.ClientSessionCode;
|
||||||
|
import org.keycloak.services.managers.UserConsentManager;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.util.AuthenticationFlowURLHelper;
|
import org.keycloak.services.util.AuthenticationFlowURLHelper;
|
||||||
import org.keycloak.services.util.BrowserHistoryHelper;
|
import org.keycloak.services.util.BrowserHistoryHelper;
|
||||||
|
@ -962,10 +963,10 @@ public class LoginActionsService {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
UserConsentModel grantedConsent = session.users().getConsentByClient(realm, user.getId(), client.getId());
|
UserConsentModel grantedConsent = UserConsentManager.getConsentByClient(session, realm, user, client.getId());
|
||||||
if (grantedConsent == null) {
|
if (grantedConsent == null) {
|
||||||
grantedConsent = new UserConsentModel(client);
|
grantedConsent = new UserConsentModel(client);
|
||||||
session.users().addConsent(realm, user.getId(), grantedConsent);
|
UserConsentManager.addConsent(session, realm, user, grantedConsent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update may not be required if all clientScopes were already granted (May happen for example with prompt=consent)
|
// Update may not be required if all clientScopes were already granted (May happen for example with prompt=consent)
|
||||||
|
@ -984,7 +985,7 @@ public class LoginActionsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateConsentRequired) {
|
if (updateConsentRequired) {
|
||||||
session.users().updateConsent(realm, user.getId(), grantedConsent);
|
UserConsentManager.updateConsent(session, realm, user, grantedConsent);
|
||||||
}
|
}
|
||||||
|
|
||||||
event.detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED);
|
event.detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED);
|
||||||
|
|
|
@ -314,7 +314,7 @@ public class AccountRestService {
|
||||||
throw ErrorResponse.error("No client with clientId: " + clientId + " found.", Response.Status.NOT_FOUND);
|
throw ErrorResponse.error("No client with clientId: " + clientId + " found.", Response.Status.NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserConsentModel consent = session.users().getConsentByClient(realm, user.getId(), client.getId());
|
UserConsentModel consent = UserConsentManager.getConsentByClient(session, realm, user, client.getId());
|
||||||
if (consent == null) {
|
if (consent == null) {
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
}
|
}
|
||||||
|
@ -403,17 +403,17 @@ public class AccountRestService {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
UserConsentModel grantedConsent = createConsent(client, consent);
|
UserConsentModel grantedConsent = createConsent(client, consent);
|
||||||
if (session.users().getConsentByClient(realm, user.getId(), client.getId()) == null) {
|
if (UserConsentManager.getConsentByClient(session, realm, user, client.getId()) == null) {
|
||||||
session.users().addConsent(realm, user.getId(), grantedConsent);
|
UserConsentManager.addConsent(session, realm, user, grantedConsent);
|
||||||
event.event(EventType.GRANT_CONSENT);
|
event.event(EventType.GRANT_CONSENT);
|
||||||
} else {
|
} else {
|
||||||
session.users().updateConsent(realm, user.getId(), grantedConsent);
|
UserConsentManager.updateConsent(session, realm, user, grantedConsent);
|
||||||
event.event(EventType.UPDATE_CONSENT);
|
event.event(EventType.UPDATE_CONSENT);
|
||||||
}
|
}
|
||||||
event.detail(Details.GRANTED_CLIENT,client.getClientId());
|
event.detail(Details.GRANTED_CLIENT,client.getClientId());
|
||||||
String scopeString = grantedConsent.getGrantedClientScopes().stream().map(cs->cs.getName()).collect(Collectors.joining(" "));
|
String scopeString = grantedConsent.getGrantedClientScopes().stream().map(cs->cs.getName()).collect(Collectors.joining(" "));
|
||||||
event.detail(Details.SCOPE, scopeString).success();
|
event.detail(Details.SCOPE, scopeString).success();
|
||||||
grantedConsent = session.users().getConsentByClient(realm, user.getId(), client.getId());
|
grantedConsent = UserConsentManager.getConsentByClient(session, realm, user, client.getId());
|
||||||
return Response.ok(modelToRepresentation(grantedConsent)).build();
|
return Response.ok(modelToRepresentation(grantedConsent)).build();
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw ErrorResponse.error(e.getMessage(), Response.Status.BAD_REQUEST);
|
throw ErrorResponse.error(e.getMessage(), Response.Status.BAD_REQUEST);
|
||||||
|
@ -490,7 +490,7 @@ public class AccountRestService {
|
||||||
.collect(Collectors.toSet()));
|
.collect(Collectors.toSet()));
|
||||||
|
|
||||||
Map<String, UserConsentModel> consentModels = new HashMap<>();
|
Map<String, UserConsentModel> consentModels = new HashMap<>();
|
||||||
clients.addAll(session.users().getConsentsStream(realm, user.getId())
|
clients.addAll(UserConsentManager.getConsentsStream(session, realm, user)
|
||||||
.peek(consent -> consentModels.put(consent.getClient().getClientId(), consent))
|
.peek(consent -> consentModels.put(consent.getClient().getClientId(), consent))
|
||||||
.map(UserConsentModel::getClient)
|
.map(UserConsentModel::getClient)
|
||||||
.collect(Collectors.toSet()));
|
.collect(Collectors.toSet()));
|
||||||
|
|
|
@ -525,7 +525,7 @@ public class UserResource {
|
||||||
Set<ClientModel> offlineClients = new UserSessionManager(session).findClientsWithOfflineToken(realm, user);
|
Set<ClientModel> offlineClients = new UserSessionManager(session).findClientsWithOfflineToken(realm, user);
|
||||||
|
|
||||||
Set<ClientModel> clientsWithUserConsents = new HashSet<>();
|
Set<ClientModel> clientsWithUserConsents = new HashSet<>();
|
||||||
List<UserConsentModel> userConsents = session.users().getConsentsStream(realm, user.getId())
|
List<UserConsentModel> userConsents = UserConsentManager.getConsentsStream(session, realm, user)
|
||||||
// collect clients with explicit user consents for later filtering
|
// collect clients with explicit user consents for later filtering
|
||||||
.peek(ucm -> clientsWithUserConsents.add(ucm.getClient()))
|
.peek(ucm -> clientsWithUserConsents.add(ucm.getClient()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
|
@ -49,9 +49,11 @@ import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.representations.idm.RoleRepresentation;
|
import org.keycloak.representations.idm.RoleRepresentation;
|
||||||
import org.keycloak.representations.idm.UserRepresentation;
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
|
import org.keycloak.representations.idm.UserSessionRepresentation;
|
||||||
import org.keycloak.testsuite.Assert;
|
import org.keycloak.testsuite.Assert;
|
||||||
import org.keycloak.testsuite.AssertEvents;
|
import org.keycloak.testsuite.AssertEvents;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
|
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
|
||||||
|
import org.keycloak.testsuite.updaters.ClientAttributeUpdater;
|
||||||
import org.keycloak.testsuite.updaters.Creator;
|
import org.keycloak.testsuite.updaters.Creator;
|
||||||
import org.keycloak.testsuite.util.AccountHelper;
|
import org.keycloak.testsuite.util.AccountHelper;
|
||||||
import org.keycloak.testsuite.util.OAuthClient;
|
import org.keycloak.testsuite.util.OAuthClient;
|
||||||
|
@ -74,14 +76,18 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.aMapWithSize;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
import static org.hamcrest.Matchers.hasItems;
|
import static org.hamcrest.Matchers.hasItems;
|
||||||
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.keycloak.testsuite.broker.BrokerTestConstants.CLIENT_ID;
|
||||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_CONS_NAME;
|
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_CONS_NAME;
|
||||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_PROV_NAME;
|
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_PROV_NAME;
|
||||||
import static org.keycloak.testsuite.broker.BrokerTestTools.getConsumerRoot;
|
import static org.keycloak.testsuite.broker.BrokerTestTools.getConsumerRoot;
|
||||||
|
@ -468,6 +474,72 @@ public final class KcOidcBrokerTransientSessionsTest extends AbstractAdvancedBro
|
||||||
Assert.assertTrue("Should be logged in", driver.getTitle().endsWith("AUTH_RESPONSE"));
|
Assert.assertTrue("Should be logged in", driver.getTitle().endsWith("AUTH_RESPONSE"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Based on ConsentsTest.testConsents, modified to use consumer realm instead
|
||||||
|
@Test
|
||||||
|
public void testConsents() throws Exception {
|
||||||
|
try (var c = ClientAttributeUpdater.forClient(adminClient, bc.consumerRealmName(), CONSUMER_BROKER_APP_CLIENT_ID).setConsentRequired(true).update()) {
|
||||||
|
oauth.clientId(CONSUMER_BROKER_APP_CLIENT_ID);
|
||||||
|
oauth.realm(bc.consumerRealmName());
|
||||||
|
oauth.doLoginSocial(bc.getIDPAlias(), bc.getUserLogin(), bc.getUserPassword());
|
||||||
|
events.clear();
|
||||||
|
oauth.updateAccountInformation(bc.getUserLogin(), bc.getUserEmail());
|
||||||
|
WaitUtils.waitForPageToLoad();
|
||||||
|
consentPage.assertCurrent();
|
||||||
|
consentPage.confirm();
|
||||||
|
|
||||||
|
EventRepresentation loginEvent;
|
||||||
|
do {
|
||||||
|
loginEvent = events.poll();
|
||||||
|
} while (loginEvent != null && ! Objects.equals(EventType.LOGIN.name(), loginEvent.getType()));
|
||||||
|
|
||||||
|
assertThat(loginEvent, notNullValue());
|
||||||
|
assertThat(loginEvent.getClientId(), is(CONSUMER_BROKER_APP_CLIENT_ID));
|
||||||
|
assertThat(loginEvent.getUserId(), Matchers.containsString(LightweightUserAdapter.ID_PREFIX));
|
||||||
|
|
||||||
|
final String lwUserId = loginEvent.getUserId();
|
||||||
|
|
||||||
|
final UserResource userResource = adminClient.realm(bc.consumerRealmName()).users().get(lwUserId);
|
||||||
|
List<Map<String, Object>> consents = userResource.getConsents();
|
||||||
|
assertThat("There should be one consent", consents, hasSize(1));
|
||||||
|
|
||||||
|
Map<String, Object> consent = consents.get(0);
|
||||||
|
Assert.assertEquals("Consent should be given to " + CONSUMER_BROKER_APP_CLIENT_ID, CONSUMER_BROKER_APP_CLIENT_ID, consent.get("clientId"));
|
||||||
|
|
||||||
|
// list sessions. Single client should be in user session
|
||||||
|
List<UserSessionRepresentation> sessions = userResource.getUserSessions();
|
||||||
|
assertThat("There should be one active session", sessions, hasSize(1));
|
||||||
|
assertThat("There should be one client in user session", sessions.get(0).getClients(), aMapWithSize(1));
|
||||||
|
|
||||||
|
// Try SSO relogging into the app before revoking consent.
|
||||||
|
oauth.clientId(CONSUMER_BROKER_APP_CLIENT_ID);
|
||||||
|
oauth.openLoginForm();
|
||||||
|
assertThat("Should be logged in", driver.getTitle(), containsString("AUTH_RESPONSE"));
|
||||||
|
|
||||||
|
// revoke consent
|
||||||
|
userResource.revokeConsent(CONSUMER_BROKER_APP_CLIENT_ID);
|
||||||
|
|
||||||
|
// list consents
|
||||||
|
consents = userResource.getConsents();
|
||||||
|
assertThat("There should be no consents", consents, empty());
|
||||||
|
|
||||||
|
// list sessions
|
||||||
|
sessions = userResource.getUserSessions();
|
||||||
|
assertThat("There should be one active session", sessions, hasSize(1));
|
||||||
|
assertThat("There should be no client in user session", sessions.get(0).getClients(), aMapWithSize(0));
|
||||||
|
|
||||||
|
// Try relogging into the app after consent was revoked.
|
||||||
|
oauth.clientId(CONSUMER_BROKER_APP_CLIENT_ID);
|
||||||
|
oauth.openLoginForm();
|
||||||
|
|
||||||
|
WaitUtils.waitForPageToLoad();
|
||||||
|
consentPage.assertCurrent();
|
||||||
|
consentPage.confirm();
|
||||||
|
|
||||||
|
WaitUtils.waitForPageToLoad();
|
||||||
|
assertThat("Should be logged in", driver.getTitle(), containsString("AUTH_RESPONSE"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUserInfoEndpoint() throws Exception {
|
public void testUserInfoEndpoint() throws Exception {
|
||||||
EventRepresentation loginEvent = loginWithBrokerUsingOAuthClient(CONSUMER_BROKER_APP_CLIENT_ID);
|
EventRepresentation loginEvent = loginWithBrokerUsingOAuthClient(CONSUMER_BROKER_APP_CLIENT_ID);
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
|
import org.keycloak.services.managers.UserConsentManager;
|
||||||
import org.keycloak.storage.client.ClientStorageProviderModel;
|
import org.keycloak.storage.client.ClientStorageProviderModel;
|
||||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||||
import org.keycloak.testsuite.ProfileAssume;
|
import org.keycloak.testsuite.ProfileAssume;
|
||||||
|
@ -122,23 +123,23 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest {
|
||||||
|
|
||||||
UserConsentModel johnFooGrant = new UserConsentModel(fooClient);
|
UserConsentModel johnFooGrant = new UserConsentModel(fooClient);
|
||||||
johnFooGrant.addGrantedClientScope(fooScope);
|
johnFooGrant.addGrantedClientScope(fooScope);
|
||||||
realmManager.getSession().users().addConsent(realm, john.getId(), johnFooGrant);
|
UserConsentManager.addConsent(realmManager.getSession(), realm, john, johnFooGrant);
|
||||||
|
|
||||||
UserConsentModel johnBarGrant = new UserConsentModel(barClient);
|
UserConsentModel johnBarGrant = new UserConsentModel(barClient);
|
||||||
johnBarGrant.addGrantedClientScope(barScope);
|
johnBarGrant.addGrantedClientScope(barScope);
|
||||||
|
|
||||||
// Update should fail as grant doesn't yet exists
|
// Update should fail as grant doesn't yet exists
|
||||||
try {
|
try {
|
||||||
realmManager.getSession().users().updateConsent(realm, john.getId(), johnBarGrant);
|
UserConsentManager.updateConsent(realmManager.getSession(), realm, john, johnBarGrant);
|
||||||
Assert.fail("Not expected to end here");
|
Assert.fail("Not expected to end here");
|
||||||
} catch (ModelException expected) {
|
} catch (ModelException expected) {
|
||||||
}
|
}
|
||||||
|
|
||||||
realmManager.getSession().users().addConsent(realm, john.getId(), johnBarGrant);
|
UserConsentManager.addConsent(realmManager.getSession(), realm, john, johnBarGrant);
|
||||||
|
|
||||||
UserConsentModel maryFooGrant = new UserConsentModel(fooClient);
|
UserConsentModel maryFooGrant = new UserConsentModel(fooClient);
|
||||||
maryFooGrant.addGrantedClientScope(fooScope);
|
maryFooGrant.addGrantedClientScope(fooScope);
|
||||||
realmManager.getSession().users().addConsent(realm, mary.getId(), maryFooGrant);
|
UserConsentManager.addConsent(realmManager.getSession(), realm, mary, maryFooGrant);
|
||||||
|
|
||||||
ClientStorageProviderModel clientStorage = new ClientStorageProviderModel();
|
ClientStorageProviderModel clientStorage = new ClientStorageProviderModel();
|
||||||
clientStorage.setProviderId(HardcodedClientStorageProviderFactory.PROVIDER_ID);
|
clientStorage.setProviderId(HardcodedClientStorageProviderFactory.PROVIDER_ID);
|
||||||
|
@ -153,7 +154,7 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest {
|
||||||
Assert.assertNotNull(hardcodedClient);
|
Assert.assertNotNull(hardcodedClient);
|
||||||
|
|
||||||
UserConsentModel maryHardcodedGrant = new UserConsentModel(hardcodedClient);
|
UserConsentModel maryHardcodedGrant = new UserConsentModel(hardcodedClient);
|
||||||
realmManager.getSession().users().addConsent(realm, mary.getId(), maryHardcodedGrant);
|
UserConsentManager.addConsent(realmManager.getSession(), realm, mary, maryHardcodedGrant);
|
||||||
realmId = realm.getId();
|
realmId = realm.getId();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -173,32 +174,32 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest {
|
||||||
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
||||||
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
||||||
|
|
||||||
UserConsentModel johnFooConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
UserConsentModel johnFooConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId());
|
||||||
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
||||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
||||||
Assert.assertNotNull("Created Date should be set", johnFooConsent.getCreatedDate());
|
Assert.assertNotNull("Created Date should be set", johnFooConsent.getCreatedDate());
|
||||||
Assert.assertNotNull("Last Updated Date should be set", johnFooConsent.getLastUpdatedDate());
|
Assert.assertNotNull("Last Updated Date should be set", johnFooConsent.getLastUpdatedDate());
|
||||||
|
|
||||||
UserConsentModel johnBarConsent = currentSession.users().getConsentByClient(realm, john.getId(), barClient.getId());
|
UserConsentModel johnBarConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, barClient.getId());
|
||||||
Assert.assertEquals(johnBarConsent.getGrantedClientScopes().size(), 1);
|
Assert.assertEquals(johnBarConsent.getGrantedClientScopes().size(), 1);
|
||||||
Assert.assertTrue(isClientScopeGranted(realm, "bar", johnBarConsent));
|
Assert.assertTrue(isClientScopeGranted(realm, "bar", johnBarConsent));
|
||||||
Assert.assertNotNull("Created Date should be set", johnBarConsent.getCreatedDate());
|
Assert.assertNotNull("Created Date should be set", johnBarConsent.getCreatedDate());
|
||||||
Assert.assertNotNull("Last Updated Date should be set", johnBarConsent.getLastUpdatedDate());
|
Assert.assertNotNull("Last Updated Date should be set", johnBarConsent.getLastUpdatedDate());
|
||||||
|
|
||||||
UserConsentModel maryConsent = currentSession.users().getConsentByClient(realm, mary.getId(), fooClient.getId());
|
UserConsentModel maryConsent = UserConsentManager.getConsentByClient(currentSession, realm, mary, fooClient.getId());
|
||||||
Assert.assertEquals(maryConsent.getGrantedClientScopes().size(), 1);
|
Assert.assertEquals(maryConsent.getGrantedClientScopes().size(), 1);
|
||||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent));
|
Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent));
|
||||||
Assert.assertNotNull("Created Date should be set", maryConsent.getCreatedDate());
|
Assert.assertNotNull("Created Date should be set", maryConsent.getCreatedDate());
|
||||||
Assert.assertNotNull("Last Updated Date should be set", maryConsent.getLastUpdatedDate());
|
Assert.assertNotNull("Last Updated Date should be set", maryConsent.getLastUpdatedDate());
|
||||||
|
|
||||||
ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client");
|
ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client");
|
||||||
UserConsentModel maryHardcodedConsent = currentSession.users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId());
|
UserConsentModel maryHardcodedConsent = UserConsentManager.getConsentByClient(currentSession, realm, mary, hardcodedClient.getId());
|
||||||
Assert.assertEquals(maryHardcodedConsent.getGrantedClientScopes().size(), 0);
|
Assert.assertEquals(maryHardcodedConsent.getGrantedClientScopes().size(), 0);
|
||||||
Assert.assertNotNull("Created Date should be set", maryHardcodedConsent.getCreatedDate());
|
Assert.assertNotNull("Created Date should be set", maryHardcodedConsent.getCreatedDate());
|
||||||
Assert.assertNotNull("Last Updated Date should be set", maryHardcodedConsent.getLastUpdatedDate());
|
Assert.assertNotNull("Last Updated Date should be set", maryHardcodedConsent.getLastUpdatedDate());
|
||||||
|
|
||||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, mary.getId(), barClient.getId()));
|
Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, mary, barClient.getId()));
|
||||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, john.getId(), hardcodedClient.getId()));
|
Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, john, hardcodedClient.getId()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,11 +216,11 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest {
|
||||||
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
||||||
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
||||||
|
|
||||||
Assert.assertEquals(2, currentSession.users().getConsentsStream(realm, john.getId()).count());
|
Assert.assertEquals(2, UserConsentManager.getConsentsStream(currentSession, realm, john).count());
|
||||||
|
|
||||||
ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client");
|
ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client");
|
||||||
|
|
||||||
List<UserConsentModel> maryConsents = currentSession.users().getConsentsStream(realm, mary.getId())
|
List<UserConsentModel> maryConsents = UserConsentManager.getConsentsStream(currentSession, realm, mary)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
Assert.assertEquals(2, maryConsents.size());
|
Assert.assertEquals(2, maryConsents.size());
|
||||||
UserConsentModel maryConsent = maryConsents.get(0);
|
UserConsentModel maryConsent = maryConsents.get(0);
|
||||||
|
@ -249,14 +250,14 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest {
|
||||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||||
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
||||||
|
|
||||||
UserConsentModel johnConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
UserConsentModel johnConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId());
|
||||||
Assert.assertEquals(1, johnConsent.getGrantedClientScopes().size());
|
Assert.assertEquals(1, johnConsent.getGrantedClientScopes().size());
|
||||||
|
|
||||||
// Remove foo protocol mapper from johnConsent
|
// Remove foo protocol mapper from johnConsent
|
||||||
ClientScopeModel fooScope = KeycloakModelUtils.getClientScopeByName(realm, "foo");
|
ClientScopeModel fooScope = KeycloakModelUtils.getClientScopeByName(realm, "foo");
|
||||||
johnConsent.getGrantedClientScopes().remove(fooScope);
|
johnConsent.getGrantedClientScopes().remove(fooScope);
|
||||||
|
|
||||||
currentSession.users().updateConsent(realm, john.getId(), johnConsent);
|
UserConsentManager.updateConsent(currentSession, realm, john, johnConsent);
|
||||||
});
|
});
|
||||||
|
|
||||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession removalTestSession2) -> {
|
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession removalTestSession2) -> {
|
||||||
|
@ -265,7 +266,7 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest {
|
||||||
|
|
||||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||||
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
||||||
UserConsentModel johnConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
UserConsentModel johnConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId());
|
||||||
|
|
||||||
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
||||||
Assert.assertTrue("Created date should be less than last updated date", johnConsent.getCreatedDate() < johnConsent.getLastUpdatedDate());
|
Assert.assertTrue("Created date should be less than last updated date", johnConsent.getCreatedDate() < johnConsent.getLastUpdatedDate());
|
||||||
|
@ -284,9 +285,9 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest {
|
||||||
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
||||||
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
||||||
|
|
||||||
currentSession.users().revokeConsentForClient(realm, john.getId(), fooClient.getId());
|
UserConsentManager.revokeConsentForClient(currentSession, realm, john, fooClient.getId());
|
||||||
ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client");
|
ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client");
|
||||||
currentSession.users().revokeConsentForClient(realm, mary.getId(), hardcodedClient.getId());
|
UserConsentManager.revokeConsentForClient(currentSession, realm, mary, hardcodedClient.getId());
|
||||||
});
|
});
|
||||||
|
|
||||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRT2) -> {
|
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRT2) -> {
|
||||||
|
@ -297,9 +298,9 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest {
|
||||||
ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client");
|
ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client");
|
||||||
|
|
||||||
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
||||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId()));
|
Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId()));
|
||||||
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
||||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId()));
|
Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, mary, hardcodedClient.getId()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,7 +338,7 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest {
|
||||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||||
|
|
||||||
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
||||||
UserConsentModel johnConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
UserConsentModel johnConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId());
|
||||||
|
|
||||||
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
||||||
});
|
});
|
||||||
|
@ -369,11 +370,11 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest {
|
||||||
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
||||||
ClientModel barClient = realm.getClientByClientId("bar-client");
|
ClientModel barClient = realm.getClientByClientId("bar-client");
|
||||||
|
|
||||||
UserConsentModel johnFooConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
UserConsentModel johnFooConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId());
|
||||||
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
||||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
||||||
|
|
||||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, john.getId(), barClientID.get()));
|
Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, john, barClientID.get()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +397,7 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest {
|
||||||
Assert.assertNull(hardcodedClient);
|
Assert.assertNull(hardcodedClient);
|
||||||
|
|
||||||
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
||||||
Assert.assertEquals(1, currentSession.users().getConsentsStream(realm, mary.getId()).count());
|
Assert.assertEquals(1, UserConsentManager.getConsentsStream(currentSession, realm, mary).count());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
|
import org.keycloak.services.managers.UserConsentManager;
|
||||||
import org.keycloak.storage.UserStorageProviderModel;
|
import org.keycloak.storage.UserStorageProviderModel;
|
||||||
import org.keycloak.storage.client.ClientStorageProviderModel;
|
import org.keycloak.storage.client.ClientStorageProviderModel;
|
||||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||||
|
@ -124,23 +125,23 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo
|
||||||
|
|
||||||
UserConsentModel johnFooGrant = new UserConsentModel(fooClient);
|
UserConsentModel johnFooGrant = new UserConsentModel(fooClient);
|
||||||
johnFooGrant.addGrantedClientScope(fooScope);
|
johnFooGrant.addGrantedClientScope(fooScope);
|
||||||
realmManager.getSession().users().addConsent(realm, john.getId(), johnFooGrant);
|
UserConsentManager.addConsent(realmManager.getSession(), realm, john, johnFooGrant);
|
||||||
|
|
||||||
UserConsentModel johnBarGrant = new UserConsentModel(barClient);
|
UserConsentModel johnBarGrant = new UserConsentModel(barClient);
|
||||||
johnBarGrant.addGrantedClientScope(barScope);
|
johnBarGrant.addGrantedClientScope(barScope);
|
||||||
|
|
||||||
// Update should fail as grant doesn't yet exists
|
// Update should fail as grant doesn't yet exists
|
||||||
try {
|
try {
|
||||||
currentSession.users().updateConsent(realm, john.getId(), johnBarGrant);
|
UserConsentManager.updateConsent(currentSession, realm, john, johnBarGrant);
|
||||||
Assert.fail("Not expected to end here");
|
Assert.fail("Not expected to end here");
|
||||||
} catch (ModelException expected) {
|
} catch (ModelException expected) {
|
||||||
}
|
}
|
||||||
|
|
||||||
realmManager.getSession().users().addConsent(realm, john.getId(), johnBarGrant);
|
UserConsentManager.addConsent(realmManager.getSession(), realm, john, johnBarGrant);
|
||||||
|
|
||||||
UserConsentModel maryFooGrant = new UserConsentModel(fooClient);
|
UserConsentModel maryFooGrant = new UserConsentModel(fooClient);
|
||||||
maryFooGrant.addGrantedClientScope(fooScope);
|
maryFooGrant.addGrantedClientScope(fooScope);
|
||||||
realmManager.getSession().users().addConsent(realm, mary.getId(), maryFooGrant);
|
UserConsentManager.addConsent(realmManager.getSession(), realm, mary, maryFooGrant);
|
||||||
|
|
||||||
ClientStorageProviderModel clientStorage = new ClientStorageProviderModel();
|
ClientStorageProviderModel clientStorage = new ClientStorageProviderModel();
|
||||||
clientStorage.setProviderId(HardcodedClientStorageProviderFactory.PROVIDER_ID);
|
clientStorage.setProviderId(HardcodedClientStorageProviderFactory.PROVIDER_ID);
|
||||||
|
@ -155,7 +156,7 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo
|
||||||
Assert.assertNotNull(hardcodedClient);
|
Assert.assertNotNull(hardcodedClient);
|
||||||
|
|
||||||
UserConsentModel maryHardcodedGrant = new UserConsentModel(hardcodedClient);
|
UserConsentModel maryHardcodedGrant = new UserConsentModel(hardcodedClient);
|
||||||
realmManager.getSession().users().addConsent(realm, mary.getId(), maryHardcodedGrant);
|
UserConsentManager.addConsent(realmManager.getSession(), realm, mary, maryHardcodedGrant);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,32 +174,32 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo
|
||||||
UserModel john = currentSessionCT.users().getUserByUsername(realm, "john");
|
UserModel john = currentSessionCT.users().getUserByUsername(realm, "john");
|
||||||
UserModel mary = currentSessionCT.users().getUserByUsername(realm, "mary");
|
UserModel mary = currentSessionCT.users().getUserByUsername(realm, "mary");
|
||||||
|
|
||||||
UserConsentModel johnFooConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
UserConsentModel johnFooConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId());
|
||||||
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
||||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
||||||
Assert.assertNotNull("Created Date should be set", johnFooConsent.getCreatedDate());
|
Assert.assertNotNull("Created Date should be set", johnFooConsent.getCreatedDate());
|
||||||
Assert.assertNotNull("Last Updated Date should be set", johnFooConsent.getLastUpdatedDate());
|
Assert.assertNotNull("Last Updated Date should be set", johnFooConsent.getLastUpdatedDate());
|
||||||
|
|
||||||
UserConsentModel johnBarConsent = currentSession.users().getConsentByClient(realm, john.getId(), barClient.getId());
|
UserConsentModel johnBarConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, barClient.getId());
|
||||||
Assert.assertEquals(johnBarConsent.getGrantedClientScopes().size(), 1);
|
Assert.assertEquals(johnBarConsent.getGrantedClientScopes().size(), 1);
|
||||||
Assert.assertTrue(isClientScopeGranted(realm, "bar", johnBarConsent));
|
Assert.assertTrue(isClientScopeGranted(realm, "bar", johnBarConsent));
|
||||||
Assert.assertNotNull("Created Date should be set", johnBarConsent.getCreatedDate());
|
Assert.assertNotNull("Created Date should be set", johnBarConsent.getCreatedDate());
|
||||||
Assert.assertNotNull("Last Updated Date should be set", johnBarConsent.getLastUpdatedDate());
|
Assert.assertNotNull("Last Updated Date should be set", johnBarConsent.getLastUpdatedDate());
|
||||||
|
|
||||||
UserConsentModel maryConsent = currentSession.users().getConsentByClient(realm, mary.getId(), fooClient.getId());
|
UserConsentModel maryConsent = UserConsentManager.getConsentByClient(currentSession, realm, mary, fooClient.getId());
|
||||||
Assert.assertEquals(maryConsent.getGrantedClientScopes().size(), 1);
|
Assert.assertEquals(maryConsent.getGrantedClientScopes().size(), 1);
|
||||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent));
|
Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent));
|
||||||
Assert.assertNotNull("Created Date should be set", maryConsent.getCreatedDate());
|
Assert.assertNotNull("Created Date should be set", maryConsent.getCreatedDate());
|
||||||
Assert.assertNotNull("Last Updated Date should be set", maryConsent.getLastUpdatedDate());
|
Assert.assertNotNull("Last Updated Date should be set", maryConsent.getLastUpdatedDate());
|
||||||
|
|
||||||
ClientModel hardcodedClient = currentSessionCT.clients().getClientByClientId(realm, "hardcoded-client");
|
ClientModel hardcodedClient = currentSessionCT.clients().getClientByClientId(realm, "hardcoded-client");
|
||||||
UserConsentModel maryHardcodedConsent = currentSession.users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId());
|
UserConsentModel maryHardcodedConsent = UserConsentManager.getConsentByClient(currentSession, realm, mary, hardcodedClient.getId());
|
||||||
Assert.assertEquals(maryHardcodedConsent.getGrantedClientScopes().size(), 0);
|
Assert.assertEquals(maryHardcodedConsent.getGrantedClientScopes().size(), 0);
|
||||||
Assert.assertNotNull("Created Date should be set", maryHardcodedConsent.getCreatedDate());
|
Assert.assertNotNull("Created Date should be set", maryHardcodedConsent.getCreatedDate());
|
||||||
Assert.assertNotNull("Last Updated Date should be set", maryHardcodedConsent.getLastUpdatedDate());
|
Assert.assertNotNull("Last Updated Date should be set", maryHardcodedConsent.getLastUpdatedDate());
|
||||||
|
|
||||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, mary.getId(), barClient.getId()));
|
Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, mary, barClient.getId()));
|
||||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, john.getId(), hardcodedClient.getId()));
|
Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, john, hardcodedClient.getId()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,11 +216,11 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo
|
||||||
UserModel john = currentSessionACT.users().getUserByUsername(realm, "john");
|
UserModel john = currentSessionACT.users().getUserByUsername(realm, "john");
|
||||||
UserModel mary = currentSessionACT.users().getUserByUsername(realm, "mary");
|
UserModel mary = currentSessionACT.users().getUserByUsername(realm, "mary");
|
||||||
|
|
||||||
Assert.assertEquals(2, currentSession.users().getConsentsStream(realm, john.getId()).count());
|
Assert.assertEquals(2, UserConsentManager.getConsentsStream(currentSession, realm, john).count());
|
||||||
|
|
||||||
ClientModel hardcodedClient = currentSessionACT.clients().getClientByClientId(realm, "hardcoded-client");
|
ClientModel hardcodedClient = currentSessionACT.clients().getClientByClientId(realm, "hardcoded-client");
|
||||||
|
|
||||||
List<UserConsentModel> maryConsents = currentSession.users().getConsentsStream(realm, mary.getId())
|
List<UserConsentModel> maryConsents = UserConsentManager.getConsentsStream(currentSession, realm, mary)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
Assert.assertEquals(2, maryConsents.size());
|
Assert.assertEquals(2, maryConsents.size());
|
||||||
UserConsentModel maryConsent = maryConsents.get(0);
|
UserConsentModel maryConsent = maryConsents.get(0);
|
||||||
|
@ -249,14 +250,14 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo
|
||||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||||
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
||||||
|
|
||||||
UserConsentModel johnConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
UserConsentModel johnConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId());
|
||||||
Assert.assertEquals(1, johnConsent.getGrantedClientScopes().size());
|
Assert.assertEquals(1, johnConsent.getGrantedClientScopes().size());
|
||||||
|
|
||||||
// Remove foo protocol mapper from johnConsent
|
// Remove foo protocol mapper from johnConsent
|
||||||
ClientScopeModel fooScope = KeycloakModelUtils.getClientScopeByName(realm, "foo");
|
ClientScopeModel fooScope = KeycloakModelUtils.getClientScopeByName(realm, "foo");
|
||||||
johnConsent.getGrantedClientScopes().remove(fooScope);
|
johnConsent.getGrantedClientScopes().remove(fooScope);
|
||||||
|
|
||||||
currentSession.users().updateConsent(realm, john.getId(), johnConsent);
|
UserConsentManager.updateConsent(currentSession, realm, john, johnConsent);
|
||||||
});
|
});
|
||||||
|
|
||||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionScopeRemoval2) -> {
|
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionScopeRemoval2) -> {
|
||||||
|
@ -265,7 +266,7 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo
|
||||||
|
|
||||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||||
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
||||||
UserConsentModel johnConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
UserConsentModel johnConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId());
|
||||||
|
|
||||||
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
||||||
Assert.assertTrue("Created date should be less than last updated date", johnConsent.getCreatedDate() < johnConsent.getLastUpdatedDate());
|
Assert.assertTrue("Created date should be less than last updated date", johnConsent.getCreatedDate() < johnConsent.getLastUpdatedDate());
|
||||||
|
@ -284,9 +285,9 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo
|
||||||
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
||||||
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
||||||
|
|
||||||
currentSession.users().revokeConsentForClient(realm, john.getId(), fooClient.getId());
|
UserConsentManager.revokeConsentForClient(currentSession, realm, john, fooClient.getId());
|
||||||
ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client");
|
ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client");
|
||||||
currentSession.users().revokeConsentForClient(realm, mary.getId(), hardcodedClient.getId());
|
UserConsentManager.revokeConsentForClient(currentSession, realm, mary, hardcodedClient.getId());
|
||||||
});
|
});
|
||||||
|
|
||||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRevoke2) -> {
|
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRevoke2) -> {
|
||||||
|
@ -297,10 +298,10 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo
|
||||||
ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client");
|
ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client");
|
||||||
|
|
||||||
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
||||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId()));
|
Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId()));
|
||||||
|
|
||||||
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
||||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId()));
|
Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, mary, hardcodedClient.getId()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +340,7 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo
|
||||||
|
|
||||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||||
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
UserModel john = currentSession.users().getUserByUsername(realm, "john");
|
||||||
UserConsentModel johnConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
UserConsentModel johnConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId());
|
||||||
|
|
||||||
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
||||||
});
|
});
|
||||||
|
@ -371,11 +372,11 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo
|
||||||
|
|
||||||
UserModel john = realmManager.getSession().users().getUserByUsername(realm, "john");
|
UserModel john = realmManager.getSession().users().getUserByUsername(realm, "john");
|
||||||
|
|
||||||
UserConsentModel johnFooConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
UserConsentModel johnFooConsent = UserConsentManager.getConsentByClient(realmManager.getSession(), realm, john, fooClient.getId());
|
||||||
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
||||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
||||||
|
|
||||||
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), barClientID.get()));
|
Assert.assertNull(UserConsentManager.getConsentByClient(realmManager.getSession(), realm, john, barClientID.get()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,7 +399,7 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo
|
||||||
Assert.assertNull(hardcodedClient);
|
Assert.assertNull(hardcodedClient);
|
||||||
|
|
||||||
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
UserModel mary = currentSession.users().getUserByUsername(realm, "mary");
|
||||||
Assert.assertEquals(1, currentSession.users().getConsentsStream(realm, mary.getId()).count());
|
Assert.assertEquals(1, UserConsentManager.getConsentsStream(currentSession, realm, mary).count());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue