blob: e956f7d35fe8f9f32a1922e92443a974587d2452 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.jackrabbit.oak.spi.security.authentication.external.basic;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.jetbrains.annotations.NotNull;
/**
* {@code DefaultSyncConfig} defines how users and groups from an external source are synced into the repository using
* the {@link org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncHandler}.
*/
public class DefaultSyncConfig {
private final User user = new User();
private final Group group = new Group();
private String name = "default";
/**
* Configures the name of this configuration
* @return the name
*/
@NotNull
public String getName() {
return name;
}
/**
* Sets the name
* @param name the name
* @return {@code this}
* @see #getName()
*/
@NotNull
public DefaultSyncConfig setName(@NotNull String name) {
this.name = name;
return this;
}
/**
* Returns the sync configuration for users.
* @return the user sync configuration.
*/
@NotNull
public User user() {
return user;
}
/**
* Returns the sync configuration for groups.
* @return the group sync configuration.
*/
@NotNull
public Group group() {
return group;
}
/**
* Base config class for users and groups
*/
public abstract static class Authorizable {
private long expirationTime;
private Set<String> autoMembership;
private Map<String, String> propertyMapping;
private String pathPrefix;
private boolean applyRFC7613UsernameCaseMapped;
/**
* Returns the duration in milliseconds until a synced authorizable gets expired. An expired authorizable will
* be re-synced.
* @return the expiration time in milliseconds.
*/
public long getExpirationTime() {
return expirationTime;
}
/**
* Sets the expiration time.
* @param expirationTime time in milliseconds.
* @return {@code this}
* @see #getExpirationTime()
*/
@NotNull
public Authorizable setExpirationTime(long expirationTime) {
this.expirationTime = expirationTime;
return this;
}
/**
* Returns true if new AuthorizableIDs will be normalized according to
* the UsernameCaseMapped profile defined in RFC7613
* @return true if new AuthorizableIDs will be normalized.
*/
public boolean isApplyRFC7613UsernameCaseMapped() {
return applyRFC7613UsernameCaseMapped;
}
/**
* Set to true if new AuthorizableIDs shall be normalized according to
* the UsernameCaseMapped profile defined in RFC7613.
* @param applyRFC7613UsernameCaseMapped true if the UsernameCaseMapped profile shall be used for normalization.
* @return {@code this}
* @see #isApplyRFC7613UsernameCaseMapped()
*/
public Authorizable setApplyRFC7613UsernameCaseMapped(boolean applyRFC7613UsernameCaseMapped) {
this.applyRFC7613UsernameCaseMapped = applyRFC7613UsernameCaseMapped;
return this;
}
/**
* Defines the set of group names that are automatically added to synced authorizable.
* @return set of group names.
*/
@NotNull
public Set<String> getAutoMembership() {
return autoMembership == null ? Collections.<String>emptySet() : autoMembership;
}
/**
* Sets the auto membership. Note that the passed group names will be trimmed
* and empty string values will be ignored (along with {@code null} values).
*
* @param autoMembership the membership
* @return {@code this}
* @see #getAutoMembership()
*/
@NotNull
public Authorizable setAutoMembership(@NotNull String ... autoMembership) {
this.autoMembership = new HashSet<String>();
for (String groupName: autoMembership) {
if (groupName != null && !groupName.trim().isEmpty()) {
this.autoMembership.add(groupName.trim());
}
}
return this;
}
/**
* Defines the mapping of internal property names from external values. Only the external properties defined as
* keys of this map are synced with the mapped internal properties. note that the property names can be relative
* paths. the intermediate nodes will be created accordingly.
*
* Example:
* <pre>{@code
* {
* "rep:fullname": "cn",
* "country", "c",
* "profile/email": "mail",
* "profile/givenName": "cn"
* }
* }</pre>
*
* The implicit properties like userid, groupname, password must not be mapped.
*
* @return the property mapping where the keys are the local property names and the values the external ones.
*/
@NotNull
public Map<String, String> getPropertyMapping() {
return propertyMapping == null ? Collections.<String, String>emptyMap() : propertyMapping;
}
/**
* Sets the property mapping.
* @param propertyMapping the mapping
* @return {@code this}
* @see #getPropertyMapping()
*/
@NotNull
public Authorizable setPropertyMapping(@NotNull Map<String, String> propertyMapping) {
this.propertyMapping = propertyMapping;
return this;
}
/**
* Defines the authorizables intermediate path prefix that is used when creating new authorizables. This prefix
* is always prepended to the path provided by the {@link org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentity}.
* @return the intermediate path prefix.
*/
@NotNull
public String getPathPrefix() {
return pathPrefix == null ? "" : pathPrefix;
}
/**
* Sets the path prefix.
* @param pathPrefix the path prefix.
* @return {@code this}
* @see #getPathPrefix()
*/
@NotNull
public Authorizable setPathPrefix(@NotNull String pathPrefix) {
this.pathPrefix = pathPrefix;
return this;
}
}
/**
* User specific config.
*/
public static class User extends Authorizable {
private long membershipExpirationTime;
private long membershipNestingDepth;
private boolean dynamicMembership;
private boolean disableMissing;
/**
* Returns the duration in milliseconds until the group membership of a user is expired. If the
* membership information is expired it is re-synced according to the maximum nesting depth.
* Note that the membership is the groups an authorizable is member of, not the list of members of a group.
* Also note, that the group membership expiration time can be higher than the user expiration time itself and
* that value has no effect when syncing individual groups only when syncing a users membership ancestry.
*
* @return the expiration time in milliseconds.
*/
public long getMembershipExpirationTime() {
return membershipExpirationTime;
}
/**
* Sets the membership expiration time
* @param membershipExpirationTime the time in milliseconds.
* @return {@code this}
* @see #getMembershipExpirationTime()
*/
@NotNull
public User setMembershipExpirationTime(long membershipExpirationTime) {
this.membershipExpirationTime = membershipExpirationTime;
return this;
}
/**
* Returns the maximum depth of group nesting when membership relations are synced. A value of 0 effectively
* disables group membership lookup. A value of 1 only adds the direct groups of a user. This value has no effect
* when syncing individual groups only when syncing a users membership ancestry.
* @return the group nesting depth
*/
public long getMembershipNestingDepth() {
return membershipNestingDepth;
}
/**
* Sets the group nesting depth.
* @param membershipNestingDepth the depth.
* @return {@code this}
* @see #getMembershipNestingDepth()
*/
@NotNull
public User setMembershipNestingDepth(long membershipNestingDepth) {
this.membershipNestingDepth = membershipNestingDepth;
return this;
}
/**
* Returns {@code true} if a dynamic group membership is enabled.
*
* Turning this option on may alter the behavior of other configuration
* options dealing with synchronization of group accounts and group membership.
* In particular it's an implementation detail if external groups may
* no longer be synchronized into the repository.
*
* @return {@code true} if dynamic group membership for external
* user identities is turn on; {@code false} otherwise.
*/
@NotNull
public boolean getDynamicMembership() {
return dynamicMembership;
}
/**
* Enable or disable the dynamic group membership. If turned external
* identities and their group membership will be synchronized such that the
* membership information is generated dynamically. External groups may
* or may not be synchronized into the repository if this option is turned
* on.
*
* @param dynamicMembership Boolean flag to enable or disable a dedicated
* dynamic group management.
* @return {@code this}
* @see #getDynamicMembership() for details.
*/
@NotNull
public User setDynamicMembership(boolean dynamicMembership) {
this.dynamicMembership = dynamicMembership;
return this;
}
/**
* Controls the behavior for users that no longer exist on the external provider. The default is to delete the repository users
* if they no longer exist on the external provider. If set to true, they will be disabled instead, and re-enabled once they appear
* again.
*/
public boolean getDisableMissing() {
return disableMissing;
}
/**
* @see #getDisableMissing()
*/
public User setDisableMissing(boolean disableMissing) {
this.disableMissing = disableMissing;
return this;
}
}
/**
* Group specific config
*/
public static class Group extends Authorizable {
}
}