Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
*
* * Copyright 2021 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.userprofile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.keycloak.models.ClientScopeProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.sessions.AuthenticationSessionModel;
/**
* @author Pedro Igor
*/
public final class AttributeMetadata {
public static final Predicate ALWAYS_TRUE = context -> true;
public static final Predicate ALWAYS_FALSE = context -> false;
private final String attributeName;
private String attributeDisplayName;
private AttributeGroupMetadata attributeGroupMetadata;
private final Predicate selector;
private final List> writeAllowed = new ArrayList<>();
/** Predicate to decide if attribute is required, it is handled as required if predicate is null */
private Predicate required;
private final List> readAllowed = new ArrayList<>();
private List validators;
private Map annotations;
private int guiOrder;
AttributeMetadata(String attributeName, int guiOrder) {
this(attributeName, guiOrder, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE);
}
AttributeMetadata(String attributeName, int guiOrder, Predicate writeAllowed, Predicate required) {
this(attributeName, guiOrder, ALWAYS_TRUE, writeAllowed, required, ALWAYS_TRUE);
}
AttributeMetadata(String attributeName, int guiOrder, Predicate selector) {
this(attributeName, guiOrder, selector, ALWAYS_FALSE, ALWAYS_TRUE, ALWAYS_TRUE);
}
AttributeMetadata(String attributeName, int guiOrder, List scopes, Predicate writeAllowed, Predicate required) {
this(attributeName, guiOrder, context -> {
KeycloakSession session = context.getSession();
AuthenticationSessionModel authSession = session.getContext().getAuthenticationSession();
if (authSession == null) {
return false;
}
ClientScopeProvider clientScopes = session.clientScopes();
RealmModel realm = session.getContext().getRealm();
// TODO UserProfile - LOOKS LIKE THIS DOESN'T WORK FOR SOME AUTH FLOWS, LIKE
// REGISTER?
if (authSession.getClientScopes().stream().anyMatch(scopes::contains)) {
return true;
}
return authSession.getClientScopes().stream()
.map(id -> clientScopes.getClientScopeById(realm, id).getName()).anyMatch(scopes::contains);
}, writeAllowed, required, ALWAYS_TRUE);
}
AttributeMetadata(String attributeName, int guiOrder, Predicate selector, Predicate writeAllowed,
Predicate required,
Predicate readAllowed) {
this.attributeName = attributeName;
this.guiOrder = guiOrder;
this.selector = selector;
addWriteCondition(writeAllowed);
this.required = required;
addReadCondition(readAllowed);
}
AttributeMetadata(String attributeName, int guiOrder, Predicate selector, List> writeAllowed,
Predicate required,
List> readAllowed) {
this.attributeName = attributeName;
this.guiOrder = guiOrder;
this.selector = selector;
this.writeAllowed.addAll(writeAllowed);
this.required = required;
this.readAllowed.addAll(readAllowed);
}
public String getName() {
return attributeName;
}
public int getGuiOrder() {
return guiOrder;
}
public AttributeMetadata setGuiOrder(int guiOrder) {
this.guiOrder = guiOrder;
return this;
}
public AttributeGroupMetadata getAttributeGroupMetadata() {
return attributeGroupMetadata;
}
public boolean isSelected(AttributeContext context) {
return selector.test(context);
}
private boolean allConditionsMet(List> predicates, AttributeContext context) {
return predicates.stream().allMatch(p -> p.test(context));
}
public AttributeMetadata addReadCondition(Predicate readAllowed) {
this.readAllowed.add(readAllowed);
return this;
}
public AttributeMetadata addWriteCondition(Predicate writeAllowed) {
this.writeAllowed.add(writeAllowed);
return this;
}
public boolean isReadOnly(AttributeContext context) {
return !canEdit(context);
}
public boolean canView(AttributeContext context) {
return allConditionsMet(readAllowed, context);
}
public boolean canEdit(AttributeContext context) {
return allConditionsMet(writeAllowed, context);
}
/**
* Check if attribute is required based on it's predicate, it is handled as required if predicate is null
* @param context to evaluate requirement of the attribute from
* @return true if attribute is required in provided context
*/
public boolean isRequired(AttributeContext context) {
return required == null || required.test(context);
}
public List getValidators() {
return validators;
}
public AttributeMetadata addValidators(List validators) {
if (this.validators == null) {
this.validators = new ArrayList<>();
}
this.validators.removeIf(validators::contains);
this.validators.addAll(validators.stream().filter(Objects::nonNull).collect(Collectors.toList()));
return this;
}
public Map getAnnotations() {
return annotations;
}
public AttributeMetadata addAnnotations(Map annotations) {
if(annotations != null) {
if(this.annotations == null) {
this.annotations = new HashMap<>();
}
this.annotations.putAll(annotations);
}
return this;
}
@Override
public AttributeMetadata clone() {
AttributeMetadata cloned = new AttributeMetadata(attributeName, guiOrder, selector, writeAllowed, required, readAllowed);
// we clone validators list to allow adding or removing validators. Validators
// itself are not cloned as we do not expect them to be reconfigured.
if (validators != null) {
cloned.addValidators(validators);
}
//we clone annotations map to allow adding to or removing from it
if(annotations != null) {
cloned.addAnnotations(annotations);
}
cloned.setAttributeDisplayName(attributeDisplayName);
if (attributeGroupMetadata != null) {
cloned.setAttributeGroupMetadata(attributeGroupMetadata.clone());
}
return cloned;
}
public String getAttributeDisplayName() {
if(attributeDisplayName == null || attributeDisplayName.trim().isEmpty())
return attributeName;
return attributeDisplayName;
}
public AttributeMetadata setAttributeDisplayName(String attributeDisplayName) {
if(attributeDisplayName != null)
this.attributeDisplayName = attributeDisplayName;
return this;
}
public AttributeMetadata setAttributeGroupMetadata(AttributeGroupMetadata attributeGroupMetadata) {
if(attributeGroupMetadata != null)
this.attributeGroupMetadata = attributeGroupMetadata;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || !(o instanceof AttributeMetadata)) return false;
AttributeMetadata that = (AttributeMetadata) o;
return that.getName().equals(getName());
}
@Override
public int hashCode() {
return attributeName.hashCode();
}
public AttributeMetadata setRequired(Predicate required) {
this.required = required;
return this;
}
public AttributeMetadata setValidators(List validators) {
this.validators = validators;
return this;
}
}