/* * Licensed to Jasig under one or more contributor license * agreements. See the NOTICE file distributed with this work * for additional information regarding copyright ownership. * Jasig licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a * copy of the License at the following location: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.jasig.cas; import static org.junit.Assert.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jasig.cas.authentication.Authentication; import org.jasig.cas.authentication.AuthenticationHandler; import org.jasig.cas.authentication.AuthenticationManager; import org.jasig.cas.authentication.BasicCredentialMetaData; import org.jasig.cas.authentication.CredentialMetaData; import org.jasig.cas.authentication.HandlerResult; import org.jasig.cas.authentication.principal.Service; import org.jasig.cas.authentication.principal.SimplePrincipal; import org.jasig.cas.logout.LogoutManager; import org.jasig.cas.services.RegisteredService; import org.jasig.cas.services.ServicesManager; import org.jasig.cas.services.UnauthorizedProxyingException; import org.jasig.cas.services.UnauthorizedServiceException; import org.jasig.cas.ticket.ExpirationPolicy; import org.jasig.cas.ticket.InvalidTicketException; import org.jasig.cas.ticket.ServiceTicket; import org.jasig.cas.ticket.TicketException; import org.jasig.cas.ticket.TicketGrantingTicket; import org.jasig.cas.ticket.registry.TicketRegistry; import org.jasig.cas.util.DefaultUniqueTicketIdGenerator; import org.jasig.cas.util.UniqueTicketIdGenerator; import org.jasig.cas.validation.Assertion; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentMatcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Unit tests with the help of Mockito framework. * * @author Dmitriy Kopylenko */ public class CentralAuthenticationServiceImplWithMokitoTests { private static final String TGT_ID = "tgt-id"; private static final String TGT2_ID = "tgt2-id"; private static final String ST_ID = "st-id"; private static final String ST2_ID = "st2-id"; private static final String SVC1_ID = "test1"; private static final String SVC2_ID = "test2"; private static final String PRINCIPAL = "principal"; private final Logger logger = LoggerFactory.getLogger(this.getClass()); private CentralAuthenticationServiceImpl cas; private Authentication authentication; private static class VerifyServiceByIdMatcher extends ArgumentMatcher<Service> { private String id; public VerifyServiceByIdMatcher(final String id) { this.id = id; } @Override public boolean matches(final Object argument) { final Service s = (Service) argument; return s != null && s.getId().equals(this.id); } } @Before public void prepareNewCAS() { this.authentication = mock(Authentication.class); when(this.authentication.getAuthenticatedDate()).thenReturn(new Date()); final CredentialMetaData metadata = new BasicCredentialMetaData(TestUtils.getCredentialsWithSameUsernameAndPassword("principal")); final Map<String, HandlerResult> successes = new HashMap<String, HandlerResult>(); successes.put("handler1", new HandlerResult(mock(AuthenticationHandler.class), metadata)); when(this.authentication.getCredentials()).thenReturn(Arrays.asList(metadata)); when(this.authentication.getSuccesses()).thenReturn(successes); when(this.authentication.getPrincipal()).thenReturn(new SimplePrincipal(PRINCIPAL)); final ServiceTicket stMock = mock(ServiceTicket.class); when(stMock.getService()).thenReturn(TestUtils.getService()); when(stMock.getId()).thenReturn(ST_ID); when(stMock.isValidFor(TestUtils.getService())).thenReturn(true); final TicketGrantingTicket tgtRootMock = mock(TicketGrantingTicket.class); when(tgtRootMock.isExpired()).thenReturn(false); when(tgtRootMock.getAuthentication()).thenReturn(this.authentication); final TicketGrantingTicket tgtMock = mock(TicketGrantingTicket.class); when(tgtMock.isExpired()).thenReturn(false); when(tgtMock.getId()).thenReturn(TGT_ID); when(tgtMock.grantServiceTicket(anyString(), argThat(new VerifyServiceByIdMatcher(TestUtils.getService().getId())), any(ExpirationPolicy.class), anyBoolean())).thenReturn(stMock); when(tgtMock.getRoot()).thenReturn(tgtRootMock); final List<Authentication> authnListMock = mock(List.class); //Size is required to be 2, so that we can simulate proxying capabilities when(authnListMock.size()).thenReturn(2); when(authnListMock.get(anyInt())).thenReturn(this.authentication); when(tgtMock.getChainedAuthentications()).thenReturn(authnListMock); when(stMock.getGrantingTicket()).thenReturn(tgtMock); final Service service2 = TestUtils.getService(SVC2_ID); final ServiceTicket stMock2 = mock(ServiceTicket.class); when(stMock2.getService()).thenReturn(service2); when(stMock2.getId()).thenReturn(ST2_ID); when(stMock2.isValidFor(service2)).thenReturn(true); final TicketGrantingTicket tgtMock2 = mock(TicketGrantingTicket.class); when(tgtMock2.isExpired()).thenReturn(false); when(tgtMock2.getId()).thenReturn(TGT2_ID); when(tgtMock2.grantServiceTicket(anyString(), argThat(new VerifyServiceByIdMatcher(service2.getId())), any(ExpirationPolicy.class), anyBoolean())).thenReturn(stMock2); when(tgtMock2.getRoot()).thenReturn(tgtRootMock); when(tgtMock2.getChainedAuthentications()).thenReturn(authnListMock); when(stMock2.getGrantingTicket()).thenReturn(tgtMock2); //Mock TicketRegistry final TicketRegistry ticketRegMock = mock(TicketRegistry.class); when(ticketRegMock.getTicket(eq(tgtMock.getId()), eq(TicketGrantingTicket.class))).thenReturn(tgtMock); when(ticketRegMock.getTicket(eq(tgtMock2.getId()), eq(TicketGrantingTicket.class))).thenReturn(tgtMock2); when(ticketRegMock.getTicket(eq(stMock.getId()), eq(ServiceTicket.class))).thenReturn(stMock); when(ticketRegMock.getTicket(eq(stMock2.getId()), eq(ServiceTicket.class))).thenReturn(stMock2); //Mock ServicesManager final RegisteredService mockRegSvc1 = mock(RegisteredService.class); when(mockRegSvc1.getServiceId()).thenReturn(SVC1_ID); when(mockRegSvc1.isEnabled()).thenReturn(true); when(mockRegSvc1.isAllowedToProxy()).thenReturn(false); when(mockRegSvc1.getName()).thenReturn(SVC1_ID); final RegisteredService mockRegSvc2 = mock(RegisteredService.class); when(mockRegSvc2.getServiceId()).thenReturn("test"); when(mockRegSvc2.isEnabled()).thenReturn(false); when(mockRegSvc2.getName()).thenReturn("test"); final RegisteredService mockRegSvc3 = mock(RegisteredService.class); when(mockRegSvc3.getServiceId()).thenReturn(service2.getId()); when(mockRegSvc3.isEnabled()).thenReturn(true); when(mockRegSvc3.isAllowedToProxy()).thenReturn(true); when(mockRegSvc3.getName()).thenReturn(service2.getId()); when(mockRegSvc3.matches(argThat(new VerifyServiceByIdMatcher(service2.getId())))).thenReturn(true); final ServicesManager smMock = mock(ServicesManager.class); when(smMock.findServiceBy(argThat(new VerifyServiceByIdMatcher(SVC1_ID)))).thenReturn(mockRegSvc1); when(smMock.findServiceBy(argThat(new VerifyServiceByIdMatcher("test")))).thenReturn(mockRegSvc2); when(smMock.findServiceBy(argThat(new VerifyServiceByIdMatcher(SVC2_ID)))).thenReturn(mockRegSvc3); final Map ticketIdGenForServiceMock = mock(Map.class); when(ticketIdGenForServiceMock.containsKey(any())).thenReturn(true); when(ticketIdGenForServiceMock.get(any())).thenReturn(new DefaultUniqueTicketIdGenerator()); this.cas = new CentralAuthenticationServiceImpl(ticketRegMock, null, mock(AuthenticationManager.class), mock(UniqueTicketIdGenerator.class), ticketIdGenForServiceMock, mock(ExpirationPolicy.class), mock(ExpirationPolicy.class), smMock, mock(LogoutManager.class)); } @Test(expected=InvalidTicketException.class) public void testNonExistentServiceWhenDelegatingTicketGrantingTicket() throws Exception { this.cas.delegateTicketGrantingTicket("bad-st", TestUtils.getCredentialsWithSameUsernameAndPassword()); } @Test(expected=UnauthorizedServiceException.class) public void testInvalidServiceWhenDelegatingTicketGrantingTicket() throws Exception { this.cas.delegateTicketGrantingTicket(ST_ID, TestUtils.getCredentialsWithSameUsernameAndPassword()); } @Test(expected=UnauthorizedProxyingException.class) public void disallowVendingServiceTicketsWhenServiceIsNotAllowedToProxyCAS1019() throws TicketException { this.cas.grantServiceTicket(TGT_ID, TestUtils.getService(SVC1_ID)); } @Test public void testChainedAuthenticationsOnValidation() throws TicketException { final Service svc = TestUtils.getService(SVC2_ID); final String st = this.cas.grantServiceTicket(TGT2_ID, svc); assertNotNull(st); final Assertion assertion = this.cas.validateServiceTicket(st, svc); assertNotNull(assertion); assertEquals(assertion.getService(), svc); assertEquals(assertion.getPrimaryAuthentication().getPrincipal().getId(), PRINCIPAL); assertTrue(assertion.getChainedAuthentications().size() == 2); for (int i = 0; i < assertion.getChainedAuthentications().size(); i++) { final Authentication auth = assertion.getChainedAuthentications().get(i); assertEquals(auth, authentication); } } }