/* * Licensed to Jasig under one or more contributor license * agreements. See the NOTICE file distributed with this work * for additional information regarding copyright ownership. * Jasig 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 the following location: * * 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.jasig.cas.authentication; import java.util.ArrayList; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.jasig.cas.authentication.principal.Principal; import org.springframework.util.Assert; /** * Constructs immutable {@link Authentication} objects using the builder pattern. * * @author Marvin S. Addison * @since 4.0 */ public class AuthenticationBuilder { /** Authenticated principal. */ private Principal principal; /** Credential metadata. */ private List<CredentialMetaData> credentials = new ArrayList<CredentialMetaData>(); /** Authentication metadata attributes. */ private Map<String, Object> attributes = new LinkedHashMap<String, Object>(); /** Map of handler names to authentication successes. */ private Map<String, HandlerResult> successes = new LinkedHashMap<String, HandlerResult>(); /** Map of handler names to authentication failures. */ private Map<String, Class<? extends Exception>> failures = new LinkedHashMap<String, Class<? extends Exception>>(); /** Authentication date. */ private Date authenticationDate; /** * Creates a new instance using the current date for the authentication date. */ public AuthenticationBuilder() { authenticationDate = new Date(); } /** * Creates a new instance using the current date for the authentication date and the given * principal for the authenticated principal. * * @param p Authenticated principal. */ public AuthenticationBuilder(final Principal p) { this(); this.principal = p; } /** * Gets the authentication date. * * @return Authentication date. */ public Date getAuthenticationDate() { return authenticationDate; } /** * Sets the authentication date and returns this instance. * * @param d Authentication date. * * @return This builder instance. */ public AuthenticationBuilder setAuthenticationDate(final Date d) { this.authenticationDate = d; return this; } /** * Gets the authenticated principal. * * @return Principal. */ public Principal getPrincipal() { return this.principal; } /** * Sets the principal returns this instance. * * @param p Authenticated principal. * * @return This builder instance. */ public AuthenticationBuilder setPrincipal(final Principal p) { this.principal = p; return this; } /** * Gets the list of credentials that were attempted to be authenticated. * * @return Non-null list of credentials that attempted authentication. */ public List<CredentialMetaData> getCredentials() { return this.credentials; } /** * Sets the list of metadata about credentials presented for authentication. * * @param credentials Non-null list of credential metadata. * * @return This builder instance. */ public AuthenticationBuilder setCredentials(final List<CredentialMetaData> credentials) { Assert.notNull(credentials, "Credential cannot be null"); this.credentials.clear(); for (final CredentialMetaData c : credentials) { this.credentials.add(c); } return this; } /** * Adds metadata about a credential presented for authentication. * * @param credential Credential metadata. * * @return This builder instance. */ public AuthenticationBuilder addCredential(final CredentialMetaData credential) { this.credentials.add(credential); return this; } /** * Gets the authentication attribute map. * * @return Non-null authentication attribute map. */ public Map<String, Object> getAttributes() { return this.attributes; } /** * Sets the authentication metadata attributes. * * @param attributes Non-null map of authentication metadata attributes. * * @return This builder instance. */ public AuthenticationBuilder setAttributes(final Map<String, Object> attributes) { Assert.notNull(attributes, "Attributes cannot be null"); this.attributes.clear(); for (final String name : attributes.keySet()) { this.attributes.put(name, attributes.get(name)); } return this; } /** * Adds an authentication metadata attribute key-value pair. * * @param key Authentication attribute key. * @param value Authentication attribute value. * * @return This builder instance. */ public AuthenticationBuilder addAttribute(final String key, final Object value) { this.attributes.put(key, value); return this; } /** * Gets the authentication success map. * * @return Non-null map of handler names to successful handler authentication results. */ public Map<String, HandlerResult> getSuccesses() { return this.successes; } /** * Sets the authentication handler success map. * * @param successes Non-null map of handler names to successful handler authentication results. * * @return This builder instance. */ public AuthenticationBuilder setSuccesses(final Map<String, HandlerResult> successes) { Assert.notNull(successes, "Successes cannot be null"); this.successes.clear(); for (final String handler : successes.keySet()) { this.successes.put(handler, successes.get(handler)); } return this; } /** * Adds an authentication success to the map of handler names to successful authentication handler results. * * @param key Authentication handler name. * @param value Successful authentication handler result produced by handler of given name. * * @return This builder instance. */ public AuthenticationBuilder addSuccess(final String key, final HandlerResult value) { this.successes.put(key, value); return this; } /** * Gets the authentication failure map. * * @return Non-null authentication failure map. */ public Map<String, Class<? extends Exception>> getFailures() { return this.failures; } /** * Sets the authentication handler failure map. * * @param failures Non-null map of handler name to authentication failures. * * @return This builder instance. */ public AuthenticationBuilder setFailures(final Map<String, Class<? extends Exception>> failures) { Assert.notNull(failures, "Failures cannot be null"); this.failures.clear(); for (final String handler : failures.keySet()) { this.failures.put(handler, failures.get(handler)); } return this; } /** * Adds an authentication failure to the map of handler names to the authentication handler failures. * * @param key Authentication handler name. * @param value Exception raised on handler failure to authenticate credential. * * @return This builder instance. */ public AuthenticationBuilder addFailure(final String key, final Class<? extends Exception> value) { this.failures.put(key, value); return this; } /** * Creates an immutable authentication instance from builder data. * * @return Immutable authentication. */ public Authentication build() { return new ImmutableAuthentication( this.authenticationDate, this.credentials, this.principal, this.attributes, this.successes, this.failures); } /** * Creates a new builder initialized with data from the given authentication source. * * @param source Authentication source. * * @return New builder instance initialized with all fields in the given authentication source. */ public static AuthenticationBuilder newInstance(final Authentication source) { final AuthenticationBuilder builder = new AuthenticationBuilder(source.getPrincipal()); builder.setAuthenticationDate(source.getAuthenticatedDate()); builder.setCredentials(source.getCredentials()); builder.setSuccesses(source.getSuccesses()); builder.setFailures(source.getFailures()); builder.setAttributes(source.getAttributes()); return builder; } }