/** * Copyright (c) 2013-2016, The SeedStack authors <http://seedstack.org> * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.seedstack.seed.security.principals; import java.io.Serializable; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; /** * Utility class to create and manipulate common principals. */ public final class Principals { public static final String IDENTITY = "userId"; public static final String LOCALE = "locale"; public static final String FIRST_NAME = "firstName"; public static final String LAST_NAME = "lastName"; public static final String FULL_NAME = "fullName"; private Principals() { } private static SimplePrincipalProvider simplePrincipal(String name, String value) { return new SimplePrincipalProvider(name, value); } /** * Simple principal to store the identity as a string * * @param identity the identity * @return the built principal */ public static SimplePrincipalProvider identityPrincipal(String identity) { return simplePrincipal(IDENTITY, identity); } /** * Simple principal to store the locale as a string * * @param locale the locale * @return the built principal */ public static SimplePrincipalProvider localePrincipal(String locale) { return simplePrincipal(LOCALE, locale); } /** * Simple principal to store the firstName as a string * * @param firstName the firstName * @return the built principal */ public static SimplePrincipalProvider firstNamePrincipal(String firstName) { return simplePrincipal(FIRST_NAME, firstName); } /** * Simple principal to store the lastName as a string * * @param lastName the lastName * @return the built principal */ public static SimplePrincipalProvider lastNamePrincipal(String lastName) { return simplePrincipal(LAST_NAME, lastName); } /** * Simple principal to store the fullName as a string * * @param fullName the fullName * @return the built principal */ public static SimplePrincipalProvider fullNamePrincipal(String fullName) { return simplePrincipal(FULL_NAME, fullName); } /** * Gets all the PrincipalProviders corresponding to a type of PrincipalProvider in a collection.<br> * <br> * For example, you can use this method to get the LDAPUser by calling :<br> * <code>getPrincipalsByType(principals, LDAPUserPrincipalProvider.class)</code> .<br> * <br> * Then on the first element of the collection : <br> * <code>LDAPUser user = * ldapUserPrincipalProvider.getPrincipal()</code>. * * @param <T> type of the PrincipalProvider * @param principalProviders the principals to find the type. * @param principalClass the PrincipalProvider type, not null * @return A collection of the user's PrincipalProviders of type principalProviderClass. Not null. */ @SuppressWarnings("unchecked") public static <T extends Serializable> Collection<PrincipalProvider<T>> getPrincipalsByType(Collection<PrincipalProvider<?>> principalProviders, Class<T> principalClass) { Collection<PrincipalProvider<T>> principals = new ArrayList<>(); for (PrincipalProvider<?> principal : principalProviders) { for (Type principalInterface : principal.getClass().getGenericInterfaces()) { if (principalInterface instanceof ParameterizedType) { ParameterizedType currentPrincipalClass = (ParameterizedType) principalInterface; Type currentType = currentPrincipalClass.getActualTypeArguments()[0]; if (!principalClass.isArray()) { if (principalClass.equals(currentType)) { principals.add((PrincipalProvider<T>) principal); } } else { if (currentType instanceof GenericArrayType && principalClass.getComponentType().equals(((GenericArrayType) currentType).getGenericComponentType())) { // JDK 5,6 principals.add((PrincipalProvider<T>) principal); } else if (currentType instanceof Class && principalClass.getComponentType().equals(((Class<?>) currentType).getComponentType())) { // JDK 7 principals.add((PrincipalProvider<T>) principal); } } } } } return principals; } /** * Gets one PrincipalProvider corresponding to a type of PrincipalProvider.<br> * <br> * For example, you can use this method to get the LDAPUser by calling :<br> * <code>getOnePrincipalsByType(principals, LDAPUserPrincipalProvider.class)</code> .<br> * <br> * Then : <br> * <code>LDAPUser user = * ldapUserPrincipalProvider.getPrincipal()</code>. * * @param <T> type of the PrincipalProvider * @param principalProviders the principals to find the type. * @param principalClass the PrincipalProvider type, not null * @return The user's PrincipalProvider of type principalProviderClass. Null if none. */ public static <T extends Serializable> PrincipalProvider<T> getOnePrincipalByType(Collection<PrincipalProvider<?>> principalProviders, Class<T> principalClass) { Collection<PrincipalProvider<T>> pps = getPrincipalsByType(principalProviders, principalClass); if (!pps.isEmpty()) { return pps.iterator().next(); } else { return null; } } /** * Extracts the simple principals of the collection of principals * * @param principalProviders the principals to extract from * @return the simple principals */ public static Collection<SimplePrincipalProvider> getSimplePrincipals(Collection<PrincipalProvider<?>> principalProviders) { Collection<SimplePrincipalProvider> principals = new ArrayList<>(); for (PrincipalProvider<?> principal : principalProviders) { if (principal instanceof SimplePrincipalProvider) { principals.add((SimplePrincipalProvider) principal); } } return principals; } /** * Gives the simple principal with the given name from the given collection of principals * * @param principalProviders the principals to search * @param principalName the name to search * @return the simple principal with the name */ public static SimplePrincipalProvider getSimplePrincipalByName(Collection<PrincipalProvider<?>> principalProviders, String principalName) { for (SimplePrincipalProvider principal : getSimplePrincipals(principalProviders)) { if (principal.getName().equals(principalName)) { return principal; } } return null; } }