package net.unicon.cas.mfa.util;
import net.unicon.cas.mfa.web.support.MultiFactorAuthenticationSupportingWebApplicationService;
import org.apache.commons.lang3.StringUtils;
import org.jasig.cas.authentication.Authentication;
import org.jasig.cas.validation.Assertion;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Utility methods to ease implementation of multifactor behavior.
* @author Misagh Moayyed
*/
public final class MultiFactorUtils {
/**
* Private constructor.
*/
private MultiFactorUtils() {
}
/**
* Generate the string the indicates the list of satisfied authentication methods.
* Methods are separated by a space.
* @param assertion the assertion carrying the methods.
* @return the space-delimited list of authentication methods, or null if none is available
*/
public static String getFulfilledAuthenticationMethodsAsString(final Assertion assertion) {
final Authentication authentication = getAuthenticationFromAssertion(assertion);
return getFulfilledAuthenticationMethodsAsString(authentication);
}
/**
* Generate the string the indicates the list of satisfied authentication methods.
* Methods are separated by a space.
* @param authentication the authentication carrying the methods.
* @return the space-delimited list of authentication methods, or null if none is available
*/
public static String getFulfilledAuthenticationMethodsAsString(final Authentication authentication) {
final Set<String> previouslyAchievedAuthenticationMethods = getSatisfiedAuthenticationMethods(authentication);
if (!previouslyAchievedAuthenticationMethods.isEmpty()) {
return StringUtils.join(previouslyAchievedAuthenticationMethods, " ");
}
return null;
}
/**
* Convert the object given into a {@link Collection} instead.
* @param obj the object to convert into a collection
* @return The collection instance containing the object provided
*/
@SuppressWarnings("unchecked")
public static Set<Object> convertValueToCollection(final Object obj) {
final Set<Object> c = new HashSet<>();
if (obj instanceof Collection) {
c.addAll((Collection<Object>) obj);
} else if (obj instanceof Map) {
throw new UnsupportedOperationException(Map.class.getCanonicalName() + " is not supoorted");
} else if (obj.getClass().isArray()) {
for (final Object object : (Object[]) obj) {
c.add(object);
}
} else {
c.add(obj);
}
return c;
}
/**
* Retrieves the collection of authentication methods available in the list
* of authentication attributes. The authentication attribute that refers to the set of methods satisfied is
* by the name of {@link MultiFactorAuthenticationSupportingWebApplicationService#CONST_PARAM_AUTHN_METHOD}.
*
* @param authentication the authentication that houses the methods.
* @return collection of fulfilled authentication methods
*/
public static Set<String> getSatisfiedAuthenticationMethods(final Authentication authentication) {
if (authentication.getAttributes().containsKey(MultiFactorAuthenticationSupportingWebApplicationService.CONST_PARAM_AUTHN_METHOD)) {
final Object methods = authentication.getAttributes().get(
MultiFactorAuthenticationSupportingWebApplicationService.CONST_PARAM_AUTHN_METHOD);
if (methods != null) {
final Set<Object> valuesAsACollection = convertValueToCollection(methods);
return new HashSet<>(Arrays.asList(valuesAsACollection.toArray(new String[]{})));
}
}
return Collections.emptySet();
}
/**
* Gets authentication from assertionfinal.
*
* @param assertion the assertion
* @return the authentication from assertionfinal
*/
public static Authentication getAuthenticationFromAssertion(final Assertion assertion) {
final List<Authentication> chainedAuthentications = assertion.getChainedAuthentications();
if (!chainedAuthentications.isEmpty()) {
final int index = chainedAuthentications.size() - 1;
return chainedAuthentications.get(index);
}
return null;
}
}