package org.apereo.cas.web.flow; import org.apereo.cas.authentication.Authentication; import org.apereo.cas.authentication.AuthenticationException; import org.apereo.cas.authentication.ContextualAuthenticationPolicy; import org.apereo.cas.authentication.PreventedException; import org.apereo.cas.ticket.InvalidTicketException; import org.apereo.cas.ticket.UnsatisfiedAuthenticationPolicyException; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.mockito.ArgumentCaptor; import org.springframework.binding.message.DefaultMessageResolver; import org.springframework.binding.message.MessageContext; import javax.security.auth.login.AccountLockedException; import javax.security.auth.login.AccountNotFoundException; import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import static org.junit.Assert.*; import static org.mockito.Mockito.*; /** * @author Marvin S. Addison * @since 4.0.0 */ @RunWith(JUnit4.class) public class AuthenticationExceptionHandlerActionTests { @Test public void handleAccountNotFoundExceptionByDefault() { final AuthenticationExceptionHandlerAction handler = new AuthenticationExceptionHandlerAction(); final MessageContext ctx = mock(MessageContext.class); final Map<String, Class<? extends Exception>> map = new HashMap<>(); map.put("notFound", AccountNotFoundException.class); final String id = handler.handle(new AuthenticationException(map), ctx); assertEquals(id, AccountNotFoundException.class.getSimpleName()); } @Test public void handleUnknownExceptionByDefault() { final AuthenticationExceptionHandlerAction handler = new AuthenticationExceptionHandlerAction(); final MessageContext ctx = mock(MessageContext.class); final Map<String, Class<? extends Exception>> map = new HashMap<>(); map.put("unknown", GeneralSecurityException.class); final String id = handler.handle(new AuthenticationException(map), ctx); assertEquals(id, "UNKNOWN"); } @Test public void handleUnknownTicketExceptionByDefault() { final AuthenticationExceptionHandlerAction handler = new AuthenticationExceptionHandlerAction(); final MessageContext ctx = mock(MessageContext.class); final String id = handler.handle(new InvalidTicketException("TGT"), ctx); assertEquals(id, "UNKNOWN"); verifyZeroInteractions(ctx); } @Test public void correctHandlersOrder() { final AuthenticationExceptionHandlerAction handler = new AuthenticationExceptionHandlerAction(); final MessageContext ctx = mock(MessageContext.class); final Map<String, Class<? extends Exception>> map = new HashMap<>(); map.put("accountLocked", AccountLockedException.class); map.put("accountNotFound", AccountNotFoundException.class); final String id = handler.handle(new AuthenticationException(map), ctx); assertEquals(id, AccountLockedException.class.getSimpleName()); } @Test public void handleUnsatisfiedAuthenticationPolicyExceptionByDefault() { final AuthenticationExceptionHandlerAction handler = new AuthenticationExceptionHandlerAction(); final MessageContext ctx = mock(MessageContext.class); final ContextualAuthenticationPolicy<?> policy = new TestContextualAuthenticationPolicy(); final String id = handler.handle(new UnsatisfiedAuthenticationPolicyException(policy), ctx); assertEquals(id, "UnsatisfiedAuthenticationPolicyException"); final ArgumentCaptor<DefaultMessageResolver> message = ArgumentCaptor.forClass(DefaultMessageResolver.class); verify(ctx, times(1)).addMessage(message.capture()); assertArrayEquals(new String[]{policy.getCode().get()}, message.getValue().getCodes()); } @Test public void customExceptionsSetterWithNullDefaultValue(){ final AuthenticationExceptionHandlerAction handler = new AuthenticationExceptionHandlerAction(); assertFalse(handler.containsCustomErrors()); final List<Class<? extends Exception>> nullCustomErrors = new ArrayList<>(); nullCustomErrors.add(null); handler.setErrors(nullCustomErrors); assertFalse(handler.containsCustomErrors()); } @Test public void customExceptionsSetterWithTwoNewValues() { final AuthenticationExceptionHandlerAction handler = new AuthenticationExceptionHandlerAction(); final List<Class<? extends Exception>> twoCustomErrors = new ArrayList<>(); twoCustomErrors.add(GeneralSecurityException.class); twoCustomErrors.add(PreventedException.class); handler.setErrors(twoCustomErrors); assertTrue(handler.containsCustomErrors()); assertTrue(handler.getErrors().containsAll(twoCustomErrors)); assertEquals(14, handler.getErrors().size()); } private static class TestContextualAuthenticationPolicy implements ContextualAuthenticationPolicy<Object> { @Override public Optional<String> getCode() { return Optional.of("CUSTOM_CODE"); } @Override public Object getContext() { return null; } @Override public boolean isSatisfiedBy(final Authentication authentication) { return false; } } }