package org.cloudfoundry.identity.uaa.login; import org.cloudfoundry.identity.uaa.authentication.AuthzAuthenticationRequest; import org.cloudfoundry.identity.uaa.authentication.InvalidCodeException; import org.cloudfoundry.identity.uaa.authentication.UaaAuthentication; import org.cloudfoundry.identity.uaa.authentication.UaaAuthenticationDetails; import org.cloudfoundry.identity.uaa.authentication.manager.AutologinAuthenticationManager; import org.cloudfoundry.identity.uaa.codestore.ExpiringCode; import org.cloudfoundry.identity.uaa.codestore.ExpiringCodeStore; import org.cloudfoundry.identity.uaa.codestore.ExpiringCodeType; import org.cloudfoundry.identity.uaa.constants.OriginKeys; import org.cloudfoundry.identity.uaa.user.UaaUser; import org.cloudfoundry.identity.uaa.user.UaaUserDatabase; import org.cloudfoundry.identity.uaa.util.JsonUtils; import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder; import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.common.util.RandomValueStringGenerator; import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.client.BaseClientDetails; import java.sql.Timestamp; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Map; import static org.hamcrest.Matchers.is; import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; /******************************************************************************* * Cloud Foundry * Copyright (c) [2009-2015] Pivotal Software, Inc. All Rights Reserved. * <p> * This product is licensed to you under the Apache License, Version 2.0 (the "License"). * You may not use this product except in compliance with the License. * <p> * This product includes a number of subcomponents with * separate copyright notices and license terms. Your use of these * subcomponents is subject to the terms and conditions of the * subcomponent's license, as noted in the LICENSE file. *******************************************************************************/ public class AutologinAuthenticationManagerTest { private AutologinAuthenticationManager manager; private ExpiringCodeStore codeStore; private Authentication authenticationToken; private UaaUserDatabase userDatabase; private ClientDetailsService clientDetailsService; private String clientId; @Before public void setUp() { clientId = new RandomValueStringGenerator().generate(); manager = new AutologinAuthenticationManager(); codeStore = mock(ExpiringCodeStore.class); userDatabase = mock(UaaUserDatabase.class); clientDetailsService = mock(ClientDetailsService.class); manager.setExpiringCodeStore(codeStore); manager.setClientDetailsService(clientDetailsService); manager.setUserDatabase(userDatabase); Map<String,String> info = new HashMap<>(); info.put("code", "the_secret_code"); UaaAuthenticationDetails details = new UaaAuthenticationDetails(new MockHttpServletRequest(), clientId); authenticationToken = new AuthzAuthenticationRequest(info, details); } @Test public void authentication_successful() throws Exception { Map<String,String> codeData = new HashMap<>(); codeData.put("user_id", "test-user-id"); codeData.put("client_id", clientId); codeData.put("username", "test-username"); codeData.put(OriginKeys.ORIGIN, OriginKeys.UAA); when(codeStore.retrieveCode("the_secret_code")).thenReturn(new ExpiringCode("the_secret_code", new Timestamp(123), JsonUtils.writeValueAsString(codeData), ExpiringCodeType.AUTOLOGIN.name())); when(clientDetailsService.loadClientByClientId(eq(clientId))).thenReturn(new BaseClientDetails("test-client-details","","","","")); when(userDatabase.retrieveUserById(eq("test-user-id"))) .thenReturn( new UaaUser("test-user-id", "test-username", "password", "email@email.com", Collections.EMPTY_LIST, "given name", "family name", new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis()), OriginKeys.UAA, "test-external-id", true, IdentityZoneHolder.get().getId(), "test-salt", new Date(System.currentTimeMillis()) ) ); Authentication authenticate = manager.authenticate(authenticationToken); assertThat(authenticate, is(instanceOf(UaaAuthentication.class))); UaaAuthentication uaaAuthentication = (UaaAuthentication)authenticate; assertThat(uaaAuthentication.getPrincipal().getId(), is("test-user-id")); assertThat(uaaAuthentication.getPrincipal().getName(), is("test-username")); assertThat(uaaAuthentication.getPrincipal().getOrigin(), is(OriginKeys.UAA)); assertThat(uaaAuthentication.getDetails(), is(instanceOf(UaaAuthenticationDetails.class))); UaaAuthenticationDetails uaaAuthDetails = (UaaAuthenticationDetails)uaaAuthentication.getDetails(); assertThat(uaaAuthDetails.getClientId(), is(clientId)); } @Test(expected = BadCredentialsException.class) public void authentication_fails_withInvalidClient() { Map<String,String> codeData = new HashMap<>(); codeData.put("user_id", "test-user-id"); codeData.put("client_id", "actual-client-id"); codeData.put("username", "test-username"); codeData.put(OriginKeys.ORIGIN, OriginKeys.UAA); codeData.put("action", ExpiringCodeType.AUTOLOGIN.name()); when(codeStore.retrieveCode("the_secret_code")).thenReturn(new ExpiringCode("the_secret_code", new Timestamp(123), JsonUtils.writeValueAsString(codeData), null)); manager.authenticate(authenticationToken); } @Test(expected = BadCredentialsException.class) public void authentication_fails_withNoClientId() { Map<String,String> codeData = new HashMap<>(); codeData.put("user_id", "test-user-id"); codeData.put("username", "test-username"); codeData.put(OriginKeys.ORIGIN, OriginKeys.UAA); codeData.put("action", ExpiringCodeType.AUTOLOGIN.name()); when(codeStore.retrieveCode("the_secret_code")).thenReturn(new ExpiringCode("the_secret_code", new Timestamp(123), JsonUtils.writeValueAsString(codeData), null)); manager.authenticate(authenticationToken); } @Test(expected = InvalidCodeException.class) public void authentication_fails_withExpiredCode() { when(codeStore.retrieveCode("the_secret_code")).thenReturn(null); manager.authenticate(authenticationToken); } @Test(expected = InvalidCodeException.class) public void authentication_fails_withCodeIntendedForDifferentPurpose() { Map<String,String> codeData = new HashMap<>(); codeData.put("user_id", "test-user-id"); codeData.put("client_id", clientId); codeData.put("username", "test-username"); codeData.put(OriginKeys.ORIGIN, OriginKeys.UAA); when(codeStore.retrieveCode("the_secret_code")).thenReturn(new ExpiringCode("the_secret_code", new Timestamp(123), JsonUtils.writeValueAsString(codeData), null)); manager.authenticate(authenticationToken); } @Test(expected = InvalidCodeException.class) public void authentication_fails_withInvalidCode() { Map<String,String> codeData = new HashMap<>(); codeData.put("action", "someotheraction"); when(codeStore.retrieveCode("the_secret_code")).thenReturn(new ExpiringCode("the_secret_code", new Timestamp(123), JsonUtils.writeValueAsString(codeData), null)); manager.authenticate(authenticationToken); } }