package com.ffii.fpsms.modules.common; import java.util.Optional; import org.springframework.dao.DataAccessException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import com.ffii.fpsms.modules.user.entity.User; /** * Security Utils - for Spring Security * * @author Patrick */ public class SecurityUtils { /** * Obtains the current {@code SecurityContext}. * * @return the security context (never {@code null}) */ public static final SecurityContext getSecurityContext() { return SecurityContextHolder.getContext(); } /** * @return the authenticated {@code Principal}) * @see Authentication#getPrincipal() */ public static final Optional getUser() { try { return Optional.of((User) getSecurityContext().getAuthentication().getPrincipal()); } catch (ClassCastException e) { // no authenticated principal return Optional.empty(); } catch (NullPointerException e) { // no authentication information is available return Optional.empty(); } } /** * Updates the Authentication Token with the user (e.g. user changed the password) * * @see SecurityContext#setAuthentication(Authentication) */ public static final void updateUserAuthentication(final UserDetails user) { getSecurityContext().setAuthentication(new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities())); } /** * Checks if the current user is GRANTED the {@code role} * * @param role * the {@code role} to check for * @return {@code true} if the current user is GRANTED the {@code role}, else {@code false} */ public static final boolean isGranted(String role) { Authentication authentication = getSecurityContext().getAuthentication(); if (authentication == null) return false; for (GrantedAuthority auth : authentication.getAuthorities()) { if (role.equals(auth.getAuthority())) return true; } return false; } /** * Checks if the current user is NOT GRANTED the {@code role} * * @param role * the {@code role} to check for * @return {@code true} if the current user is NOT GRANTED the {@code role}, else {@code false} */ public static final boolean isNotGranted(String role) { return !isGranted(role); } /** * Checks if the current user is GRANTED ANY of the {@code role}s * * @param roles * the {@code role}s to check for * @return {@code true} if the current user is GRANTED ANY of the {@code role}s, else {@code false} */ public static final boolean isGrantedAny(String... roles) { for (int i = 0; i < roles.length; i++) { if (isGranted(roles[i])) return true; } return false; } /** * Checks if the current user is NOT GRANTED ANY of the {@code role}s * * @param roles * the {@code role}s to check for * @return {@code true} if the current user is NOT GRANTED ANY of the {@code role}s, else {@code false} */ public static final boolean isNotGrantedAny(String... roles) { return !isGrantedAny(roles); } /** * Checks if the current user is GRANTED ALL of the {@code role}s * * @param roles * the {@code role}s to check for * @return {@code true} if the current user is GRANTED ALL of the {@code role}s, else {@code false} */ public static final boolean isGrantedAll(String... roles) { for (int i = 0; i < roles.length; i++) { if (isNotGranted(roles[i])) return false; } return true; } /** * Login a user non-interactively * * @param userService * any implementation of {@link UserDetailsService} * @param username * the username * * @throws UsernameNotFoundException * if the user could not be found or the user has no GrantedAuthority * @throws DataAccessException * if user could not be found for a repository-specific reason */ public static final void loginUser(UserDetailsService userService, String username) { /* load the user, throw exception if user not found */ UserDetails userDetails = userService.loadUserByUsername(username); /* create authentication token for the specified user */ Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities()); getSecurityContext().setAuthentication(authentication); } }