package net.unicon.cas.mfa.web.flow;
import net.unicon.cas.mfa.authentication.AuthenticationSupport;
import net.unicon.cas.mfa.authentication.AuthenticationMethod;
import net.unicon.cas.mfa.authentication.JsonBackedAuthenticationMethodConfigurationProvider;
import net.unicon.cas.mfa.authentication.MultiFactorAuthenticationRequestContext;
import net.unicon.cas.mfa.authentication.MultiFactorAuthenticationTransactionContext;
import net.unicon.cas.mfa.authentication.OrderedMultiFactorMethodRankingStrategy;
import net.unicon.cas.mfa.web.flow.util.MultiFactorRequestContextUtils;
import net.unicon.cas.mfa.web.support.MultiFactorAuthenticationSupportingWebApplicationService;
import org.jasig.cas.authentication.Authentication;
import org.jasig.cas.authentication.principal.Principal;
import org.jasig.cas.authentication.principal.Response;
import org.jasig.cas.authentication.principal.Service;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.core.collection.ParameterMap;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(JUnit4.class)
public class ValidateInitialMultiFactorAuthenticationRequestActionTests {
private static final String TGT_ID = "TGT-1";
private ValidateInitialMultiFactorAuthenticationRequestAction action;
@Mock
private RequestContext requestContext;
@Mock
private Authentication authentication;
private MutableAttributeMap mockFlowScope;
private MultiFactorAuthenticationTransactionContext mfaTx =
new MultiFactorAuthenticationTransactionContext("test service").addMfaRequest(
new MultiFactorAuthenticationRequestContext(
new MultiFactorAuthenticationSupportingWebApplicationService() {
private static final long serialVersionUID = 2674549680880441113L;
@Override
public String getAuthenticationMethod() {
return "strong_two_factor";
}
@Override
public AuthenticationMethodSource getAuthenticationMethodSource() {
return AuthenticationMethodSource.REQUEST_PARAM;
}
@Override
public Response getResponse(final String ticketId) {
return null;
}
@Override
public String getArtifactId() {
return null;
}
@Override
public String getOriginalUrl() {
return "test service";
}
@Override
public void setPrincipal(final Principal principal) {
}
@Override
public boolean matches(final Service service) {
return false;
}
@Override
public String getId() {
return "test service";
}
@Override
public Map<String, Object> getAttributes() {
return null;
}
}, 3));
public ValidateInitialMultiFactorAuthenticationRequestActionTests() {
MockitoAnnotations.initMocks(this);
}
@Before
public void setup() {
final AuthenticationSupport support = mock(AuthenticationSupport.class);
when(support.getAuthenticationFrom(TGT_ID)).thenReturn(authentication);
final SortedSet<AuthenticationMethod> validAuthenticationMethods =
new TreeSet<>();
validAuthenticationMethods.add(new AuthenticationMethod("sample_two_factor", 2));
validAuthenticationMethods.add(new AuthenticationMethod("strong_two_factor", 4));
final JsonBackedAuthenticationMethodConfigurationProvider loader =
new JsonBackedAuthenticationMethodConfigurationProvider(validAuthenticationMethods);
this.action = new ValidateInitialMultiFactorAuthenticationRequestAction(support,
new OrderedMultiFactorMethodRankingStrategy(loader));
mockFlowScope = mock(MutableAttributeMap.class);
when(requestContext.getFlowScope()).thenReturn(mockFlowScope);
when(requestContext.getConversationScope()).thenReturn(mockFlowScope);
final ParameterMap requestParams = mock(ParameterMap.class);
when(requestContext.getRequestParameters()).thenReturn(requestParams);
/*when(requestContext.getConversationScope().get(MultiFactorAuthenticationTransactionContext.class.getSimpleName()))
.thenReturn(mfaTx);*/
}
private void setMockTgtContextWith(final String tgt, final MultiFactorAuthenticationTransactionContext mfaTx) {
when(requestContext.getFlowScope().get(MultiFactorRequestContextUtils.CAS_TICKET_GRANTING_TICKET_ATTR_NAME)).thenReturn(tgt);
when(requestContext.getConversationScope().get(MultiFactorAuthenticationTransactionContext.class.getSimpleName()))
.thenReturn(mfaTx);
}
private void setMockServiceContextWith(final Service svc) {
when(requestContext.getFlowScope().get("service")).thenReturn(svc);
}
/**
* When there is no existing mfa transaction in conversation scope the Action should return the Event
* indicating the flow should proceed as per normal.
* @throws Exception the exception
*/
@Test
public void testMissingMfaTransactionProceedsFlowAsNormal() throws Exception {
setMockTgtContextWith(TGT_ID, null);
final Event ev = this.action.doExecute(this.requestContext);
assertNotNull(ev);
assertEquals(ValidateInitialMultiFactorAuthenticationRequestAction.EVENT_ID_REQUIRE_TGT, ev.getId());
}
/**
* When there is no existing TGT (no existing single sign-on session), the Action should return the Event
* indicating the flow should proceed as per normal.
* @throws Exception the exception
*/
@Test
public void testMissingTgtProceedsFlowAsNormal() throws Exception {
setMockTgtContextWith(null, mfaTx);
setMockServiceContextWith(mock(MultiFactorAuthenticationSupportingWebApplicationService.class));
final Event ev = this.action.doExecute(this.requestContext);
assertNotNull(ev);
assertEquals(ValidateInitialMultiFactorAuthenticationRequestAction.EVENT_ID_REQUIRE_TGT, ev.getId());
}
}