org.opensaml.saml.common.profile.AbstractNameIdentifierGenerator Maven / Gradle / Ivy
/*
* Licensed to the University Corporation for Advanced Internet Development,
* Inc. (UCAID) under one or more contributor license agreements. See the
* NOTICE file distributed with this work for additional information regarding
* copyright ownership. The UCAID 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.opensaml.saml.common.profile;
import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.component.AbstractIdentifiableInitializableComponent;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.primitive.StringSupport;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.saml.common.SAMLException;
import org.opensaml.saml.common.SAMLObject;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
/**
* Abstract base class for simple implementations of {@link NameIdentifierGenerator}.
*
*
* This class is suitable for implementing generators that produce simple kinds of identifiers. It supports various
* options controlling the inclusion of qualifier attributes.
*
*
*
* Subclasses must override one of {@link #doGenerate(ProfileRequestContext)} or
* {@link #getIdentifier(ProfileRequestContext)}.
*
*
* @param type of object produced
*/
public abstract class AbstractNameIdentifierGenerator
extends AbstractIdentifiableInitializableComponent
implements FormatSpecificNameIdentifierGenerator, Predicate {
/** A predicate indicating whether the component applies to a request. */
@Nonnull private Predicate activationCondition;
/** Optional lookup function for obtaining default NameQualifier. */
@Nullable private Function defaultIdPNameQualifierLookupStrategy;
/** Optional lookup function for obtaining default SPNameQualifier. */
@Nullable private Function defaultSPNameQualifierLookupStrategy;
/** Flag allowing qualifier(s) to be omitted when they would match defaults or are not set. */
private boolean omitQualifiers;
/** The identifier Format supported. */
@NonnullAfterInit @NotEmpty private String format;
/** Explicit NameQualifier, if any. */
@Nullable private String idpNameQualifier;
/** Explicit SPNameQualifier, if any. */
@Nullable private String spNameQualifier;
/** SPProvidedID, if any. */
@Nullable private String spProvidedId;
/** Constructor. */
protected AbstractNameIdentifierGenerator() {
activationCondition = Predicates.alwaysTrue();
}
/**
* Set an activation condition that determines whether to run or not.
*
* @param condition an activation condition
*/
public void setActivationCondition(@Nonnull final Predicate condition) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
activationCondition = Constraint.isNotNull(condition, "Predicate cannot be null");
}
/**
* Get the lookup strategy to obtain the default IdP NameQualifier.
*
* @return lookup strategy
*/
@Nullable public Function getDefaultIdPNameQualifierLookupStrategy() {
return defaultIdPNameQualifierLookupStrategy;
}
/**
* Set the lookup strategy to obtain the default IdP NameQualifier.
*
* @param strategy lookup strategy
*/
public void setDefaultIdPNameQualifierLookupStrategy(
@Nullable final Function strategy) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
defaultIdPNameQualifierLookupStrategy = strategy;
}
/**
* Get the lookup strategy to obtain the default SPNameQualifier.
*
* @return lookup strategy
*/
@Nullable public Function getDefaultSPNameQualifierLookupStrategy() {
return defaultSPNameQualifierLookupStrategy;
}
/**
* Set the lookup strategy to obtain the default SPNameQualifier.
*
* @param strategy lookup strategy
*/
public void setDefaultSPNameQualifierLookupStrategy(
@Nullable final Function strategy) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
defaultSPNameQualifierLookupStrategy = strategy;
}
/**
* Get whether to omit NameQualifier/SPNameQualifier attributes if the qualifiers are not explicitly set or are set
* to values matching the IdP and relying party names respectively.
*
* @return whether to omit qualifiers
*/
public boolean isOmitQualifiers() {
return omitQualifiers;
}
/**
* Set whether to omit NameQualifier/SPNameQualifier attributes if the qualifiers are not explicitly set or are set
* to values matching the IdP and relying party names respectively.
*
* @param flag flag to set
*/
public void setOmitQualifiers(final boolean flag) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
omitQualifiers = flag;
}
/** {@inheritDoc} */
@Override @NonnullAfterInit @NotEmpty public String getFormat() {
return format;
}
/**
* Set the Format attribute supported.
*
* @param f format to set
*/
public void setFormat(@Nonnull @NotEmpty final String f) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
format = Constraint.isNotNull(StringSupport.trimOrNull(f), "Format cannot be null or empty");
}
/**
* Get the NameQualifier attribute.
*
* @return the qualifier attribute
*/
@Nullable public String getIdPNameQualifier() {
return idpNameQualifier;
}
/**
* Set the NameQualifier attribute.
*
*
* If not set, and {@link #isOmitQualifiers()} is false, then the value used will be derived from the IdP identity.
*
*
* @param qualifier qualifier to set
*/
public void setIdPNameQualifier(@Nullable final String qualifier) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
idpNameQualifier = StringSupport.trimOrNull(qualifier);
}
/**
* Get the SPNameQualifier attribute.
*
* @return the qualifier attribute
*/
@Nullable public String getSPNameQualifier() {
return spNameQualifier;
}
/**
* Set the SPNameQualifier attribute.
*
*
* If not set, and {@link #isOmitQualifiers()} is false, then the value used will be derived from the relying party
* identity.
*
*
* @param qualifier qualifier to set
*/
public void setSPNameQualifier(@Nullable final String qualifier) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
spNameQualifier = StringSupport.trimOrNull(qualifier);
}
/**
* Get the SPProvidedID attribute.
*
* @return the secondary ID attribute
*/
@Nullable public String getSPProvidedID() {
return spProvidedId;
}
/**
* Set the SPProvidedID attribute.
*
* @param id value to set
*/
public void setSPProvidedId(@Nullable final String id) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
spProvidedId = id;
}
/** {@inheritDoc} */
@Override
protected void doInitialize() throws ComponentInitializationException {
super.doInitialize();
if (format == null) {
throw new ComponentInitializationException("Format value cannot be null or empty");
}
}
/** {@inheritDoc} */
@Override
public boolean apply(@Nullable final ProfileRequestContext input) {
return activationCondition.apply(input);
}
/** {@inheritDoc} */
@Override
@Nullable public NameIdType generate(@Nonnull final ProfileRequestContext profileRequestContext,
@Nonnull @NotEmpty final String theFormat) throws SAMLException {
ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
if (!Objects.equals(format, theFormat)) {
throw new SAMLException("The format to generate does not match the value configured");
} else if (!apply(profileRequestContext)) {
return null;
}
return doGenerate(profileRequestContext);
}
/**
* Override this method to fully control the generation process.
*
* @param profileRequestContext current profile request context
* @return the generated object
* @throws SAMLException if an error occurs
*/
@Nullable protected abstract NameIdType doGenerate(@Nonnull final ProfileRequestContext profileRequestContext)
throws SAMLException;
/**
* Override this method to reuse this implementation of {@link #doGenerate(ProfileRequestContext)}, and return the
* identifier to be included as the value of the eventual element.
*
* @param profileRequestContext current profile request context
*
* @return the generated identifier
* @throws SAMLException if an error occurs
*/
@Nullable protected String getIdentifier(@Nonnull final ProfileRequestContext profileRequestContext)
throws SAMLException {
return null;
}
/**
* Get the effective NameQualifier to apply based on the properties set and the current request.
*
* @param profileRequestContext current profile context
*
* @return the effective NameQualifier to set, or null
*/
@Nullable protected String getEffectiveIdPNameQualifier(
@Nonnull final ProfileRequestContext profileRequestContext) {
if (idpNameQualifier != null) {
if (omitQualifiers) {
if (defaultIdPNameQualifierLookupStrategy == null
|| !Objects.equals(idpNameQualifier,
defaultIdPNameQualifierLookupStrategy.apply(profileRequestContext))) {
return idpNameQualifier;
} else {
return null;
}
} else {
return idpNameQualifier;
}
} else if (!omitQualifiers && defaultIdPNameQualifierLookupStrategy != null) {
return defaultIdPNameQualifierLookupStrategy.apply(profileRequestContext);
} else {
return null;
}
}
/**
* Get the effective SPNameQualifier to apply based on the properties set and the current request.
*
* @param profileRequestContext current profile context
*
* @return the effective NameQualifier to set, or null
*/
@Nullable protected String getEffectiveSPNameQualifier(@Nonnull final ProfileRequestContext profileRequestContext) {
if (spNameQualifier != null) {
if (omitQualifiers) {
if (defaultSPNameQualifierLookupStrategy == null
|| !Objects.equals(spNameQualifier,
defaultSPNameQualifierLookupStrategy.apply(profileRequestContext))) {
return spNameQualifier;
} else {
return null;
}
} else {
return spNameQualifier;
}
} else if (!omitQualifiers && defaultSPNameQualifierLookupStrategy != null) {
return defaultSPNameQualifierLookupStrategy.apply(profileRequestContext);
} else {
return null;
}
}
}