/* * ****************************************************************************** * * Cloud Foundry * * Copyright (c) [2009-2015] Pivotal Software, Inc. All Rights Reserved. * * * * 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. * * * * 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. * ****************************************************************************** */ package org.cloudfoundry.identity.uaa.authentication; import org.cloudfoundry.identity.uaa.util.JsonUtils; import org.hamcrest.Matchers; import org.junit.Test; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.everyItem; import static org.hamcrest.Matchers.isIn; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class UaaAuthenticationSerializationTests { public static final String COST_CENTER = "costCenter"; public static final String DENVER_CO = "Denver,CO"; public static final String MANAGER = "manager"; public static final String JOHN_THE_SLOTH = "John the Sloth"; public static final String KARI_THE_ANT_EATER = "Kari the Ant Eater"; @Test public void test_serialization() throws Exception { UaaPrincipal principal = new UaaPrincipal("id","username","email","origin","externalId","zoneId"); HttpSession session = mock(HttpSession.class); when(session.getId()).thenReturn("id"); HttpServletRequest request = mock(HttpServletRequest.class); when(request.getRemoteAddr()).thenReturn("remoteAddr"); when(request.getSession(false)).thenReturn(session); UaaAuthenticationDetails details = new UaaAuthenticationDetails(request, "clientId"); details.setAddNew(true); List<? extends GrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority("role1"), new SimpleGrantedAuthority("role2")); String credentials = "credentials"; Map<String,List<String>> userAttributes = new HashMap<>(); userAttributes.put("atest", Arrays.asList("test1","test2","test3")); userAttributes.put("btest", Arrays.asList("test1", "test2", "test3")); Set<String> externalGroups = new HashSet<>(Arrays.asList("group1","group2","group3")); boolean authenticated = true; long authenticatedTime = System.currentTimeMillis(); long expiresAt = Long.MAX_VALUE; UaaAuthentication expected = new UaaAuthentication(principal,credentials, authorities, externalGroups,userAttributes, details, authenticated, authenticatedTime, expiresAt); String authenticationAsJson = JsonUtils.writeValueAsString(expected); UaaAuthentication actual = JsonUtils.readValue(authenticationAsJson, UaaAuthentication.class); //validate authentication details UaaAuthenticationDetails actualDetails = (UaaAuthenticationDetails)actual.getDetails(); assertNotNull(actualDetails); assertEquals("remoteAddr", actualDetails.getOrigin()); assertEquals("id", actualDetails.getSessionId()); assertEquals("clientId", actualDetails.getClientId()); assertEquals(true, actualDetails.isAddNew()); //validate principal UaaPrincipal actualPrincipal = actual.getPrincipal(); assertEquals("id",actualPrincipal.getId()); assertEquals("username",actualPrincipal.getName()); assertEquals("email",actualPrincipal.getEmail()); assertEquals("origin",actualPrincipal.getOrigin()); assertEquals("externalId",actualPrincipal.getExternalId()); assertEquals("zoneId", actualPrincipal.getZoneId()); //validate authorities assertThat(actual.getAuthorities(), containsInAnyOrder(new SimpleGrantedAuthority("role1"), new SimpleGrantedAuthority("role2"))); //validate external groups assertThat(actual.getExternalGroups(), containsInAnyOrder("group1","group2","group3")); //validate user attributes assertEquals(2, actual.getUserAttributes().size()); assertThat(actual.getUserAttributes().get("atest"),containsInAnyOrder("test1","test2","test3")); assertThat(actual.getUserAttributes().get("btest"),containsInAnyOrder("test1","test2","test3")); //validate authenticated assertEquals(authenticated, actual.isAuthenticated()); //validate authenticated time assertEquals(authenticatedTime, actual.getAuthenticatedTime()); //validate expires at time assertEquals(expiresAt, actual.getExpiresAt()); } @Test public void testDeserializationWithoutAuthenticatedTime() throws Exception { String data ="{\"principal\":{\"id\":\"user-id\",\"name\":\"username\",\"email\":\"email\",\"origin\":\"uaa\",\"externalId\":null,\"zoneId\":\"uaa\"},\"credentials\":null,\"authorities\":[],\"details\":null,\"authenticated\":true,\"authenticatedTime\":1438649464353,\"name\":\"username\"}"; UaaAuthentication authentication1 = JsonUtils.readValue(data, UaaAuthentication.class); assertEquals(1438649464353l, authentication1.getAuthenticatedTime()); assertEquals(-1l, authentication1.getExpiresAt()); assertTrue(authentication1.isAuthenticated()); assertNull(authentication1.getAuthContextClassRef()); String dataWithoutTime ="{\"principal\":{\"id\":\"user-id\",\"name\":\"username\",\"email\":\"email\",\"origin\":\"uaa\",\"externalId\":null,\"zoneId\":\"uaa\"},\"credentials\":null,\"authorities\":[],\"details\":null,\"authenticated\":true,\"name\":\"username\"}"; UaaAuthentication authentication2 = JsonUtils.readValue(dataWithoutTime, UaaAuthentication.class); assertEquals(-1, authentication2.getAuthenticatedTime()); long inThePast = System.currentTimeMillis() - 1000l * 60l; data ="{\"principal\":{\"id\":\"user-id\",\"name\":\"username\",\"email\":\"email\",\"origin\":\"uaa\",\"externalId\":null,\"zoneId\":\"uaa\"},\"credentials\":null,\"authorities\":[],\"details\":null,\"authenticated\":true,\"authenticatedTime\":1438649464353,\"name\":\"username\", \"expiresAt\":"+inThePast+"}"; UaaAuthentication authentication3 = JsonUtils.readValue(data, UaaAuthentication.class); assertEquals(1438649464353l, authentication3.getAuthenticatedTime()); assertEquals(inThePast, authentication3.getExpiresAt()); assertFalse(authentication3.isAuthenticated()); long inTheFuture = System.currentTimeMillis() + 1000l * 60l; data ="{\"principal\":{\"id\":\"user-id\",\"name\":\"username\",\"email\":\"email\",\"origin\":\"uaa\",\"externalId\":null,\"zoneId\":\"uaa\"},\"credentials\":null,\"authorities\":[],\"details\":null,\"authenticated\":true,\"authenticatedTime\":1438649464353,\"name\":\"username\", \"expiresAt\":"+inTheFuture+"}"; UaaAuthentication authentication4 = JsonUtils.readValue(data, UaaAuthentication.class); assertEquals(1438649464353l, authentication4.getAuthenticatedTime()); assertEquals(inTheFuture, authentication4.getExpiresAt()); assertTrue(authentication4.isAuthenticated()); } @Test public void deserialization_with_external_groups() throws Exception { String dataWithExternalGroups ="{\"principal\":{\"id\":\"user-id\",\"name\":\"username\",\"email\":\"email\",\"origin\":\"uaa\",\"externalId\":null,\"zoneId\":\"uaa\"},\"credentials\":null,\"authorities\":[],\"externalGroups\":[\"something\",\"or\",\"other\",\"something\"],\"details\":null,\"authenticated\":true,\"authenticatedTime\":null,\"name\":\"username\"}"; UaaAuthentication authentication = JsonUtils.readValue(dataWithExternalGroups, UaaAuthentication.class); assertEquals(3, authentication.getExternalGroups().size()); assertThat(authentication.getExternalGroups(), Matchers.containsInAnyOrder("something", "or", "other")); assertTrue(authentication.isAuthenticated()); } @Test public void deserialization_with_user_attributes() throws Exception { String dataWithoutUserAttributes ="{\"principal\":{\"id\":\"user-id\",\"name\":\"username\",\"email\":\"email\",\"origin\":\"uaa\",\"externalId\":null,\"zoneId\":\"uaa\"},\"credentials\":null,\"authorities\":[],\"externalGroups\":[\"something\",\"or\",\"other\",\"something\"],\"details\":null,\"authenticated\":true,\"authenticatedTime\":null,\"name\":\"username\", \"previousLoginSuccessTime\":1485305759347}"; UaaAuthentication authentication = JsonUtils.readValue(dataWithoutUserAttributes, UaaAuthentication.class); assertEquals(3, authentication.getExternalGroups().size()); assertThat(authentication.getExternalGroups(), Matchers.containsInAnyOrder("something", "or", "other")); assertTrue(authentication.isAuthenticated()); MultiValueMap<String,String> userAttributes = new LinkedMultiValueMap<>(); userAttributes.add(COST_CENTER, DENVER_CO); userAttributes.add(MANAGER, JOHN_THE_SLOTH); userAttributes.add(MANAGER, KARI_THE_ANT_EATER); authentication.setUserAttributes(userAttributes); String dataWithUserAttributes = JsonUtils.writeValueAsString(authentication); assertTrue("userAttributes should be part of the JSON", dataWithUserAttributes.contains("userAttributes")); UaaAuthentication authWithUserData = JsonUtils.readValue(dataWithUserAttributes, UaaAuthentication.class); assertNotNull(authWithUserData.getUserAttributes()); assertThat(authWithUserData.getUserAttributes().entrySet(), everyItem(isIn(userAttributes.entrySet()))); assertThat(userAttributes.entrySet(), everyItem(isIn(authWithUserData.getUserAttributes().entrySet()))); assertEquals(3, authentication.getExternalGroups().size()); assertThat(authentication.getExternalGroups(), Matchers.containsInAnyOrder("something", "or", "other")); assertTrue(authentication.isAuthenticated()); assertEquals((Long) 1485305759347L, authentication.getLastLoginSuccessTime()); } }