KEYCLOAK-6630 Client scopes initial support (#5076)
* KEYCLOAK-6630 KEYCLOAK-349 Client Scopes Co-authored-by: vramik <vramik@redhat.com> * KEYCLOAK-6630 Change some clientTemplate occurences to clientScope
This commit is contained in:
parent
4d1474afe0
commit
49407c2e4f
290 changed files with 8253 additions and 6812 deletions
|
@ -250,7 +250,16 @@
|
|||
baseUrl = kc.endpoints.authorize();
|
||||
}
|
||||
|
||||
var scope = (options && options.scope) ? "openid " + options.scope : "openid";
|
||||
var scope;
|
||||
if (options && options.scope) {
|
||||
if (options.scope.indexOf("openid") != -1) {
|
||||
scope = options.scope;
|
||||
} else {
|
||||
scope = "openid " + options.scope;
|
||||
}
|
||||
} else {
|
||||
scope = "openid";
|
||||
}
|
||||
|
||||
var url = baseUrl
|
||||
+ '?client_id=' + encodeURIComponent(kc.clientId)
|
||||
|
|
|
@ -97,6 +97,21 @@ public class AccessToken extends IDToken {
|
|||
}
|
||||
}
|
||||
|
||||
// KEYCLOAK-6771 Certificate Bound Token
|
||||
// https://tools.ietf.org/html/draft-ietf-oauth-mtls-08#section-3.1
|
||||
public static class CertConf {
|
||||
@JsonProperty("x5t#S256")
|
||||
protected String certThumbprint;
|
||||
|
||||
public String getCertThumbprint() {
|
||||
return certThumbprint;
|
||||
}
|
||||
|
||||
public void setCertThumbprint(String certThumbprint) {
|
||||
this.certThumbprint = certThumbprint;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonProperty("trusted-certs")
|
||||
protected Set<String> trustedCertificates;
|
||||
|
||||
|
@ -112,6 +127,12 @@ public class AccessToken extends IDToken {
|
|||
@JsonProperty("authorization")
|
||||
protected Authorization authorization;
|
||||
|
||||
@JsonProperty("cnf")
|
||||
protected CertConf certConf;
|
||||
|
||||
@JsonProperty("scope")
|
||||
protected String scope;
|
||||
|
||||
public Map<String, Access> getResourceAccess() {
|
||||
return resourceAccess;
|
||||
}
|
||||
|
@ -234,24 +255,6 @@ public class AccessToken extends IDToken {
|
|||
this.authorization = authorization;
|
||||
}
|
||||
|
||||
// KEYCLOAK-6771 Certificate Bound Token
|
||||
// https://tools.ietf.org/html/draft-ietf-oauth-mtls-08#section-3.1
|
||||
public static class CertConf {
|
||||
@JsonProperty("x5t#S256")
|
||||
protected String certThumbprint;
|
||||
|
||||
public String getCertThumbprint() {
|
||||
return certThumbprint;
|
||||
}
|
||||
|
||||
public void setCertThumbprint(String certThumbprint) {
|
||||
this.certThumbprint = certThumbprint;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonProperty("cnf")
|
||||
protected CertConf certConf;
|
||||
|
||||
public CertConf getCertConf() {
|
||||
return certConf;
|
||||
}
|
||||
|
@ -259,4 +262,12 @@ public class AccessToken extends IDToken {
|
|||
public void setCertConf(CertConf certConf) {
|
||||
this.certConf = certConf;
|
||||
}
|
||||
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ public class RefreshToken extends AccessToken {
|
|||
this.sessionState = token.sessionState;
|
||||
this.nonce = token.nonce;
|
||||
this.audience = token.audience;
|
||||
this.scope = token.scope;
|
||||
if (token.realmAccess != null) {
|
||||
realmAccess = token.realmAccess.clone();
|
||||
}
|
||||
|
@ -56,4 +57,5 @@ public class RefreshToken extends AccessToken {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -61,10 +61,19 @@ public class ClientRepresentation {
|
|||
protected Integer nodeReRegistrationTimeout;
|
||||
protected Map<String, Integer> registeredNodes;
|
||||
protected List<ProtocolMapperRepresentation> protocolMappers;
|
||||
|
||||
@Deprecated
|
||||
protected String clientTemplate;
|
||||
@Deprecated
|
||||
private Boolean useTemplateConfig;
|
||||
@Deprecated
|
||||
private Boolean useTemplateScope;
|
||||
@Deprecated
|
||||
private Boolean useTemplateMappers;
|
||||
|
||||
protected List<String> defaultClientScopes;
|
||||
protected List<String> optionalClientScopes;
|
||||
|
||||
private ResourceServerRepresentation authorizationSettings;
|
||||
private Map<String, Boolean> access;
|
||||
protected String origin;
|
||||
|
@ -338,36 +347,40 @@ public class ClientRepresentation {
|
|||
this.protocolMappers = protocolMappers;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getClientTemplate() {
|
||||
return clientTemplate;
|
||||
}
|
||||
|
||||
public void setClientTemplate(String clientTemplate) {
|
||||
this.clientTemplate = clientTemplate;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Boolean isUseTemplateConfig() {
|
||||
return useTemplateConfig;
|
||||
}
|
||||
|
||||
public void setUseTemplateConfig(Boolean useTemplateConfig) {
|
||||
this.useTemplateConfig = useTemplateConfig;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Boolean isUseTemplateScope() {
|
||||
return useTemplateScope;
|
||||
}
|
||||
|
||||
public void setUseTemplateScope(Boolean useTemplateScope) {
|
||||
this.useTemplateScope = useTemplateScope;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Boolean isUseTemplateMappers() {
|
||||
return useTemplateMappers;
|
||||
}
|
||||
|
||||
public void setUseTemplateMappers(Boolean useTemplateMappers) {
|
||||
this.useTemplateMappers = useTemplateMappers;
|
||||
public List<String> getDefaultClientScopes() {
|
||||
return defaultClientScopes;
|
||||
}
|
||||
|
||||
public void setDefaultClientScopes(List<String> defaultClientScopes) {
|
||||
this.defaultClientScopes = defaultClientScopes;
|
||||
}
|
||||
|
||||
public List<String> getOptionalClientScopes() {
|
||||
return optionalClientScopes;
|
||||
}
|
||||
|
||||
public void setOptionalClientScopes(List<String> optionalClientScopes) {
|
||||
this.optionalClientScopes = optionalClientScopes;
|
||||
}
|
||||
|
||||
public ResourceServerRepresentation getAuthorizationSettings() {
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.representations.idm;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown=true) // Backwards compatibility of admin REST endpoints (ClientTemplateRepresentation was more rich)
|
||||
public class ClientScopeRepresentation {
|
||||
|
||||
protected String id;
|
||||
protected String name;
|
||||
protected String description;
|
||||
protected String protocol;
|
||||
protected Map<String, String> attributes;
|
||||
|
||||
protected List<ProtocolMapperRepresentation> protocolMappers;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
public List<ProtocolMapperRepresentation> getProtocolMappers() {
|
||||
return protocolMappers;
|
||||
}
|
||||
|
||||
public void setProtocolMappers(List<ProtocolMapperRepresentation> protocolMappers) {
|
||||
this.protocolMappers = protocolMappers;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public Map<String, String> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(Map<String, String> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
}
|
2
core/src/main/java/org/keycloak/representations/idm/ClientTemplateRepresentation.java
Executable file → Normal file
2
core/src/main/java/org/keycloak/representations/idm/ClientTemplateRepresentation.java
Executable file → Normal file
|
@ -24,6 +24,7 @@ import java.util.Map;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Deprecated // Use ClientScopeRepresentation instead
|
||||
public class ClientTemplateRepresentation {
|
||||
/**
|
||||
* Use this value in ClientRepresentation.setClientTemplate when you want to clear this value
|
||||
|
@ -167,3 +168,4 @@ public class ClientTemplateRepresentation {
|
|||
this.attributes = attributes;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,11 @@ public class ProtocolMapperRepresentation {
|
|||
protected String name;
|
||||
protected String protocol;
|
||||
protected String protocolMapper;
|
||||
|
||||
@Deprecated // backwards compatibility only
|
||||
protected boolean consentRequired;
|
||||
|
||||
@Deprecated // backwards compatibility only
|
||||
protected String consentText;
|
||||
protected Map<String, String> config = new HashMap<String, String>();
|
||||
|
||||
|
@ -74,19 +78,14 @@ public class ProtocolMapperRepresentation {
|
|||
this.config = config;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean isConsentRequired() {
|
||||
return consentRequired;
|
||||
}
|
||||
|
||||
public void setConsentRequired(boolean consentRequired) {
|
||||
this.consentRequired = consentRequired;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getConsentText() {
|
||||
return consentText;
|
||||
}
|
||||
|
||||
public void setConsentText(String consentText) {
|
||||
this.consentText = consentText;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,7 +106,9 @@ public class RealmRepresentation {
|
|||
protected List<ScopeMappingRepresentation> scopeMappings;
|
||||
protected Map<String, List<ScopeMappingRepresentation>> clientScopeMappings;
|
||||
protected List<ClientRepresentation> clients;
|
||||
protected List<ClientTemplateRepresentation> clientTemplates;
|
||||
protected List<ClientScopeRepresentation> clientScopes;
|
||||
protected List<String> defaultDefaultClientScopes;
|
||||
protected List<String> defaultOptionalClientScopes;
|
||||
protected Map<String, String> browserSecurityHeaders;
|
||||
protected Map<String, String> smtpServer;
|
||||
protected List<UserFederationProviderRepresentation> userFederationProviders;
|
||||
|
@ -159,6 +161,8 @@ public class RealmRepresentation {
|
|||
protected List<ApplicationRepresentation> applications;
|
||||
@Deprecated
|
||||
protected List<OAuthClientRepresentation> oauthClients;
|
||||
@Deprecated
|
||||
protected List<ClientTemplateRepresentation> clientTemplates;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
|
@ -304,9 +308,9 @@ public class RealmRepresentation {
|
|||
return mapping;
|
||||
}
|
||||
|
||||
public ScopeMappingRepresentation clientTemplateScopeMapping(String clientTemplateName) {
|
||||
public ScopeMappingRepresentation clientScopeScopeMapping(String clientScopeName) {
|
||||
ScopeMappingRepresentation mapping = new ScopeMappingRepresentation();
|
||||
mapping.setClientTemplate(clientTemplateName);
|
||||
mapping.setClientScope(clientScopeName);
|
||||
if (scopeMappings == null) scopeMappings = new ArrayList<ScopeMappingRepresentation>();
|
||||
scopeMappings.add(mapping);
|
||||
return mapping;
|
||||
|
@ -930,12 +934,33 @@ public class RealmRepresentation {
|
|||
this.groups = groups;
|
||||
}
|
||||
|
||||
@Deprecated // use getClientScopes() instead
|
||||
public List<ClientTemplateRepresentation> getClientTemplates() {
|
||||
return clientTemplates;
|
||||
}
|
||||
|
||||
public void setClientTemplates(List<ClientTemplateRepresentation> clientTemplates) {
|
||||
this.clientTemplates = clientTemplates;
|
||||
public List<ClientScopeRepresentation> getClientScopes() {
|
||||
return clientScopes;
|
||||
}
|
||||
|
||||
public void setClientScopes(List<ClientScopeRepresentation> clientScopes) {
|
||||
this.clientScopes = clientScopes;
|
||||
}
|
||||
|
||||
public List<String> getDefaultDefaultClientScopes() {
|
||||
return defaultDefaultClientScopes;
|
||||
}
|
||||
|
||||
public void setDefaultDefaultClientScopes(List<String> defaultDefaultClientScopes) {
|
||||
this.defaultDefaultClientScopes = defaultDefaultClientScopes;
|
||||
}
|
||||
|
||||
public List<String> getDefaultOptionalClientScopes() {
|
||||
return defaultOptionalClientScopes;
|
||||
}
|
||||
|
||||
public void setDefaultOptionalClientScopes(List<String> defaultOptionalClientScopes) {
|
||||
this.defaultOptionalClientScopes = defaultOptionalClientScopes;
|
||||
}
|
||||
|
||||
public MultivaluedHashMap<String, ComponentExportRepresentation> getComponents() {
|
||||
|
|
|
@ -29,6 +29,7 @@ public class RoleRepresentation {
|
|||
protected String id;
|
||||
protected String name;
|
||||
protected String description;
|
||||
@Deprecated
|
||||
protected Boolean scopeParamRequired;
|
||||
protected boolean composite;
|
||||
protected Composites composites;
|
||||
|
@ -96,14 +97,11 @@ public class RoleRepresentation {
|
|||
this.description = description;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Boolean isScopeParamRequired() {
|
||||
return scopeParamRequired;
|
||||
}
|
||||
|
||||
public void setScopeParamRequired(Boolean scopeParamRequired) {
|
||||
this.scopeParamRequired = scopeParamRequired;
|
||||
}
|
||||
|
||||
public Composites getComposites() {
|
||||
return composites;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,10 @@ import java.util.Set;
|
|||
public class ScopeMappingRepresentation {
|
||||
protected String self; // link
|
||||
protected String client;
|
||||
|
||||
@Deprecated // Replaced by clientScope
|
||||
protected String clientTemplate;
|
||||
protected String clientScope;
|
||||
protected Set<String> roles;
|
||||
|
||||
public String getSelf() {
|
||||
|
@ -46,12 +49,17 @@ public class ScopeMappingRepresentation {
|
|||
this.client = client;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getClientTemplate() {
|
||||
return clientTemplate;
|
||||
}
|
||||
|
||||
public void setClientTemplate(String clientTemplate) {
|
||||
this.clientTemplate = clientTemplate;
|
||||
public String getClientScope() {
|
||||
return clientScope;
|
||||
}
|
||||
|
||||
public void setClientScope(String clientScope) {
|
||||
this.clientScope = clientScope;
|
||||
}
|
||||
|
||||
public Set<String> getRoles() {
|
||||
|
|
|
@ -20,25 +20,25 @@ package org.keycloak.representations.idm;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown=true)
|
||||
public class UserConsentRepresentation {
|
||||
|
||||
protected String clientId;
|
||||
|
||||
// Key is protocol, Value is list of granted consents for this protocol
|
||||
protected Map<String, List<String>> grantedProtocolMappers;
|
||||
|
||||
protected List<String> grantedRealmRoles;
|
||||
|
||||
// Key is clientId, Value is list of granted roles of this client
|
||||
protected Map<String, List<String>> grantedClientRoles;
|
||||
protected List<String> grantedClientScopes;
|
||||
|
||||
private Long createdDate;
|
||||
|
||||
private Long lastUpdatedDate;
|
||||
|
||||
@Deprecated
|
||||
protected List<String> grantedRealmRoles;
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
@ -47,28 +47,12 @@ public class UserConsentRepresentation {
|
|||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getGrantedProtocolMappers() {
|
||||
return grantedProtocolMappers;
|
||||
public List<String> getGrantedClientScopes() {
|
||||
return grantedClientScopes;
|
||||
}
|
||||
|
||||
public void setGrantedProtocolMappers(Map<String, List<String>> grantedProtocolMappers) {
|
||||
this.grantedProtocolMappers = grantedProtocolMappers;
|
||||
}
|
||||
|
||||
public List<String> getGrantedRealmRoles() {
|
||||
return grantedRealmRoles;
|
||||
}
|
||||
|
||||
public void setGrantedRealmRoles(List<String> grantedRealmRoles) {
|
||||
this.grantedRealmRoles = grantedRealmRoles;
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getGrantedClientRoles() {
|
||||
return grantedClientRoles;
|
||||
}
|
||||
|
||||
public void setGrantedClientRoles(Map<String, List<String>> grantedClientRoles) {
|
||||
this.grantedClientRoles = grantedClientRoles;
|
||||
public void setGrantedClientScopes(List<String> grantedClientScopes) {
|
||||
this.grantedClientScopes = grantedClientScopes;
|
||||
}
|
||||
|
||||
public void setCreatedDate(Long createdDate) {
|
||||
|
@ -86,4 +70,9 @@ public class UserConsentRepresentation {
|
|||
public Long getLastUpdatedDate() {
|
||||
return lastUpdatedDate;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public List<String> getGrantedRealmRoles() {
|
||||
return grantedRealmRoles;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,8 @@ public class TokenUtil {
|
|||
public static String attachOIDCScope(String scopeParam) {
|
||||
if (scopeParam == null || scopeParam.isEmpty()) {
|
||||
return OAuth2Constants.SCOPE_OPENID;
|
||||
} else if (hasScope(scopeParam, OAuth2Constants.SCOPE_OPENID)) {
|
||||
return scopeParam;
|
||||
} else {
|
||||
return OAuth2Constants.SCOPE_OPENID + " " + scopeParam;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
"protocolMapper" : "oidc-usermodel-property-mapper",
|
||||
"protocol" : "openid-connect",
|
||||
"name" : "username",
|
||||
"consentText" : "username",
|
||||
"consentRequired" : true,
|
||||
"config" : {
|
||||
"Claim JSON Type" : "String",
|
||||
"user.attribute" : "username",
|
||||
|
@ -42,8 +40,6 @@
|
|||
"protocolMapper" : "oidc-usersessionmodel-note-mapper",
|
||||
"protocol" : "openid-connect",
|
||||
"name" : "gss delegation credential",
|
||||
"consentText" : "gss delegation credential",
|
||||
"consentRequired" : true,
|
||||
"config" : {
|
||||
"user.session.note" : "gss_delegation_credential",
|
||||
"claim.name" : "gss_delegation_credential",
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
"protocolMapper" : "oidc-usermodel-property-mapper",
|
||||
"protocol" : "openid-connect",
|
||||
"name" : "username",
|
||||
"consentText" : "${username}",
|
||||
"consentRequired" : true,
|
||||
"config" : {
|
||||
"Claim JSON Type" : "String",
|
||||
"user.attribute" : "username",
|
||||
|
@ -41,8 +39,6 @@
|
|||
"protocolMapper" : "oidc-full-name-mapper",
|
||||
"protocol" : "openid-connect",
|
||||
"name" : "full name",
|
||||
"consentText" : "${fullName}",
|
||||
"consentRequired" : true,
|
||||
"config" : {
|
||||
"id.token.claim" : "true",
|
||||
"access.token.claim" : "true"
|
||||
|
@ -52,8 +48,6 @@
|
|||
"protocolMapper" : "oidc-usermodel-property-mapper",
|
||||
"protocol" : "openid-connect",
|
||||
"name" : "given name",
|
||||
"consentText" : "${givenName}",
|
||||
"consentRequired" : true,
|
||||
"config" : {
|
||||
"Claim JSON Type" : "String",
|
||||
"user.attribute" : "firstName",
|
||||
|
@ -66,8 +60,6 @@
|
|||
"protocolMapper" : "oidc-usermodel-property-mapper",
|
||||
"protocol" : "openid-connect",
|
||||
"name" : "family name",
|
||||
"consentText" : "${familyName}",
|
||||
"consentRequired" : true,
|
||||
"config" : {
|
||||
"Claim JSON Type" : "String",
|
||||
"user.attribute" : "lastName",
|
||||
|
@ -80,8 +72,6 @@
|
|||
"protocolMapper" : "oidc-usermodel-property-mapper",
|
||||
"protocol" : "openid-connect",
|
||||
"name" : "email",
|
||||
"consentText" : "${email}",
|
||||
"consentRequired" : true,
|
||||
"config" : {
|
||||
"Claim JSON Type" : "String",
|
||||
"user.attribute" : "email",
|
||||
|
@ -94,8 +84,6 @@
|
|||
"protocolMapper" : "oidc-usermodel-attribute-mapper",
|
||||
"protocol" : "openid-connect",
|
||||
"name" : "postal code",
|
||||
"consentText" : "${postal_code}",
|
||||
"consentRequired" : true,
|
||||
"config" : {
|
||||
"Claim JSON Type" : "String",
|
||||
"user.attribute" : "postal_code",
|
||||
|
@ -109,8 +97,6 @@
|
|||
"protocolMapper" : "oidc-usermodel-attribute-mapper",
|
||||
"protocol" : "openid-connect",
|
||||
"name" : "street",
|
||||
"consentText" : "${street}",
|
||||
"consentRequired" : true,
|
||||
"config" : {
|
||||
"Claim JSON Type" : "String",
|
||||
"user.attribute" : "street",
|
||||
|
@ -124,8 +110,6 @@
|
|||
"protocolMapper" : "oidc-usermodel-attribute-mapper",
|
||||
"protocol" : "openid-connect",
|
||||
"name" : "picture",
|
||||
"consentText" : "Picture",
|
||||
"consentRequired" : true,
|
||||
"config" : {
|
||||
"Claim JSON Type" : "String",
|
||||
"user.attribute" : "picture",
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.keycloak.admin.client.resource;
|
|||
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||
import org.keycloak.representations.adapters.action.GlobalRequestResult;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.ClientScopeRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.representations.idm.UserSessionRepresentation;
|
||||
|
@ -122,6 +123,42 @@ public interface ClientResource {
|
|||
@Path("/roles")
|
||||
public RolesResource roles();
|
||||
|
||||
/**
|
||||
* Get default client scopes. Only name and ids are returned.
|
||||
*
|
||||
* @return default client scopes
|
||||
*/
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("default-client-scopes")
|
||||
List<ClientScopeRepresentation> getDefaultClientScopes();
|
||||
|
||||
@PUT
|
||||
@Path("default-client-scopes/{clientScopeId}")
|
||||
void addDefaultClientScope(@PathParam("clientScopeId") String clientScopeId);
|
||||
|
||||
@DELETE
|
||||
@Path("default-client-scopes/{clientScopeId}")
|
||||
void removeDefaultClientScope(@PathParam("clientScopeId") String clientScopeId);
|
||||
|
||||
/**
|
||||
* Get optional client scopes. Only name and ids are returned.
|
||||
*
|
||||
* @return optional client scopes
|
||||
*/
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("optional-client-scopes")
|
||||
List<ClientScopeRepresentation> getOptionalClientScopes();
|
||||
|
||||
@PUT
|
||||
@Path("optional-client-scopes/{clientScopeId}")
|
||||
void addOptionalClientScope(@PathParam("clientScopeId") String clientScopeId);
|
||||
|
||||
@DELETE
|
||||
@Path("optional-client-scopes/{clientScopeId}")
|
||||
void removeOptionalClientScope(@PathParam("clientScopeId") String clientScopeId);
|
||||
|
||||
@Path("/service-account-user")
|
||||
@GET
|
||||
@NoCache
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
package org.keycloak.admin.client.resource;
|
||||
|
||||
import org.keycloak.representations.idm.ClientTemplateRepresentation;
|
||||
import org.keycloak.representations.idm.ClientScopeRepresentation;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
|
@ -30,7 +30,7 @@ import javax.ws.rs.core.MediaType;
|
|||
/**
|
||||
* @author rodrigo.sasaki@icarros.com.br
|
||||
*/
|
||||
public interface ClientTemplateResource {
|
||||
public interface ClientScopeResource {
|
||||
|
||||
@Path("protocol-mappers")
|
||||
public ProtocolMappersResource getProtocolMappers();
|
||||
|
@ -40,11 +40,11 @@ public interface ClientTemplateResource {
|
|||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public ClientTemplateRepresentation toRepresentation();
|
||||
public ClientScopeRepresentation toRepresentation();
|
||||
|
||||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public void update(ClientTemplateRepresentation rep);
|
||||
public void update(ClientScopeRepresentation rep);
|
||||
|
||||
@DELETE
|
||||
public void remove();
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
package org.keycloak.admin.client.resource;
|
||||
|
||||
import org.keycloak.representations.idm.ClientTemplateRepresentation;
|
||||
import org.keycloak.representations.idm.ClientScopeRepresentation;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
|
@ -32,18 +32,18 @@ import java.util.List;
|
|||
/**
|
||||
* @author rodrigo.sasaki@icarros.com.br
|
||||
*/
|
||||
public interface ClientTemplatesResource {
|
||||
public interface ClientScopesResource {
|
||||
|
||||
@Path("{id}")
|
||||
public ClientTemplateResource get(@PathParam("id") String id);
|
||||
ClientScopeResource get(@PathParam("id") String id);
|
||||
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Response create(ClientTemplateRepresentation clientRepresentation);
|
||||
public Response create(ClientScopeRepresentation clientScopeRepresentation);
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public List<ClientTemplateRepresentation> findAll();
|
||||
public List<ClientScopeRepresentation> findAll();
|
||||
|
||||
|
||||
|
|
@ -21,6 +21,7 @@ import org.jboss.resteasy.annotations.cache.NoCache;
|
|||
import org.keycloak.representations.adapters.action.GlobalRequestResult;
|
||||
import org.keycloak.representations.idm.AdminEventRepresentation;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.ClientScopeRepresentation;
|
||||
import org.keycloak.representations.idm.EventRepresentation;
|
||||
import org.keycloak.representations.idm.GroupRepresentation;
|
||||
import org.keycloak.representations.idm.PartialImportRepresentation;
|
||||
|
@ -39,7 +40,7 @@ import javax.ws.rs.Produces;
|
|||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -59,8 +60,34 @@ public interface RealmResource {
|
|||
@Path("clients")
|
||||
ClientsResource clients();
|
||||
|
||||
@Path("client-templates")
|
||||
ClientTemplatesResource clientTemplates();
|
||||
@Path("client-scopes")
|
||||
ClientScopesResource clientScopes();
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("default-default-client-scopes")
|
||||
List<ClientScopeRepresentation> getDefaultDefaultClientScopes();
|
||||
|
||||
@PUT
|
||||
@Path("default-default-client-scopes/{clientScopeId}")
|
||||
void addDefaultDefaultClientScope(@PathParam("clientScopeId") String clientScopeId);
|
||||
|
||||
@DELETE
|
||||
@Path("default-default-client-scopes/{clientScopeId}")
|
||||
void removeDefaultDefaultClientScope(@PathParam("clientScopeId") String clientScopeId);
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("default-optional-client-scopes")
|
||||
List<ClientScopeRepresentation> getDefaultOptionalClientScopes();
|
||||
|
||||
@PUT
|
||||
@Path("default-optional-client-scopes/{clientScopeId}")
|
||||
void addDefaultOptionalClientScope(@PathParam("clientScopeId") String clientScopeId);
|
||||
|
||||
@DELETE
|
||||
@Path("default-optional-client-scopes/{clientScopeId}")
|
||||
void removeDefaultOptionalClientScope(@PathParam("clientScopeId") String clientScopeId);
|
||||
|
||||
@Path("client-description-converter")
|
||||
@POST
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package org.keycloak.models.cache.infinispan;
|
||||
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleContainerModel;
|
||||
|
@ -97,60 +97,37 @@ public class ClientAdapter implements ClientModel, CachedObject {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ClientTemplateModel getClientTemplate() {
|
||||
if (isUpdated()) return updated.getClientTemplate();
|
||||
if (cached.getClientTemplate() == null) return null;
|
||||
return cacheSession.getClientTemplateById(cached.getClientTemplate(), cachedRealm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClientTemplate(ClientTemplateModel template) {
|
||||
public void addClientScope(ClientScopeModel clientScope, boolean defaultScope) {
|
||||
getDelegateForUpdate();
|
||||
updated.setClientTemplate(template);
|
||||
|
||||
updated.addClientScope(clientScope, defaultScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useTemplateScope() {
|
||||
if (isUpdated()) return updated.useTemplateScope();
|
||||
return cached.isUseTemplateScope();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUseTemplateScope(boolean value) {
|
||||
public void removeClientScope(ClientScopeModel clientScope) {
|
||||
getDelegateForUpdate();
|
||||
updated.setUseTemplateScope(value);
|
||||
|
||||
updated.removeClientScope(clientScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useTemplateConfig() {
|
||||
if (isUpdated()) return updated.useTemplateConfig();
|
||||
return cached.isUseTemplateConfig();
|
||||
public Map<String, ClientScopeModel> getClientScopes(boolean defaultScope, boolean filterByProtocol) {
|
||||
if (isUpdated()) return updated.getClientScopes(defaultScope, filterByProtocol);
|
||||
List<String> clientScopeIds = defaultScope ? cached.getDefaultClientScopesIds() : cached.getOptionalClientScopesIds();
|
||||
|
||||
// Defaults to openid-connect
|
||||
String clientProtocol = getProtocol() == null ? "openid-connect" : getProtocol();
|
||||
|
||||
Map<String, ClientScopeModel> clientScopes = new HashMap<>();
|
||||
for (String scopeId : clientScopeIds) {
|
||||
ClientScopeModel clientScope = cacheSession.getClientScopeById(scopeId, cachedRealm);
|
||||
if (clientScope != null) {
|
||||
if (!filterByProtocol || clientScope.getProtocol().equals(clientProtocol)) {
|
||||
clientScopes.put(clientScope.getName(), clientScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUseTemplateConfig(boolean value) {
|
||||
getDelegateForUpdate();
|
||||
updated.setUseTemplateConfig(value);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useTemplateMappers() {
|
||||
if (isUpdated()) return updated.useTemplateMappers();
|
||||
return cached.isUseTemplateMappers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUseTemplateMappers(boolean value) {
|
||||
getDelegateForUpdate();
|
||||
updated.setUseTemplateMappers(value);
|
||||
|
||||
return clientScopes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void addWebOrigin(String webOrigin) {
|
||||
getDelegateForUpdate();
|
||||
updated.addWebOrigin(webOrigin);
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
package org.keycloak.models.cache.infinispan;
|
||||
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleContainerModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.cache.infinispan.entities.CachedClientTemplate;
|
||||
import org.keycloak.models.cache.infinispan.entities.CachedClientScope;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -34,14 +34,14 @@ import java.util.Set;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class ClientTemplateAdapter implements ClientTemplateModel {
|
||||
public class ClientScopeAdapter implements ClientScopeModel {
|
||||
protected RealmCacheSession cacheSession;
|
||||
protected RealmModel cachedRealm;
|
||||
|
||||
protected ClientTemplateModel updated;
|
||||
protected CachedClientTemplate cached;
|
||||
protected ClientScopeModel updated;
|
||||
protected CachedClientScope cached;
|
||||
|
||||
public ClientTemplateAdapter(RealmModel cachedRealm, CachedClientTemplate cached, RealmCacheSession cacheSession) {
|
||||
public ClientScopeAdapter(RealmModel cachedRealm, CachedClientScope cached, RealmCacheSession cacheSession) {
|
||||
this.cachedRealm = cachedRealm;
|
||||
this.cacheSession = cacheSession;
|
||||
this.cached = cached;
|
||||
|
@ -49,8 +49,8 @@ public class ClientTemplateAdapter implements ClientTemplateModel {
|
|||
|
||||
private void getDelegateForUpdate() {
|
||||
if (updated == null) {
|
||||
cacheSession.registerClientTemplateInvalidation(cached.getId());
|
||||
updated = cacheSession.getRealmDelegate().getClientTemplateById(cached.getId(), cachedRealm);
|
||||
cacheSession.registerClientScopeInvalidation(cached.getId());
|
||||
updated = cacheSession.getRealmDelegate().getClientScopeById(cached.getId(), cachedRealm);
|
||||
if (updated == null) throw new IllegalStateException("Not found in database");
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel {
|
|||
protected boolean isUpdated() {
|
||||
if (updated != null) return true;
|
||||
if (!invalidated) return false;
|
||||
updated = cacheSession.getRealmDelegate().getClientTemplateById(cached.getId(), cachedRealm);
|
||||
updated = cacheSession.getRealmDelegate().getClientScopeById(cached.getId(), cachedRealm);
|
||||
if (updated == null) throw new IllegalStateException("Not found in database");
|
||||
return true;
|
||||
}
|
||||
|
@ -157,19 +157,6 @@ public class ClientTemplateAdapter implements ClientTemplateModel {
|
|||
updated.setProtocol(protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullScopeAllowed() {
|
||||
if (isUpdated()) return updated.isFullScopeAllowed();
|
||||
return cached.isFullScopeAllowed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFullScopeAllowed(boolean value) {
|
||||
getDelegateForUpdate();
|
||||
updated.setFullScopeAllowed(value);
|
||||
|
||||
}
|
||||
|
||||
public Set<RoleModel> getScopeMappings() {
|
||||
if (isUpdated()) return updated.getScopeMappings();
|
||||
Set<RoleModel> roles = new HashSet<RoleModel>();
|
||||
|
@ -209,7 +196,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel {
|
|||
@Override
|
||||
public boolean hasScope(RoleModel role) {
|
||||
if (isUpdated()) return updated.hasScope(role);
|
||||
if (cached.isFullScopeAllowed() || cached.getScope().contains(role.getId())) return true;
|
||||
if (cached.getScope().contains(role.getId())) return true;
|
||||
|
||||
Set<RoleModel> roles = getScopeMappings();
|
||||
|
||||
|
@ -219,25 +206,6 @@ public class ClientTemplateAdapter implements ClientTemplateModel {
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean isPublicClient() {
|
||||
if (isUpdated()) return updated.isPublicClient();
|
||||
return cached.isPublicClient();
|
||||
}
|
||||
|
||||
public void setPublicClient(boolean flag) {
|
||||
getDelegateForUpdate();
|
||||
updated.setPublicClient(flag);
|
||||
}
|
||||
|
||||
public boolean isFrontchannelLogout() {
|
||||
if (isUpdated()) return updated.isPublicClient();
|
||||
return cached.isFrontchannelLogout();
|
||||
}
|
||||
|
||||
public void setFrontchannelLogout(boolean flag) {
|
||||
getDelegateForUpdate();
|
||||
updated.setFrontchannelLogout(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, String value) {
|
||||
|
@ -267,87 +235,13 @@ public class ClientTemplateAdapter implements ClientTemplateModel {
|
|||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBearerOnly() {
|
||||
if (isUpdated()) return updated.isBearerOnly();
|
||||
return cached.isBearerOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBearerOnly(boolean only) {
|
||||
getDelegateForUpdate();
|
||||
updated.setBearerOnly(only);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConsentRequired() {
|
||||
if (isUpdated()) return updated.isConsentRequired();
|
||||
return cached.isConsentRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConsentRequired(boolean consentRequired) {
|
||||
getDelegateForUpdate();
|
||||
updated.setConsentRequired(consentRequired);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStandardFlowEnabled() {
|
||||
if (isUpdated()) return updated.isStandardFlowEnabled();
|
||||
return cached.isStandardFlowEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStandardFlowEnabled(boolean standardFlowEnabled) {
|
||||
getDelegateForUpdate();
|
||||
updated.setStandardFlowEnabled(standardFlowEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImplicitFlowEnabled() {
|
||||
if (isUpdated()) return updated.isImplicitFlowEnabled();
|
||||
return cached.isImplicitFlowEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitFlowEnabled(boolean implicitFlowEnabled) {
|
||||
getDelegateForUpdate();
|
||||
updated.setImplicitFlowEnabled(implicitFlowEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirectAccessGrantsEnabled() {
|
||||
if (isUpdated()) return updated.isDirectAccessGrantsEnabled();
|
||||
return cached.isDirectAccessGrantsEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirectAccessGrantsEnabled(boolean directAccessGrantsEnabled) {
|
||||
getDelegateForUpdate();
|
||||
updated.setDirectAccessGrantsEnabled(directAccessGrantsEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isServiceAccountsEnabled() {
|
||||
if (isUpdated()) return updated.isServiceAccountsEnabled();
|
||||
return cached.isServiceAccountsEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServiceAccountsEnabled(boolean serviceAccountsEnabled) {
|
||||
getDelegateForUpdate();
|
||||
updated.setServiceAccountsEnabled(serviceAccountsEnabled);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || !(o instanceof ClientModel)) return false;
|
||||
|
||||
ClientTemplateModel that = (ClientTemplateModel) o;
|
||||
ClientScopeModel that = (ClientScopeModel) o;
|
||||
return that.getId().equals(getId());
|
||||
}
|
||||
|
|
@ -1287,15 +1287,15 @@ public class RealmAdapter implements CachedRealmModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ClientTemplateModel> getClientTemplates() {
|
||||
if (isUpdated()) return updated.getClientTemplates();
|
||||
List<String> clientTemplates = cached.getClientTemplates();
|
||||
if (clientTemplates.isEmpty()) return Collections.EMPTY_LIST;
|
||||
List<ClientTemplateModel> apps = new LinkedList<ClientTemplateModel>();
|
||||
for (String id : clientTemplates) {
|
||||
ClientTemplateModel model = cacheSession.getClientTemplateById(id, this);
|
||||
public List<ClientScopeModel> getClientScopes() {
|
||||
if (isUpdated()) return updated.getClientScopes();
|
||||
List<String> clientScopes = cached.getClientScopes();
|
||||
if (clientScopes.isEmpty()) return Collections.EMPTY_LIST;
|
||||
List<ClientScopeModel> apps = new LinkedList<ClientScopeModel>();
|
||||
for (String id : clientScopes) {
|
||||
ClientScopeModel model = cacheSession.getClientScopeById(id, this);
|
||||
if (model == null) {
|
||||
throw new IllegalStateException("Cached clientemplate not found: " + id);
|
||||
throw new IllegalStateException("Cached clientScope not found: " + id);
|
||||
}
|
||||
apps.add(model);
|
||||
}
|
||||
|
@ -1304,32 +1304,60 @@ public class RealmAdapter implements CachedRealmModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ClientTemplateModel addClientTemplate(String name) {
|
||||
public ClientScopeModel addClientScope(String name) {
|
||||
getDelegateForUpdate();
|
||||
ClientTemplateModel app = updated.addClientTemplate(name);
|
||||
cacheSession.registerClientTemplateInvalidation(app.getId());
|
||||
ClientScopeModel app = updated.addClientScope(name);
|
||||
cacheSession.registerClientScopeInvalidation(app.getId());
|
||||
return app;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientTemplateModel addClientTemplate(String id, String name) {
|
||||
public ClientScopeModel addClientScope(String id, String name) {
|
||||
getDelegateForUpdate();
|
||||
ClientTemplateModel app = updated.addClientTemplate(id, name);
|
||||
cacheSession.registerClientTemplateInvalidation(app.getId());
|
||||
ClientScopeModel app = updated.addClientScope(id, name);
|
||||
cacheSession.registerClientScopeInvalidation(app.getId());
|
||||
return app;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeClientTemplate(String id) {
|
||||
cacheSession.registerClientTemplateInvalidation(id);
|
||||
public boolean removeClientScope(String id) {
|
||||
cacheSession.registerClientScopeInvalidation(id);
|
||||
getDelegateForUpdate();
|
||||
return updated.removeClientTemplate(id);
|
||||
return updated.removeClientScope(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientTemplateModel getClientTemplateById(String id) {
|
||||
if (isUpdated()) return updated.getClientTemplateById(id);
|
||||
return cacheSession.getClientTemplateById(id, this);
|
||||
public ClientScopeModel getClientScopeById(String id) {
|
||||
if (isUpdated()) return updated.getClientScopeById(id);
|
||||
return cacheSession.getClientScopeById(id, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDefaultClientScope(ClientScopeModel clientScope, boolean defaultScope) {
|
||||
getDelegateForUpdate();
|
||||
updated.addDefaultClientScope(clientScope, defaultScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDefaultClientScope(ClientScopeModel clientScope) {
|
||||
getDelegateForUpdate();
|
||||
updated.removeDefaultClientScope(clientScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClientScopeModel> getDefaultClientScopes(boolean defaultScope) {
|
||||
if (isUpdated()) return updated.getDefaultClientScopes(defaultScope);
|
||||
|
||||
List<String> clientScopeIds = defaultScope ? cached.getDefaultDefaultClientScopes() : cached.getOptionalDefaultClientScopes();
|
||||
|
||||
List<ClientScopeModel> clientScopes = new LinkedList<>();
|
||||
for (String scopeId : clientScopeIds) {
|
||||
ClientScopeModel clientScope = cacheSession.getClientScopeById(scopeId, this);
|
||||
if (clientScope != null) {
|
||||
clientScopes.add(clientScope);
|
||||
}
|
||||
}
|
||||
return clientScopes;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.keycloak.models.cache.CachedRealmModel;
|
|||
import org.keycloak.models.cache.infinispan.entities.*;
|
||||
import org.keycloak.models.cache.infinispan.events.*;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.storage.CacheableStorageProviderModel;
|
||||
import org.keycloak.storage.StorageId;
|
||||
import org.keycloak.storage.client.ClientStorageProviderModel;
|
||||
|
||||
|
@ -105,7 +104,7 @@ public class RealmCacheSession implements CacheRealmProvider {
|
|||
|
||||
protected Map<String, RealmAdapter> managedRealms = new HashMap<>();
|
||||
protected Map<String, ClientModel> managedApplications = new HashMap<>();
|
||||
protected Map<String, ClientTemplateAdapter> managedClientTemplates = new HashMap<>();
|
||||
protected Map<String, ClientScopeAdapter> managedClientScopes = new HashMap<>();
|
||||
protected Map<String, RoleAdapter> managedRoles = new HashMap<>();
|
||||
protected Map<String, GroupAdapter> managedGroups = new HashMap<>();
|
||||
protected Set<String> listInvalidations = new HashSet<>();
|
||||
|
@ -182,16 +181,16 @@ public class RealmCacheSession implements CacheRealmProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void registerClientTemplateInvalidation(String id) {
|
||||
invalidateClientTemplate(id);
|
||||
// Note: Adding/Removing client template is supposed to invalidate CachedRealm as well, so the list of clientTemplates is invalidated.
|
||||
public void registerClientScopeInvalidation(String id) {
|
||||
invalidateClientScope(id);
|
||||
// Note: Adding/Removing client template is supposed to invalidate CachedRealm as well, so the list of clientScopes is invalidated.
|
||||
// But separate RealmUpdatedEvent will be sent for it. So ClientTemplateEvent don't need to take care of it.
|
||||
invalidationEvents.add(ClientTemplateEvent.create(id));
|
||||
}
|
||||
|
||||
private void invalidateClientTemplate(String id) {
|
||||
private void invalidateClientScope(String id) {
|
||||
invalidations.add(id);
|
||||
ClientTemplateAdapter adapter = managedClientTemplates.get(id);
|
||||
ClientScopeAdapter adapter = managedClientScopes.get(id);
|
||||
if (adapter != null) adapter.invalidate();
|
||||
}
|
||||
|
||||
|
@ -218,9 +217,9 @@ public class RealmCacheSession implements CacheRealmProvider {
|
|||
group.invalidate();
|
||||
continue;
|
||||
}
|
||||
ClientTemplateAdapter clientTemplate = managedClientTemplates.get(id);
|
||||
if (clientTemplate != null) {
|
||||
clientTemplate.invalidate();
|
||||
ClientScopeAdapter clientScope = managedClientScopes.get(id);
|
||||
if (clientScope != null) {
|
||||
clientScope.invalidate();
|
||||
continue;
|
||||
}
|
||||
RoleAdapter role = managedRoles.get(id);
|
||||
|
@ -1134,26 +1133,26 @@ public class RealmCacheSession implements CacheRealmProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ClientTemplateModel getClientTemplateById(String id, RealmModel realm) {
|
||||
CachedClientTemplate cached = cache.get(id, CachedClientTemplate.class);
|
||||
public ClientScopeModel getClientScopeById(String id, RealmModel realm) {
|
||||
CachedClientScope cached = cache.get(id, CachedClientScope.class);
|
||||
if (cached != null && !cached.getRealm().equals(realm.getId())) {
|
||||
cached = null;
|
||||
}
|
||||
|
||||
if (cached == null) {
|
||||
Long loaded = cache.getCurrentRevision(id);
|
||||
ClientTemplateModel model = getRealmDelegate().getClientTemplateById(id, realm);
|
||||
ClientScopeModel model = getRealmDelegate().getClientScopeById(id, realm);
|
||||
if (model == null) return null;
|
||||
if (invalidations.contains(id)) return model;
|
||||
cached = new CachedClientTemplate(loaded, realm, model);
|
||||
cached = new CachedClientScope(loaded, realm, model);
|
||||
cache.addRevisioned(cached, startupRevision);
|
||||
} else if (invalidations.contains(id)) {
|
||||
return getRealmDelegate().getClientTemplateById(id, realm);
|
||||
} else if (managedClientTemplates.containsKey(id)) {
|
||||
return managedClientTemplates.get(id);
|
||||
return getRealmDelegate().getClientScopeById(id, realm);
|
||||
} else if (managedClientScopes.containsKey(id)) {
|
||||
return managedClientScopes.get(id);
|
||||
}
|
||||
ClientTemplateAdapter adapter = new ClientTemplateAdapter(realm, cached, this);
|
||||
managedClientTemplates.put(id, adapter);
|
||||
ClientScopeAdapter adapter = new ClientScopeAdapter(realm, cached, this);
|
||||
managedClientScopes.put(id, adapter);
|
||||
return adapter;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,18 +88,6 @@ public class RoleAdapter implements RoleModel {
|
|||
updated.setDescription(description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isScopeParamRequired() {
|
||||
if (isUpdated()) return updated.isScopeParamRequired();
|
||||
return cached.isScopeParamRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScopeParamRequired(boolean scopeParamRequired) {
|
||||
getDelegateForUpdate();
|
||||
updated.setScopeParamRequired(scopeParamRequired);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
if (isUpdated()) return updated.getId();
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.models.cache.infinispan;
|
|||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.cluster.ClusterProvider;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.cache.CachedObject;
|
||||
import org.keycloak.models.cache.infinispan.events.InvalidationEvent;
|
||||
import org.keycloak.common.constants.ServiceAccountConstants;
|
||||
|
@ -49,6 +50,7 @@ import org.keycloak.models.cache.infinispan.events.UserFederationLinkRemovedEven
|
|||
import org.keycloak.models.cache.infinispan.events.UserFederationLinkUpdatedEvent;
|
||||
import org.keycloak.models.cache.infinispan.events.UserFullInvalidationEvent;
|
||||
import org.keycloak.models.cache.infinispan.events.UserUpdatedEvent;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.models.utils.ReadOnlyUserModelDelegate;
|
||||
import org.keycloak.storage.CacheableStorageProviderModel;
|
||||
import org.keycloak.storage.StorageId;
|
||||
|
@ -715,15 +717,13 @@ public class UserCacheSession implements UserCache {
|
|||
consentModel.setCreatedDate(cachedConsent.getCreatedDate());
|
||||
consentModel.setLastUpdatedDate(cachedConsent.getLastUpdatedDate());
|
||||
|
||||
for (String roleId : cachedConsent.getRoleIds()) {
|
||||
RoleModel role = session.realms().getRoleById(roleId, realm);
|
||||
if (role != null) {
|
||||
consentModel.addGrantedRole(role);
|
||||
for (String clientScopeId : cachedConsent.getClientScopeIds()) {
|
||||
ClientScopeModel clientScope = KeycloakModelUtils.findClientScopeById(realm, clientScopeId);
|
||||
if (clientScope != null) {
|
||||
consentModel.addGrantedClientScope(clientScope);
|
||||
}
|
||||
}
|
||||
for (ProtocolMapperModel protocolMapper : cachedConsent.getProtocolMappers()) {
|
||||
consentModel.addGrantedProtocolMapper(protocolMapper);
|
||||
}
|
||||
|
||||
return consentModel;
|
||||
}
|
||||
|
||||
|
@ -852,6 +852,12 @@ public class UserCacheSession implements UserCache {
|
|||
getDelegate().preRemove(protocolMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preRemove(ClientScopeModel clientScope) {
|
||||
// Not needed to invalidate realm probably. Just consents are affected ATM and they are checked if they exists
|
||||
getDelegate().preRemove(clientScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preRemove(RealmModel realm, ComponentModel component) {
|
||||
if (!component.getProviderType().equals(UserStorageProvider.class.getName()) && !component.getProviderType().equals(ClientStorageProvider.class.getName())) return;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package org.keycloak.models.cache.infinispan.entities;
|
||||
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
|
@ -67,10 +68,8 @@ public class CachedClient extends AbstractRevisioned implements InRealm {
|
|||
protected boolean serviceAccountsEnabled;
|
||||
protected int nodeReRegistrationTimeout;
|
||||
protected Map<String, Integer> registeredNodes;
|
||||
protected String clientTemplate;
|
||||
protected boolean useTemplateScope;
|
||||
protected boolean useTemplateConfig;
|
||||
protected boolean useTemplateMappers;
|
||||
protected List<String> defaultClientScopesIds;
|
||||
protected List<String> optionalClientScopesIds;
|
||||
|
||||
public CachedClient(Long revision, RealmModel realm, ClientModel model) {
|
||||
super(revision, model.getId());
|
||||
|
@ -111,12 +110,15 @@ public class CachedClient extends AbstractRevisioned implements InRealm {
|
|||
|
||||
nodeReRegistrationTimeout = model.getNodeReRegistrationTimeout();
|
||||
registeredNodes = new TreeMap<>(model.getRegisteredNodes());
|
||||
if (model.getClientTemplate() != null) {
|
||||
clientTemplate = model.getClientTemplate().getId();
|
||||
|
||||
defaultClientScopesIds = new LinkedList<>();
|
||||
for (ClientScopeModel clientScope : model.getClientScopes(true, false).values()) {
|
||||
defaultClientScopesIds.add(clientScope.getId());
|
||||
}
|
||||
optionalClientScopesIds = new LinkedList<>();
|
||||
for (ClientScopeModel clientScope : model.getClientScopes(false, false).values()) {
|
||||
optionalClientScopesIds.add(clientScope.getId());
|
||||
}
|
||||
useTemplateConfig = model.useTemplateConfig();
|
||||
useTemplateMappers = model.useTemplateMappers();
|
||||
useTemplateScope = model.useTemplateScope();
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
|
@ -243,20 +245,12 @@ public class CachedClient extends AbstractRevisioned implements InRealm {
|
|||
return registeredNodes;
|
||||
}
|
||||
|
||||
public String getClientTemplate() {
|
||||
return clientTemplate;
|
||||
public List<String> getDefaultClientScopesIds() {
|
||||
return defaultClientScopesIds;
|
||||
}
|
||||
|
||||
public boolean isUseTemplateScope() {
|
||||
return useTemplateScope;
|
||||
}
|
||||
|
||||
public boolean isUseTemplateConfig() {
|
||||
return useTemplateConfig;
|
||||
}
|
||||
|
||||
public boolean isUseTemplateMappers() {
|
||||
return useTemplateMappers;
|
||||
public List<String> getOptionalClientScopesIds() {
|
||||
return optionalClientScopesIds;
|
||||
}
|
||||
|
||||
public Map<String, String> getAuthFlowBindings() {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
package org.keycloak.models.cache.infinispan.entities;
|
||||
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
|
@ -31,32 +31,22 @@ import java.util.Set;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class CachedClientTemplate extends AbstractRevisioned implements InRealm {
|
||||
public class CachedClientScope extends AbstractRevisioned implements InRealm {
|
||||
|
||||
private String name;
|
||||
private String description;
|
||||
private String realm;
|
||||
private String protocol;
|
||||
private boolean fullScopeAllowed;
|
||||
private boolean publicClient;
|
||||
private boolean frontchannelLogout;
|
||||
private boolean bearerOnly;
|
||||
private boolean consentRequired;
|
||||
private boolean standardFlowEnabled;
|
||||
private boolean implicitFlowEnabled;
|
||||
private boolean directAccessGrantsEnabled;
|
||||
private boolean serviceAccountsEnabled;
|
||||
private Set<String> scope = new HashSet<>();
|
||||
private Set<ProtocolMapperModel> protocolMappers = new HashSet<ProtocolMapperModel>();
|
||||
private Map<String, String> attributes = new HashMap<>();
|
||||
|
||||
public CachedClientTemplate(Long revision, RealmModel realm, ClientTemplateModel model) {
|
||||
public CachedClientScope(Long revision, RealmModel realm, ClientScopeModel model) {
|
||||
super(revision, model.getId());
|
||||
name = model.getName();
|
||||
description = model.getDescription();
|
||||
this.realm = realm.getId();
|
||||
protocol = model.getProtocol();
|
||||
fullScopeAllowed = model.isFullScopeAllowed();
|
||||
for (ProtocolMapperModel mapper : model.getProtocolMappers()) {
|
||||
this.protocolMappers.add(mapper);
|
||||
}
|
||||
|
@ -64,14 +54,6 @@ public class CachedClientTemplate extends AbstractRevisioned implements InRealm
|
|||
scope.add(role.getId());
|
||||
}
|
||||
attributes.putAll(model.getAttributes());
|
||||
frontchannelLogout = model.isFrontchannelLogout();
|
||||
publicClient = model.isPublicClient();
|
||||
bearerOnly = model.isBearerOnly();
|
||||
consentRequired = model.isConsentRequired();
|
||||
standardFlowEnabled = model.isStandardFlowEnabled();
|
||||
implicitFlowEnabled = model.isImplicitFlowEnabled();
|
||||
directAccessGrantsEnabled = model.isDirectAccessGrantsEnabled();
|
||||
serviceAccountsEnabled = model.isServiceAccountsEnabled();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
@ -93,46 +75,10 @@ public class CachedClientTemplate extends AbstractRevisioned implements InRealm
|
|||
return protocol;
|
||||
}
|
||||
|
||||
public boolean isFullScopeAllowed() {
|
||||
return fullScopeAllowed;
|
||||
}
|
||||
|
||||
public Set<String> getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public boolean isPublicClient() {
|
||||
return publicClient;
|
||||
}
|
||||
|
||||
public boolean isFrontchannelLogout() {
|
||||
return frontchannelLogout;
|
||||
}
|
||||
|
||||
public boolean isBearerOnly() {
|
||||
return bearerOnly;
|
||||
}
|
||||
|
||||
public boolean isConsentRequired() {
|
||||
return consentRequired;
|
||||
}
|
||||
|
||||
public boolean isStandardFlowEnabled() {
|
||||
return standardFlowEnabled;
|
||||
}
|
||||
|
||||
public boolean isImplicitFlowEnabled() {
|
||||
return implicitFlowEnabled;
|
||||
}
|
||||
|
||||
public boolean isDirectAccessGrantsEnabled() {
|
||||
return directAccessGrantsEnabled;
|
||||
}
|
||||
|
||||
public boolean isServiceAccountsEnabled() {
|
||||
return serviceAccountsEnabled;
|
||||
}
|
||||
|
||||
public Map<String, String> getAttributes() {
|
||||
return attributes;
|
||||
}
|
|
@ -24,7 +24,7 @@ import org.keycloak.models.AuthenticationExecutionModel;
|
|||
import org.keycloak.models.AuthenticationFlowModel;
|
||||
import org.keycloak.models.AuthenticatorConfigModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.IdentityProviderMapperModel;
|
||||
import org.keycloak.models.IdentityProviderModel;
|
||||
|
@ -135,7 +135,9 @@ public class CachedRealm extends AbstractExtendableRevisioned {
|
|||
}
|
||||
|
||||
protected List<String> defaultGroups = new LinkedList<String>();
|
||||
protected List<String> clientTemplates= new LinkedList<>();
|
||||
protected List<String> clientScopes = new LinkedList<>();
|
||||
protected List<String> defaultDefaultClientScopes = new LinkedList<>();
|
||||
protected List<String> optionalDefaultClientScopes = new LinkedList<>();
|
||||
protected boolean internationalizationEnabled;
|
||||
protected Set<String> supportedLocales;
|
||||
protected String defaultLocale;
|
||||
|
@ -227,7 +229,7 @@ public class CachedRealm extends AbstractExtendableRevisioned {
|
|||
ClientModel masterAdminClient = model.getMasterAdminClient();
|
||||
this.masterAdminClient = (masterAdminClient != null) ? masterAdminClient.getId() : null;
|
||||
|
||||
cacheClientTemplates(model);
|
||||
cacheClientScopes(model);
|
||||
|
||||
internationalizationEnabled = model.isInternationalizationEnabled();
|
||||
supportedLocales = model.getSupportedLocales();
|
||||
|
@ -279,9 +281,15 @@ public class CachedRealm extends AbstractExtendableRevisioned {
|
|||
|
||||
}
|
||||
|
||||
protected void cacheClientTemplates(RealmModel model) {
|
||||
for (ClientTemplateModel template : model.getClientTemplates()) {
|
||||
clientTemplates.add(template.getId());
|
||||
protected void cacheClientScopes(RealmModel model) {
|
||||
for (ClientScopeModel clientScope : model.getClientScopes()) {
|
||||
clientScopes.add(clientScope.getId());
|
||||
}
|
||||
for (ClientScopeModel clientScope : model.getDefaultClientScopes(true)) {
|
||||
defaultDefaultClientScopes.add(clientScope.getId());
|
||||
}
|
||||
for (ClientScopeModel clientScope : model.getDefaultClientScopes(false)) {
|
||||
optionalDefaultClientScopes.add(clientScope.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -585,8 +593,16 @@ public class CachedRealm extends AbstractExtendableRevisioned {
|
|||
return defaultGroups;
|
||||
}
|
||||
|
||||
public List<String> getClientTemplates() {
|
||||
return clientTemplates;
|
||||
public List<String> getClientScopes() {
|
||||
return clientScopes;
|
||||
}
|
||||
|
||||
public List<String> getDefaultDefaultClientScopes() {
|
||||
return defaultDefaultClientScopes;
|
||||
}
|
||||
|
||||
public List<String> getOptionalDefaultClientScopes() {
|
||||
return optionalDefaultClientScopes;
|
||||
}
|
||||
|
||||
public List<AuthenticationFlowModel> getAuthenticationFlowList() {
|
||||
|
|
|
@ -32,7 +32,6 @@ public class CachedRole extends AbstractRevisioned implements InRealm {
|
|||
final protected String name;
|
||||
final protected String realm;
|
||||
final protected String description;
|
||||
final protected Boolean scopeParamRequired;
|
||||
final protected boolean composite;
|
||||
final protected Set<String> composites = new HashSet<String>();
|
||||
|
||||
|
@ -41,7 +40,6 @@ public class CachedRole extends AbstractRevisioned implements InRealm {
|
|||
composite = model.isComposite();
|
||||
description = model.getDescription();
|
||||
name = model.getName();
|
||||
scopeParamRequired = model.isScopeParamRequired();
|
||||
this.realm = realm.getId();
|
||||
if (composite) {
|
||||
for (RoleModel child : model.getComposites()) {
|
||||
|
@ -63,10 +61,6 @@ public class CachedRole extends AbstractRevisioned implements InRealm {
|
|||
return description;
|
||||
}
|
||||
|
||||
public Boolean isScopeParamRequired() {
|
||||
return scopeParamRequired;
|
||||
}
|
||||
|
||||
public boolean isComposite() {
|
||||
return composite;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.keycloak.models.cache.infinispan.entities;
|
||||
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserConsentModel;
|
||||
|
@ -30,16 +31,14 @@ import java.util.Set;
|
|||
public class CachedUserConsent {
|
||||
|
||||
private final String clientDbId;
|
||||
private final Set<ProtocolMapperModel> protocolMappers = new HashSet<>();
|
||||
private final Set<String> roleIds = new HashSet<>();
|
||||
private final Set<String> clientScopeIds = new HashSet<>();
|
||||
private final Long createdDate;
|
||||
private final Long lastUpdatedDate;
|
||||
|
||||
public CachedUserConsent(UserConsentModel consentModel) {
|
||||
this.clientDbId = consentModel.getClient().getId();
|
||||
this.protocolMappers.addAll(consentModel.getGrantedProtocolMappers());
|
||||
for (RoleModel role : consentModel.getGrantedRoles()) {
|
||||
this.roleIds.add(role.getId());
|
||||
for (ClientScopeModel clientScope : consentModel.getGrantedClientScopes()) {
|
||||
this.clientScopeIds.add(clientScope.getId());
|
||||
}
|
||||
this.createdDate = consentModel.getCreatedDate();
|
||||
this.lastUpdatedDate = consentModel.getLastUpdatedDate();
|
||||
|
@ -49,12 +48,8 @@ public class CachedUserConsent {
|
|||
return clientDbId;
|
||||
}
|
||||
|
||||
public Set<ProtocolMapperModel> getProtocolMappers() {
|
||||
return protocolMappers;
|
||||
}
|
||||
|
||||
public Set<String> getRoleIds() {
|
||||
return roleIds;
|
||||
public Set<String> getClientScopeIds() {
|
||||
return clientScopeIds;
|
||||
}
|
||||
|
||||
public Long getCreatedDate() {
|
||||
|
|
|
@ -28,6 +28,9 @@ import org.infinispan.commons.marshall.MarshallUtil;
|
|||
import org.infinispan.commons.marshall.SerializeWith;
|
||||
|
||||
/**
|
||||
* TODO Leave the name ClientTemplateEvent just due the backwards compatibility of infinispan migration. See if can be renamed based on
|
||||
* rolling upgrades plan...
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@SerializeWith(ClientTemplateEvent.ExternalizerImpl.class)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.keycloak.models.cache.infinispan.stream;
|
||||
|
||||
import org.keycloak.models.cache.infinispan.entities.CachedClient;
|
||||
import org.keycloak.models.cache.infinispan.entities.CachedClientTemplate;
|
||||
import org.keycloak.models.cache.infinispan.entities.CachedClientScope;
|
||||
import org.keycloak.models.cache.infinispan.entities.CachedGroup;
|
||||
import org.keycloak.models.cache.infinispan.entities.CachedRole;
|
||||
import org.keycloak.models.cache.infinispan.entities.Revisioned;
|
||||
|
@ -55,9 +55,9 @@ public class HasRolePredicate implements Predicate<Map.Entry<String, Revisioned>
|
|||
if (cachedClient.getScope().contains(role)) return true;
|
||||
|
||||
}
|
||||
if (value instanceof CachedClientTemplate) {
|
||||
CachedClientTemplate cachedClientTemplate = (CachedClientTemplate)value;
|
||||
if (cachedClientTemplate.getScope().contains(role)) return true;
|
||||
if (value instanceof CachedClientScope) {
|
||||
CachedClientScope cachedClientScope = (CachedClientScope)value;
|
||||
if (cachedClientScope.getScope().contains(role)) return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -238,44 +238,6 @@ public class AuthenticatedClientSessionAdapter implements AuthenticatedClientSes
|
|||
update(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRoles() {
|
||||
return entity.getRoles();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRoles(Set<String> roles) {
|
||||
ClientSessionUpdateTask task = new ClientSessionUpdateTask() {
|
||||
|
||||
@Override
|
||||
public void runUpdate(AuthenticatedClientSessionEntity entity) {
|
||||
entity.setRoles(roles); // TODO not thread-safe. But we will remove setRoles anyway...?
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
update(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getProtocolMappers() {
|
||||
return entity.getProtocolMappers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProtocolMappers(Set<String> protocolMappers) {
|
||||
ClientSessionUpdateTask task = new ClientSessionUpdateTask() {
|
||||
|
||||
@Override
|
||||
public void runUpdate(AuthenticatedClientSessionEntity entity) {
|
||||
entity.setProtocolMappers(protocolMappers); // TODO not thread-safe. But we will remove setProtocolMappers anyway...?
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
update(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNote(String name) {
|
||||
return entity.getNotes().get(name);
|
||||
|
|
|
@ -99,26 +99,14 @@ public class AuthenticationSessionAdapter implements AuthenticationSessionModel
|
|||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRoles() {
|
||||
if (entity.getRoles() == null || entity.getRoles().isEmpty()) return Collections.emptySet();
|
||||
return new HashSet<>(entity.getRoles());
|
||||
public Set<String> getClientScopes() {
|
||||
if (entity.getClientScopes() == null || entity.getClientScopes().isEmpty()) return Collections.emptySet();
|
||||
return new HashSet<>(entity.getClientScopes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRoles(Set<String> roles) {
|
||||
entity.setRoles(roles);
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getProtocolMappers() {
|
||||
if (entity.getProtocolMappers() == null || entity.getProtocolMappers().isEmpty()) return Collections.emptySet();
|
||||
return new HashSet<>(entity.getProtocolMappers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProtocolMappers(Set<String> protocolMappers) {
|
||||
entity.setProtocolMappers(protocolMappers);
|
||||
public void setClientScopes(Set<String> clientScopes) {
|
||||
entity.setClientScopes(clientScopes);
|
||||
update();
|
||||
}
|
||||
|
||||
|
|
|
@ -925,9 +925,7 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
|
|||
entity.setAuthMethod(clientSession.getProtocol());
|
||||
|
||||
entity.setNotes(clientSession.getNotes() == null ? new ConcurrentHashMap<>() : clientSession.getNotes());
|
||||
entity.setProtocolMappers(clientSession.getProtocolMappers());
|
||||
entity.setRedirectUri(clientSession.getRedirectUri());
|
||||
entity.setRoles(clientSession.getRoles());
|
||||
entity.setTimestamp(clientSession.getTimestamp());
|
||||
|
||||
SessionUpdateTask<AuthenticatedClientSessionEntity> createClientSessionTask = Tasks.addIfAbsentSync();
|
||||
|
|
|
@ -41,7 +41,6 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.io.IOException;
|
|||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.infinispan.commons.marshall.Externalizer;
|
||||
|
@ -49,8 +48,6 @@ public class AuthenticatedClientSessionEntity extends SessionEntity {
|
|||
private volatile int timestamp;
|
||||
private String action;
|
||||
|
||||
private Set<String> roles;
|
||||
private Set<String> protocolMappers;
|
||||
private Map<String, String> notes = new ConcurrentHashMap<>();
|
||||
|
||||
private String currentRefreshToken;
|
||||
|
@ -94,22 +91,6 @@ public class AuthenticatedClientSessionEntity extends SessionEntity {
|
|||
this.action = action;
|
||||
}
|
||||
|
||||
public Set<String> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setRoles(Set<String> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
public Set<String> getProtocolMappers() {
|
||||
return protocolMappers;
|
||||
}
|
||||
|
||||
public void setProtocolMappers(Set<String> protocolMappers) {
|
||||
this.protocolMappers = protocolMappers;
|
||||
}
|
||||
|
||||
public Map<String, String> getNotes() {
|
||||
return notes;
|
||||
}
|
||||
|
@ -199,9 +180,6 @@ public class AuthenticatedClientSessionEntity extends SessionEntity {
|
|||
Map<String, String> notes = session.getNotes();
|
||||
KeycloakMarshallUtil.writeMap(notes, KeycloakMarshallUtil.STRING_EXT, KeycloakMarshallUtil.STRING_EXT, output);
|
||||
|
||||
KeycloakMarshallUtil.writeCollection(session.getProtocolMappers(), KeycloakMarshallUtil.STRING_EXT, output);
|
||||
KeycloakMarshallUtil.writeCollection(session.getRoles(), KeycloakMarshallUtil.STRING_EXT, output);
|
||||
|
||||
MarshallUtil.marshallString(session.getCurrentRefreshToken(), output);
|
||||
MarshallUtil.marshallInt(output, session.getCurrentRefreshTokenUseCount());
|
||||
}
|
||||
|
@ -222,12 +200,6 @@ public class AuthenticatedClientSessionEntity extends SessionEntity {
|
|||
new KeycloakMarshallUtil.ConcurrentHashMapBuilder<>());
|
||||
sessionEntity.setNotes(notes);
|
||||
|
||||
Set<String> protocolMappers = KeycloakMarshallUtil.readCollection(input, KeycloakMarshallUtil.STRING_EXT, new KeycloakMarshallUtil.HashSetBuilder<>());
|
||||
sessionEntity.setProtocolMappers(protocolMappers);
|
||||
|
||||
Set<String> roles = KeycloakMarshallUtil.readCollection(input, KeycloakMarshallUtil.STRING_EXT, new KeycloakMarshallUtil.HashSetBuilder<>());
|
||||
sessionEntity.setRoles(roles);
|
||||
|
||||
sessionEntity.setCurrentRefreshToken(MarshallUtil.unmarshallString(input));
|
||||
sessionEntity.setCurrentRefreshTokenUseCount(MarshallUtil.unmarshallInt(input));
|
||||
|
||||
|
|
|
@ -45,8 +45,7 @@ public class AuthenticationSessionEntity implements Serializable {
|
|||
|
||||
private String redirectUri;
|
||||
private String action;
|
||||
private Set<String> roles;
|
||||
private Set<String> protocolMappers;
|
||||
private Set<String> clientScopes;
|
||||
|
||||
private Map<String, AuthenticationSessionModel.ExecutionStatus> executionStatus = new ConcurrentHashMap<>();
|
||||
private String protocol;
|
||||
|
@ -62,7 +61,7 @@ public class AuthenticationSessionEntity implements Serializable {
|
|||
public AuthenticationSessionEntity(
|
||||
String clientUUID,
|
||||
String authUserId,
|
||||
String redirectUri, String action, Set<String> roles, Set<String> protocolMappers,
|
||||
String redirectUri, String action, Set<String> clientScopes,
|
||||
Map<String, AuthenticationSessionModel.ExecutionStatus> executionStatus, String protocol,
|
||||
Map<String, String> clientNotes, Map<String, String> authNotes, Set<String> requiredActions, Map<String, String> userSessionNotes) {
|
||||
this.clientUUID = clientUUID;
|
||||
|
@ -71,8 +70,7 @@ public class AuthenticationSessionEntity implements Serializable {
|
|||
|
||||
this.redirectUri = redirectUri;
|
||||
this.action = action;
|
||||
this.roles = roles;
|
||||
this.protocolMappers = protocolMappers;
|
||||
this.clientScopes = clientScopes;
|
||||
|
||||
this.executionStatus = executionStatus;
|
||||
this.protocol = protocol;
|
||||
|
@ -115,20 +113,12 @@ public class AuthenticationSessionEntity implements Serializable {
|
|||
this.action = action;
|
||||
}
|
||||
|
||||
public Set<String> getRoles() {
|
||||
return roles;
|
||||
public Set<String> getClientScopes() {
|
||||
return clientScopes;
|
||||
}
|
||||
|
||||
public void setRoles(Set<String> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
public Set<String> getProtocolMappers() {
|
||||
return protocolMappers;
|
||||
}
|
||||
|
||||
public void setProtocolMappers(Set<String> protocolMappers) {
|
||||
this.protocolMappers = protocolMappers;
|
||||
public void setClientScopes(Set<String> clientScopes) {
|
||||
this.clientScopes = clientScopes;
|
||||
}
|
||||
|
||||
public Map<String, AuthenticationSessionModel.ExecutionStatus> getExecutionStatus() {
|
||||
|
@ -215,8 +205,7 @@ public class AuthenticationSessionEntity implements Serializable {
|
|||
|
||||
MarshallUtil.marshallString(value.redirectUri, output);
|
||||
MarshallUtil.marshallString(value.action, output);
|
||||
KeycloakMarshallUtil.writeCollection(value.roles, KeycloakMarshallUtil.STRING_EXT, output);
|
||||
KeycloakMarshallUtil.writeCollection(value.protocolMappers, KeycloakMarshallUtil.STRING_EXT, output);
|
||||
KeycloakMarshallUtil.writeCollection(value.clientScopes, KeycloakMarshallUtil.STRING_EXT, output);
|
||||
|
||||
KeycloakMarshallUtil.writeMap(value.executionStatus, KeycloakMarshallUtil.STRING_EXT, EXECUTION_STATUS_EXT, output);
|
||||
MarshallUtil.marshallString(value.protocol, output);
|
||||
|
@ -245,8 +234,7 @@ public class AuthenticationSessionEntity implements Serializable {
|
|||
|
||||
MarshallUtil.unmarshallString(input), // redirectUri
|
||||
MarshallUtil.unmarshallString(input), // action
|
||||
KeycloakMarshallUtil.readCollection(input, KeycloakMarshallUtil.STRING_EXT, size -> new ConcurrentHashSet<>()), // roles
|
||||
KeycloakMarshallUtil.readCollection(input, KeycloakMarshallUtil.STRING_EXT, size -> new ConcurrentHashSet<>()), // protocolMappers
|
||||
KeycloakMarshallUtil.readCollection(input, KeycloakMarshallUtil.STRING_EXT, size -> new ConcurrentHashSet<>()), // clientScopes
|
||||
|
||||
KeycloakMarshallUtil.readMap(input, KeycloakMarshallUtil.STRING_EXT, EXECUTION_STATUS_EXT, size -> new ConcurrentHashMap<>(size)), // executionStatus
|
||||
MarshallUtil.unmarshallString(input), // protocol
|
||||
|
|
|
@ -178,8 +178,6 @@ public class ConcurrencyJDGRemoveSessionTest {
|
|||
clientSession.setAuthMethod("saml");
|
||||
clientSession.setAction("something");
|
||||
clientSession.setTimestamp(1234);
|
||||
clientSession.setProtocolMappers(new HashSet<>(Arrays.asList("mapper1", "mapper2")));
|
||||
clientSession.setRoles(new HashSet<>(Arrays.asList("role1", "role2")));
|
||||
session.getAuthenticatedClientSessions().put(CLIENT_1_UUID.toString(), clientSession.getId());
|
||||
|
||||
SessionEntityWrapper<UserSessionEntity> wrappedSession = new SessionEntityWrapper<>(session);
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
package org.keycloak.cluster.infinispan;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
@ -97,8 +95,6 @@ public class ConcurrencyJDGSessionsCacheTest {
|
|||
clientSession.setAuthMethod("saml");
|
||||
clientSession.setAction("something");
|
||||
clientSession.setTimestamp(1234);
|
||||
clientSession.setProtocolMappers(new HashSet<>(Arrays.asList("mapper1", "mapper2")));
|
||||
clientSession.setRoles(new HashSet<>(Arrays.asList("role1", "role2")));
|
||||
session.getAuthenticatedClientSessions().put(CLIENT_1_UUID.toString(), clientSession.getId());
|
||||
|
||||
SessionEntityWrapper<UserSessionEntity> wrappedSession = new SessionEntityWrapper<>(session);
|
||||
|
|
|
@ -75,8 +75,6 @@ public class DistributedCacheConcurrentWritesTest {
|
|||
clientSession.setAuthMethod("saml");
|
||||
clientSession.setAction("something");
|
||||
clientSession.setTimestamp(1234);
|
||||
clientSession.setProtocolMappers(new HashSet<>(Arrays.asList("mapper1", "mapper2")));
|
||||
clientSession.setRoles(new HashSet<>(Arrays.asList("role1", "role2")));
|
||||
session.getAuthenticatedClientSessions().put(CLIENT_1_UUID.toString(), clientSession.getId());
|
||||
|
||||
cache1.put("123", session);
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
|
||||
package org.keycloak.models.sessions.infinispan.initializer;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
|
@ -75,8 +73,6 @@ public class DistributedCacheWriteSkewTest {
|
|||
clientSession.setAuthMethod("saml");
|
||||
clientSession.setAction("something");
|
||||
clientSession.setTimestamp(1234);
|
||||
clientSession.setProtocolMappers(new HashSet<>(Arrays.asList("mapper1", "mapper2")));
|
||||
clientSession.setRoles(new HashSet<>(Arrays.asList("role1", "role2")));
|
||||
session.getAuthenticatedClientSessions().put(CLIENT_1_UUID.toString(), clientSession.getId());
|
||||
|
||||
cache1.put("123", session);
|
||||
|
|
|
@ -327,8 +327,7 @@ public class JpaUpdate1_2_0_Beta1 extends CustomKeycloakTask {
|
|||
.addColumnValue("ID", mapperId)
|
||||
.addColumnValue("PROTOCOL", protocolMapper.getProtocol())
|
||||
.addColumnValue("NAME", protocolMapper.getName())
|
||||
.addColumnValue("CONSENT_REQUIRED", protocolMapper.isConsentRequired())
|
||||
.addColumnValue("CONSENT_TEXT", protocolMapper.getConsentText())
|
||||
.addColumnValue("CONSENT_REQUIRED", false)
|
||||
.addColumnValue("PROTOCOL_MAPPER_NAME", protocolMapper.getProtocolMapper())
|
||||
.addColumnValue("CLIENT_ID", resultSet.getString("ID"));
|
||||
statements.add(insert);
|
||||
|
|
|
@ -18,20 +18,27 @@
|
|||
package org.keycloak.models.jpa;
|
||||
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ModelDuplicateException;
|
||||
import org.keycloak.models.ModelException;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleContainerModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.jpa.entities.ClientEntity;
|
||||
import org.keycloak.models.jpa.entities.ClientTemplateEntity;
|
||||
import org.keycloak.models.jpa.entities.ClientScopeClientMappingEntity;
|
||||
import org.keycloak.models.jpa.entities.ClientScopeEntity;
|
||||
import org.keycloak.models.jpa.entities.ClientScopeRoleMappingEntity;
|
||||
import org.keycloak.models.jpa.entities.ProtocolMapperEntity;
|
||||
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -317,56 +324,48 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ClientTemplateModel getClientTemplate() {
|
||||
ClientTemplateEntity templateEntity = entity.getClientTemplate();
|
||||
if (templateEntity == null) return null;
|
||||
return session.realms().getClientTemplateById(templateEntity.getId(), realm);
|
||||
public void addClientScope(ClientScopeModel clientScope, boolean defaultScope) {
|
||||
if (getClientScopes(defaultScope, false).containsKey(clientScope.getName())) return;
|
||||
|
||||
ClientScopeClientMappingEntity entity = new ClientScopeClientMappingEntity();
|
||||
entity.setClientScope(ClientScopeAdapter.toClientScopeEntity(clientScope, em));
|
||||
entity.setClient(getEntity());
|
||||
entity.setDefaultScope(defaultScope);
|
||||
em.persist(entity);
|
||||
em.flush();
|
||||
em.detach(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClientTemplate(ClientTemplateModel template) {
|
||||
if (template == null) {
|
||||
entity.setClientTemplate(null);
|
||||
|
||||
} else {
|
||||
ClientTemplateEntity templateEntity = em.getReference(ClientTemplateEntity.class, template.getId());
|
||||
entity.setClientTemplate(templateEntity);
|
||||
}
|
||||
|
||||
public void removeClientScope(ClientScopeModel clientScope) {
|
||||
int numRemoved = em.createNamedQuery("deleteClientScopeClientMapping")
|
||||
.setParameter("clientScope", ClientScopeAdapter.toClientScopeEntity(clientScope, em))
|
||||
.setParameter("client", getEntity())
|
||||
.executeUpdate();
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useTemplateScope() {
|
||||
return entity.isUseTemplateScope();
|
||||
public Map<String, ClientScopeModel> getClientScopes(boolean defaultScope, boolean filterByProtocol) {
|
||||
TypedQuery<String> query = em.createNamedQuery("clientScopeClientMappingIdsByClient", String.class);
|
||||
query.setParameter("client", getEntity());
|
||||
query.setParameter("defaultScope", defaultScope);
|
||||
List<String> ids = query.getResultList();
|
||||
|
||||
// Defaults to openid-connect
|
||||
String clientProtocol = getProtocol() == null ? OIDCLoginProtocol.LOGIN_PROTOCOL : getProtocol();
|
||||
|
||||
Map<String, ClientScopeModel> clientScopes = new HashMap<>();
|
||||
for (String clientScopeId : ids) {
|
||||
ClientScopeModel clientScope = realm.getClientScopeById(clientScopeId);
|
||||
if (clientScope == null) continue;
|
||||
if (!filterByProtocol || clientScope.getProtocol().equals(clientProtocol)) {
|
||||
clientScopes.put(clientScope.getName(), clientScope);
|
||||
}
|
||||
}
|
||||
return clientScopes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUseTemplateScope(boolean flag) {
|
||||
entity.setUseTemplateScope(flag);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useTemplateMappers() {
|
||||
return entity.isUseTemplateMappers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUseTemplateMappers(boolean flag) {
|
||||
entity.setUseTemplateMappers(flag);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useTemplateConfig() {
|
||||
return entity.isUseTemplateConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUseTemplateConfig(boolean flag) {
|
||||
entity.setUseTemplateConfig(flag);
|
||||
|
||||
}
|
||||
|
||||
public static boolean contains(String str, String[] array) {
|
||||
for (String s : array) {
|
||||
|
@ -384,8 +383,6 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
|
|||
mapping.setName(entity.getName());
|
||||
mapping.setProtocol(entity.getProtocol());
|
||||
mapping.setProtocolMapper(entity.getProtocolMapper());
|
||||
mapping.setConsentRequired(entity.isConsentRequired());
|
||||
mapping.setConsentText(entity.getConsentText());
|
||||
Map<String, String> config = new HashMap<String, String>();
|
||||
if (entity.getConfig() != null) {
|
||||
config.putAll(entity.getConfig());
|
||||
|
@ -409,8 +406,6 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
|
|||
entity.setProtocolMapper(model.getProtocolMapper());
|
||||
entity.setClient(this.entity);
|
||||
entity.setConfig(model.getConfig());
|
||||
entity.setConsentRequired(model.isConsentRequired());
|
||||
entity.setConsentText(model.getConsentText());
|
||||
|
||||
em.persist(entity);
|
||||
this.entity.getProtocolMappers().add(entity);
|
||||
|
@ -453,8 +448,6 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
|
|||
public void updateProtocolMapper(ProtocolMapperModel mapping) {
|
||||
ProtocolMapperEntity entity = getProtocolMapperEntity(mapping.getId());
|
||||
entity.setProtocolMapper(mapping.getProtocolMapper());
|
||||
entity.setConsentRequired(mapping.isConsentRequired());
|
||||
entity.setConsentText(mapping.getConsentText());
|
||||
if (entity.getConfig() == null) {
|
||||
entity.setConfig(mapping.getConfig());
|
||||
} else {
|
||||
|
@ -485,8 +478,6 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
|
|||
mapping.setName(entity.getName());
|
||||
mapping.setProtocol(entity.getProtocol());
|
||||
mapping.setProtocolMapper(entity.getProtocolMapper());
|
||||
mapping.setConsentRequired(entity.isConsentRequired());
|
||||
mapping.setConsentText(entity.getConsentText());
|
||||
Map<String, String> config = new HashMap<String, String>();
|
||||
if (entity.getConfig() != null) config.putAll(entity.getConfig());
|
||||
mapping.setConfig(config);
|
||||
|
|
|
@ -17,17 +17,17 @@
|
|||
|
||||
package org.keycloak.models.jpa;
|
||||
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ModelDuplicateException;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleContainerModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.jpa.entities.ClientTemplateEntity;
|
||||
import org.keycloak.models.jpa.entities.ClientScopeEntity;
|
||||
import org.keycloak.models.jpa.entities.ClientScopeRoleMappingEntity;
|
||||
import org.keycloak.models.jpa.entities.ProtocolMapperEntity;
|
||||
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||
import org.keycloak.models.jpa.entities.TemplateScopeMappingEntity;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
@ -42,21 +42,21 @@ import java.util.Set;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class ClientTemplateAdapter implements ClientTemplateModel , JpaModel<ClientTemplateEntity> {
|
||||
public class ClientScopeAdapter implements ClientScopeModel, JpaModel<ClientScopeEntity> {
|
||||
|
||||
protected KeycloakSession session;
|
||||
protected RealmModel realm;
|
||||
protected EntityManager em;
|
||||
protected ClientTemplateEntity entity;
|
||||
protected ClientScopeEntity entity;
|
||||
|
||||
public ClientTemplateAdapter(RealmModel realm, EntityManager em, KeycloakSession session, ClientTemplateEntity entity) {
|
||||
public ClientScopeAdapter(RealmModel realm, EntityManager em, KeycloakSession session, ClientScopeEntity entity) {
|
||||
this.session = session;
|
||||
this.realm = realm;
|
||||
this.em = em;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public ClientTemplateEntity getEntity() {
|
||||
public ClientScopeEntity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel , JpaModel<Cli
|
|||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
name = KeycloakModelUtils.convertClientScopeName(name);
|
||||
entity.setName(name);
|
||||
}
|
||||
|
||||
|
@ -106,8 +107,6 @@ public class ClientTemplateAdapter implements ClientTemplateModel , JpaModel<Cli
|
|||
mapping.setName(entity.getName());
|
||||
mapping.setProtocol(entity.getProtocol());
|
||||
mapping.setProtocolMapper(entity.getProtocolMapper());
|
||||
mapping.setConsentRequired(entity.isConsentRequired());
|
||||
mapping.setConsentText(entity.getConsentText());
|
||||
Map<String, String> config = new HashMap<String, String>();
|
||||
if (entity.getConfig() != null) {
|
||||
config.putAll(entity.getConfig());
|
||||
|
@ -129,10 +128,8 @@ public class ClientTemplateAdapter implements ClientTemplateModel , JpaModel<Cli
|
|||
entity.setName(model.getName());
|
||||
entity.setProtocol(model.getProtocol());
|
||||
entity.setProtocolMapper(model.getProtocolMapper());
|
||||
entity.setClientTemplate(this.entity);
|
||||
entity.setClientScope(this.entity);
|
||||
entity.setConfig(model.getConfig());
|
||||
entity.setConsentRequired(model.isConsentRequired());
|
||||
entity.setConsentText(model.getConsentText());
|
||||
|
||||
em.persist(entity);
|
||||
this.entity.getProtocolMappers().add(entity);
|
||||
|
@ -175,8 +172,6 @@ public class ClientTemplateAdapter implements ClientTemplateModel , JpaModel<Cli
|
|||
public void updateProtocolMapper(ProtocolMapperModel mapping) {
|
||||
ProtocolMapperEntity entity = getProtocolMapperEntity(mapping.getId());
|
||||
entity.setProtocolMapper(mapping.getProtocolMapper());
|
||||
entity.setConsentRequired(mapping.isConsentRequired());
|
||||
entity.setConsentText(mapping.getConsentText());
|
||||
if (entity.getConfig() == null) {
|
||||
entity.setConfig(mapping.getConfig());
|
||||
} else {
|
||||
|
@ -207,24 +202,12 @@ public class ClientTemplateAdapter implements ClientTemplateModel , JpaModel<Cli
|
|||
mapping.setName(entity.getName());
|
||||
mapping.setProtocol(entity.getProtocol());
|
||||
mapping.setProtocolMapper(entity.getProtocolMapper());
|
||||
mapping.setConsentRequired(entity.isConsentRequired());
|
||||
mapping.setConsentText(entity.getConsentText());
|
||||
Map<String, String> config = new HashMap<String, String>();
|
||||
if (entity.getConfig() != null) config.putAll(entity.getConfig());
|
||||
mapping.setConfig(config);
|
||||
return mapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullScopeAllowed() {
|
||||
return entity.isFullScopeAllowed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFullScopeAllowed(boolean value) {
|
||||
entity.setFullScopeAllowed(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getRealmScopeMappings() {
|
||||
Set<RoleModel> roleMappings = getScopeMappings();
|
||||
|
@ -233,7 +216,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel , JpaModel<Cli
|
|||
for (RoleModel role : roleMappings) {
|
||||
RoleContainerModel container = role.getContainer();
|
||||
if (container instanceof RealmModel) {
|
||||
if (((RealmModel) container).getId().equals(realm.getId())) {
|
||||
if (container.getId().equals(realm.getId())) {
|
||||
appRoles.add(role);
|
||||
}
|
||||
}
|
||||
|
@ -244,8 +227,8 @@ public class ClientTemplateAdapter implements ClientTemplateModel , JpaModel<Cli
|
|||
|
||||
@Override
|
||||
public Set<RoleModel> getScopeMappings() {
|
||||
TypedQuery<String> query = em.createNamedQuery("clientTemplateScopeMappingIds", String.class);
|
||||
query.setParameter("template", getEntity());
|
||||
TypedQuery<String> query = em.createNamedQuery("clientScopeRoleMappingIds", String.class);
|
||||
query.setParameter("clientScope", getEntity());
|
||||
List<String> ids = query.getResultList();
|
||||
Set<RoleModel> roles = new HashSet<RoleModel>();
|
||||
for (String roleId : ids) {
|
||||
|
@ -259,8 +242,8 @@ public class ClientTemplateAdapter implements ClientTemplateModel , JpaModel<Cli
|
|||
@Override
|
||||
public void addScopeMapping(RoleModel role) {
|
||||
if (hasScope(role)) return;
|
||||
TemplateScopeMappingEntity entity = new TemplateScopeMappingEntity();
|
||||
entity.setTemplate(getEntity());
|
||||
ClientScopeRoleMappingEntity entity = new ClientScopeRoleMappingEntity();
|
||||
entity.setClientScope(getEntity());
|
||||
RoleEntity roleEntity = RoleAdapter.toRoleEntity(role, em);
|
||||
entity.setRole(roleEntity);
|
||||
em.persist(entity);
|
||||
|
@ -270,17 +253,17 @@ public class ClientTemplateAdapter implements ClientTemplateModel , JpaModel<Cli
|
|||
|
||||
@Override
|
||||
public void deleteScopeMapping(RoleModel role) {
|
||||
TypedQuery<TemplateScopeMappingEntity> query = getRealmScopeMappingQuery(role);
|
||||
List<TemplateScopeMappingEntity> results = query.getResultList();
|
||||
TypedQuery<ClientScopeRoleMappingEntity> query = getRealmScopeMappingQuery(role);
|
||||
List<ClientScopeRoleMappingEntity> results = query.getResultList();
|
||||
if (results.size() == 0) return;
|
||||
for (TemplateScopeMappingEntity entity : results) {
|
||||
for (ClientScopeRoleMappingEntity entity : results) {
|
||||
em.remove(entity);
|
||||
}
|
||||
}
|
||||
|
||||
protected TypedQuery<TemplateScopeMappingEntity> getRealmScopeMappingQuery(RoleModel role) {
|
||||
TypedQuery<TemplateScopeMappingEntity> query = em.createNamedQuery("templateHasScope", TemplateScopeMappingEntity.class);
|
||||
query.setParameter("template", getEntity());
|
||||
protected TypedQuery<ClientScopeRoleMappingEntity> getRealmScopeMappingQuery(RoleModel role) {
|
||||
TypedQuery<ClientScopeRoleMappingEntity> query = em.createNamedQuery("clientScopeHasRole", ClientScopeRoleMappingEntity.class);
|
||||
query.setParameter("clientScope", getEntity());
|
||||
RoleEntity roleEntity = RoleAdapter.toRoleEntity(role, em);
|
||||
query.setParameter("role", roleEntity);
|
||||
return query;
|
||||
|
@ -288,7 +271,6 @@ public class ClientTemplateAdapter implements ClientTemplateModel , JpaModel<Cli
|
|||
|
||||
@Override
|
||||
public boolean hasScope(RoleModel role) {
|
||||
if (isFullScopeAllowed()) return true;
|
||||
Set<RoleModel> roles = getScopeMappings();
|
||||
if (roles.contains(role)) return true;
|
||||
|
||||
|
@ -298,26 +280,6 @@ public class ClientTemplateAdapter implements ClientTemplateModel , JpaModel<Cli
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPublicClient() {
|
||||
return entity.isPublicClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPublicClient(boolean flag) {
|
||||
entity.setPublicClient(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFrontchannelLogout() {
|
||||
return entity.isFrontchannelLogout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFrontchannelLogout(boolean flag) {
|
||||
entity.setFrontchannelLogout(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, String value) {
|
||||
entity.getAttributes().put(name, value);
|
||||
|
@ -334,6 +296,13 @@ public class ClientTemplateAdapter implements ClientTemplateModel , JpaModel<Cli
|
|||
return entity.getAttributes().get(name);
|
||||
}
|
||||
|
||||
public static ClientScopeEntity toClientScopeEntity(ClientScopeModel model, EntityManager em) {
|
||||
if (model instanceof ClientScopeAdapter) {
|
||||
return ((ClientScopeAdapter)model).getEntity();
|
||||
}
|
||||
return em.getReference(ClientScopeEntity.class, model.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAttributes() {
|
||||
Map<String, String> copy = new HashMap<>();
|
||||
|
@ -341,74 +310,13 @@ public class ClientTemplateAdapter implements ClientTemplateModel , JpaModel<Cli
|
|||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBearerOnly() {
|
||||
return entity.isBearerOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBearerOnly(boolean only) {
|
||||
entity.setBearerOnly(only);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConsentRequired() {
|
||||
return entity.isConsentRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConsentRequired(boolean consentRequired) {
|
||||
entity.setConsentRequired(consentRequired);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStandardFlowEnabled() {
|
||||
return entity.isStandardFlowEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStandardFlowEnabled(boolean standardFlowEnabled) {
|
||||
entity.setStandardFlowEnabled(standardFlowEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImplicitFlowEnabled() {
|
||||
return entity.isImplicitFlowEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitFlowEnabled(boolean implicitFlowEnabled) {
|
||||
entity.setImplicitFlowEnabled(implicitFlowEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirectAccessGrantsEnabled() {
|
||||
return entity.isDirectAccessGrantsEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirectAccessGrantsEnabled(boolean directAccessGrantsEnabled) {
|
||||
entity.setDirectAccessGrantsEnabled(directAccessGrantsEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isServiceAccountsEnabled() {
|
||||
return entity.isServiceAccountsEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServiceAccountsEnabled(boolean serviceAccountsEnabled) {
|
||||
entity.setServiceAccountsEnabled(serviceAccountsEnabled);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || !(o instanceof ClientTemplateModel)) return false;
|
||||
if (o == null || !(o instanceof ClientScopeModel)) return false;
|
||||
|
||||
ClientTemplateModel that = (ClientTemplateModel) o;
|
||||
ClientScopeModel that = (ClientScopeModel) o;
|
||||
return that.getId().equals(getId());
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ import org.keycloak.connections.jpa.util.JpaUtils;
|
|||
import org.keycloak.migration.MigrationModel;
|
||||
import org.keycloak.models.ClientInitialAccessModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ModelDuplicateException;
|
||||
|
@ -33,7 +33,7 @@ import org.keycloak.models.RoleContainerModel;
|
|||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.jpa.entities.ClientEntity;
|
||||
import org.keycloak.models.jpa.entities.ClientInitialAccessEntity;
|
||||
import org.keycloak.models.jpa.entities.ClientTemplateEntity;
|
||||
import org.keycloak.models.jpa.entities.ClientScopeEntity;
|
||||
import org.keycloak.models.jpa.entities.GroupEntity;
|
||||
import org.keycloak.models.jpa.entities.RealmEntity;
|
||||
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||
|
@ -142,8 +142,11 @@ public class JpaRealmProvider implements RealmProvider {
|
|||
removeClient(client, adapter);
|
||||
}
|
||||
|
||||
for (ClientTemplateEntity a : new LinkedList<>(realm.getClientTemplates())) {
|
||||
adapter.removeClientTemplate(a.getId());
|
||||
num = em.createNamedQuery("deleteDefaultClientScopeRealmMappingByRealm")
|
||||
.setParameter("realm", realm).executeUpdate();
|
||||
|
||||
for (ClientScopeEntity a : new LinkedList<>(realm.getClientScopes())) {
|
||||
adapter.removeClientScope(a.getId());
|
||||
}
|
||||
|
||||
for (RoleModel role : adapter.getRoles()) {
|
||||
|
@ -285,7 +288,7 @@ public class JpaRealmProvider implements RealmProvider {
|
|||
String compositeRoleTable = JpaUtils.getTableNameForNativeQuery("COMPOSITE_ROLE", em);
|
||||
em.createNativeQuery("delete from " + compositeRoleTable + " where CHILD_ROLE = :role").setParameter("role", roleEntity).executeUpdate();
|
||||
realm.getClients().forEach(c -> c.deleteScopeMapping(role));
|
||||
em.createNamedQuery("deleteTemplateScopeMappingByRole").setParameter("role", roleEntity).executeUpdate();
|
||||
em.createNamedQuery("deleteClientScopeRoleMappingByRole").setParameter("role", roleEntity).executeUpdate();
|
||||
int val = em.createNamedQuery("deleteGroupRoleMappingsByRole").setParameter("roleId", roleEntity.getId()).executeUpdate();
|
||||
|
||||
em.flush();
|
||||
|
@ -567,6 +570,9 @@ public class JpaRealmProvider implements RealmProvider {
|
|||
}
|
||||
});
|
||||
|
||||
int countRemoved = em.createNamedQuery("deleteClientScopeClientMappingByClient")
|
||||
.setParameter("client", clientEntity)
|
||||
.executeUpdate();
|
||||
em.remove(clientEntity); // i have no idea why, but this needs to come before deleteScopeMapping
|
||||
|
||||
try {
|
||||
|
@ -580,12 +586,12 @@ public class JpaRealmProvider implements RealmProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ClientTemplateModel getClientTemplateById(String id, RealmModel realm) {
|
||||
ClientTemplateEntity app = em.find(ClientTemplateEntity.class, id);
|
||||
public ClientScopeModel getClientScopeById(String id, RealmModel realm) {
|
||||
ClientScopeEntity app = em.find(ClientScopeEntity.class, id);
|
||||
|
||||
// Check if application belongs to this realm
|
||||
if (app == null || !realm.getId().equals(app.getRealm().getId())) return null;
|
||||
ClientTemplateAdapter adapter = new ClientTemplateAdapter(realm, em, session, app);
|
||||
ClientScopeAdapter adapter = new ClientScopeAdapter(realm, em, session, app);
|
||||
return adapter;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import org.keycloak.component.ComponentModel;
|
|||
import org.keycloak.credential.CredentialModel;
|
||||
import org.keycloak.credential.UserCredentialStore;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.FederatedIdentityModel;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
|
@ -39,9 +39,8 @@ import org.keycloak.models.UserProvider;
|
|||
import org.keycloak.models.jpa.entities.CredentialAttributeEntity;
|
||||
import org.keycloak.models.jpa.entities.CredentialEntity;
|
||||
import org.keycloak.models.jpa.entities.FederatedIdentityEntity;
|
||||
import org.keycloak.models.jpa.entities.UserConsentClientScopeEntity;
|
||||
import org.keycloak.models.jpa.entities.UserConsentEntity;
|
||||
import org.keycloak.models.jpa.entities.UserConsentProtocolMapperEntity;
|
||||
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;
|
||||
|
@ -132,8 +131,7 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
|||
em.createNamedQuery("deleteUserRoleMappingsByUser").setParameter("user", user).executeUpdate();
|
||||
em.createNamedQuery("deleteUserGroupMembershipsByUser").setParameter("user", user).executeUpdate();
|
||||
em.createNamedQuery("deleteFederatedIdentityByUser").setParameter("user", user).executeUpdate();
|
||||
em.createNamedQuery("deleteUserConsentRolesByUser").setParameter("user", user).executeUpdate();
|
||||
em.createNamedQuery("deleteUserConsentProtMappersByUser").setParameter("user", user).executeUpdate();
|
||||
em.createNamedQuery("deleteUserConsentClientScopesByUser").setParameter("user", user).executeUpdate();
|
||||
em.createNamedQuery("deleteUserConsentsByUser").setParameter("user", user).executeUpdate();
|
||||
em.flush();
|
||||
// not sure why i have to do a clear() here. I was getting some messed up errors that Hibernate couldn't
|
||||
|
@ -297,36 +295,12 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
|||
model.setCreatedDate(entity.getCreatedDate());
|
||||
model.setLastUpdatedDate(entity.getLastUpdatedDate());
|
||||
|
||||
Collection<UserConsentRoleEntity> grantedRoleEntities = entity.getGrantedRoles();
|
||||
if (grantedRoleEntities != null) {
|
||||
for (UserConsentRoleEntity grantedRole : grantedRoleEntities) {
|
||||
RoleModel grantedRoleModel = realm.getRoleById(grantedRole.getRoleId());
|
||||
if (grantedRoleModel != null) {
|
||||
model.addGrantedRole(grantedRoleModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collection<UserConsentProtocolMapperEntity> grantedProtocolMapperEntities = entity.getGrantedProtocolMappers();
|
||||
if (grantedProtocolMapperEntities != null) {
|
||||
|
||||
ClientTemplateModel clientTemplate = null;
|
||||
if (client.useTemplateMappers()) {
|
||||
clientTemplate = client.getClientTemplate();
|
||||
}
|
||||
|
||||
for (UserConsentProtocolMapperEntity grantedProtMapper : grantedProtocolMapperEntities) {
|
||||
ProtocolMapperModel protocolMapper = client.getProtocolMapperById(grantedProtMapper.getProtocolMapperId());
|
||||
|
||||
// Fallback to client template
|
||||
if (protocolMapper == null) {
|
||||
if (clientTemplate != null) {
|
||||
protocolMapper = clientTemplate.getProtocolMapperById(grantedProtMapper.getProtocolMapperId());
|
||||
}
|
||||
}
|
||||
|
||||
if (protocolMapper != null) {
|
||||
model.addGrantedProtocolMapper(protocolMapper);
|
||||
Collection<UserConsentClientScopeEntity> grantedClientScopeEntities = entity.getGrantedClientScopes();
|
||||
if (grantedClientScopeEntities != null) {
|
||||
for (UserConsentClientScopeEntity grantedClientScope : grantedClientScopeEntities) {
|
||||
ClientScopeModel grantedClientScopeModel = KeycloakModelUtils.findClientScopeById(realm, grantedClientScope.getScopeId());
|
||||
if (grantedClientScopeModel != null) {
|
||||
model.addGrantedClientScope(grantedClientScopeModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -336,48 +310,26 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
|||
|
||||
// Update roles and protocolMappers to given consentEntity from the consentModel
|
||||
private void updateGrantedConsentEntity(UserConsentEntity consentEntity, UserConsentModel consentModel) {
|
||||
Collection<UserConsentProtocolMapperEntity> grantedProtocolMapperEntities = consentEntity.getGrantedProtocolMappers();
|
||||
Collection<UserConsentProtocolMapperEntity> mappersToRemove = new HashSet<UserConsentProtocolMapperEntity>(grantedProtocolMapperEntities);
|
||||
Collection<UserConsentClientScopeEntity> grantedClientScopeEntities = consentEntity.getGrantedClientScopes();
|
||||
Collection<UserConsentClientScopeEntity> scopesToRemove = new HashSet<>(grantedClientScopeEntities);
|
||||
|
||||
for (ProtocolMapperModel protocolMapper : consentModel.getGrantedProtocolMappers()) {
|
||||
UserConsentProtocolMapperEntity grantedProtocolMapperEntity = new UserConsentProtocolMapperEntity();
|
||||
grantedProtocolMapperEntity.setUserConsent(consentEntity);
|
||||
grantedProtocolMapperEntity.setProtocolMapperId(protocolMapper.getId());
|
||||
for (ClientScopeModel clientScope : consentModel.getGrantedClientScopes()) {
|
||||
UserConsentClientScopeEntity grantedClientScopeEntity = new UserConsentClientScopeEntity();
|
||||
grantedClientScopeEntity.setUserConsent(consentEntity);
|
||||
grantedClientScopeEntity.setScopeId(clientScope.getId());
|
||||
|
||||
// Check if it's already there
|
||||
if (!grantedProtocolMapperEntities.contains(grantedProtocolMapperEntity)) {
|
||||
em.persist(grantedProtocolMapperEntity);
|
||||
if (!grantedClientScopeEntities.contains(grantedClientScopeEntity)) {
|
||||
em.persist(grantedClientScopeEntity);
|
||||
em.flush();
|
||||
grantedProtocolMapperEntities.add(grantedProtocolMapperEntity);
|
||||
grantedClientScopeEntities.add(grantedClientScopeEntity);
|
||||
} else {
|
||||
mappersToRemove.remove(grantedProtocolMapperEntity);
|
||||
scopesToRemove.remove(grantedClientScopeEntity);
|
||||
}
|
||||
}
|
||||
// Those mappers were no longer on consentModel and will be removed
|
||||
for (UserConsentProtocolMapperEntity toRemove : mappersToRemove) {
|
||||
grantedProtocolMapperEntities.remove(toRemove);
|
||||
em.remove(toRemove);
|
||||
}
|
||||
|
||||
Collection<UserConsentRoleEntity> grantedRoleEntities = consentEntity.getGrantedRoles();
|
||||
Set<UserConsentRoleEntity> rolesToRemove = new HashSet<UserConsentRoleEntity>(grantedRoleEntities);
|
||||
for (RoleModel role : consentModel.getGrantedRoles()) {
|
||||
UserConsentRoleEntity consentRoleEntity = new UserConsentRoleEntity();
|
||||
consentRoleEntity.setUserConsent(consentEntity);
|
||||
consentRoleEntity.setRoleId(role.getId());
|
||||
|
||||
// Check if it's already there
|
||||
if (!grantedRoleEntities.contains(consentRoleEntity)) {
|
||||
em.persist(consentRoleEntity);
|
||||
em.flush();
|
||||
grantedRoleEntities.add(consentRoleEntity);
|
||||
} else {
|
||||
rolesToRemove.remove(consentRoleEntity);
|
||||
}
|
||||
}
|
||||
// Those roles were no longer on consentModel and will be removed
|
||||
for (UserConsentRoleEntity toRemove : rolesToRemove) {
|
||||
grantedRoleEntities.remove(toRemove);
|
||||
// Those client scopes were no longer on consentModel and will be removed
|
||||
for (UserConsentClientScopeEntity toRemove : scopesToRemove) {
|
||||
grantedClientScopeEntities.remove(toRemove);
|
||||
em.remove(toRemove);
|
||||
}
|
||||
|
||||
|
@ -409,9 +361,7 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
|||
|
||||
@Override
|
||||
public void preRemove(RealmModel realm) {
|
||||
int num = em.createNamedQuery("deleteUserConsentRolesByRealm")
|
||||
.setParameter("realmId", realm.getId()).executeUpdate();
|
||||
num = em.createNamedQuery("deleteUserConsentProtMappersByRealm")
|
||||
int num = em.createNamedQuery("deleteUserConsentClientScopesByRealm")
|
||||
.setParameter("realmId", realm.getId()).executeUpdate();
|
||||
num = em.createNamedQuery("deleteUserConsentsByRealm")
|
||||
.setParameter("realmId", realm.getId()).executeUpdate();
|
||||
|
@ -463,11 +413,7 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
|||
.setParameter("realmId", realm.getId())
|
||||
.setParameter("link", storageProviderId)
|
||||
.executeUpdate();
|
||||
num = em.createNamedQuery("deleteUserConsentProtMappersByRealmAndLink")
|
||||
.setParameter("realmId", realm.getId())
|
||||
.setParameter("link", storageProviderId)
|
||||
.executeUpdate();
|
||||
num = em.createNamedQuery("deleteUserConsentRolesByRealmAndLink")
|
||||
num = em.createNamedQuery("deleteUserConsentClientScopesByRealmAndLink")
|
||||
.setParameter("realmId", realm.getId())
|
||||
.setParameter("link", storageProviderId)
|
||||
.executeUpdate();
|
||||
|
@ -491,7 +437,6 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
|||
|
||||
@Override
|
||||
public void preRemove(RealmModel realm, RoleModel role) {
|
||||
em.createNamedQuery("deleteUserConsentRolesByRole").setParameter("roleId", role.getId()).executeUpdate();
|
||||
em.createNamedQuery("deleteUserRoleMappingsByRole").setParameter("roleId", role.getId()).executeUpdate();
|
||||
}
|
||||
|
||||
|
@ -499,21 +444,14 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
|||
public void preRemove(RealmModel realm, ClientModel client) {
|
||||
StorageId clientStorageId = new StorageId(client.getId());
|
||||
if (clientStorageId.isLocal()) {
|
||||
em.createNamedQuery("deleteUserConsentProtMappersByClient")
|
||||
int num = em.createNamedQuery("deleteUserConsentClientScopesByClient")
|
||||
.setParameter("clientId", client.getId())
|
||||
.executeUpdate();
|
||||
em.createNamedQuery("deleteUserConsentRolesByClient")
|
||||
.setParameter("clientId", client.getId())
|
||||
.executeUpdate();
|
||||
em.createNamedQuery("deleteUserConsentsByClient")
|
||||
num = em.createNamedQuery("deleteUserConsentsByClient")
|
||||
.setParameter("clientId", client.getId())
|
||||
.executeUpdate();
|
||||
} else {
|
||||
em.createNamedQuery("deleteUserConsentProtMappersByExternalClient")
|
||||
.setParameter("clientStorageProvider", clientStorageId.getProviderId())
|
||||
.setParameter("externalClientId",clientStorageId.getExternalId())
|
||||
.executeUpdate();
|
||||
em.createNamedQuery("deleteUserConsentRolesByExternalClient")
|
||||
em.createNamedQuery("deleteUserConsentClientScopesByExternalClient")
|
||||
.setParameter("clientStorageProvider", clientStorageId.getProviderId())
|
||||
.setParameter("externalClientId", clientStorageId.getExternalId())
|
||||
.executeUpdate();
|
||||
|
@ -527,8 +465,13 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
|||
|
||||
@Override
|
||||
public void preRemove(ProtocolMapperModel protocolMapper) {
|
||||
em.createNamedQuery("deleteUserConsentProtMappersByProtocolMapper")
|
||||
.setParameter("protocolMapperId", protocolMapper.getId())
|
||||
// No-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preRemove(ClientScopeModel clientScope) {
|
||||
em.createNamedQuery("deleteUserConsentClientScopesByClientScope")
|
||||
.setParameter("scopeId", clientScope.getId())
|
||||
.executeUpdate();
|
||||
}
|
||||
|
||||
|
@ -863,10 +806,7 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
|||
}
|
||||
|
||||
protected void removeConsentByClientStorageProvider(RealmModel realm, String providerId) {
|
||||
em.createNamedQuery("deleteUserConsentProtMappersByClientStorageProvider")
|
||||
.setParameter("clientStorageProvider", providerId)
|
||||
.executeUpdate();
|
||||
em.createNamedQuery("deleteUserConsentRolesByClientStorageProvider")
|
||||
em.createNamedQuery("deleteUserConsentClientScopesByClientStorageProvider")
|
||||
.setParameter("clientStorageProvider", providerId)
|
||||
.executeUpdate();
|
||||
em.createNamedQuery("deleteUserConsentsByClientStorageProvider")
|
||||
|
|
|
@ -28,6 +28,8 @@ import org.keycloak.models.utils.ComponentUtil;
|
|||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -1769,60 +1771,64 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ClientTemplateModel> getClientTemplates() {
|
||||
Collection<ClientTemplateEntity> entities = realm.getClientTemplates();
|
||||
public List<ClientScopeModel> getClientScopes() {
|
||||
Collection<ClientScopeEntity> entities = realm.getClientScopes();
|
||||
if (entities == null || entities.isEmpty()) return Collections.EMPTY_LIST;
|
||||
List<ClientTemplateModel> list = new LinkedList<>();
|
||||
for (ClientTemplateEntity entity : entities) {
|
||||
list.add(session.realms().getClientTemplateById(entity.getId(), this));
|
||||
List<ClientScopeModel> list = new LinkedList<>();
|
||||
for (ClientScopeEntity entity : entities) {
|
||||
list.add(session.realms().getClientScopeById(entity.getId(), this));
|
||||
}
|
||||
return Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientTemplateModel addClientTemplate(String name) {
|
||||
return this.addClientTemplate(KeycloakModelUtils.generateId(), name);
|
||||
public ClientScopeModel addClientScope(String name) {
|
||||
return this.addClientScope(KeycloakModelUtils.generateId(), name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientTemplateModel addClientTemplate(String id, String name) {
|
||||
ClientTemplateEntity entity = new ClientTemplateEntity();
|
||||
public ClientScopeModel addClientScope(String id, String name) {
|
||||
ClientScopeEntity entity = new ClientScopeEntity();
|
||||
entity.setId(id);
|
||||
name = KeycloakModelUtils.convertClientScopeName(name);
|
||||
entity.setName(name);
|
||||
entity.setRealm(realm);
|
||||
realm.getClientTemplates().add(entity);
|
||||
realm.getClientScopes().add(entity);
|
||||
em.persist(entity);
|
||||
em.flush();
|
||||
final ClientTemplateModel resource = new ClientTemplateAdapter(this, em, session, entity);
|
||||
final ClientScopeModel resource = new ClientScopeAdapter(this, em, session, entity);
|
||||
em.flush();
|
||||
return resource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeClientTemplate(String id) {
|
||||
public boolean removeClientScope(String id) {
|
||||
if (id == null) return false;
|
||||
ClientTemplateModel client = getClientTemplateById(id);
|
||||
if (client == null) return false;
|
||||
if (KeycloakModelUtils.isClientTemplateUsed(this, client)) {
|
||||
throw new ModelException("Cannot remove client template, it is currently in use");
|
||||
ClientScopeModel clientScope = getClientScopeById(id);
|
||||
if (clientScope == null) return false;
|
||||
if (KeycloakModelUtils.isClientScopeUsed(this, clientScope)) {
|
||||
throw new ModelException("Cannot remove client scope, it is currently in use");
|
||||
}
|
||||
|
||||
ClientTemplateEntity clientEntity = null;
|
||||
Iterator<ClientTemplateEntity> it = realm.getClientTemplates().iterator();
|
||||
ClientScopeEntity clientScopeEntity = null;
|
||||
Iterator<ClientScopeEntity> it = realm.getClientScopes().iterator();
|
||||
while (it.hasNext()) {
|
||||
ClientTemplateEntity ae = it.next();
|
||||
ClientScopeEntity ae = it.next();
|
||||
if (ae.getId().equals(id)) {
|
||||
clientEntity = ae;
|
||||
clientScopeEntity = ae;
|
||||
it.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (client == null) {
|
||||
if (clientScope == null) {
|
||||
return false;
|
||||
}
|
||||
em.createNamedQuery("deleteTemplateScopeMappingByClient").setParameter("template", clientEntity).executeUpdate();
|
||||
|
||||
session.users().preRemove(clientScope);
|
||||
|
||||
em.createNamedQuery("deleteClientScopeRoleMappingByClientScope").setParameter("clientScope", clientScopeEntity).executeUpdate();
|
||||
em.flush();
|
||||
em.remove(clientEntity);
|
||||
em.remove(clientScopeEntity);
|
||||
em.flush();
|
||||
|
||||
|
||||
|
@ -1830,8 +1836,44 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ClientTemplateModel getClientTemplateById(String id) {
|
||||
return session.realms().getClientTemplateById(id, this);
|
||||
public ClientScopeModel getClientScopeById(String id) {
|
||||
return session.realms().getClientScopeById(id, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDefaultClientScope(ClientScopeModel clientScope, boolean defaultScope) {
|
||||
DefaultClientScopeRealmMappingEntity entity = new DefaultClientScopeRealmMappingEntity();
|
||||
entity.setClientScope(ClientScopeAdapter.toClientScopeEntity(clientScope, em));
|
||||
entity.setRealm(getEntity());
|
||||
entity.setDefaultScope(defaultScope);
|
||||
em.persist(entity);
|
||||
em.flush();
|
||||
em.detach(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDefaultClientScope(ClientScopeModel clientScope) {
|
||||
int numRemoved = em.createNamedQuery("deleteDefaultClientScopeRealmMapping")
|
||||
.setParameter("clientScope", ClientScopeAdapter.toClientScopeEntity(clientScope, em))
|
||||
.setParameter("realm", getEntity())
|
||||
.executeUpdate();
|
||||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClientScopeModel> getDefaultClientScopes(boolean defaultScope) {
|
||||
TypedQuery<String> query = em.createNamedQuery("defaultClientScopeRealmMappingIdsByRealm", String.class);
|
||||
query.setParameter("realm", getEntity());
|
||||
query.setParameter("defaultScope", defaultScope);
|
||||
List<String> ids = query.getResultList();
|
||||
|
||||
List<ClientScopeModel> clientScopes = new LinkedList<>();
|
||||
for (String clientScopeId : ids) {
|
||||
ClientScopeModel clientScope = getClientScopeById(clientScopeId);
|
||||
if (clientScope == null) continue;
|
||||
clientScopes.add(clientScope);
|
||||
}
|
||||
return clientScopes;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -68,16 +68,6 @@ public class RoleAdapter implements RoleModel, JpaModel<RoleEntity> {
|
|||
role.setDescription(description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isScopeParamRequired() {
|
||||
return role.isScopeParamRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScopeParamRequired(boolean scopeParamRequired) {
|
||||
role.setScopeParamRequired(scopeParamRequired);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return role.getId();
|
||||
|
|
|
@ -90,19 +90,6 @@ public class ClientEntity {
|
|||
@Column(name="FULL_SCOPE_ALLOWED")
|
||||
private boolean fullScopeAllowed;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "CLIENT_TEMPLATE_ID")
|
||||
protected ClientTemplateEntity clientTemplate;
|
||||
|
||||
@Column(name="USE_TEMPLATE_CONFIG")
|
||||
private boolean useTemplateConfig;
|
||||
|
||||
@Column(name="USE_TEMPLATE_SCOPE")
|
||||
private boolean useTemplateScope;
|
||||
|
||||
@Column(name="USE_TEMPLATE_MAPPERS")
|
||||
private boolean useTemplateMappers;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "REALM_ID")
|
||||
protected RealmEntity realm;
|
||||
|
@ -435,38 +422,6 @@ public class ClientEntity {
|
|||
this.registeredNodes = registeredNodes;
|
||||
}
|
||||
|
||||
public ClientTemplateEntity getClientTemplate() {
|
||||
return clientTemplate;
|
||||
}
|
||||
|
||||
public void setClientTemplate(ClientTemplateEntity clientTemplate) {
|
||||
this.clientTemplate = clientTemplate;
|
||||
}
|
||||
|
||||
public boolean isUseTemplateConfig() {
|
||||
return useTemplateConfig;
|
||||
}
|
||||
|
||||
public void setUseTemplateConfig(boolean useTemplateConfig) {
|
||||
this.useTemplateConfig = useTemplateConfig;
|
||||
}
|
||||
|
||||
public boolean isUseTemplateScope() {
|
||||
return useTemplateScope;
|
||||
}
|
||||
|
||||
public void setUseTemplateScope(boolean useTemplateScope) {
|
||||
this.useTemplateScope = useTemplateScope;
|
||||
}
|
||||
|
||||
public boolean isUseTemplateMappers() {
|
||||
return useTemplateMappers;
|
||||
}
|
||||
|
||||
public void setUseTemplateMappers(boolean useTemplateMappers) {
|
||||
this.useTemplateMappers = useTemplateMappers;
|
||||
}
|
||||
|
||||
public Set<RoleEntity> getScopeMapping() {
|
||||
return scopeMapping;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright 2017 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.jpa.entities;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* Binding between client and clientScope
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="clientScopeClientMappingIdsByClient", query="select m.clientScope.id from ClientScopeClientMappingEntity m where m.client = :client and m.defaultScope = :defaultScope"),
|
||||
@NamedQuery(name="deleteClientScopeClientMapping", query="delete from ClientScopeClientMappingEntity where client = :client and clientScope = :clientScope"),
|
||||
@NamedQuery(name="deleteClientScopeClientMappingByClient", query="delete from ClientScopeClientMappingEntity where client = :client")
|
||||
})
|
||||
@Entity
|
||||
@Table(name="CLIENT_SCOPE_CLIENT")
|
||||
@IdClass(ClientScopeClientMappingEntity.Key.class)
|
||||
public class ClientScopeClientMappingEntity {
|
||||
|
||||
@Id
|
||||
@ManyToOne(fetch= FetchType.LAZY)
|
||||
@JoinColumn(name = "SCOPE_ID")
|
||||
protected ClientScopeEntity clientScope;
|
||||
|
||||
@Id
|
||||
@ManyToOne(fetch= FetchType.LAZY)
|
||||
@JoinColumn(name="CLIENT_ID")
|
||||
protected ClientEntity client;
|
||||
|
||||
@Column(name="DEFAULT_SCOPE")
|
||||
protected boolean defaultScope;
|
||||
|
||||
public ClientScopeEntity getClientScope() {
|
||||
return clientScope;
|
||||
}
|
||||
|
||||
public void setClientScope(ClientScopeEntity clientScope) {
|
||||
this.clientScope = clientScope;
|
||||
}
|
||||
|
||||
public ClientEntity getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public void setClient(ClientEntity client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public boolean isDefaultScope() {
|
||||
return defaultScope;
|
||||
}
|
||||
|
||||
public void setDefaultScope(boolean defaultScope) {
|
||||
this.defaultScope = defaultScope;
|
||||
}
|
||||
|
||||
public static class Key implements Serializable {
|
||||
|
||||
protected ClientScopeEntity clientScope;
|
||||
|
||||
protected ClientEntity client;
|
||||
|
||||
public Key() {
|
||||
}
|
||||
|
||||
public Key(ClientScopeEntity clientScope, ClientEntity client) {
|
||||
this.clientScope = clientScope;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public ClientScopeEntity getClientScope() {
|
||||
return clientScope;
|
||||
}
|
||||
|
||||
public ClientEntity getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
ClientScopeClientMappingEntity.Key key = (ClientScopeClientMappingEntity.Key) o;
|
||||
|
||||
if (clientScope != null ? !clientScope.getId().equals(key.clientScope != null ? key.clientScope.getId() : null) : key.clientScope != null) return false;
|
||||
if (client != null ? !client.getId().equals(key.client != null ? key.client.getId() : null) : key.client != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = clientScope != null ? clientScope.getId().hashCode() : 0;
|
||||
result = 31 * result + (client != null ? client.getId().hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (!(o instanceof ClientScopeClientMappingEntity)) return false;
|
||||
|
||||
ClientScopeClientMappingEntity key = (ClientScopeClientMappingEntity) o;
|
||||
|
||||
if (clientScope != null ? !clientScope.getId().equals(key.clientScope != null ? key.clientScope.getId() : null) : key.clientScope != null) return false;
|
||||
if (client != null ? !client.getId().equals(key.client != null ? key.client.getId() : null) : key.client != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = clientScope != null ? clientScope.getId().hashCode() : 0;
|
||||
result = 31 * result + (client != null ? client.getId().hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -44,8 +44,8 @@ import java.util.Map;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Entity
|
||||
@Table(name="CLIENT_TEMPLATE", uniqueConstraints = {@UniqueConstraint(columnNames = {"REALM_ID", "NAME"})})
|
||||
public class ClientTemplateEntity {
|
||||
@Table(name="CLIENT_SCOPE", uniqueConstraints = {@UniqueConstraint(columnNames = {"REALM_ID", "NAME"})})
|
||||
public class ClientScopeEntity {
|
||||
|
||||
@Id
|
||||
@Column(name="ID", length = 36)
|
||||
|
@ -56,7 +56,7 @@ public class ClientTemplateEntity {
|
|||
@Nationalized
|
||||
@Column(name = "DESCRIPTION")
|
||||
private String description;
|
||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "clientTemplate")
|
||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "clientScope")
|
||||
Collection<ProtocolMapperEntity> protocolMappers = new ArrayList<ProtocolMapperEntity>();
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "REALM_ID")
|
||||
|
@ -65,36 +65,11 @@ public class ClientTemplateEntity {
|
|||
@Column(name="PROTOCOL")
|
||||
private String protocol;
|
||||
|
||||
@Column(name="FULL_SCOPE_ALLOWED")
|
||||
private boolean fullScopeAllowed;
|
||||
|
||||
@Column(name="CONSENT_REQUIRED")
|
||||
private boolean consentRequired;
|
||||
|
||||
@Column(name="STANDARD_FLOW_ENABLED")
|
||||
private boolean standardFlowEnabled;
|
||||
|
||||
@Column(name="IMPLICIT_FLOW_ENABLED")
|
||||
private boolean implicitFlowEnabled;
|
||||
|
||||
@Column(name="DIRECT_ACCESS_GRANTS_ENABLED")
|
||||
private boolean directAccessGrantsEnabled;
|
||||
|
||||
@Column(name="SERVICE_ACCOUNTS_ENABLED")
|
||||
private boolean serviceAccountsEnabled;
|
||||
|
||||
@Column(name="FRONTCHANNEL_LOGOUT")
|
||||
private boolean frontchannelLogout;
|
||||
@Column(name="PUBLIC_CLIENT")
|
||||
private boolean publicClient;
|
||||
@Column(name="BEARER_ONLY")
|
||||
private boolean bearerOnly;
|
||||
|
||||
|
||||
@ElementCollection
|
||||
@MapKeyColumn(name="NAME")
|
||||
@Column(name="VALUE", length = 2048)
|
||||
@CollectionTable(name="CLIENT_TEMPLATE_ATTRIBUTES", joinColumns={ @JoinColumn(name="TEMPLATE_ID") })
|
||||
@CollectionTable(name="CLIENT_SCOPE_ATTRIBUTES", joinColumns={ @JoinColumn(name="SCOPE_ID") })
|
||||
protected Map<String, String> attributes = new HashMap<String, String>();
|
||||
|
||||
public RealmEntity getRealm() {
|
||||
|
@ -145,14 +120,6 @@ public class ClientTemplateEntity {
|
|||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public boolean isFullScopeAllowed() {
|
||||
return fullScopeAllowed;
|
||||
}
|
||||
|
||||
public void setFullScopeAllowed(boolean fullScopeAllowed) {
|
||||
this.fullScopeAllowed = fullScopeAllowed;
|
||||
}
|
||||
|
||||
public Map<String, String> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
@ -161,77 +128,13 @@ public class ClientTemplateEntity {
|
|||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public boolean isConsentRequired() {
|
||||
return consentRequired;
|
||||
}
|
||||
|
||||
public void setConsentRequired(boolean consentRequired) {
|
||||
this.consentRequired = consentRequired;
|
||||
}
|
||||
|
||||
public boolean isStandardFlowEnabled() {
|
||||
return standardFlowEnabled;
|
||||
}
|
||||
|
||||
public void setStandardFlowEnabled(boolean standardFlowEnabled) {
|
||||
this.standardFlowEnabled = standardFlowEnabled;
|
||||
}
|
||||
|
||||
public boolean isImplicitFlowEnabled() {
|
||||
return implicitFlowEnabled;
|
||||
}
|
||||
|
||||
public void setImplicitFlowEnabled(boolean implicitFlowEnabled) {
|
||||
this.implicitFlowEnabled = implicitFlowEnabled;
|
||||
}
|
||||
|
||||
public boolean isDirectAccessGrantsEnabled() {
|
||||
return directAccessGrantsEnabled;
|
||||
}
|
||||
|
||||
public void setDirectAccessGrantsEnabled(boolean directAccessGrantsEnabled) {
|
||||
this.directAccessGrantsEnabled = directAccessGrantsEnabled;
|
||||
}
|
||||
|
||||
public boolean isServiceAccountsEnabled() {
|
||||
return serviceAccountsEnabled;
|
||||
}
|
||||
|
||||
public void setServiceAccountsEnabled(boolean serviceAccountsEnabled) {
|
||||
this.serviceAccountsEnabled = serviceAccountsEnabled;
|
||||
}
|
||||
|
||||
public boolean isFrontchannelLogout() {
|
||||
return frontchannelLogout;
|
||||
}
|
||||
|
||||
public void setFrontchannelLogout(boolean frontchannelLogout) {
|
||||
this.frontchannelLogout = frontchannelLogout;
|
||||
}
|
||||
|
||||
public boolean isPublicClient() {
|
||||
return publicClient;
|
||||
}
|
||||
|
||||
public void setPublicClient(boolean publicClient) {
|
||||
this.publicClient = publicClient;
|
||||
}
|
||||
|
||||
public boolean isBearerOnly() {
|
||||
return bearerOnly;
|
||||
}
|
||||
|
||||
public void setBearerOnly(boolean bearerOnly) {
|
||||
this.bearerOnly = bearerOnly;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null) return false;
|
||||
if (!(o instanceof ClientTemplateEntity)) return false;
|
||||
if (!(o instanceof ClientScopeEntity)) return false;
|
||||
|
||||
ClientTemplateEntity that = (ClientTemplateEntity) o;
|
||||
ClientScopeEntity that = (ClientScopeEntity) o;
|
||||
|
||||
if (!id.equals(that.getId())) return false;
|
||||
|
|
@ -33,33 +33,32 @@ import java.io.Serializable;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="templateHasScope", query="select m from TemplateScopeMappingEntity m where m.template = :template and m.role = :role"),
|
||||
@NamedQuery(name="clientTemplateScopeMappings", query="select m from TemplateScopeMappingEntity m where m.template = :template"),
|
||||
@NamedQuery(name="clientTemplateScopeMappingIds", query="select m.role.id from TemplateScopeMappingEntity m where m.template = :template"),
|
||||
@NamedQuery(name="deleteTemplateScopeMappingByRole", query="delete from TemplateScopeMappingEntity where role = :role"),
|
||||
@NamedQuery(name="deleteTemplateScopeMappingByClient", query="delete from TemplateScopeMappingEntity where template = :template")
|
||||
@NamedQuery(name="clientScopeHasRole", query="select m from ClientScopeRoleMappingEntity m where m.clientScope = :clientScope and m.role = :role"),
|
||||
@NamedQuery(name="clientScopeRoleMappingIds", query="select m.role.id from ClientScopeRoleMappingEntity m where m.clientScope = :clientScope"),
|
||||
@NamedQuery(name="deleteClientScopeRoleMappingByRole", query="delete from ClientScopeRoleMappingEntity where role = :role"),
|
||||
@NamedQuery(name="deleteClientScopeRoleMappingByClientScope", query="delete from ClientScopeRoleMappingEntity where clientScope = :clientScope")
|
||||
})
|
||||
@Table(name="TEMPLATE_SCOPE_MAPPING")
|
||||
@Table(name="CLIENT_SCOPE_ROLE_MAPPING")
|
||||
@Entity
|
||||
@IdClass(TemplateScopeMappingEntity.Key.class)
|
||||
public class TemplateScopeMappingEntity {
|
||||
@IdClass(ClientScopeRoleMappingEntity.Key.class)
|
||||
public class ClientScopeRoleMappingEntity {
|
||||
|
||||
@Id
|
||||
@ManyToOne(fetch= FetchType.LAZY)
|
||||
@JoinColumn(name = "TEMPLATE_ID")
|
||||
protected ClientTemplateEntity template;
|
||||
@JoinColumn(name = "SCOPE_ID")
|
||||
protected ClientScopeEntity clientScope;
|
||||
|
||||
@Id
|
||||
@ManyToOne(fetch= FetchType.LAZY)
|
||||
@JoinColumn(name="ROLE_ID")
|
||||
protected RoleEntity role;
|
||||
|
||||
public ClientTemplateEntity getTemplate() {
|
||||
return template;
|
||||
public ClientScopeEntity getClientScope() {
|
||||
return clientScope;
|
||||
}
|
||||
|
||||
public void setTemplate(ClientTemplateEntity template) {
|
||||
this.template = template;
|
||||
public void setClientScope(ClientScopeEntity clientScope) {
|
||||
this.clientScope = clientScope;
|
||||
}
|
||||
|
||||
public RoleEntity getRole() {
|
||||
|
@ -72,20 +71,20 @@ public class TemplateScopeMappingEntity {
|
|||
|
||||
public static class Key implements Serializable {
|
||||
|
||||
protected ClientTemplateEntity template;
|
||||
protected ClientScopeEntity clientScope;
|
||||
|
||||
protected RoleEntity role;
|
||||
|
||||
public Key() {
|
||||
}
|
||||
|
||||
public Key(ClientTemplateEntity template, RoleEntity role) {
|
||||
this.template = template;
|
||||
public Key(ClientScopeEntity clientScope, RoleEntity role) {
|
||||
this.clientScope = clientScope;
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public ClientTemplateEntity getTemplate() {
|
||||
return template;
|
||||
public ClientScopeEntity getClientScope() {
|
||||
return clientScope;
|
||||
}
|
||||
|
||||
public RoleEntity getRole() {
|
||||
|
@ -99,7 +98,7 @@ public class TemplateScopeMappingEntity {
|
|||
|
||||
Key key = (Key) o;
|
||||
|
||||
if (template != null ? !template.getId().equals(key.template != null ? key.template.getId() : null) : key.template != null) return false;
|
||||
if (clientScope != null ? !clientScope.getId().equals(key.clientScope != null ? key.clientScope.getId() : null) : key.clientScope != null) return false;
|
||||
if (role != null ? !role.getId().equals(key.role != null ? key.role.getId() : null) : key.role != null) return false;
|
||||
|
||||
return true;
|
||||
|
@ -107,7 +106,7 @@ public class TemplateScopeMappingEntity {
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = template != null ? template.getId().hashCode() : 0;
|
||||
int result = clientScope != null ? clientScope.getId().hashCode() : 0;
|
||||
result = 31 * result + (role != null ? role.getId().hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
@ -117,11 +116,11 @@ public class TemplateScopeMappingEntity {
|
|||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (!(o instanceof TemplateScopeMappingEntity)) return false;
|
||||
if (!(o instanceof ClientScopeRoleMappingEntity)) return false;
|
||||
|
||||
TemplateScopeMappingEntity key = (TemplateScopeMappingEntity) o;
|
||||
ClientScopeRoleMappingEntity key = (ClientScopeRoleMappingEntity) o;
|
||||
|
||||
if (template != null ? !template.getId().equals(key.template != null ? key.template.getId() : null) : key.template != null) return false;
|
||||
if (clientScope != null ? !clientScope.getId().equals(key.clientScope != null ? key.clientScope.getId() : null) : key.clientScope != null) return false;
|
||||
if (role != null ? !role.getId().equals(key.role != null ? key.role.getId() : null) : key.role != null) return false;
|
||||
|
||||
return true;
|
||||
|
@ -129,7 +128,7 @@ public class TemplateScopeMappingEntity {
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = template != null ? template.getId().hashCode() : 0;
|
||||
int result = clientScope != null ? clientScope.getId().hashCode() : 0;
|
||||
result = 31 * result + (role != null ? role.getId().hashCode() : 0);
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright 2017 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.jpa.entities;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* Binding between realm and default clientScope
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="defaultClientScopeRealmMappingIdsByRealm", query="select m.clientScope.id from DefaultClientScopeRealmMappingEntity m where m.realm = :realm and m.defaultScope = :defaultScope"),
|
||||
@NamedQuery(name="deleteDefaultClientScopeRealmMapping", query="delete from DefaultClientScopeRealmMappingEntity where realm = :realm and clientScope = :clientScope"),
|
||||
@NamedQuery(name="deleteDefaultClientScopeRealmMappingByRealm", query="delete from DefaultClientScopeRealmMappingEntity where realm = :realm")
|
||||
})
|
||||
@Entity
|
||||
@Table(name="DEFAULT_CLIENT_SCOPE")
|
||||
@IdClass(DefaultClientScopeRealmMappingEntity.Key.class)
|
||||
public class DefaultClientScopeRealmMappingEntity {
|
||||
|
||||
@Id
|
||||
@ManyToOne(fetch= FetchType.LAZY)
|
||||
@JoinColumn(name = "SCOPE_ID")
|
||||
protected ClientScopeEntity clientScope;
|
||||
|
||||
@Id
|
||||
@ManyToOne(fetch= FetchType.LAZY)
|
||||
@JoinColumn(name="REALM_ID")
|
||||
protected RealmEntity realm;
|
||||
|
||||
@Column(name="DEFAULT_SCOPE")
|
||||
protected boolean defaultScope;
|
||||
|
||||
public ClientScopeEntity getClientScope() {
|
||||
return clientScope;
|
||||
}
|
||||
|
||||
public void setClientScope(ClientScopeEntity clientScope) {
|
||||
this.clientScope = clientScope;
|
||||
}
|
||||
|
||||
public RealmEntity getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
public void setRealm(RealmEntity realm) {
|
||||
this.realm = realm;
|
||||
}
|
||||
|
||||
public boolean isDefaultScope() {
|
||||
return defaultScope;
|
||||
}
|
||||
|
||||
public void setDefaultScope(boolean defaultScope) {
|
||||
this.defaultScope = defaultScope;
|
||||
}
|
||||
|
||||
public static class Key implements Serializable {
|
||||
|
||||
protected ClientScopeEntity clientScope;
|
||||
|
||||
protected RealmEntity realm;
|
||||
|
||||
public Key() {
|
||||
}
|
||||
|
||||
public Key(ClientScopeEntity clientScope, RealmEntity realm) {
|
||||
this.clientScope = clientScope;
|
||||
this.realm = realm;
|
||||
}
|
||||
|
||||
public ClientScopeEntity getClientScope() {
|
||||
return clientScope;
|
||||
}
|
||||
|
||||
public RealmEntity getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
DefaultClientScopeRealmMappingEntity.Key key = (DefaultClientScopeRealmMappingEntity.Key) o;
|
||||
|
||||
if (clientScope != null ? !clientScope.getId().equals(key.clientScope != null ? key.clientScope.getId() : null) : key.clientScope != null) return false;
|
||||
if (realm != null ? !realm.getId().equals(key.realm != null ? key.realm.getId() : null) : key.realm != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = clientScope != null ? clientScope.getId().hashCode() : 0;
|
||||
result = 31 * result + (realm != null ? realm.getId().hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (!(o instanceof DefaultClientScopeRealmMappingEntity)) return false;
|
||||
|
||||
DefaultClientScopeRealmMappingEntity key = (DefaultClientScopeRealmMappingEntity) o;
|
||||
|
||||
if (clientScope != null ? !clientScope.getId().equals(key.clientScope != null ? key.clientScope.getId() : null) : key.clientScope != null) return false;
|
||||
if (realm != null ? !realm.getId().equals(key.realm != null ? key.realm.getId() : null) : key.realm != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = clientScope != null ? clientScope.getId().hashCode() : 0;
|
||||
result = 31 * result + (realm != null ? realm.getId().hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -51,10 +51,6 @@ public class ProtocolMapperEntity {
|
|||
protected String protocol;
|
||||
@Column(name = "PROTOCOL_MAPPER_NAME")
|
||||
protected String protocolMapper;
|
||||
@Column(name="CONSENT_REQUIRED")
|
||||
protected boolean consentRequired;
|
||||
@Column(name="CONSENT_TEXT")
|
||||
protected String consentText;
|
||||
|
||||
@ElementCollection
|
||||
@MapKeyColumn(name="NAME")
|
||||
|
@ -67,8 +63,8 @@ public class ProtocolMapperEntity {
|
|||
private ClientEntity client;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "CLIENT_TEMPLATE_ID")
|
||||
private ClientTemplateEntity clientTemplate;
|
||||
@JoinColumn(name = "CLIENT_SCOPE_ID")
|
||||
private ClientScopeEntity clientScope;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
|
@ -118,29 +114,14 @@ public class ProtocolMapperEntity {
|
|||
this.client = client;
|
||||
}
|
||||
|
||||
public ClientTemplateEntity getClientTemplate() {
|
||||
return clientTemplate;
|
||||
public ClientScopeEntity getClientScope() {
|
||||
return clientScope;
|
||||
}
|
||||
|
||||
public void setClientTemplate(ClientTemplateEntity clientTemplate) {
|
||||
this.clientTemplate = clientTemplate;
|
||||
public void setClientScope(ClientScopeEntity clientScope) {
|
||||
this.clientScope = clientScope;
|
||||
}
|
||||
|
||||
public boolean isConsentRequired() {
|
||||
return consentRequired;
|
||||
}
|
||||
|
||||
public void setConsentRequired(boolean consentRequired) {
|
||||
this.consentRequired = consentRequired;
|
||||
}
|
||||
|
||||
public String getConsentText() {
|
||||
return consentText;
|
||||
}
|
||||
|
||||
public void setConsentText(String consentText) {
|
||||
this.consentText = consentText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
|
|
@ -145,7 +145,7 @@ public class RealmEntity {
|
|||
Collection<UserFederationMapperEntity> userFederationMappers = new ArrayList<UserFederationMapperEntity>();
|
||||
|
||||
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
||||
Collection<ClientTemplateEntity> clientTemplates = new ArrayList<>();
|
||||
Collection<ClientScopeEntity> clientScopes = new ArrayList<>();
|
||||
|
||||
@ElementCollection
|
||||
@MapKeyColumn(name="NAME")
|
||||
|
@ -757,12 +757,12 @@ public class RealmEntity {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Collection<ClientTemplateEntity> getClientTemplates() {
|
||||
return clientTemplates;
|
||||
public Collection<ClientScopeEntity> getClientScopes() {
|
||||
return clientScopes;
|
||||
}
|
||||
|
||||
public void setClientTemplates(Collection<ClientTemplateEntity> clientTemplates) {
|
||||
this.clientTemplates = clientTemplates;
|
||||
public void setClientScopes(Collection<ClientScopeEntity> clientScopes) {
|
||||
this.clientScopes = clientScopes;
|
||||
}
|
||||
|
||||
public void setAllowUserManagedAccess(boolean allowUserManagedAccess) {
|
||||
|
|
|
@ -69,8 +69,6 @@ public class RoleEntity {
|
|||
@Nationalized
|
||||
@Column(name = "DESCRIPTION")
|
||||
private String description;
|
||||
@Column(name = "SCOPE_PARAM_REQUIRED")
|
||||
private boolean scopeParamRequired;
|
||||
|
||||
// hax! couldn't get constraint to work properly
|
||||
@Column(name = "REALM_ID")
|
||||
|
@ -129,14 +127,6 @@ public class RoleEntity {
|
|||
this.description = description;
|
||||
}
|
||||
|
||||
public boolean isScopeParamRequired() {
|
||||
return scopeParamRequired;
|
||||
}
|
||||
|
||||
public void setScopeParamRequired(boolean scopeParamRequired) {
|
||||
this.scopeParamRequired = scopeParamRequired;
|
||||
}
|
||||
|
||||
public Set<RoleEntity> getCompositeRoles() {
|
||||
return compositeRoles;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright 2017 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.jpa.entities;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="deleteUserConsentClientScopesByRealm", query="delete from UserConsentClientScopeEntity grantedScope where grantedScope.userConsent IN (select consent from UserConsentEntity consent where consent.user IN (select user from UserEntity user where user.realmId = :realmId))"),
|
||||
@NamedQuery(name="deleteUserConsentClientScopesByRealmAndLink", query="delete from UserConsentClientScopeEntity grantedScope where grantedScope.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="deleteUserConsentClientScopesByUser", query="delete from UserConsentClientScopeEntity grantedScope where grantedScope.userConsent IN (select consent from UserConsentEntity consent where consent.user = :user)"),
|
||||
@NamedQuery(name="deleteUserConsentClientScopesByClientScope", query="delete from UserConsentClientScopeEntity grantedScope where grantedScope.scopeId = :scopeId)"),
|
||||
@NamedQuery(name="deleteUserConsentClientScopesByClient", query="delete from UserConsentClientScopeEntity grantedScope where grantedScope.userConsent IN (select consent from UserConsentEntity consent where consent.clientId = :clientId)"),
|
||||
@NamedQuery(name="deleteUserConsentClientScopesByExternalClient", query="delete from UserConsentClientScopeEntity grantedScope where grantedScope.userConsent IN (select consent from UserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider and consent.externalClientId = :externalClientId)"),
|
||||
@NamedQuery(name="deleteUserConsentClientScopesByClientStorageProvider", query="delete from UserConsentClientScopeEntity grantedScope where grantedScope.userConsent IN (select consent from UserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider)"),
|
||||
})
|
||||
@Entity
|
||||
@Table(name="USER_CONSENT_CLIENT_SCOPE")
|
||||
@IdClass(UserConsentClientScopeEntity.Key.class)
|
||||
public class UserConsentClientScopeEntity {
|
||||
|
||||
@Id
|
||||
@ManyToOne(fetch= FetchType.LAZY)
|
||||
@JoinColumn(name = "USER_CONSENT_ID")
|
||||
protected UserConsentEntity userConsent;
|
||||
|
||||
@Id
|
||||
@Column(name="SCOPE_ID")
|
||||
protected String scopeId;
|
||||
|
||||
public UserConsentEntity getUserConsent() {
|
||||
return userConsent;
|
||||
}
|
||||
|
||||
public void setUserConsent(UserConsentEntity userConsent) {
|
||||
this.userConsent = userConsent;
|
||||
}
|
||||
|
||||
public String getScopeId() {
|
||||
return scopeId;
|
||||
}
|
||||
|
||||
public void setScopeId(String scopeId) {
|
||||
this.scopeId = scopeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null) return false;
|
||||
if (!(o instanceof UserConsentClientScopeEntity)) return false;
|
||||
|
||||
UserConsentClientScopeEntity that = (UserConsentClientScopeEntity)o;
|
||||
UserConsentClientScopeEntity.Key myKey = new UserConsentClientScopeEntity.Key(this.userConsent, this.scopeId);
|
||||
UserConsentClientScopeEntity.Key hisKey = new UserConsentClientScopeEntity.Key(that.userConsent, that.scopeId);
|
||||
return myKey.equals(hisKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
UserConsentClientScopeEntity.Key myKey = new UserConsentClientScopeEntity.Key(this.userConsent, this.scopeId);
|
||||
return myKey.hashCode();
|
||||
}
|
||||
|
||||
public static class Key implements Serializable {
|
||||
|
||||
protected UserConsentEntity userConsent;
|
||||
|
||||
protected String scopeId;
|
||||
|
||||
public Key() {
|
||||
}
|
||||
|
||||
public Key(UserConsentEntity userConsent, String scopeId) {
|
||||
this.userConsent = userConsent;
|
||||
this.scopeId = scopeId;
|
||||
}
|
||||
|
||||
public UserConsentEntity getUserConsent() {
|
||||
return userConsent;
|
||||
}
|
||||
|
||||
public String getScopeId() {
|
||||
return scopeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
UserConsentClientScopeEntity.Key key = (UserConsentClientScopeEntity.Key) o;
|
||||
|
||||
if (userConsent != null ? !userConsent.getId().equals(key.userConsent != null ? key.userConsent.getId() : null) : key.userConsent != null) return false;
|
||||
if (scopeId != null ? !scopeId.equals(key.scopeId) : key.scopeId != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = userConsent != null ? userConsent.getId().hashCode() : 0;
|
||||
result = 31 * result + (scopeId != null ? scopeId.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -73,10 +73,7 @@ public class UserConsentEntity {
|
|||
protected String externalClientId;
|
||||
|
||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "userConsent")
|
||||
Collection<UserConsentRoleEntity> grantedRoles = new ArrayList<UserConsentRoleEntity>();
|
||||
|
||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "userConsent")
|
||||
Collection<UserConsentProtocolMapperEntity> grantedProtocolMappers = new ArrayList<UserConsentProtocolMapperEntity>();
|
||||
Collection<UserConsentClientScopeEntity> grantedClientScopes = new ArrayList<>();
|
||||
|
||||
@Column(name = "CREATED_DATE")
|
||||
private Long createdDate;
|
||||
|
@ -100,20 +97,12 @@ public class UserConsentEntity {
|
|||
this.user = user;
|
||||
}
|
||||
|
||||
public Collection<UserConsentRoleEntity> getGrantedRoles() {
|
||||
return grantedRoles;
|
||||
public Collection<UserConsentClientScopeEntity> getGrantedClientScopes() {
|
||||
return grantedClientScopes;
|
||||
}
|
||||
|
||||
public void setGrantedRoles(Collection<UserConsentRoleEntity> grantedRoles) {
|
||||
this.grantedRoles = grantedRoles;
|
||||
}
|
||||
|
||||
public Collection<UserConsentProtocolMapperEntity> getGrantedProtocolMappers() {
|
||||
return grantedProtocolMappers;
|
||||
}
|
||||
|
||||
public void setGrantedProtocolMappers(Collection<UserConsentProtocolMapperEntity> grantedProtocolMappers) {
|
||||
this.grantedProtocolMappers = grantedProtocolMappers;
|
||||
public void setGrantedClientScopes(Collection<UserConsentClientScopeEntity> grantedClientScopes) {
|
||||
this.grantedClientScopes = grantedClientScopes;
|
||||
}
|
||||
|
||||
public Long getCreatedDate() {
|
||||
|
|
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.Table;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="deleteUserConsentProtMappersByRealm", query=
|
||||
"delete from UserConsentProtocolMapperEntity csm where csm.userConsent IN (select consent from UserConsentEntity consent where consent.user IN (select user from UserEntity user where user.realmId = :realmId))"),
|
||||
@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="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")
|
||||
@IdClass(UserConsentProtocolMapperEntity.Key.class)
|
||||
public class UserConsentProtocolMapperEntity {
|
||||
|
||||
@Id
|
||||
@ManyToOne(fetch= FetchType.LAZY)
|
||||
@JoinColumn(name = "USER_CONSENT_ID")
|
||||
protected UserConsentEntity userConsent;
|
||||
|
||||
@Id
|
||||
@Column(name="PROTOCOL_MAPPER_ID")
|
||||
protected String protocolMapperId;
|
||||
|
||||
public UserConsentEntity getUserConsent() {
|
||||
return userConsent;
|
||||
}
|
||||
|
||||
public void setUserConsent(UserConsentEntity userConsent) {
|
||||
this.userConsent = userConsent;
|
||||
}
|
||||
|
||||
public String getProtocolMapperId() {
|
||||
return protocolMapperId;
|
||||
}
|
||||
|
||||
public void setProtocolMapperId(String protocolMapperId) {
|
||||
this.protocolMapperId = protocolMapperId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null) return false;
|
||||
if (!(o instanceof UserConsentProtocolMapperEntity)) return false;
|
||||
|
||||
UserConsentProtocolMapperEntity that = (UserConsentProtocolMapperEntity)o;
|
||||
Key myKey = new Key(this.userConsent, this.protocolMapperId);
|
||||
Key hisKey = new Key(that.userConsent, that.protocolMapperId);
|
||||
return myKey.equals(hisKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
Key myKey = new Key(this.userConsent, this.protocolMapperId);
|
||||
return myKey.hashCode();
|
||||
}
|
||||
|
||||
public static class Key implements Serializable {
|
||||
|
||||
protected UserConsentEntity userConsent;
|
||||
|
||||
protected String protocolMapperId;
|
||||
|
||||
public Key() {
|
||||
}
|
||||
|
||||
public Key(UserConsentEntity userConsent, String protocolMapperId) {
|
||||
this.userConsent = userConsent;
|
||||
this.protocolMapperId = protocolMapperId;
|
||||
}
|
||||
|
||||
public UserConsentEntity getUserConsent() {
|
||||
return userConsent;
|
||||
}
|
||||
|
||||
public String getProtocolMapperId() {
|
||||
return protocolMapperId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Key key = (Key) o;
|
||||
|
||||
if (userConsent != null ? !userConsent.getId().equals(key.userConsent != null ? key.userConsent.getId() : null) : key.userConsent != null) return false;
|
||||
if (protocolMapperId != null ? !protocolMapperId.equals(key.protocolMapperId) : key.protocolMapperId != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = userConsent != null ? userConsent.getId().hashCode() : 0;
|
||||
result = 31 * result + (protocolMapperId != null ? protocolMapperId.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.models.jpa.entities;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.Table;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="deleteUserConsentRolesByRealm", query="delete from UserConsentRoleEntity grantedRole where grantedRole.userConsent IN (select consent from UserConsentEntity consent where consent.user IN (select user from UserEntity user where user.realmId = :realmId))"),
|
||||
@NamedQuery(name="deleteUserConsentRolesByRealmAndLink", query="delete from UserConsentRoleEntity grantedRole where grantedRole.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="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")
|
||||
@IdClass(UserConsentRoleEntity.Key.class)
|
||||
public class UserConsentRoleEntity {
|
||||
|
||||
@Id
|
||||
@ManyToOne(fetch= FetchType.LAZY)
|
||||
@JoinColumn(name = "USER_CONSENT_ID")
|
||||
protected UserConsentEntity userConsent;
|
||||
|
||||
@Id
|
||||
@Column(name="ROLE_ID")
|
||||
protected String roleId;
|
||||
|
||||
public UserConsentEntity getUserConsent() {
|
||||
return userConsent;
|
||||
}
|
||||
|
||||
public void setUserConsent(UserConsentEntity userConsent) {
|
||||
this.userConsent = userConsent;
|
||||
}
|
||||
|
||||
public String getRoleId() {
|
||||
return roleId;
|
||||
}
|
||||
|
||||
public void setRoleId(String roleId) {
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null) return false;
|
||||
if (!(o instanceof UserConsentRoleEntity)) return false;
|
||||
|
||||
UserConsentRoleEntity that = (UserConsentRoleEntity)o;
|
||||
Key myKey = new Key(this.userConsent, this.roleId);
|
||||
Key hisKey = new Key(that.userConsent, that.roleId);
|
||||
return myKey.equals(hisKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
Key myKey = new Key(this.userConsent, this.roleId);
|
||||
return myKey.hashCode();
|
||||
}
|
||||
|
||||
public static class Key implements Serializable {
|
||||
|
||||
protected UserConsentEntity userConsent;
|
||||
|
||||
protected String roleId;
|
||||
|
||||
public Key() {
|
||||
}
|
||||
|
||||
public Key(UserConsentEntity userConsent, String roleId) {
|
||||
this.userConsent = userConsent;
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
public UserConsentEntity getUserConsent() {
|
||||
return userConsent;
|
||||
}
|
||||
|
||||
public String getRoleId() {
|
||||
return roleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Key key = (Key) o;
|
||||
|
||||
if (userConsent != null ? !userConsent.getId().equals(key.userConsent != null ? key.userConsent.getId() : null) : key.userConsent != null) return false;
|
||||
if (roleId != null ? !roleId.equals(key.roleId) : key.roleId != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = userConsent != null ? userConsent.getId().hashCode() : 0;
|
||||
result = 31 * result + (roleId != null ? roleId.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -22,6 +22,7 @@ import org.keycloak.component.ComponentModel;
|
|||
import org.keycloak.credential.CredentialModel;
|
||||
import org.keycloak.credential.UserCredentialStore;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.FederatedIdentityModel;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
|
@ -32,7 +33,6 @@ 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;
|
||||
|
@ -41,9 +41,8 @@ import org.keycloak.storage.federated.UserFederatedStorageProvider;
|
|||
import org.keycloak.storage.jpa.entity.BrokerLinkEntity;
|
||||
import org.keycloak.storage.jpa.entity.FederatedUser;
|
||||
import org.keycloak.storage.jpa.entity.FederatedUserAttributeEntity;
|
||||
import org.keycloak.storage.jpa.entity.FederatedUserConsentClientScopeEntity;
|
||||
import org.keycloak.storage.jpa.entity.FederatedUserConsentEntity;
|
||||
import org.keycloak.storage.jpa.entity.FederatedUserConsentProtocolMapperEntity;
|
||||
import org.keycloak.storage.jpa.entity.FederatedUserConsentRoleEntity;
|
||||
import org.keycloak.storage.jpa.entity.FederatedUserCredentialAttributeEntity;
|
||||
import org.keycloak.storage.jpa.entity.FederatedUserCredentialEntity;
|
||||
import org.keycloak.storage.jpa.entity.FederatedUserGroupMembershipEntity;
|
||||
|
@ -361,71 +360,41 @@ public class JpaUserFederatedStorageProvider implements
|
|||
model.setCreatedDate(entity.getCreatedDate());
|
||||
model.setLastUpdatedDate(entity.getLastUpdatedDate());
|
||||
|
||||
Collection<FederatedUserConsentRoleEntity> grantedRoleEntities = entity.getGrantedRoles();
|
||||
if (grantedRoleEntities != null) {
|
||||
for (FederatedUserConsentRoleEntity grantedRole : grantedRoleEntities) {
|
||||
RoleModel grantedRoleModel = realm.getRoleById(grantedRole.getRoleId());
|
||||
if (grantedRoleModel != null) {
|
||||
model.addGrantedRole(grantedRoleModel);
|
||||
Collection<FederatedUserConsentClientScopeEntity> grantedClientScopeEntities = entity.getGrantedClientScopes();
|
||||
if (grantedClientScopeEntities != null) {
|
||||
for (FederatedUserConsentClientScopeEntity grantedClientScope : grantedClientScopeEntities) {
|
||||
ClientScopeModel grantedClientScopeModel = realm.getClientScopeById(grantedClientScope.getScopeId());
|
||||
if (grantedClientScopeModel != null) {
|
||||
model.addGrantedClientScope(grantedClientScopeModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collection<FederatedUserConsentProtocolMapperEntity> grantedProtocolMapperEntities = entity.getGrantedProtocolMappers();
|
||||
if (grantedProtocolMapperEntities != null) {
|
||||
for (FederatedUserConsentProtocolMapperEntity grantedProtMapper : grantedProtocolMapperEntities) {
|
||||
ProtocolMapperModel protocolMapper = client.getProtocolMapperById(grantedProtMapper.getProtocolMapperId());
|
||||
model.addGrantedProtocolMapper(protocolMapper);
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
// Update roles and protocolMappers to given consentEntity from the consentModel
|
||||
private void updateGrantedConsentEntity(FederatedUserConsentEntity consentEntity, UserConsentModel consentModel) {
|
||||
Collection<FederatedUserConsentProtocolMapperEntity> grantedProtocolMapperEntities = consentEntity.getGrantedProtocolMappers();
|
||||
Collection<FederatedUserConsentProtocolMapperEntity> mappersToRemove = new HashSet<>(grantedProtocolMapperEntities);
|
||||
Collection<FederatedUserConsentClientScopeEntity> grantedClientScopeEntities = consentEntity.getGrantedClientScopes();
|
||||
Collection<FederatedUserConsentClientScopeEntity> scopesToRemove = new HashSet<>(grantedClientScopeEntities);
|
||||
|
||||
for (ProtocolMapperModel protocolMapper : consentModel.getGrantedProtocolMappers()) {
|
||||
FederatedUserConsentProtocolMapperEntity grantedProtocolMapperEntity = new FederatedUserConsentProtocolMapperEntity();
|
||||
grantedProtocolMapperEntity.setUserConsent(consentEntity);
|
||||
grantedProtocolMapperEntity.setProtocolMapperId(protocolMapper.getId());
|
||||
for (ClientScopeModel clientScope : consentModel.getGrantedClientScopes()) {
|
||||
FederatedUserConsentClientScopeEntity grantedClientScopeEntity = new FederatedUserConsentClientScopeEntity();
|
||||
grantedClientScopeEntity.setUserConsent(consentEntity);
|
||||
grantedClientScopeEntity.setScopeId(clientScope.getId());
|
||||
|
||||
// Check if it's already there
|
||||
if (!grantedProtocolMapperEntities.contains(grantedProtocolMapperEntity)) {
|
||||
em.persist(grantedProtocolMapperEntity);
|
||||
if (!grantedClientScopeEntities.contains(grantedClientScopeEntity)) {
|
||||
em.persist(grantedClientScopeEntity);
|
||||
em.flush();
|
||||
grantedProtocolMapperEntities.add(grantedProtocolMapperEntity);
|
||||
grantedClientScopeEntities.add(grantedClientScopeEntity);
|
||||
} else {
|
||||
mappersToRemove.remove(grantedProtocolMapperEntity);
|
||||
scopesToRemove.remove(grantedClientScopeEntity);
|
||||
}
|
||||
}
|
||||
// Those mappers were no longer on consentModel and will be removed
|
||||
for (FederatedUserConsentProtocolMapperEntity toRemove : mappersToRemove) {
|
||||
grantedProtocolMapperEntities.remove(toRemove);
|
||||
em.remove(toRemove);
|
||||
}
|
||||
|
||||
Collection<FederatedUserConsentRoleEntity> grantedRoleEntities = consentEntity.getGrantedRoles();
|
||||
Set<FederatedUserConsentRoleEntity> rolesToRemove = new HashSet<>(grantedRoleEntities);
|
||||
for (RoleModel role : consentModel.getGrantedRoles()) {
|
||||
FederatedUserConsentRoleEntity consentRoleEntity = new FederatedUserConsentRoleEntity();
|
||||
consentRoleEntity.setUserConsent(consentEntity);
|
||||
consentRoleEntity.setRoleId(role.getId());
|
||||
|
||||
// Check if it's already there
|
||||
if (!grantedRoleEntities.contains(consentRoleEntity)) {
|
||||
em.persist(consentRoleEntity);
|
||||
em.flush();
|
||||
grantedRoleEntities.add(consentRoleEntity);
|
||||
} else {
|
||||
rolesToRemove.remove(consentRoleEntity);
|
||||
}
|
||||
}
|
||||
// Those roles were no longer on consentModel and will be removed
|
||||
for (FederatedUserConsentRoleEntity toRemove : rolesToRemove) {
|
||||
grantedRoleEntities.remove(toRemove);
|
||||
for (FederatedUserConsentClientScopeEntity toRemove : scopesToRemove) {
|
||||
grantedClientScopeEntities.remove(toRemove);
|
||||
em.remove(toRemove);
|
||||
}
|
||||
|
||||
|
@ -804,9 +773,7 @@ public class JpaUserFederatedStorageProvider implements
|
|||
|
||||
@Override
|
||||
public void preRemove(RealmModel realm) {
|
||||
int num = em.createNamedQuery("deleteFederatedUserConsentRolesByRealm")
|
||||
.setParameter("realmId", realm.getId()).executeUpdate();
|
||||
num = em.createNamedQuery("deleteFederatedUserConsentProtMappersByRealm")
|
||||
int num = em.createNamedQuery("deleteFederatedUserConsentClientScopesByRealm")
|
||||
.setParameter("realmId", realm.getId()).executeUpdate();
|
||||
num = em.createNamedQuery("deleteFederatedUserConsentsByRealm")
|
||||
.setParameter("realmId", realm.getId()).executeUpdate();
|
||||
|
@ -831,7 +798,6 @@ public class JpaUserFederatedStorageProvider implements
|
|||
@Override
|
||||
public void preRemove(RealmModel realm, RoleModel role) {
|
||||
em.createNamedQuery("deleteFederatedUserRoleMappingsByRole").setParameter("roleId", role.getId()).executeUpdate();
|
||||
em.createNamedQuery("deleteFederatedUserRoleMappingsByRole").setParameter("roleId", role.getId()).executeUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -843,15 +809,10 @@ public class JpaUserFederatedStorageProvider implements
|
|||
public void preRemove(RealmModel realm, ClientModel client) {
|
||||
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("deleteFederatedUserConsentClientScopesByClient").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")
|
||||
em.createNamedQuery("deleteFederatedUserConsentClientScopesByExternalClient")
|
||||
.setParameter("clientStorageProvider", clientStorageId.getProviderId())
|
||||
.setParameter("externalClientId",clientStorageId.getExternalId())
|
||||
.executeUpdate();
|
||||
|
@ -865,8 +826,13 @@ public class JpaUserFederatedStorageProvider implements
|
|||
|
||||
@Override
|
||||
public void preRemove(ProtocolMapperModel protocolMapper) {
|
||||
em.createNamedQuery("deleteFederatedUserConsentProtMappersByProtocolMapper")
|
||||
.setParameter("protocolMapperId", protocolMapper.getId())
|
||||
// No op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preRemove(ClientScopeModel clientScope) {
|
||||
em.createNamedQuery("deleteFederatedUserConsentClientScopesByClientScope")
|
||||
.setParameter("scopeId", clientScope.getId())
|
||||
.executeUpdate();
|
||||
}
|
||||
|
||||
|
@ -880,11 +846,7 @@ public class JpaUserFederatedStorageProvider implements
|
|||
.setParameter("userId", user.getId())
|
||||
.setParameter("realmId", realm.getId())
|
||||
.executeUpdate();
|
||||
em.createNamedQuery("deleteFederatedUserConsentProtMappersByUser")
|
||||
.setParameter("userId", user.getId())
|
||||
.setParameter("realmId", realm.getId())
|
||||
.executeUpdate();
|
||||
em.createNamedQuery("deleteFederatedUserConsentRolesByUser")
|
||||
em.createNamedQuery("deleteFederatedUserConsentClientScopesByUser")
|
||||
.setParameter("userId", user.getId())
|
||||
.setParameter("realmId", realm.getId())
|
||||
.executeUpdate();
|
||||
|
@ -929,10 +891,7 @@ public class JpaUserFederatedStorageProvider implements
|
|||
em.createNamedQuery("deleteFederatedAttributesByStorageProvider")
|
||||
.setParameter("storageProviderId", model.getId())
|
||||
.executeUpdate();
|
||||
em.createNamedQuery("deleteFederatedUserConsentProtMappersByStorageProvider")
|
||||
.setParameter("storageProviderId", model.getId())
|
||||
.executeUpdate();
|
||||
em.createNamedQuery("deleteFederatedUserRoleMappingsByStorageProvider")
|
||||
em.createNamedQuery("deleteFederatedUserConsentClientScopesByStorageProvider")
|
||||
.setParameter("storageProviderId", model.getId())
|
||||
.executeUpdate();
|
||||
em.createNamedQuery("deleteFederatedUserConsentsByStorageProvider")
|
||||
|
@ -957,10 +916,7 @@ public class JpaUserFederatedStorageProvider implements
|
|||
.setParameter("storageProviderId", model.getId())
|
||||
.executeUpdate();
|
||||
} else if (model.getProviderType().equals(ClientStorageProvider.class.getName())) {
|
||||
em.createNamedQuery("deleteFederatedUserConsentProtMappersByClientStorageProvider")
|
||||
.setParameter("clientStorageProvider", model.getId())
|
||||
.executeUpdate();
|
||||
em.createNamedQuery("deleteFederatedUserConsentRolesByClientStorageProvider")
|
||||
em.createNamedQuery("deleteFederatedUserConsentClientScopesByClientStorageProvider")
|
||||
.setParameter("clientStorageProvider", model.getId())
|
||||
.executeUpdate();
|
||||
em.createNamedQuery("deleteFederatedUserConsentsByClientStorageProvider")
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright 2017 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.storage.jpa.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="deleteFederatedUserConsentClientScopesByRealm", query="delete from FederatedUserConsentClientScopeEntity grantedScope where grantedScope.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.realmId = :realmId)"),
|
||||
@NamedQuery(name="deleteFederatedUserConsentClientScopesByUser", query="delete from FederatedUserConsentClientScopeEntity grantedScope where grantedScope.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.userId = :userId and consent.realmId = :realmId)"),
|
||||
@NamedQuery(name="deleteFederatedUserConsentClientScopesByStorageProvider", query="delete from FederatedUserConsentClientScopeEntity grantedScope where grantedScope.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.storageProviderId = :storageProviderId)"),
|
||||
@NamedQuery(name="deleteFederatedUserConsentClientScopesByClientScope", query="delete from FederatedUserConsentClientScopeEntity grantedScope where grantedScope.scopeId = :scopeId"),
|
||||
@NamedQuery(name="deleteFederatedUserConsentClientScopesByClient", query="delete from FederatedUserConsentClientScopeEntity grantedScope where grantedScope.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.clientId = :clientId)"),
|
||||
@NamedQuery(name="deleteFederatedUserConsentClientScopesByExternalClient", query="delete from FederatedUserConsentClientScopeEntity grantedScope where grantedScope.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider and consent.externalClientId = :externalClientId)"),
|
||||
@NamedQuery(name="deleteFederatedUserConsentClientScopesByClientStorageProvider", query="delete from FederatedUserConsentClientScopeEntity grantedScope where grantedScope.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.clientStorageProvider = :clientStorageProvider)"),
|
||||
})
|
||||
@Entity
|
||||
@Table(name="FED_USER_CONSENT_CL_SCOPE")
|
||||
@IdClass(FederatedUserConsentClientScopeEntity.Key.class)
|
||||
public class FederatedUserConsentClientScopeEntity {
|
||||
|
||||
@Id
|
||||
@ManyToOne(fetch= FetchType.LAZY)
|
||||
@JoinColumn(name = "USER_CONSENT_ID")
|
||||
protected FederatedUserConsentEntity userConsent;
|
||||
|
||||
@Id
|
||||
@Column(name="SCOPE_ID")
|
||||
protected String scopeId;
|
||||
|
||||
public FederatedUserConsentEntity getUserConsent() {
|
||||
return userConsent;
|
||||
}
|
||||
|
||||
public void setUserConsent(FederatedUserConsentEntity userConsent) {
|
||||
this.userConsent = userConsent;
|
||||
}
|
||||
|
||||
public String getScopeId() {
|
||||
return scopeId;
|
||||
}
|
||||
|
||||
public void setScopeId(String scopeId) {
|
||||
this.scopeId = scopeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null) return false;
|
||||
if (!(o instanceof FederatedUserConsentClientScopeEntity)) return false;
|
||||
|
||||
FederatedUserConsentClientScopeEntity that = ( FederatedUserConsentClientScopeEntity)o;
|
||||
FederatedUserConsentClientScopeEntity.Key myKey = new FederatedUserConsentClientScopeEntity.Key(this.userConsent, this.scopeId);
|
||||
FederatedUserConsentClientScopeEntity.Key hisKey = new FederatedUserConsentClientScopeEntity.Key(that.userConsent, that.scopeId);
|
||||
return myKey.equals(hisKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
FederatedUserConsentClientScopeEntity.Key myKey = new FederatedUserConsentClientScopeEntity.Key(this.userConsent, this.scopeId);
|
||||
return myKey.hashCode();
|
||||
}
|
||||
|
||||
public static class Key implements Serializable {
|
||||
|
||||
protected FederatedUserConsentEntity userConsent;
|
||||
|
||||
protected String scopeId;
|
||||
|
||||
public Key() {
|
||||
}
|
||||
|
||||
public Key(FederatedUserConsentEntity userConsent, String scopeId) {
|
||||
this.userConsent = userConsent;
|
||||
this.scopeId = scopeId;
|
||||
}
|
||||
|
||||
public FederatedUserConsentEntity getUserConsent() {
|
||||
return userConsent;
|
||||
}
|
||||
|
||||
public String getScopeId() {
|
||||
return scopeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
FederatedUserConsentClientScopeEntity.Key key = (FederatedUserConsentClientScopeEntity.Key) o;
|
||||
|
||||
if (userConsent != null ? !userConsent.getId().equals(key.userConsent != null ? key.userConsent.getId() : null) : key.userConsent != null) return false;
|
||||
if (scopeId != null ? !scopeId.equals(key.scopeId) : key.scopeId != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = userConsent != null ? userConsent.getId().hashCode() : 0;
|
||||
result = 31 * result + (scopeId != null ? scopeId.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -83,10 +83,7 @@ public class FederatedUserConsentEntity {
|
|||
|
||||
|
||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "userConsent")
|
||||
Collection<FederatedUserConsentRoleEntity> grantedRoles = new ArrayList<FederatedUserConsentRoleEntity>();
|
||||
|
||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "userConsent")
|
||||
Collection<FederatedUserConsentProtocolMapperEntity> grantedProtocolMappers = new ArrayList<FederatedUserConsentProtocolMapperEntity>();
|
||||
Collection<FederatedUserConsentClientScopeEntity> grantedClientScopes = new ArrayList<>();
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
|
@ -144,20 +141,12 @@ public class FederatedUserConsentEntity {
|
|||
this.externalClientId = externalClientId;
|
||||
}
|
||||
|
||||
public Collection<FederatedUserConsentRoleEntity> getGrantedRoles() {
|
||||
return grantedRoles;
|
||||
public Collection<FederatedUserConsentClientScopeEntity> getGrantedClientScopes() {
|
||||
return grantedClientScopes;
|
||||
}
|
||||
|
||||
public void setGrantedRoles(Collection<FederatedUserConsentRoleEntity> grantedRoles) {
|
||||
this.grantedRoles = grantedRoles;
|
||||
}
|
||||
|
||||
public Collection<FederatedUserConsentProtocolMapperEntity> getGrantedProtocolMappers() {
|
||||
return grantedProtocolMappers;
|
||||
}
|
||||
|
||||
public void setGrantedProtocolMappers(Collection<FederatedUserConsentProtocolMapperEntity> grantedProtocolMappers) {
|
||||
this.grantedProtocolMappers = grantedProtocolMappers;
|
||||
public void setGrantedClientScopes(Collection<FederatedUserConsentClientScopeEntity> grantedClientScopes) {
|
||||
this.grantedClientScopes = grantedClientScopes;
|
||||
}
|
||||
|
||||
public Long getCreatedDate() {
|
||||
|
|
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.storage.jpa.entity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.Table;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="deleteFederatedUserConsentProtMappersByRealm", query=
|
||||
"delete from FederatedUserConsentProtocolMapperEntity csm where csm.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.realmId = :realmId)"),
|
||||
@NamedQuery(name="deleteFederatedUserConsentProtMappersByUser", query="delete from FederatedUserConsentProtocolMapperEntity csm where csm.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.userId = :userId and consent.realmId = :realmId)"),
|
||||
@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")
|
||||
@IdClass(FederatedUserConsentProtocolMapperEntity.Key.class)
|
||||
public class FederatedUserConsentProtocolMapperEntity {
|
||||
|
||||
@Id
|
||||
@ManyToOne(fetch= FetchType.LAZY)
|
||||
@JoinColumn(name = "USER_CONSENT_ID")
|
||||
protected FederatedUserConsentEntity userConsent;
|
||||
|
||||
@Id
|
||||
@Column(name="PROTOCOL_MAPPER_ID")
|
||||
protected String protocolMapperId;
|
||||
|
||||
public FederatedUserConsentEntity getUserConsent() {
|
||||
return userConsent;
|
||||
}
|
||||
|
||||
public void setUserConsent(FederatedUserConsentEntity userConsent) {
|
||||
this.userConsent = userConsent;
|
||||
}
|
||||
|
||||
public String getProtocolMapperId() {
|
||||
return protocolMapperId;
|
||||
}
|
||||
|
||||
public void setProtocolMapperId(String protocolMapperId) {
|
||||
this.protocolMapperId = protocolMapperId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null) return false;
|
||||
if (!(o instanceof FederatedUserConsentProtocolMapperEntity)) return false;
|
||||
|
||||
FederatedUserConsentProtocolMapperEntity that = (FederatedUserConsentProtocolMapperEntity)o;
|
||||
Key myKey = new Key(this.userConsent, this.protocolMapperId);
|
||||
Key hisKey = new Key(that.userConsent, that.protocolMapperId);
|
||||
return myKey.equals(hisKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
Key myKey = new Key(this.userConsent, this.protocolMapperId);
|
||||
return myKey.hashCode();
|
||||
}
|
||||
|
||||
public static class Key implements Serializable {
|
||||
|
||||
protected FederatedUserConsentEntity userConsent;
|
||||
|
||||
protected String protocolMapperId;
|
||||
|
||||
public Key() {
|
||||
}
|
||||
|
||||
public Key(FederatedUserConsentEntity userConsent, String protocolMapperId) {
|
||||
this.userConsent = userConsent;
|
||||
this.protocolMapperId = protocolMapperId;
|
||||
}
|
||||
|
||||
public FederatedUserConsentEntity getUserConsent() {
|
||||
return userConsent;
|
||||
}
|
||||
|
||||
public String getProtocolMapperId() {
|
||||
return protocolMapperId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Key key = (Key) o;
|
||||
|
||||
if (userConsent != null ? !userConsent.getId().equals(key.userConsent != null ? key.userConsent.getId() : null) : key.userConsent != null) return false;
|
||||
if (protocolMapperId != null ? !protocolMapperId.equals(key.protocolMapperId) : key.protocolMapperId != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = userConsent != null ? userConsent.getId().hashCode() : 0;
|
||||
result = 31 * result + (protocolMapperId != null ? protocolMapperId.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.storage.jpa.entity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.Table;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="deleteFederatedUserConsentRolesByRealm", query="delete from FederatedUserConsentRoleEntity grantedRole where grantedRole.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.realmId = :realmId)"),
|
||||
@NamedQuery(name="deleteFederatedUserConsentRolesByUser", query="delete from FederatedUserConsentRoleEntity grantedRole where grantedRole.userConsent IN (select consent from FederatedUserConsentEntity consent where consent.userId = :userId and consent.realmId = :realmId)"),
|
||||
@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")
|
||||
@IdClass(FederatedUserConsentRoleEntity.Key.class)
|
||||
public class FederatedUserConsentRoleEntity {
|
||||
|
||||
@Id
|
||||
@ManyToOne(fetch= FetchType.LAZY)
|
||||
@JoinColumn(name = "USER_CONSENT_ID")
|
||||
protected FederatedUserConsentEntity userConsent;
|
||||
|
||||
@Id
|
||||
@Column(name="ROLE_ID")
|
||||
protected String roleId;
|
||||
|
||||
public FederatedUserConsentEntity getUserConsent() {
|
||||
return userConsent;
|
||||
}
|
||||
|
||||
public void setUserConsent(FederatedUserConsentEntity userConsent) {
|
||||
this.userConsent = userConsent;
|
||||
}
|
||||
|
||||
public String getRoleId() {
|
||||
return roleId;
|
||||
}
|
||||
|
||||
public void setRoleId(String roleId) {
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null) return false;
|
||||
if (!(o instanceof FederatedUserConsentRoleEntity)) return false;
|
||||
|
||||
FederatedUserConsentRoleEntity that = (FederatedUserConsentRoleEntity)o;
|
||||
Key myKey = new Key(this.userConsent, this.roleId);
|
||||
Key hisKey = new Key(that.userConsent, that.roleId);
|
||||
return myKey.equals(hisKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
Key myKey = new Key(this.userConsent, this.roleId);
|
||||
return myKey.hashCode();
|
||||
}
|
||||
|
||||
public static class Key implements Serializable {
|
||||
|
||||
protected FederatedUserConsentEntity userConsent;
|
||||
|
||||
protected String roleId;
|
||||
|
||||
public Key() {
|
||||
}
|
||||
|
||||
public Key(FederatedUserConsentEntity userConsent, String roleId) {
|
||||
this.userConsent = userConsent;
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
public FederatedUserConsentEntity getUserConsent() {
|
||||
return userConsent;
|
||||
}
|
||||
|
||||
public String getRoleId() {
|
||||
return roleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Key key = (Key) o;
|
||||
|
||||
if (userConsent != null ? !userConsent.getId().equals(key.userConsent != null ? key.userConsent.getId() : null) : key.userConsent != null) return false;
|
||||
if (roleId != null ? !roleId.equals(key.roleId) : key.roleId != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = userConsent != null ? userConsent.getId().hashCode() : 0;
|
||||
result = 31 * result + (roleId != null ? roleId.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -84,4 +84,184 @@
|
|||
<addPrimaryKey columnNames="USER_SESSION_ID,CLIENT_ID, CLIENT_STORAGE_PROVIDER, EXTERNAL_CLIENT_ID, OFFLINE_FLAG" constraintName="CONSTRAINT_OFFL_CL_SES_PK3" tableName="OFFLINE_CLIENT_SESSION"/>
|
||||
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="mposolda@redhat.com" id="4.0.0-KEYCLOAK-5579">
|
||||
|
||||
<!-- 1 - Rename clientTemplate to clientScope and drop some unused things from clientTemplate -->
|
||||
<dropForeignKeyConstraint baseTableName="CLIENT_TEMPLATE_ATTRIBUTES" constraintName="FK_CL_TEMPL_ATTR_TEMPL" />
|
||||
<renameTable oldTableName="CLIENT_TEMPLATE_ATTRIBUTES" newTableName="CLIENT_SCOPE_ATTRIBUTES" />
|
||||
<renameColumn tableName="CLIENT_SCOPE_ATTRIBUTES" newColumnName="SCOPE_ID" oldColumnName="TEMPLATE_ID" columnDataType="VARCHAR(36)" />
|
||||
|
||||
<dropForeignKeyConstraint baseTableName="TEMPLATE_SCOPE_MAPPING" constraintName="FK_TEMPL_SCOPE_TEMPL" />
|
||||
<dropForeignKeyConstraint baseTableName="TEMPLATE_SCOPE_MAPPING" constraintName="FK_TEMPL_SCOPE_ROLE" />
|
||||
<renameTable oldTableName="TEMPLATE_SCOPE_MAPPING" newTableName="CLIENT_SCOPE_ROLE_MAPPING" />
|
||||
<renameColumn tableName="CLIENT_SCOPE_ROLE_MAPPING" newColumnName="SCOPE_ID" oldColumnName="TEMPLATE_ID" columnDataType="VARCHAR(36)" />
|
||||
|
||||
<dropForeignKeyConstraint baseTableName="CLIENT" constraintName="FK_CLI_TMPLT_CLIENT" />
|
||||
|
||||
<dropForeignKeyConstraint baseTableName="PROTOCOL_MAPPER" constraintName="FK_CLI_TMPLT_MAPPER" />
|
||||
<renameColumn tableName="PROTOCOL_MAPPER" newColumnName="CLIENT_SCOPE_ID" oldColumnName="CLIENT_TEMPLATE_ID" columnDataType="VARCHAR(36)" />
|
||||
|
||||
<dropForeignKeyConstraint baseTableName="CLIENT_TEMPLATE" constraintName="FK_REALM_CLI_TMPLT" />
|
||||
<dropUniqueConstraint constraintName="UK_CLI_TEMPLATE" tableName="CLIENT_TEMPLATE"/>
|
||||
|
||||
<dropDefaultValue tableName="CLIENT_TEMPLATE" columnName="FULL_SCOPE_ALLOWED" />
|
||||
<dropDefaultValue tableName="CLIENT_TEMPLATE" columnName="CONSENT_REQUIRED" />
|
||||
<dropDefaultValue tableName="CLIENT_TEMPLATE" columnName="STANDARD_FLOW_ENABLED" />
|
||||
<dropDefaultValue tableName="CLIENT_TEMPLATE" columnName="IMPLICIT_FLOW_ENABLED" />
|
||||
<dropDefaultValue tableName="CLIENT_TEMPLATE" columnName="DIRECT_ACCESS_GRANTS_ENABLED" />
|
||||
<dropDefaultValue tableName="CLIENT_TEMPLATE" columnName="SERVICE_ACCOUNTS_ENABLED" />
|
||||
<dropDefaultValue tableName="CLIENT_TEMPLATE" columnName="FRONTCHANNEL_LOGOUT" />
|
||||
<dropDefaultValue tableName="CLIENT_TEMPLATE" columnName="BEARER_ONLY" />
|
||||
<dropDefaultValue tableName="CLIENT_TEMPLATE" columnName="PUBLIC_CLIENT" />
|
||||
|
||||
<dropIndex tableName="CLIENT_SCOPE_ROLE_MAPPING" indexName="IDX_TEMPL_SCOPE_MAPP_ROLE" />
|
||||
<dropIndex tableName="PROTOCOL_MAPPER" indexName="IDX_PROTO_MAPP_CLIENT_TEMPL" />
|
||||
<dropIndex tableName="CLIENT" indexName="IDX_CLIENT_CLIENT_TEMPL_ID" />
|
||||
|
||||
<dropColumn tableName="CLIENT_TEMPLATE" columnName="FULL_SCOPE_ALLOWED" />
|
||||
<dropColumn tableName="CLIENT_TEMPLATE" columnName="CONSENT_REQUIRED" />
|
||||
<dropColumn tableName="CLIENT_TEMPLATE" columnName="STANDARD_FLOW_ENABLED" />
|
||||
<dropColumn tableName="CLIENT_TEMPLATE" columnName="IMPLICIT_FLOW_ENABLED" />
|
||||
<dropColumn tableName="CLIENT_TEMPLATE" columnName="DIRECT_ACCESS_GRANTS_ENABLED" />
|
||||
<dropColumn tableName="CLIENT_TEMPLATE" columnName="SERVICE_ACCOUNTS_ENABLED" />
|
||||
<dropColumn tableName="CLIENT_TEMPLATE" columnName="FRONTCHANNEL_LOGOUT" />
|
||||
<dropColumn tableName="CLIENT_TEMPLATE" columnName="BEARER_ONLY" />
|
||||
<dropColumn tableName="CLIENT_TEMPLATE" columnName="PUBLIC_CLIENT" />
|
||||
|
||||
<renameTable oldTableName="CLIENT_TEMPLATE" newTableName="CLIENT_SCOPE" />
|
||||
|
||||
<addUniqueConstraint columnNames="REALM_ID,NAME" constraintName="UK_CLI_SCOPE" tableName="CLIENT_SCOPE"/>
|
||||
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="CLIENT_SCOPE"
|
||||
constraintName="FK_REALM_CLI_SCOPE" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||
|
||||
<addForeignKeyConstraint baseColumnNames="CLIENT_SCOPE_ID" baseTableName="PROTOCOL_MAPPER"
|
||||
constraintName="FK_CLI_SCOPE_MAPPER" referencedColumnNames="ID" referencedTableName="CLIENT_SCOPE"/>
|
||||
|
||||
<addForeignKeyConstraint baseColumnNames="SCOPE_ID" baseTableName="CLIENT_SCOPE_ROLE_MAPPING"
|
||||
constraintName="FK_CL_SCOPE_RM_SCOPE" referencedColumnNames="ID" referencedTableName="CLIENT_SCOPE"/>
|
||||
<addForeignKeyConstraint baseColumnNames="ROLE_ID" baseTableName="CLIENT_SCOPE_ROLE_MAPPING"
|
||||
constraintName="FK_CL_SCOPE_RM_ROLE" referencedColumnNames="ID" referencedTableName="KEYCLOAK_ROLE"/>
|
||||
|
||||
<addForeignKeyConstraint baseTableName="CLIENT_SCOPE_ATTRIBUTES" baseColumnNames="SCOPE_ID"
|
||||
constraintName="FK_CL_SCOPE_ATTR_SCOPE" referencedTableName="CLIENT_SCOPE" referencedColumnNames="ID" />
|
||||
|
||||
<!-- 2 - Client binding to more clientScopes -->
|
||||
<!-- Foreign key dropped above TODO:mposolda migration existing clientTemplate to default clientScope -->
|
||||
<dropColumn tableName="CLIENT" columnName="CLIENT_TEMPLATE_ID" />
|
||||
<dropDefaultValue tableName="CLIENT" columnName="USE_TEMPLATE_CONFIG"/>
|
||||
<dropDefaultValue tableName="CLIENT" columnName="USE_TEMPLATE_SCOPE" />
|
||||
<dropDefaultValue tableName="CLIENT" columnName="USE_TEMPLATE_MAPPERS" />
|
||||
<dropColumn tableName="CLIENT" columnName="USE_TEMPLATE_CONFIG" />
|
||||
<dropColumn tableName="CLIENT" columnName="USE_TEMPLATE_SCOPE" />
|
||||
<dropColumn tableName="CLIENT" columnName="USE_TEMPLATE_MAPPERS" />
|
||||
|
||||
<createTable tableName="CLIENT_SCOPE_CLIENT">
|
||||
<column name="CLIENT_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="SCOPE_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="DEFAULT_SCOPE" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<addPrimaryKey columnNames="CLIENT_ID, SCOPE_ID" constraintName="C_CLI_SCOPE_BIND" tableName="CLIENT_SCOPE_CLIENT"/>
|
||||
<addForeignKeyConstraint baseColumnNames="CLIENT_ID" baseTableName="CLIENT_SCOPE_CLIENT" constraintName="FK_C_CLI_SCOPE_CLIENT" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||
<addForeignKeyConstraint baseColumnNames="SCOPE_ID" baseTableName="CLIENT_SCOPE_CLIENT" constraintName="FK_C_CLI_SCOPE_SCOPE" referencedColumnNames="ID" referencedTableName="CLIENT_SCOPE"/>
|
||||
|
||||
<!-- Default client scopes (global scopes configured at realm level) -->
|
||||
<createTable tableName="DEFAULT_CLIENT_SCOPE">
|
||||
<column name="REALM_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="SCOPE_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="DEFAULT_SCOPE" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<addPrimaryKey columnNames="REALM_ID, SCOPE_ID" constraintName="R_DEF_CLI_SCOPE_BIND" tableName="DEFAULT_CLIENT_SCOPE"/>
|
||||
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="DEFAULT_CLIENT_SCOPE" constraintName="FK_R_DEF_CLI_SCOPE_REALM" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||
<addForeignKeyConstraint baseColumnNames="SCOPE_ID" baseTableName="DEFAULT_CLIENT_SCOPE" constraintName="FK_R_DEF_CLI_SCOPE_SCOPE" referencedColumnNames="ID" referencedTableName="CLIENT_SCOPE"/>
|
||||
|
||||
<!-- Remove scopeParamRequired -->
|
||||
<dropDefaultValue tableName="KEYCLOAK_ROLE" columnName="SCOPE_PARAM_REQUIRED" />
|
||||
<dropColumn tableName="KEYCLOAK_ROLE" columnName="SCOPE_PARAM_REQUIRED" />
|
||||
|
||||
<!-- Drop consent stuff from protocolMappers table -->
|
||||
<dropDefaultValue tableName="PROTOCOL_MAPPER" columnName="CONSENT_REQUIRED" />
|
||||
<dropColumn tableName="PROTOCOL_MAPPER" columnName="CONSENT_REQUIRED" />
|
||||
<dropColumn tableName="PROTOCOL_MAPPER" columnName="CONSENT_TEXT" />
|
||||
|
||||
<!-- Consents related changes -->
|
||||
<dropForeignKeyConstraint baseTableName="USER_CONSENT_ROLE" constraintName="FK_GRNTCSNT_ROLE_GR" />
|
||||
<dropTable tableName="USER_CONSENT_ROLE" />
|
||||
<dropForeignKeyConstraint baseTableName="USER_CONSENT_PROT_MAPPER" constraintName="FK_GRNTCSNT_PRM_GR" />
|
||||
<dropTable tableName="USER_CONSENT_PROT_MAPPER" />
|
||||
|
||||
<createTable tableName="USER_CONSENT_CLIENT_SCOPE">
|
||||
<column name="USER_CONSENT_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="SCOPE_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<addPrimaryKey columnNames="USER_CONSENT_ID, SCOPE_ID" constraintName="CONSTRAINT_GRNTCSNT_CLSC_PM" tableName="USER_CONSENT_CLIENT_SCOPE"/>
|
||||
<addForeignKeyConstraint baseColumnNames="USER_CONSENT_ID" baseTableName="USER_CONSENT_CLIENT_SCOPE" constraintName="FK_GRNTCSNT_CLSC_USC" referencedColumnNames="ID" referencedTableName="USER_CONSENT"/>
|
||||
|
||||
<!-- Federated consents related changes -->
|
||||
<dropTable tableName="FED_USER_CONSENT_ROLE" />
|
||||
<dropTable tableName="FED_USER_CONSENT_PROT_MAPPER" />
|
||||
|
||||
<createTable tableName="FED_USER_CONSENT_CL_SCOPE">
|
||||
<column name="USER_CONSENT_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="SCOPE_ID" type="VARCHAR(36)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<addPrimaryKey columnNames="USER_CONSENT_ID, SCOPE_ID" constraintName="CONSTRAINT_FGRNTCSNT_CLSC_PM" tableName="FED_USER_CONSENT_CL_SCOPE"/>
|
||||
|
||||
<!-- Indexes for foreign keys -->
|
||||
<createIndex indexName="IDX_REALM_CLSCOPE" tableName="CLIENT_SCOPE">
|
||||
<column name="REALM_ID" type="VARCHAR(36)"/>
|
||||
</createIndex>
|
||||
<createIndex indexName="IDX_CLSCOPE_PROTMAP" tableName="PROTOCOL_MAPPER">
|
||||
<column name="CLIENT_SCOPE_ID" type="VARCHAR(36)"/>
|
||||
</createIndex>
|
||||
<createIndex indexName="IDX_CLSCOPE_ROLE" tableName="CLIENT_SCOPE_ROLE_MAPPING">
|
||||
<column name="SCOPE_ID" type="VARCHAR(36)"/>
|
||||
</createIndex>
|
||||
<createIndex indexName="IDX_ROLE_CLSCOPE" tableName="CLIENT_SCOPE_ROLE_MAPPING">
|
||||
<column name="ROLE_ID" type="VARCHAR(36)"/>
|
||||
</createIndex>
|
||||
<createIndex indexName="IDX_CLSCOPE_ATTRS" tableName="CLIENT_SCOPE_ATTRIBUTES">
|
||||
<column name="SCOPE_ID" type="VARCHAR(36)"/>
|
||||
</createIndex>
|
||||
|
||||
<createIndex indexName="IDX_CLSCOPE_CL" tableName="CLIENT_SCOPE_CLIENT">
|
||||
<column name="CLIENT_ID" type="VARCHAR(36)"/>
|
||||
</createIndex>
|
||||
<createIndex indexName="IDX_CL_CLSCOPE" tableName="CLIENT_SCOPE_CLIENT">
|
||||
<column name="SCOPE_ID" type="VARCHAR(36)"/>
|
||||
</createIndex>
|
||||
|
||||
<createIndex indexName="IDX_DEFCLS_REALM" tableName="DEFAULT_CLIENT_SCOPE">
|
||||
<column name="REALM_ID" type="VARCHAR(36)"/>
|
||||
</createIndex>
|
||||
<createIndex indexName="IDX_DEFCLS_SCOPE" tableName="DEFAULT_CLIENT_SCOPE">
|
||||
<column name="SCOPE_ID" type="VARCHAR(36)"/>
|
||||
</createIndex>
|
||||
|
||||
<createIndex indexName="IDX_USCONSENT_CLSCOPE" tableName="USER_CONSENT_CLIENT_SCOPE">
|
||||
<column name="USER_CONSENT_ID" type="VARCHAR(36)"/>
|
||||
</createIndex>
|
||||
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
|
|
|
@ -41,8 +41,7 @@
|
|||
<class>org.keycloak.models.jpa.entities.IdentityProviderMapperEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.ProtocolMapperEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.UserConsentEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.UserConsentRoleEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.UserConsentProtocolMapperEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.UserConsentClientScopeEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.AuthenticationFlowEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.AuthenticationExecutionEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.AuthenticatorConfigEntity</class>
|
||||
|
@ -53,8 +52,10 @@
|
|||
<class>org.keycloak.models.jpa.entities.GroupAttributeEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.GroupRoleMappingEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.UserGroupMembershipEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.ClientTemplateEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.TemplateScopeMappingEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.ClientScopeEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.ClientScopeRoleMappingEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.ClientScopeClientMappingEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.DefaultClientScopeRealmMappingEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.ClientInitialAccessEntity</class>
|
||||
|
||||
<!-- JpaAuditProviders -->
|
||||
|
@ -74,8 +75,7 @@
|
|||
<class>org.keycloak.storage.jpa.entity.FederatedUser</class>
|
||||
<class>org.keycloak.storage.jpa.entity.FederatedUserAttributeEntity</class>
|
||||
<class>org.keycloak.storage.jpa.entity.FederatedUserConsentEntity</class>
|
||||
<class>org.keycloak.storage.jpa.entity.FederatedUserConsentRoleEntity</class>
|
||||
<class>org.keycloak.storage.jpa.entity.FederatedUserConsentProtocolMapperEntity</class>
|
||||
<class>org.keycloak.storage.jpa.entity.FederatedUserConsentClientScopeEntity</class>
|
||||
<class>org.keycloak.storage.jpa.entity.FederatedUserCredentialEntity</class>
|
||||
<class>org.keycloak.storage.jpa.entity.FederatedUserCredentialAttributeEntity</class>
|
||||
<class>org.keycloak.storage.jpa.entity.FederatedUserGroupMembershipEntity</class>
|
||||
|
|
|
@ -47,6 +47,7 @@ public interface Details {
|
|||
String REASON = "reason";
|
||||
String REVOKED_CLIENT = "revoked_client";
|
||||
String AUDIENCE = "audience";
|
||||
String SCOPE = "scope";
|
||||
String REQUESTED_ISSUER = "requested_issuer";
|
||||
String REQUESTED_SUBJECT = "requested_subject";
|
||||
String CLIENT_SESSION_STATE = "client_session_state";
|
||||
|
|
|
@ -141,7 +141,7 @@ public enum ResourceType {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
, CLIENT_TEMPLATE
|
||||
, CLIENT_SCOPE
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.keycloak.forms.login;
|
||||
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
@ -84,8 +85,7 @@ public interface LoginFormsProvider extends Provider {
|
|||
|
||||
LoginFormsProvider setClientSessionCode(String accessCode);
|
||||
|
||||
LoginFormsProvider setAccessRequest(List<RoleModel> realmRolesRequested, MultivaluedMap<String,RoleModel> resourceRolesRequested, List<ProtocolMapperModel> protocolMappers);
|
||||
LoginFormsProvider setAccessRequest(String message);
|
||||
LoginFormsProvider setAccessRequest(List<ClientScopeModel> clientScopesRequested);
|
||||
|
||||
/**
|
||||
* Set one global error message.
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.keycloak.migration.migrators.MigrateTo3_2_0;
|
|||
import org.keycloak.migration.migrators.MigrateTo3_4_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo3_4_1;
|
||||
import org.keycloak.migration.migrators.MigrateTo3_4_2;
|
||||
import org.keycloak.migration.migrators.MigrateTo4_0_0;
|
||||
import org.keycloak.migration.migrators.Migration;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
|
@ -70,7 +71,8 @@ public class MigrationModelManager {
|
|||
new MigrateTo3_2_0(),
|
||||
new MigrateTo3_4_0(),
|
||||
new MigrateTo3_4_1(),
|
||||
new MigrateTo3_4_2()
|
||||
new MigrateTo3_4_2(),
|
||||
new MigrateTo4_0_0()
|
||||
};
|
||||
|
||||
public static void migrate(KeycloakSession session) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.keycloak.provider.Provider;
|
|||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Various common utils needed for migration from older version to newer
|
||||
|
@ -37,7 +38,7 @@ public interface MigrationProvider extends Provider {
|
|||
*/
|
||||
List<ProtocolMapperRepresentation> getMappersForClaimMask(Long claimMask);
|
||||
|
||||
List<ProtocolMapperModel> getBuiltinMappers(String protocol);
|
||||
Map<String, ProtocolMapperModel> getBuiltinMappers(String protocol);
|
||||
|
||||
void setupAdminCli(RealmModel realm);
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@ public class MigrateTo1_2_0 implements Migration {
|
|||
if (roleModel != null) continue;
|
||||
roleModel = client.addRole(role);
|
||||
roleModel.setDescription("${role_" + role.toLowerCase().replaceAll("_", "-") + "}");
|
||||
roleModel.setScopeParamRequired(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,13 +45,7 @@ public class MigrateTo1_6_0 implements Migration {
|
|||
public void migrate(KeycloakSession session) {
|
||||
MigrationProvider provider = session.getProvider(MigrationProvider.class);
|
||||
|
||||
List<ProtocolMapperModel> builtinMappers = provider.getBuiltinMappers("openid-connect");
|
||||
ProtocolMapperModel localeMapper = null;
|
||||
for (ProtocolMapperModel m : builtinMappers) {
|
||||
if (m.getName().equals("locale")) {
|
||||
localeMapper = m;
|
||||
}
|
||||
}
|
||||
ProtocolMapperModel localeMapper = provider.getBuiltinMappers("openid-connect").get("locale");
|
||||
|
||||
if (localeMapper == null) {
|
||||
throw new RuntimeException("Can't find default locale mapper");
|
||||
|
@ -66,13 +60,8 @@ public class MigrateTo1_6_0 implements Migration {
|
|||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
MigrationProvider provider = session.getProvider(MigrationProvider.class);
|
||||
List<ProtocolMapperModel> builtinMappers = provider.getBuiltinMappers("openid-connect");
|
||||
ProtocolMapperModel localeMapper = null;
|
||||
for (ProtocolMapperModel m : builtinMappers) {
|
||||
if (m.getName().equals("locale")) {
|
||||
localeMapper = m;
|
||||
}
|
||||
}
|
||||
ProtocolMapperModel localeMapper = provider.getBuiltinMappers("openid-connect").get("locale");
|
||||
|
||||
if (localeMapper == null) {
|
||||
throw new RuntimeException("Can't find default locale mapper");
|
||||
}
|
||||
|
@ -85,16 +74,7 @@ public class MigrateTo1_6_0 implements Migration {
|
|||
realm.setOfflineSessionIdleTimeout(Constants.DEFAULT_OFFLINE_SESSION_IDLE_TIMEOUT);
|
||||
|
||||
if (realm.getRole(Constants.OFFLINE_ACCESS_ROLE) == null) {
|
||||
for (RoleModel realmRole : realm.getRoles()) {
|
||||
realmRole.setScopeParamRequired(false);
|
||||
}
|
||||
for (ClientModel client : realm.getClients()) {
|
||||
for (RoleModel clientRole : client.getRoles()) {
|
||||
clientRole.setScopeParamRequired(false);
|
||||
}
|
||||
}
|
||||
|
||||
KeycloakModelUtils.setupOfflineTokens(realm);
|
||||
KeycloakModelUtils.setupOfflineRole(realm);
|
||||
RoleModel role = realm.getRole(Constants.OFFLINE_ACCESS_ROLE);
|
||||
|
||||
// Bulk grant of offline_access role to all users
|
||||
|
@ -110,7 +90,6 @@ public class MigrateTo1_6_0 implements Migration {
|
|||
if (client.getRole(AdminRoles.CREATE_CLIENT) == null) {
|
||||
RoleModel role = client.addRole(AdminRoles.CREATE_CLIENT);
|
||||
role.setDescription("${role_" + AdminRoles.CREATE_CLIENT + "}");
|
||||
role.setScopeParamRequired(false);
|
||||
|
||||
client.getRealm().getRole(AdminRoles.ADMIN).addCompositeRole(role);
|
||||
}
|
||||
|
@ -120,8 +99,6 @@ public class MigrateTo1_6_0 implements Migration {
|
|||
if (client.getRole(AdminRoles.CREATE_CLIENT) == null) {
|
||||
RoleModel role = client.addRole(AdminRoles.CREATE_CLIENT);
|
||||
role.setDescription("${role_" + AdminRoles.CREATE_CLIENT + "}");
|
||||
role.setScopeParamRequired(false);
|
||||
|
||||
client.getRole(AdminRoles.REALM_ADMIN).addCompositeRole(role);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ package org.keycloak.migration.migrators;
|
|||
|
||||
import org.keycloak.migration.ModelVersion;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
@ -44,8 +44,8 @@ public class MigrateTo2_3_0 implements Migration {
|
|||
MigrationUtils.updateProtocolMappers(client);
|
||||
}
|
||||
|
||||
for (ClientTemplateModel clientTemplate : realm.getClientTemplates()) {
|
||||
MigrationUtils.updateProtocolMappers(clientTemplate);
|
||||
for (ClientScopeModel clientScope : realm.getClientScopes()) {
|
||||
MigrationUtils.updateProtocolMappers(clientScope);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@ package org.keycloak.migration.migrators;
|
|||
|
||||
|
||||
import org.keycloak.migration.ModelVersion;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.DefaultKeyProviders;
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright 2017 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.migration.migrators;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.migration.ModelVersion;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.utils.DefaultClientScopes;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class MigrateTo4_0_0 implements Migration {
|
||||
|
||||
public static final ModelVersion VERSION = new ModelVersion("4.0.0");
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(MigrateTo4_0_0.class);
|
||||
|
||||
@Override
|
||||
public ModelVersion getVersion() {
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrate(KeycloakSession session) {
|
||||
session.realms().getRealms().stream().forEach(
|
||||
r -> {
|
||||
migrateRealm(session, r, false);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
migrateRealm(session, realm, true);
|
||||
}
|
||||
|
||||
|
||||
protected void migrateRealm(KeycloakSession session, RealmModel realm, boolean json) {
|
||||
// Upgrade names of clientScopes to not contain space
|
||||
for (ClientScopeModel clientScope : realm.getClientScopes()) {
|
||||
if (clientScope.getName().contains(" ")) {
|
||||
LOG.debugf("Replacing spaces with underscores in the name of client scope '%s' of realm '%s'", clientScope.getName(), realm.getName());
|
||||
String replacedName = clientScope.getName().replaceAll(" ", "_");
|
||||
clientScope.setName(replacedName);
|
||||
}
|
||||
}
|
||||
|
||||
if (!json) {
|
||||
// Add default client scopes. But don't add them to existing clients. For JSON, they were already added
|
||||
LOG.debugf("Adding defaultClientScopes for realm '%s'", realm.getName());
|
||||
DefaultClientScopes.createDefaultClientScopes(session, realm, false);
|
||||
}
|
||||
|
||||
// Upgrade configuration of "allowed-client-templates" client registration policy
|
||||
for (ComponentModel component : realm.getComponents(realm.getId(), "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy")) {
|
||||
if ("allowed-client-templates".equals(component.getProviderId())) {
|
||||
List<String> configVal = component.getConfig().remove("allowed-client-templates");
|
||||
if (configVal != null) {
|
||||
component.getConfig().put("allowed-client-scopes", configVal);
|
||||
}
|
||||
component.put("allow-default-scopes", true);
|
||||
|
||||
realm.updateComponent(component);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If client has scope for offline_access role (either directly or through fullScopeAllowed), then add offline_access client
|
||||
// scope as optional scope to the client. If it's indirectly (no fullScopeAllowed), then remove role from the scoped roles
|
||||
RoleModel offlineAccessRole = realm.getRole(OAuth2Constants.OFFLINE_ACCESS);
|
||||
ClientScopeModel offlineAccessScope = null;
|
||||
if (offlineAccessRole == null) {
|
||||
LOG.infof("Role 'offline_access' not available in realm '%s'. Skip migration of offline_access client scope.", realm.getName());
|
||||
} else {
|
||||
offlineAccessScope = KeycloakModelUtils.getClientScopeByName(realm, OAuth2Constants.OFFLINE_ACCESS);
|
||||
if (offlineAccessScope == null) {
|
||||
LOG.infof("Client scope 'offline_access' not available in realm '%s'. Skip migration of offline_access client scope.", realm.getName());
|
||||
} else {
|
||||
for (ClientModel client : realm.getClients()) {
|
||||
if ("openid-connect".equals(client.getProtocol())
|
||||
&& !client.isBearerOnly()
|
||||
&& client.hasScope(offlineAccessRole)
|
||||
&& !client.getClientScopes(false, true).containsKey(OAuth2Constants.OFFLINE_ACCESS)) {
|
||||
LOG.debugf("Adding client scope 'offline_access' as optional scope to client '%s' in realm '%s'.", client.getClientId(), realm.getName());
|
||||
client.addClientScope(offlineAccessScope, false);
|
||||
|
||||
if (!client.isFullScopeAllowed()) {
|
||||
LOG.debugf("Removing role scope mapping for role 'offline_access' from client '%s' in realm '%s'.", client.getClientId(), realm.getName());
|
||||
client.deleteScopeMapping(offlineAccessRole);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Clients with consentRequired, which don't have any client scopes will be added itself to require consent, so that consent screen is shown when users authenticate
|
||||
for (ClientModel client : realm.getClients()) {
|
||||
if (client.isConsentRequired() && client.getClientScopes(true, true).isEmpty()) {
|
||||
LOG.debugf("Adding client '%s' of realm '%s' to display itself on consent screen", client.getClientId(), realm.getName());
|
||||
client.setDisplayOnConsentScreen(true);
|
||||
String consentText = client.getName()==null ? client.getClientId() : client.getName();
|
||||
client.setConsentScreenText(consentText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,18 +17,27 @@
|
|||
|
||||
package org.keycloak.migration.migrators;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.OAuthErrorException;
|
||||
import org.keycloak.models.AdminRoles;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ProtocolMapperContainerModel;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RequiredActionProviderModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserConsentModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
|
@ -40,7 +49,6 @@ public class MigrationUtils {
|
|||
if (client != null && client.getRole(roleName) == null) {
|
||||
RoleModel role = client.addRole(roleName);
|
||||
role.setDescription("${role_" + roleName + "}");
|
||||
role.setScopeParamRequired(false);
|
||||
|
||||
client.getRealm().getRole(AdminRoles.ADMIN).addCompositeRole(role);
|
||||
}
|
||||
|
@ -50,7 +58,6 @@ public class MigrationUtils {
|
|||
if (client != null && client.getRole(roleName) == null) {
|
||||
RoleModel role = client.addRole(roleName);
|
||||
role.setDescription("${role_" + roleName + "}");
|
||||
role.setScopeParamRequired(false);
|
||||
|
||||
client.getRole(AdminRoles.REALM_ADMIN).addCompositeRole(role);
|
||||
}
|
||||
|
@ -79,4 +86,27 @@ public class MigrationUtils {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Called when offline token older than 4.0 (Offline token without clientScopeIds) is called
|
||||
public static void migrateOldOfflineToken(KeycloakSession session, RealmModel realm, ClientModel client, UserModel user) throws OAuthErrorException {
|
||||
ClientScopeModel offlineScope = KeycloakModelUtils.getClientScopeByName(realm, OAuth2Constants.OFFLINE_ACCESS);
|
||||
if (offlineScope == null) {
|
||||
throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Offline Access scope not found");
|
||||
}
|
||||
|
||||
if (client.isConsentRequired()) {
|
||||
// Automatically add consents for client and for offline_access. We know that both were defacto approved by user already and offlineSession is still valid
|
||||
UserConsentModel consent = session.users().getConsentByClient(realm, user.getId(), client.getId());
|
||||
if (consent != null) {
|
||||
if (client.isDisplayOnConsentScreen()) {
|
||||
consent.addGrantedClientScope(client);
|
||||
}
|
||||
if (offlineScope.isDisplayOnConsentScreen()) {
|
||||
consent.addGrantedClientScope(offlineScope);
|
||||
}
|
||||
session.users().updateConsent(realm, user.getId(), consent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,55 +18,35 @@
|
|||
package org.keycloak.models;
|
||||
|
||||
/**
|
||||
* TODO: remove this class entirely?
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class ClientConfigResolver {
|
||||
protected ClientModel client;
|
||||
protected ClientTemplateModel clientTemplate;
|
||||
|
||||
public ClientConfigResolver(ClientModel client) {
|
||||
this.client = client;
|
||||
this.clientTemplate = client.getClientTemplate();
|
||||
}
|
||||
|
||||
public String resolveAttribute(String name) {
|
||||
if (clientTemplate != null && client.useTemplateConfig()) {
|
||||
return clientTemplate.getAttribute(name);
|
||||
} else {
|
||||
return client.getAttribute(name);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFrontchannelLogout() {
|
||||
if (clientTemplate != null && client.useTemplateConfig()) {
|
||||
return clientTemplate.isFrontchannelLogout();
|
||||
}
|
||||
|
||||
return client.isFrontchannelLogout();
|
||||
}
|
||||
|
||||
boolean isConsentRequired() {
|
||||
if (clientTemplate != null && client.useTemplateConfig()) {
|
||||
return clientTemplate.isConsentRequired();
|
||||
}
|
||||
|
||||
return client.isConsentRequired();
|
||||
}
|
||||
|
||||
boolean isStandardFlowEnabled() {
|
||||
if (clientTemplate != null && client.useTemplateConfig()) {
|
||||
return clientTemplate.isStandardFlowEnabled();
|
||||
}
|
||||
|
||||
return client.isStandardFlowEnabled();
|
||||
}
|
||||
|
||||
boolean isServiceAccountsEnabled() {
|
||||
if (clientTemplate != null && client.useTemplateConfig()) {
|
||||
return clientTemplate.isServiceAccountsEnabled();
|
||||
}
|
||||
|
||||
return client.isServiceAccountsEnabled();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,4 +69,6 @@ public interface Constants {
|
|||
String GENERATE = "GENERATE";
|
||||
|
||||
int DEFAULT_MAX_RESULTS = 100;
|
||||
|
||||
String OFFLINE_ACCESS_SCOPE_CONSENT_TEXT = "${offlineAccessScopeConsentText}";
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@ public class ImpersonationConstants {
|
|||
if (realmAdminApp.getRole(IMPERSONATION_ROLE) != null) return;
|
||||
RoleModel impersonationRole = realmAdminApp.addRole(IMPERSONATION_ROLE);
|
||||
impersonationRole.setDescription("${role_" + IMPERSONATION_ROLE + "}");
|
||||
impersonationRole.setScopeParamRequired(false);
|
||||
adminRole.addCompositeRole(impersonationRole);
|
||||
}
|
||||
|
||||
|
@ -54,7 +53,6 @@ public class ImpersonationConstants {
|
|||
if (realmAdminApp.getRole(IMPERSONATION_ROLE) != null) return;
|
||||
RoleModel impersonationRole = realmAdminApp.addRole(IMPERSONATION_ROLE);
|
||||
impersonationRole.setDescription("${role_" + IMPERSONATION_ROLE + "}");
|
||||
impersonationRole.setScopeParamRequired(false);
|
||||
RoleModel adminRole = realmAdminApp.getRole(AdminRoles.REALM_ADMIN);
|
||||
adminRole.addCompositeRole(impersonationRole);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ public interface CacheRealmProvider extends RealmProvider {
|
|||
void registerRealmInvalidation(String id, String name);
|
||||
|
||||
void registerClientInvalidation(String id, String clientId, String realmId);
|
||||
void registerClientTemplateInvalidation(String id);
|
||||
void registerClientScopeInvalidation(String id);
|
||||
|
||||
void registerRoleInvalidation(String id, String roleName, String roleContainerId);
|
||||
|
||||
|
|
|
@ -48,9 +48,7 @@ public class PersistentAuthenticatedClientSessionAdapter implements Authenticate
|
|||
data.setAction(clientSession.getAction());
|
||||
data.setAuthMethod(clientSession.getProtocol());
|
||||
data.setNotes(clientSession.getNotes());
|
||||
data.setProtocolMappers(clientSession.getProtocolMappers());
|
||||
data.setRedirectUri(clientSession.getRedirectUri());
|
||||
data.setRoles(clientSession.getRoles());
|
||||
|
||||
model = new PersistentClientSessionModel();
|
||||
model.setClientId(clientSession.getClient().getId());
|
||||
|
@ -174,26 +172,6 @@ public class PersistentAuthenticatedClientSessionAdapter implements Authenticate
|
|||
getData().setAction(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRoles() {
|
||||
return getData().getRoles();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRoles(Set<String> roles) {
|
||||
getData().setRoles(roles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getProtocolMappers() {
|
||||
return getData().getProtocolMappers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProtocolMappers(Set<String> protocolMappers) {
|
||||
getData().setProtocolMappers(protocolMappers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocol() {
|
||||
return getData().getAuthMethod();
|
||||
|
@ -256,12 +234,6 @@ public class PersistentAuthenticatedClientSessionAdapter implements Authenticate
|
|||
@JsonProperty("redirectUri")
|
||||
private String redirectUri;
|
||||
|
||||
@JsonProperty("protocolMappers")
|
||||
private Set<String> protocolMappers;
|
||||
|
||||
@JsonProperty("roles")
|
||||
private Set<String> roles;
|
||||
|
||||
@JsonProperty("notes")
|
||||
private Map<String, String> notes;
|
||||
|
||||
|
@ -275,6 +247,10 @@ public class PersistentAuthenticatedClientSessionAdapter implements Authenticate
|
|||
private Map<String, Object> executionStatus;
|
||||
@JsonProperty("requiredActions")
|
||||
private Set<String> requiredActions;
|
||||
@JsonProperty("protocolMappers")
|
||||
private Set<String> protocolMappers;
|
||||
@JsonProperty("roles")
|
||||
private Set<String> roles;
|
||||
|
||||
|
||||
public String getAuthMethod() {
|
||||
|
@ -293,22 +269,6 @@ public class PersistentAuthenticatedClientSessionAdapter implements Authenticate
|
|||
this.redirectUri = redirectUri;
|
||||
}
|
||||
|
||||
public Set<String> getProtocolMappers() {
|
||||
return protocolMappers;
|
||||
}
|
||||
|
||||
public void setProtocolMappers(Set<String> protocolMappers) {
|
||||
this.protocolMappers = protocolMappers;
|
||||
}
|
||||
|
||||
public Set<String> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setRoles(Set<String> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
public Map<String, String> getNotes() {
|
||||
return notes;
|
||||
}
|
||||
|
@ -348,5 +308,21 @@ public class PersistentAuthenticatedClientSessionAdapter implements Authenticate
|
|||
public void setRequiredActions(Set<String> requiredActions) {
|
||||
this.requiredActions = requiredActions;
|
||||
}
|
||||
|
||||
public Set<String> getProtocolMappers() {
|
||||
return protocolMappers;
|
||||
}
|
||||
|
||||
public void setProtocolMappers(Set<String> protocolMappers) {
|
||||
this.protocolMappers = protocolMappers;
|
||||
}
|
||||
|
||||
public Set<String> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setRoles(Set<String> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ public class PersistentUserSessionAdapter implements OfflineUserSessionModel {
|
|||
private final PersistentUserSessionModel model;
|
||||
private UserModel user;
|
||||
private String userId;
|
||||
private String username;
|
||||
private final RealmModel realm;
|
||||
private KeycloakSession session;
|
||||
private final Map<String, AuthenticatedClientSessionModel> authenticatedClientSessions;
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright 2017 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.utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.protocol.LoginProtocol;
|
||||
import org.keycloak.protocol.LoginProtocolFactory;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class DefaultClientScopes {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param session
|
||||
* @param realm
|
||||
* @param addScopesToExistingClients true when creating new realm. False when migrating from previous version
|
||||
*/
|
||||
public static void createDefaultClientScopes(KeycloakSession session, RealmModel realm, boolean addScopesToExistingClients) {
|
||||
List<ProviderFactory> loginProtocolFactories = session.getKeycloakSessionFactory().getProviderFactories(LoginProtocol.class);
|
||||
for (ProviderFactory factory : loginProtocolFactories) {
|
||||
LoginProtocolFactory lpf = (LoginProtocolFactory) factory;
|
||||
lpf.createDefaultClientScopes(realm, addScopesToExistingClients);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Asumption is that newRealm and offlineRole are not null AND offline_access clientScope doesn't yet exists in the realm. Caller of this method is supposed to ensure that.
|
||||
public static void createOfflineAccessClientScope(RealmModel newRealm, RoleModel offlineRole) {
|
||||
ClientScopeModel offlineAccessScope = newRealm.addClientScope(OAuth2Constants.OFFLINE_ACCESS);
|
||||
offlineAccessScope.setDescription("OpenID Connect built-in scope: offline_access");
|
||||
offlineAccessScope.setDisplayOnConsentScreen(true);
|
||||
offlineAccessScope.setConsentScreenText(Constants.OFFLINE_ACCESS_SCOPE_CONSENT_TEXT);
|
||||
offlineAccessScope.setProtocol("openid-connect");
|
||||
offlineAccessScope.addScopeMapping(offlineRole);
|
||||
|
||||
// Optional scope. Needs to be requested by scope parameter
|
||||
newRealm.addDefaultClientScope(offlineAccessScope, false);
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@ import org.keycloak.component.ComponentModel;
|
|||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.AuthenticationFlowModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.IdentityProviderModel;
|
||||
|
@ -303,13 +303,16 @@ public final class KeycloakModelUtils {
|
|||
return str==null ? null : str.toLowerCase();
|
||||
}
|
||||
|
||||
public static void setupOfflineTokens(RealmModel realm) {
|
||||
if (realm.getRole(Constants.OFFLINE_ACCESS_ROLE) == null) {
|
||||
RoleModel role = realm.addRole(Constants.OFFLINE_ACCESS_ROLE);
|
||||
role.setDescription("${role_offline-access}");
|
||||
role.setScopeParamRequired(true);
|
||||
public static RoleModel setupOfflineRole(RealmModel realm) {
|
||||
RoleModel offlineRole = realm.getRole(Constants.OFFLINE_ACCESS_ROLE);
|
||||
|
||||
if (offlineRole == null) {
|
||||
offlineRole = realm.addRole(Constants.OFFLINE_ACCESS_ROLE);
|
||||
offlineRole.setDescription("${role_offline-access}");
|
||||
realm.addDefaultRole(Constants.OFFLINE_ACCESS_ROLE);
|
||||
}
|
||||
|
||||
return offlineRole;
|
||||
}
|
||||
|
||||
|
||||
|
@ -500,29 +503,54 @@ public final class KeycloakModelUtils {
|
|||
|
||||
}
|
||||
|
||||
public static boolean isClientTemplateUsed(RealmModel realm, ClientTemplateModel template) {
|
||||
public static boolean isClientScopeUsed(RealmModel realm, ClientScopeModel clientScope) {
|
||||
for (ClientModel client : realm.getClients()) {
|
||||
if (client.getClientTemplate() != null && client.getClientTemplate().getId().equals(template.getId())) return true;
|
||||
if ((client.getClientScopes(true, false).containsKey(clientScope.getName())) ||
|
||||
(client.getClientScopes(false, false).containsKey(clientScope.getName()))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static ClientTemplateModel getClientTemplateByName(RealmModel realm, String templateName) {
|
||||
for (ClientTemplateModel clientTemplate : realm.getClientTemplates()) {
|
||||
if (templateName.equals(clientTemplate.getName())) {
|
||||
return clientTemplate;
|
||||
public static ClientScopeModel getClientScopeByName(RealmModel realm, String clientScopeName) {
|
||||
for (ClientScopeModel clientScope : realm.getClientScopes()) {
|
||||
if (clientScopeName.equals(clientScope.getName())) {
|
||||
return clientScope;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup clientScope OR client by id. Method is useful if you know just ID, but you don't know
|
||||
* if underlying model is clientScope or client
|
||||
*/
|
||||
public static ClientScopeModel findClientScopeById(RealmModel realm, String clientScopeId) {
|
||||
ClientScopeModel clientScope = realm.getClientScopeById(clientScopeId);
|
||||
|
||||
if (clientScope != null) {
|
||||
return clientScope;
|
||||
} else {
|
||||
return realm.getClientById(clientScopeId);
|
||||
}
|
||||
}
|
||||
|
||||
/** Replace spaces in the name with underscore, so that scope name can be used as value of scope parameter **/
|
||||
public static String convertClientScopeName(String previousName) {
|
||||
if (previousName.contains(" ")) {
|
||||
return previousName.replaceAll(" ", "_");
|
||||
} else {
|
||||
return previousName;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setupAuthorizationServices(RealmModel realm) {
|
||||
for (String roleName : Constants.AUTHZ_DEFAULT_AUTHORIZATION_ROLES) {
|
||||
if (realm.getRole(roleName) == null) {
|
||||
RoleModel role = realm.addRole(roleName);
|
||||
role.setDescription("${role_" + roleName + "}");
|
||||
role.setScopeParamRequired(false);
|
||||
realm.addDefaultRole(roleName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,7 +211,6 @@ public class ModelToRepresentation {
|
|||
rep.setId(role.getId());
|
||||
rep.setName(role.getName());
|
||||
rep.setDescription(role.getDescription());
|
||||
rep.setScopeParamRequired(role.isScopeParamRequired());
|
||||
rep.setComposite(role.isComposite());
|
||||
rep.setClientRole(role.isClientRole());
|
||||
rep.setContainerId(role.getContainerId());
|
||||
|
@ -468,20 +467,21 @@ public class ModelToRepresentation {
|
|||
return rep;
|
||||
}
|
||||
|
||||
public static ClientTemplateRepresentation toRepresentation(ClientTemplateModel clientModel) {
|
||||
ClientTemplateRepresentation rep = new ClientTemplateRepresentation();
|
||||
rep.setId(clientModel.getId());
|
||||
rep.setName(clientModel.getName());
|
||||
rep.setDescription(clientModel.getDescription());
|
||||
rep.setProtocol(clientModel.getProtocol());
|
||||
if (!clientModel.getProtocolMappers().isEmpty()) {
|
||||
public static ClientScopeRepresentation toRepresentation(ClientScopeModel clientScopeModel) {
|
||||
ClientScopeRepresentation rep = new ClientScopeRepresentation();
|
||||
rep.setId(clientScopeModel.getId());
|
||||
rep.setName(clientScopeModel.getName());
|
||||
rep.setDescription(clientScopeModel.getDescription());
|
||||
rep.setProtocol(clientScopeModel.getProtocol());
|
||||
if (!clientScopeModel.getProtocolMappers().isEmpty()) {
|
||||
List<ProtocolMapperRepresentation> mappings = new LinkedList<>();
|
||||
for (ProtocolMapperModel model : clientModel.getProtocolMappers()) {
|
||||
for (ProtocolMapperModel model : clientScopeModel.getProtocolMappers()) {
|
||||
mappings.add(toRepresentation(model));
|
||||
}
|
||||
rep.setProtocolMappers(mappings);
|
||||
}
|
||||
rep.setFullScopeAllowed(clientModel.isFullScopeAllowed());
|
||||
|
||||
rep.setAttributes(new HashMap<>(clientScopeModel.getAttributes()));
|
||||
|
||||
return rep;
|
||||
}
|
||||
|
@ -515,7 +515,9 @@ public class ModelToRepresentation {
|
|||
rep.setNotBefore(clientModel.getNotBefore());
|
||||
rep.setNodeReRegistrationTimeout(clientModel.getNodeReRegistrationTimeout());
|
||||
rep.setClientAuthenticatorType(clientModel.getClientAuthenticatorType());
|
||||
if (clientModel.getClientTemplate() != null) rep.setClientTemplate(clientModel.getClientTemplate().getName());
|
||||
|
||||
rep.setDefaultClientScopes(new LinkedList<>(clientModel.getClientScopes(true, false).keySet()));
|
||||
rep.setOptionalClientScopes(new LinkedList<>(clientModel.getClientScopes(false, false).keySet()));
|
||||
|
||||
Set<String> redirectUris = clientModel.getRedirectUris();
|
||||
if (redirectUris != null) {
|
||||
|
@ -542,9 +544,6 @@ public class ModelToRepresentation {
|
|||
}
|
||||
rep.setProtocolMappers(mappings);
|
||||
}
|
||||
rep.setUseTemplateMappers(clientModel.useTemplateMappers());
|
||||
rep.setUseTemplateConfig(clientModel.useTemplateConfig());
|
||||
rep.setUseTemplateScope(clientModel.useTemplateScope());
|
||||
|
||||
return rep;
|
||||
}
|
||||
|
@ -596,8 +595,6 @@ public class ModelToRepresentation {
|
|||
rep.setConfig(config);
|
||||
rep.setName(model.getName());
|
||||
rep.setProtocolMapper(model.getProtocolMapper());
|
||||
rep.setConsentText(model.getConsentText());
|
||||
rep.setConsentRequired(model.isConsentRequired());
|
||||
return rep;
|
||||
}
|
||||
|
||||
|
@ -616,33 +613,14 @@ public class ModelToRepresentation {
|
|||
public static UserConsentRepresentation toRepresentation(UserConsentModel model) {
|
||||
String clientId = model.getClient().getClientId();
|
||||
|
||||
Map<String, List<String>> grantedProtocolMappers = new HashMap<String, List<String>>();
|
||||
for (ProtocolMapperModel protocolMapper : model.getGrantedProtocolMappers()) {
|
||||
String protocol = protocolMapper.getProtocol();
|
||||
List<String> currentProtocolMappers = grantedProtocolMappers.computeIfAbsent(protocol, k -> new LinkedList<String>());
|
||||
currentProtocolMappers.add(protocolMapper.getName());
|
||||
List<String> grantedClientScopes = new LinkedList<>();
|
||||
for (ClientScopeModel clientScope : model.getGrantedClientScopes()) {
|
||||
grantedClientScopes.add(clientScope.getName());
|
||||
}
|
||||
|
||||
List<String> grantedRealmRoles = new LinkedList<String>();
|
||||
Map<String, List<String>> grantedClientRoles = new HashMap<String, List<String>>();
|
||||
for (RoleModel role : model.getGrantedRoles()) {
|
||||
if (role.getContainer() instanceof RealmModel) {
|
||||
grantedRealmRoles.add(role.getName());
|
||||
} else {
|
||||
ClientModel client2 = (ClientModel) role.getContainer();
|
||||
|
||||
String clientId2 = client2.getClientId();
|
||||
List<String> currentClientRoles = grantedClientRoles.computeIfAbsent(clientId2, k -> new LinkedList<String>());
|
||||
currentClientRoles.add(role.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UserConsentRepresentation consentRep = new UserConsentRepresentation();
|
||||
consentRep.setClientId(clientId);
|
||||
consentRep.setGrantedProtocolMappers(grantedProtocolMappers);
|
||||
consentRep.setGrantedRealmRoles(grantedRealmRoles);
|
||||
consentRep.setGrantedClientRoles(grantedClientRoles);
|
||||
consentRep.setGrantedClientScopes(grantedClientScopes);
|
||||
consentRep.setCreatedDate(model.getCreatedDate());
|
||||
consentRep.setLastUpdatedDate(model.getLastUpdatedDate());
|
||||
return consentRep;
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.util.function.Function;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.AuthorizationProviderFactory;
|
||||
import org.keycloak.authorization.model.PermissionTicket;
|
||||
|
@ -61,7 +62,7 @@ import org.keycloak.models.AuthenticatorConfigModel;
|
|||
import org.keycloak.models.BrowserSecurityHeaders;
|
||||
import org.keycloak.models.ClaimMask;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.FederatedIdentityModel;
|
||||
import org.keycloak.models.GroupModel;
|
||||
|
@ -91,6 +92,7 @@ import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
|||
import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
|
||||
import org.keycloak.representations.idm.ClaimRepresentation;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.ClientScopeRepresentation;
|
||||
import org.keycloak.representations.idm.ClientTemplateRepresentation;
|
||||
import org.keycloak.representations.idm.ComponentExportRepresentation;
|
||||
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||
|
@ -144,6 +146,7 @@ public class RepresentationToModel {
|
|||
public static void importRealm(KeycloakSession session, RealmRepresentation rep, RealmModel newRealm, boolean skipUserDependent) {
|
||||
convertDeprecatedSocialProviders(rep);
|
||||
convertDeprecatedApplications(session, rep);
|
||||
convertDeprecatedClientTemplates(rep);
|
||||
|
||||
newRealm.setName(rep.getRealm());
|
||||
if (rep.getDisplayName() != null) newRealm.setDisplayName(rep.getDisplayName());
|
||||
|
@ -258,8 +261,29 @@ public class RepresentationToModel {
|
|||
importIdentityProviders(rep, newRealm);
|
||||
importIdentityProviderMappers(rep, newRealm);
|
||||
|
||||
if (rep.getClientTemplates() != null) {
|
||||
createClientTemplates(session, rep, newRealm);
|
||||
Map<String, ClientScopeModel> clientScopes = new HashMap<>();
|
||||
if (rep.getClientScopes() != null) {
|
||||
clientScopes = createClientScopes(session, rep.getClientScopes(), newRealm);
|
||||
}
|
||||
if (rep.getDefaultDefaultClientScopes() != null) {
|
||||
for (String clientScopeName : rep.getDefaultDefaultClientScopes()) {
|
||||
ClientScopeModel clientScope = clientScopes.get(clientScopeName);
|
||||
if (clientScope != null) {
|
||||
newRealm.addDefaultClientScope(clientScope, true);
|
||||
} else {
|
||||
logger.warnf("Referenced client scope '%s' doesn't exists", clientScopeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rep.getDefaultOptionalClientScopes() != null) {
|
||||
for (String clientScopeName : rep.getDefaultOptionalClientScopes()) {
|
||||
ClientScopeModel clientScope = clientScopes.get(clientScopeName);
|
||||
if (clientScope != null) {
|
||||
newRealm.addDefaultClientScope(clientScope, false);
|
||||
} else {
|
||||
logger.warnf("Referenced client scope '%s' doesn't exists", clientScopeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rep.getClients() != null) {
|
||||
|
@ -471,8 +495,6 @@ public class RepresentationToModel {
|
|||
// Application role may already exists (for example if it is defaultRole)
|
||||
RoleModel role = roleRep.getId() != null ? client.addRole(roleRep.getId(), roleRep.getName()) : client.addRole(roleRep.getName());
|
||||
role.setDescription(roleRep.getDescription());
|
||||
boolean scopeParamRequired = roleRep.isScopeParamRequired() == null ? false : roleRep.isScopeParamRequired();
|
||||
role.setScopeParamRequired(scopeParamRequired);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -762,6 +784,28 @@ public class RepresentationToModel {
|
|||
}
|
||||
}
|
||||
|
||||
private static void convertDeprecatedClientTemplates(RealmRepresentation realm) {
|
||||
if (realm.getClientTemplates() != null) {
|
||||
|
||||
logger.warnf("Using deprecated 'clientTemplates' configuration in JSON representation for realm '%s'. It will be removed in future versions", realm.getRealm());
|
||||
|
||||
List<ClientScopeRepresentation> clientScopes = new LinkedList<>();
|
||||
for (ClientTemplateRepresentation template : realm.getClientTemplates()) {
|
||||
ClientScopeRepresentation scopeRep = new ClientScopeRepresentation();
|
||||
scopeRep.setId(template.getId());
|
||||
scopeRep.setName(template.getName());
|
||||
scopeRep.setProtocol(template.getProtocol());
|
||||
scopeRep.setDescription(template.getDescription());
|
||||
scopeRep.setAttributes(template.getAttributes());
|
||||
scopeRep.setProtocolMappers(template.getProtocolMappers());
|
||||
|
||||
clientScopes.add(scopeRep);
|
||||
}
|
||||
|
||||
realm.setClientScopes(clientScopes);
|
||||
}
|
||||
}
|
||||
|
||||
public static void renameRealm(RealmModel realm, String name) {
|
||||
if (name.equals(realm.getName())) return;
|
||||
|
||||
|
@ -973,8 +1017,6 @@ public class RepresentationToModel {
|
|||
public static void createRole(RealmModel newRealm, RoleRepresentation roleRep) {
|
||||
RoleModel role = roleRep.getId() != null ? newRealm.addRole(roleRep.getId(), roleRep.getName()) : newRealm.addRole(roleRep.getName());
|
||||
if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
|
||||
boolean scopeParamRequired = roleRep.isScopeParamRequired() == null ? false : roleRep.isScopeParamRequired();
|
||||
role.setScopeParamRequired(scopeParamRequired);
|
||||
}
|
||||
|
||||
private static void addComposites(RoleModel role, RoleRepresentation roleRep, RealmModel realm) {
|
||||
|
@ -1159,40 +1201,51 @@ public class RepresentationToModel {
|
|||
}
|
||||
|
||||
if (resourceRep.getClientTemplate() != null) {
|
||||
for (ClientTemplateModel template : realm.getClientTemplates()) {
|
||||
if (template.getName().equals(resourceRep.getClientTemplate())) {
|
||||
client.setClientTemplate(template);
|
||||
break;
|
||||
String clientTemplateName = KeycloakModelUtils.convertClientScopeName(resourceRep.getClientTemplate());
|
||||
addClientScopeToClient(realm, client, clientTemplateName, true);
|
||||
}
|
||||
MigrationUtils.updateProtocolMappers(template);
|
||||
|
||||
if (resourceRep.getDefaultClientScopes() != null) {
|
||||
// First remove all default/built in client scopes
|
||||
for (ClientScopeModel clientScope : client.getClientScopes(true, false).values()) {
|
||||
client.removeClientScope(clientScope);
|
||||
}
|
||||
|
||||
for (String clientScopeName : resourceRep.getDefaultClientScopes()) {
|
||||
addClientScopeToClient(realm, client, clientScopeName, true);
|
||||
}
|
||||
}
|
||||
if (resourceRep.getOptionalClientScopes() != null) {
|
||||
// First remove all default/built in client scopes
|
||||
for (ClientScopeModel clientScope : client.getClientScopes(false, false).values()) {
|
||||
client.removeClientScope(clientScope);
|
||||
}
|
||||
|
||||
for (String clientScopeName : resourceRep.getOptionalClientScopes()) {
|
||||
addClientScopeToClient(realm, client, clientScopeName, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (resourceRep.isFullScopeAllowed() != null) {
|
||||
client.setFullScopeAllowed(resourceRep.isFullScopeAllowed());
|
||||
} else {
|
||||
if (client.getClientTemplate() != null) {
|
||||
client.setFullScopeAllowed(!client.isConsentRequired() && client.getClientTemplate().isFullScopeAllowed());
|
||||
|
||||
} else {
|
||||
client.setFullScopeAllowed(!client.isConsentRequired());
|
||||
}
|
||||
}
|
||||
if (resourceRep.isUseTemplateConfig() != null) client.setUseTemplateConfig(resourceRep.isUseTemplateConfig());
|
||||
else client.setUseTemplateConfig(false); // default to false for now
|
||||
|
||||
if (resourceRep.isUseTemplateScope() != null) client.setUseTemplateScope(resourceRep.isUseTemplateScope());
|
||||
else client.setUseTemplateScope(resourceRep.getClientTemplate() != null);
|
||||
|
||||
if (resourceRep.isUseTemplateMappers() != null)
|
||||
client.setUseTemplateMappers(resourceRep.isUseTemplateMappers());
|
||||
else client.setUseTemplateMappers(resourceRep.getClientTemplate() != null);
|
||||
|
||||
client.updateClient();
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
private static void addClientScopeToClient(RealmModel realm, ClientModel client, String clientScopeName, boolean defaultScope) {
|
||||
ClientScopeModel clientScope = KeycloakModelUtils.getClientScopeByName(realm, clientScopeName);
|
||||
if (clientScope != null) {
|
||||
client.addClientScope(clientScope, defaultScope);
|
||||
} else {
|
||||
logger.warnf("Referenced client scope '%s' doesn't exists. Ignoring", clientScopeName);
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateClient(ClientRepresentation rep, ClientModel resource) {
|
||||
if (rep.getClientId() != null) resource.setClientId(rep.getClientId());
|
||||
if (rep.getName() != null) resource.setName(rep.getName());
|
||||
|
@ -1267,108 +1320,57 @@ public class RepresentationToModel {
|
|||
}
|
||||
}
|
||||
|
||||
if (rep.isUseTemplateConfig() != null) resource.setUseTemplateConfig(rep.isUseTemplateConfig());
|
||||
if (rep.isUseTemplateScope() != null) resource.setUseTemplateScope(rep.isUseTemplateScope());
|
||||
if (rep.isUseTemplateMappers() != null) resource.setUseTemplateMappers(rep.isUseTemplateMappers());
|
||||
|
||||
if (rep.getSecret() != null) resource.setSecret(rep.getSecret());
|
||||
|
||||
if (rep.getClientTemplate() != null) {
|
||||
if (rep.getClientTemplate().equals(ClientTemplateRepresentation.NONE)) {
|
||||
resource.setClientTemplate(null);
|
||||
} else {
|
||||
RealmModel realm = resource.getRealm();
|
||||
for (ClientTemplateModel template : realm.getClientTemplates()) {
|
||||
|
||||
if (template.getName().equals(rep.getClientTemplate())) {
|
||||
resource.setClientTemplate(template);
|
||||
if (rep.isUseTemplateConfig() == null) resource.setUseTemplateConfig(true);
|
||||
if (rep.isUseTemplateScope() == null) resource.setUseTemplateScope(true);
|
||||
if (rep.isUseTemplateMappers() == null) resource.setUseTemplateMappers(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource.updateClient();
|
||||
}
|
||||
|
||||
// CLIENT TEMPLATES
|
||||
// CLIENT SCOPES
|
||||
|
||||
private static Map<String, ClientTemplateModel> createClientTemplates(KeycloakSession session, RealmRepresentation rep, RealmModel realm) {
|
||||
Map<String, ClientTemplateModel> appMap = new HashMap<>();
|
||||
for (ClientTemplateRepresentation resourceRep : rep.getClientTemplates()) {
|
||||
ClientTemplateModel app = createClientTemplate(session, realm, resourceRep);
|
||||
private static Map<String, ClientScopeModel> createClientScopes(KeycloakSession session, List<ClientScopeRepresentation> clientScopes, RealmModel realm) {
|
||||
Map<String, ClientScopeModel> appMap = new HashMap<>();
|
||||
for (ClientScopeRepresentation resourceRep : clientScopes) {
|
||||
ClientScopeModel app = createClientScope(session, realm, resourceRep);
|
||||
appMap.put(app.getName(), app);
|
||||
}
|
||||
return appMap;
|
||||
}
|
||||
|
||||
public static ClientTemplateModel createClientTemplate(KeycloakSession session, RealmModel realm, ClientTemplateRepresentation resourceRep) {
|
||||
logger.debug("Create client template: {0}" + resourceRep.getName());
|
||||
public static ClientScopeModel createClientScope(KeycloakSession session, RealmModel realm, ClientScopeRepresentation resourceRep) {
|
||||
logger.debug("Create client scope: {0}" + resourceRep.getName());
|
||||
|
||||
ClientTemplateModel client = resourceRep.getId() != null ? realm.addClientTemplate(resourceRep.getId(), resourceRep.getName()) : realm.addClientTemplate(resourceRep.getName());
|
||||
if (resourceRep.getName() != null) client.setName(resourceRep.getName());
|
||||
if (resourceRep.getDescription() != null) client.setDescription(resourceRep.getDescription());
|
||||
if (resourceRep.getProtocol() != null) client.setProtocol(resourceRep.getProtocol());
|
||||
if (resourceRep.isFullScopeAllowed() != null) client.setFullScopeAllowed(resourceRep.isFullScopeAllowed());
|
||||
ClientScopeModel clientScope = resourceRep.getId() != null ? realm.addClientScope(resourceRep.getId(), resourceRep.getName()) : realm.addClientScope(resourceRep.getName());
|
||||
if (resourceRep.getName() != null) clientScope.setName(resourceRep.getName());
|
||||
if (resourceRep.getDescription() != null) clientScope.setDescription(resourceRep.getDescription());
|
||||
if (resourceRep.getProtocol() != null) clientScope.setProtocol(resourceRep.getProtocol());
|
||||
if (resourceRep.getProtocolMappers() != null) {
|
||||
// first, remove all default/built in mappers
|
||||
Set<ProtocolMapperModel> mappers = client.getProtocolMappers();
|
||||
for (ProtocolMapperModel mapper : mappers) client.removeProtocolMapper(mapper);
|
||||
Set<ProtocolMapperModel> mappers = clientScope.getProtocolMappers();
|
||||
for (ProtocolMapperModel mapper : mappers) clientScope.removeProtocolMapper(mapper);
|
||||
|
||||
for (ProtocolMapperRepresentation mapper : resourceRep.getProtocolMappers()) {
|
||||
client.addProtocolMapper(toModel(mapper));
|
||||
clientScope.addProtocolMapper(toModel(mapper));
|
||||
}
|
||||
MigrationUtils.updateProtocolMappers(clientScope);
|
||||
}
|
||||
if (resourceRep.isBearerOnly() != null) client.setBearerOnly(resourceRep.isBearerOnly());
|
||||
if (resourceRep.isConsentRequired() != null) client.setConsentRequired(resourceRep.isConsentRequired());
|
||||
|
||||
if (resourceRep.isStandardFlowEnabled() != null)
|
||||
client.setStandardFlowEnabled(resourceRep.isStandardFlowEnabled());
|
||||
if (resourceRep.isImplicitFlowEnabled() != null)
|
||||
client.setImplicitFlowEnabled(resourceRep.isImplicitFlowEnabled());
|
||||
if (resourceRep.isDirectAccessGrantsEnabled() != null)
|
||||
client.setDirectAccessGrantsEnabled(resourceRep.isDirectAccessGrantsEnabled());
|
||||
if (resourceRep.isServiceAccountsEnabled() != null)
|
||||
client.setServiceAccountsEnabled(resourceRep.isServiceAccountsEnabled());
|
||||
|
||||
if (resourceRep.isPublicClient() != null) client.setPublicClient(resourceRep.isPublicClient());
|
||||
if (resourceRep.isFrontchannelLogout() != null)
|
||||
client.setFrontchannelLogout(resourceRep.isFrontchannelLogout());
|
||||
|
||||
if (resourceRep.getAttributes() != null) {
|
||||
for (Map.Entry<String, String> entry : resourceRep.getAttributes().entrySet()) {
|
||||
client.setAttribute(entry.getKey(), entry.getValue());
|
||||
clientScope.setAttribute(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return client;
|
||||
return clientScope;
|
||||
}
|
||||
|
||||
public static void updateClientTemplate(ClientTemplateRepresentation rep, ClientTemplateModel resource) {
|
||||
public static void updateClientScope(ClientScopeRepresentation rep, ClientScopeModel resource) {
|
||||
if (rep.getName() != null) resource.setName(rep.getName());
|
||||
if (rep.getDescription() != null) resource.setDescription(rep.getDescription());
|
||||
if (rep.isFullScopeAllowed() != null) {
|
||||
resource.setFullScopeAllowed(rep.isFullScopeAllowed());
|
||||
}
|
||||
|
||||
|
||||
if (rep.getProtocol() != null) resource.setProtocol(rep.getProtocol());
|
||||
|
||||
if (rep.isBearerOnly() != null) resource.setBearerOnly(rep.isBearerOnly());
|
||||
if (rep.isConsentRequired() != null) resource.setConsentRequired(rep.isConsentRequired());
|
||||
if (rep.isStandardFlowEnabled() != null) resource.setStandardFlowEnabled(rep.isStandardFlowEnabled());
|
||||
if (rep.isImplicitFlowEnabled() != null) resource.setImplicitFlowEnabled(rep.isImplicitFlowEnabled());
|
||||
if (rep.isDirectAccessGrantsEnabled() != null)
|
||||
resource.setDirectAccessGrantsEnabled(rep.isDirectAccessGrantsEnabled());
|
||||
if (rep.isServiceAccountsEnabled() != null) resource.setServiceAccountsEnabled(rep.isServiceAccountsEnabled());
|
||||
if (rep.isPublicClient() != null) resource.setPublicClient(rep.isPublicClient());
|
||||
if (rep.isFullScopeAllowed() != null) resource.setFullScopeAllowed(rep.isFullScopeAllowed());
|
||||
if (rep.isFrontchannelLogout() != null) resource.setFrontchannelLogout(rep.isFrontchannelLogout());
|
||||
|
||||
if (rep.getAttributes() != null) {
|
||||
for (Map.Entry<String, String> entry : rep.getAttributes().entrySet()) {
|
||||
resource.setAttribute(entry.getKey(), entry.getValue());
|
||||
|
@ -1456,14 +1458,21 @@ public class RepresentationToModel {
|
|||
throw new RuntimeException("Unknown client specification in scope mappings: " + scope.getClient());
|
||||
}
|
||||
return client;
|
||||
} else if (scope.getClientTemplate() != null) {
|
||||
ClientTemplateModel clientTemplate = KeycloakModelUtils.getClientTemplateByName(realm, scope.getClientTemplate());
|
||||
} else if (scope.getClientScope() != null) {
|
||||
ClientScopeModel clientScope = KeycloakModelUtils.getClientScopeByName(realm, scope.getClientScope());
|
||||
if (clientScope == null) {
|
||||
throw new RuntimeException("Unknown clientScope specification in scope mappings: " + scope.getClientScope());
|
||||
}
|
||||
return clientScope;
|
||||
} else if (scope.getClientTemplate() != null) { // Backwards compatibility
|
||||
String templateName = KeycloakModelUtils.convertClientScopeName(scope.getClientTemplate());
|
||||
ClientScopeModel clientTemplate = KeycloakModelUtils.getClientScopeByName(realm, templateName);
|
||||
if (clientTemplate == null) {
|
||||
throw new RuntimeException("Unknown clientTemplate specification in scope mappings: " + scope.getClientTemplate());
|
||||
throw new RuntimeException("Unknown clientScope specification in scope mappings: " + templateName);
|
||||
}
|
||||
return clientTemplate;
|
||||
} else {
|
||||
throw new RuntimeException("Either client or clientTemplate needs to be specified in scope mappings");
|
||||
throw new RuntimeException("Either client or clientScope needs to be specified in scope mappings");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1734,8 +1743,6 @@ public class RepresentationToModel {
|
|||
ProtocolMapperModel model = new ProtocolMapperModel();
|
||||
model.setId(rep.getId());
|
||||
model.setName(rep.getName());
|
||||
model.setConsentRequired(rep.isConsentRequired());
|
||||
model.setConsentText(rep.getConsentText());
|
||||
model.setProtocol(rep.getProtocol());
|
||||
model.setProtocolMapper(rep.getProtocolMapper());
|
||||
model.setConfig(removeEmptyString(rep.getConfig()));
|
||||
|
@ -1762,44 +1769,27 @@ public class RepresentationToModel {
|
|||
consentModel.setCreatedDate(consentRep.getCreatedDate());
|
||||
consentModel.setLastUpdatedDate(consentRep.getLastUpdatedDate());
|
||||
|
||||
if (consentRep.getGrantedRealmRoles() != null) {
|
||||
for (String roleName : consentRep.getGrantedRealmRoles()) {
|
||||
RoleModel role = newRealm.getRole(roleName);
|
||||
if (role == null) {
|
||||
throw new RuntimeException("Unable to find realm role referenced in consent mappings of user. Role name: " + roleName);
|
||||
if (consentRep.getGrantedClientScopes() != null) {
|
||||
for (String scopeName : consentRep.getGrantedClientScopes()) {
|
||||
ClientScopeModel clientScope = KeycloakModelUtils.getClientScopeByName(newRealm, scopeName);
|
||||
if (clientScope == null) {
|
||||
throw new RuntimeException("Unable to find client scope referenced in consent mappings of user. Client scope name: " + scopeName);
|
||||
}
|
||||
consentModel.addGrantedRole(role);
|
||||
consentModel.addGrantedClientScope(clientScope);
|
||||
}
|
||||
}
|
||||
if (consentRep.getGrantedClientRoles() != null) {
|
||||
for (Map.Entry<String, List<String>> entry : consentRep.getGrantedClientRoles().entrySet()) {
|
||||
String clientId2 = entry.getKey();
|
||||
ClientModel client2 = newRealm.getClientByClientId(clientId2);
|
||||
if (client2 == null) {
|
||||
throw new RuntimeException("Unable to find client referenced in consent mappings. Client ID: " + clientId2);
|
||||
}
|
||||
for (String clientRoleName : entry.getValue()) {
|
||||
RoleModel clientRole = client2.getRole(clientRoleName);
|
||||
if (clientRole == null) {
|
||||
throw new RuntimeException("Unable to find client role referenced in consent mappings of user. Role name: " + clientRole + ", Client: " + clientId2);
|
||||
}
|
||||
consentModel.addGrantedRole(clientRole);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (consentRep.getGrantedProtocolMappers() != null) {
|
||||
for (Map.Entry<String, List<String>> protocolEntry : consentRep.getGrantedProtocolMappers().entrySet()) {
|
||||
String protocol = protocolEntry.getKey();
|
||||
for (String protocolMapperName : protocolEntry.getValue()) {
|
||||
ProtocolMapperModel protocolMapper = client.getProtocolMapperByName(protocol, protocolMapperName);
|
||||
if (protocolMapper == null) {
|
||||
throw new RuntimeException("Unable to find protocol mapper for protocol " + protocol + ", mapper name " + protocolMapperName);
|
||||
}
|
||||
|
||||
consentModel.addGrantedProtocolMapper(protocolMapper);
|
||||
}
|
||||
// Backwards compatibility. If user had consent for "offline_access" role, we treat it as he has consent for "offline_access" client scope
|
||||
if (consentRep.getGrantedRealmRoles() != null) {
|
||||
if (consentRep.getGrantedRealmRoles().contains(OAuth2Constants.OFFLINE_ACCESS)) {
|
||||
ClientScopeModel offlineScope = client.getClientScopes(false, true).get(OAuth2Constants.OFFLINE_ACCESS);
|
||||
if (offlineScope == null) {
|
||||
logger.warn("Unable to find offline_access scope referenced in grantedRoles of user");
|
||||
}
|
||||
consentModel.addGrantedClientScope(offlineScope);
|
||||
}
|
||||
}
|
||||
|
||||
return consentModel;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.protocol;
|
|||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.provider.ProviderEvent;
|
||||
|
@ -41,12 +42,45 @@ public abstract class AbstractLoginProtocolFactory implements LoginProtocolFacto
|
|||
public void onEvent(ProviderEvent event) {
|
||||
if (event instanceof RealmModel.ClientCreationEvent) {
|
||||
ClientModel client = ((RealmModel.ClientCreationEvent)event).getCreatedClient();
|
||||
addDefaultClientScopes(client.getRealm(), client);
|
||||
addDefaults(client);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void createDefaultClientScopes(RealmModel newRealm, boolean addScopesToExistingClients) {
|
||||
createDefaultClientScopesImpl(newRealm);
|
||||
|
||||
// Create default client scopes for realm built-in clients too
|
||||
if (addScopesToExistingClients) {
|
||||
for (ClientModel client : newRealm.getClients()) {
|
||||
addDefaultClientScopes(newRealm, client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Impl should create default client scopes. This is called usually when new realm is created
|
||||
*/
|
||||
protected abstract void createDefaultClientScopesImpl(RealmModel newRealm);
|
||||
|
||||
|
||||
protected void addDefaultClientScopes(RealmModel realm, ClientModel newClient) {
|
||||
for (ClientScopeModel clientScope : realm.getDefaultClientScopes(true)) {
|
||||
if (getId().equals(clientScope.getProtocol())) {
|
||||
newClient.addClientScope(clientScope, true);
|
||||
}
|
||||
}
|
||||
for (ClientScopeModel clientScope : realm.getDefaultClientScopes(false)) {
|
||||
if (getId().equals(clientScope.getProtocol())) {
|
||||
newClient.addClientScope(clientScope, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void addDefaults(ClientModel realm);
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.keycloak.protocol;
|
|||
import org.keycloak.events.EventBuilder;
|
||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientSessionContext;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
|
@ -67,7 +68,7 @@ public interface LoginProtocol extends Provider {
|
|||
|
||||
LoginProtocol setEventBuilder(EventBuilder event);
|
||||
|
||||
Response authenticated(UserSessionModel userSession, AuthenticatedClientSessionModel clientSession);
|
||||
Response authenticated(UserSessionModel userSession, ClientSessionContext clientSessionCtx);
|
||||
|
||||
Response sendError(AuthenticationSessionModel authSession, Error error);
|
||||
|
||||
|
|
|
@ -19,14 +19,11 @@ package org.keycloak.protocol;
|
|||
|
||||
import org.keycloak.events.EventBuilder;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.ClientTemplateRepresentation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -38,16 +35,21 @@ public interface LoginProtocolFactory extends ProviderFactory<LoginProtocol> {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
List<ProtocolMapperModel> getBuiltinMappers();
|
||||
Map<String, ProtocolMapperModel> getBuiltinMappers();
|
||||
|
||||
/**
|
||||
* List of mappers, which are added to new clients by default
|
||||
* @return
|
||||
*/
|
||||
List<ProtocolMapperModel> getDefaultBuiltinMappers();
|
||||
|
||||
Object createProtocolEndpoint(RealmModel realm, EventBuilder event);
|
||||
|
||||
|
||||
/**
|
||||
* Called when new realm is created
|
||||
*
|
||||
* @param newRealm
|
||||
* @param addScopesToExistingClients If true, then existing realm clients will be updated (created realm default scopes will be added to them)
|
||||
*/
|
||||
void createDefaultClientScopes(RealmModel newRealm, boolean addScopesToExistingClients);
|
||||
|
||||
|
||||
/**
|
||||
* Setup default values for new clients. This expects that the representation has already set up the client
|
||||
*
|
||||
|
@ -56,11 +58,4 @@ public interface LoginProtocolFactory extends ProviderFactory<LoginProtocol> {
|
|||
*/
|
||||
void setupClientDefaults(ClientRepresentation rep, ClientModel newClient);
|
||||
|
||||
/**
|
||||
* Setup default values for new templates. This expects that the representation has already set up the template
|
||||
*
|
||||
* @param clientRep
|
||||
* @param newClient
|
||||
*/
|
||||
void setupTemplateDefaults(ClientTemplateRepresentation clientRep, ClientTemplateModel newClient);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
package org.keycloak.storage.client;
|
||||
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
|
@ -214,27 +214,13 @@ public abstract class AbstractReadOnlyClientStorageAdapter extends AbstractClien
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setClientTemplate(ClientTemplateModel template) {
|
||||
throw new ReadOnlyException("client is read only for this update");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUseTemplateScope(boolean flag) {
|
||||
|
||||
public void addClientScope(ClientScopeModel clientScope, boolean defaultScope) {
|
||||
throw new ReadOnlyException("client is read only for this update");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUseTemplateMappers(boolean flag) {
|
||||
public void removeClientScope(ClientScopeModel clientScope) {
|
||||
throw new ReadOnlyException("client is read only for this update");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUseTemplateConfig(boolean flag) {
|
||||
throw new ReadOnlyException("client is read only for this update");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -24,7 +24,7 @@ import java.util.Set;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface ClientModel extends RoleContainerModel, ProtocolMapperContainerModel, ScopeContainerModel {
|
||||
public interface ClientModel extends ClientScopeModel, RoleContainerModel, ProtocolMapperContainerModel, ScopeContainerModel {
|
||||
|
||||
// COMMON ATTRIBUTES
|
||||
|
||||
|
@ -133,6 +133,9 @@ public interface ClientModel extends RoleContainerModel, ProtocolMapperContaine
|
|||
boolean isFrontchannelLogout();
|
||||
void setFrontchannelLogout(boolean flag);
|
||||
|
||||
boolean isFullScopeAllowed();
|
||||
void setFullScopeAllowed(boolean value);
|
||||
|
||||
|
||||
boolean isPublicClient();
|
||||
void setPublicClient(boolean flag);
|
||||
|
@ -154,14 +157,24 @@ public interface ClientModel extends RoleContainerModel, ProtocolMapperContaine
|
|||
|
||||
RealmModel getRealm();
|
||||
|
||||
ClientTemplateModel getClientTemplate();
|
||||
void setClientTemplate(ClientTemplateModel template);
|
||||
boolean useTemplateScope();
|
||||
void setUseTemplateScope(boolean flag);
|
||||
boolean useTemplateMappers();
|
||||
void setUseTemplateMappers(boolean flag);
|
||||
boolean useTemplateConfig();
|
||||
void setUseTemplateConfig(boolean flag);
|
||||
/**
|
||||
* Add clientScope with this client. Add it as default scope (if parameter 'defaultScope' is true) or optional scope (if parameter 'defaultScope' is false)
|
||||
* @param clientScope
|
||||
* @param defaultScope
|
||||
*/
|
||||
void addClientScope(ClientScopeModel clientScope, boolean defaultScope);
|
||||
|
||||
void removeClientScope(ClientScopeModel clientScope);
|
||||
|
||||
/**
|
||||
* Return all default scopes (if 'defaultScope' is true) or all optional scopes (if 'defaultScope' is false) linked with this client
|
||||
*
|
||||
* @param defaultScope
|
||||
* @param filterByProtocol if true, then just client scopes of same protocol like current client will be returned
|
||||
* @return map where key is the name of the clientScope, value is particular clientScope. Returns empty map if no scopes linked (never returns null).
|
||||
*/
|
||||
Map<String, ClientScopeModel> getClientScopes(boolean defaultScope, boolean filterByProtocol);
|
||||
|
||||
|
||||
/**
|
||||
* Time in seconds since epoc
|
||||
|
@ -183,4 +196,22 @@ public interface ClientModel extends RoleContainerModel, ProtocolMapperContaine
|
|||
void registerNode(String nodeHost, int registrationTime);
|
||||
|
||||
void unregisterNode(String nodeHost);
|
||||
|
||||
|
||||
// Clients are not displayed on consent screen by default
|
||||
@Override
|
||||
default boolean isDisplayOnConsentScreen() {
|
||||
String displayVal = getAttribute(DISPLAY_ON_CONSENT_SCREEN);
|
||||
return displayVal==null ? false : Boolean.parseBoolean(displayVal);
|
||||
}
|
||||
|
||||
// Fallback to name or clientId if consentScreenText attribute is null
|
||||
@Override
|
||||
default String getConsentScreenText() {
|
||||
String consentScreenText = ClientScopeModel.super.getConsentScreenText();
|
||||
if (consentScreenText == null) {
|
||||
consentScreenText = getClientId();
|
||||
}
|
||||
return consentScreenText;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import java.util.Map;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface ClientTemplateModel extends ProtocolMapperContainerModel, ScopeContainerModel {
|
||||
public interface ClientScopeModel extends ProtocolMapperContainerModel, ScopeContainerModel {
|
||||
String getId();
|
||||
|
||||
String getName();
|
||||
|
@ -43,30 +43,33 @@ public interface ClientTemplateModel extends ProtocolMapperContainerModel, Scope
|
|||
String getAttribute(String name);
|
||||
Map<String, String> getAttributes();
|
||||
|
||||
boolean isFrontchannelLogout();
|
||||
void setFrontchannelLogout(boolean flag);
|
||||
|
||||
boolean isBearerOnly();
|
||||
void setBearerOnly(boolean only);
|
||||
// CONFIGS
|
||||
|
||||
boolean isPublicClient();
|
||||
void setPublicClient(boolean flag);
|
||||
String DISPLAY_ON_CONSENT_SCREEN = "display.on.consent.screen";
|
||||
String CONSENT_SCREEN_TEXT = "consent.screen.text";
|
||||
|
||||
boolean isConsentRequired();
|
||||
void setConsentRequired(boolean consentRequired);
|
||||
default boolean isDisplayOnConsentScreen() {
|
||||
String displayVal = getAttribute(DISPLAY_ON_CONSENT_SCREEN);
|
||||
return displayVal==null ? true : Boolean.parseBoolean(displayVal);
|
||||
}
|
||||
|
||||
boolean isStandardFlowEnabled();
|
||||
void setStandardFlowEnabled(boolean standardFlowEnabled);
|
||||
default void setDisplayOnConsentScreen(boolean displayOnConsentScreen) {
|
||||
setAttribute(DISPLAY_ON_CONSENT_SCREEN, String.valueOf(displayOnConsentScreen));
|
||||
}
|
||||
|
||||
boolean isImplicitFlowEnabled();
|
||||
void setImplicitFlowEnabled(boolean implicitFlowEnabled);
|
||||
|
||||
boolean isDirectAccessGrantsEnabled();
|
||||
void setDirectAccessGrantsEnabled(boolean directAccessGrantsEnabled);
|
||||
|
||||
boolean isServiceAccountsEnabled();
|
||||
void setServiceAccountsEnabled(boolean serviceAccountsEnabled);
|
||||
// Fallback to name if consentScreenText attribute is null
|
||||
default String getConsentScreenText() {
|
||||
String consentScreenText = getAttribute(CONSENT_SCREEN_TEXT);
|
||||
if (consentScreenText == null) {
|
||||
consentScreenText = getName();
|
||||
}
|
||||
return consentScreenText;
|
||||
}
|
||||
|
||||
default void setConsentScreenText(String consentScreenText) {
|
||||
setAttribute(CONSENT_SCREEN_TEXT, consentScreenText);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright 2017 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;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Request-scoped context object
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public interface ClientSessionContext {
|
||||
|
||||
AuthenticatedClientSessionModel getClientSession();
|
||||
|
||||
Set<String> getClientScopeIds();
|
||||
|
||||
Set<ClientScopeModel> getClientScopes();
|
||||
|
||||
Set<RoleModel> getRoles();
|
||||
|
||||
Set<ProtocolMapperModel> getProtocolMappers();
|
||||
|
||||
String getScopeString();
|
||||
}
|
|
@ -69,22 +69,6 @@ public class ProtocolMapperModel implements Serializable {
|
|||
this.protocolMapper = protocolMapper;
|
||||
}
|
||||
|
||||
public boolean isConsentRequired() {
|
||||
return consentRequired;
|
||||
}
|
||||
|
||||
public void setConsentRequired(boolean consentRequired) {
|
||||
this.consentRequired = consentRequired;
|
||||
}
|
||||
|
||||
public String getConsentText() {
|
||||
return consentText;
|
||||
}
|
||||
|
||||
public void setConsentText(String consentText) {
|
||||
this.consentText = consentText;
|
||||
}
|
||||
|
||||
public Map<String, String> getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
|
|
@ -437,14 +437,18 @@ public interface RealmModel extends RoleContainerModel {
|
|||
boolean removeGroup(GroupModel group);
|
||||
void moveGroup(GroupModel group, GroupModel toParent);
|
||||
|
||||
List<ClientTemplateModel> getClientTemplates();
|
||||
List<ClientScopeModel> getClientScopes();
|
||||
|
||||
ClientTemplateModel addClientTemplate(String name);
|
||||
ClientScopeModel addClientScope(String name);
|
||||
|
||||
ClientTemplateModel addClientTemplate(String id, String name);
|
||||
ClientScopeModel addClientScope(String id, String name);
|
||||
|
||||
boolean removeClientTemplate(String id);
|
||||
boolean removeClientScope(String id);
|
||||
|
||||
ClientTemplateModel getClientTemplateById(String id);
|
||||
ClientScopeModel getClientScopeById(String id);
|
||||
|
||||
void addDefaultClientScope(ClientScopeModel clientScope, boolean defaultScope);
|
||||
void removeDefaultClientScope(ClientScopeModel clientScope);
|
||||
List<ClientScopeModel> getDefaultClientScopes(boolean defaultScope);
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.keycloak.models;
|
|||
|
||||
import org.keycloak.migration.MigrationModel;
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.storage.client.ClientLookupProvider;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -72,7 +71,7 @@ public interface RealmProvider extends Provider, ClientProvider {
|
|||
|
||||
RoleModel getRoleById(String id, RealmModel realm);
|
||||
|
||||
ClientTemplateModel getClientTemplateById(String id, RealmModel realm);
|
||||
ClientScopeModel getClientScopeById(String id, RealmModel realm);
|
||||
GroupModel getGroupById(String id, RealmModel realm);
|
||||
|
||||
|
||||
|
|
|
@ -34,10 +34,6 @@ public interface RoleModel {
|
|||
|
||||
void setName(String name);
|
||||
|
||||
boolean isScopeParamRequired();
|
||||
|
||||
void setScopeParamRequired(boolean scopeParamRequired);
|
||||
|
||||
boolean isComposite();
|
||||
|
||||
void addCompositeRole(RoleModel role);
|
||||
|
|
|
@ -24,9 +24,6 @@ import java.util.Set;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface ScopeContainerModel {
|
||||
boolean isFullScopeAllowed();
|
||||
|
||||
void setFullScopeAllowed(boolean value);
|
||||
|
||||
Set<RoleModel> getScopeMappings();
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue