/******************************************************************************* * Cloud Foundry * Copyright (c) [2009-2014] 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.login; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Matchers; import org.mockito.Mockito; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.mock.env.MockEnvironment; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestTemplate; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.view.RedirectView; import java.security.Principal; import java.util.Collections; import java.util.HashMap; import java.util.Map; /** * @author Dave Syer */ public class RemoteUaaControllerTests { private RemoteUaaController controller = new RemoteUaaController(new MockEnvironment(), new RestTemplate()); private MockHttpServletRequest request = new MockHttpServletRequest(); private Map<String, Object> model = new HashMap<String, Object>(); private HttpHeaders headers = new HttpHeaders(); private Principal principal = new UsernamePasswordAuthenticationToken("username", "<NONE>"); private Map<String, String> parameters = new HashMap<String, String>(); private RestOperations authorizationTemplate = Mockito.mock(RestOperations.class); public RemoteUaaControllerTests() { controller.setAuthorizationTemplate(authorizationTemplate); } @Test public void testApprovalNeeded() throws Exception { setResponse(Collections.<String, Object> singletonMap("options", "{}"), null, HttpStatus.OK); ModelAndView result = controller.startAuthorization(request, parameters, model, headers, principal); assertEquals("access_confirmation", result.getViewName()); } @Test public void testCookieSentWithoutAttributes() throws Exception { HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.add("Set-Cookie", "JSESSIONID=FOO; Path=/; HttpOnly"); setResponse(Collections.<String, Object> singletonMap("options", "{}"), responseHeaders, HttpStatus.OK); ModelAndView result = controller.startAuthorization(request, parameters, model, headers, principal); assertEquals("access_confirmation", result.getViewName()); assertEquals("JSESSIONID=FOO", model.get("cookie")); } @Test public void testMultipleCookies() throws Exception { HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.add("Set-Cookie", "__VCAP_ID__=BAR"); responseHeaders.add("Set-Cookie", "JSESSIONID=FOO; Path=/; HttpOnly"); setResponse(Collections.<String, Object>singletonMap("options", "{}"), responseHeaders, HttpStatus.OK); ModelAndView result = controller.startAuthorization(request, parameters, model, headers, principal); assertEquals("access_confirmation", result.getViewName()); assertEquals("__VCAP_ID__=BAR;JSESSIONID=FOO", model.get("cookie")); } @Test public void testRedirectUri() throws Exception { Map<String, String> requestParams = new HashMap<String, String>(); requestParams.put("redirect-uri", "http://www.google.com"); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.add("Location", "http://www.example.com"); setResponse(null, responseHeaders, HttpStatus.FOUND); ModelAndView result = controller.startAuthorization(request, requestParams, model, headers, principal); RedirectView view = (RedirectView) result.getView(); assertTrue(view.toString().contains("http://www.example.com")); ArgumentCaptor<HttpEntity> uaaRequest = ArgumentCaptor.forClass(HttpEntity.class); Mockito.verify(authorizationTemplate).exchange(Matchers.anyString(), Matchers.any(HttpMethod.class), uaaRequest.capture(), Matchers.any(Class.class)); MultiValueMap<String, String> uaaRequestBody = (MultiValueMap<String, String>) uaaRequest.getValue().getBody(); String requestUri = uaaRequestBody.getFirst("redirect-uri"); assertTrue(requestUri.contains("http://www.google.com")); assertFalse(requestUri.contains("http://http://www.google.com")); } @Test public void testRedirectUriWithMissingProtocol() throws Exception { Map<String, String> requestParams = new HashMap<String, String>(); requestParams.put("redirect-uri", "www.google.com"); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.add("Location", "http://www.example.com"); setResponse(null, responseHeaders, HttpStatus.FOUND); controller.startAuthorization(request, requestParams, model, headers, principal); ArgumentCaptor<HttpEntity> uaaRequest = ArgumentCaptor.forClass(HttpEntity.class); Mockito.verify(authorizationTemplate).exchange(Matchers.anyString(), Matchers.any(HttpMethod.class), uaaRequest.capture(), Matchers.any(Class.class)); MultiValueMap<String, String> uaaRequestBody = (MultiValueMap<String, String>) uaaRequest.getValue().getBody(); assertTrue(uaaRequestBody.getFirst("redirect-uri").contains("http://www.google.com")); } @Test public void testProtocolRelativeRedirectUri() throws Exception { Map<String, String> requestParams = new HashMap<String, String>(); requestParams.put("redirect-uri", "//www.google.com"); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.add("Location", "http://www.example.com"); setResponse(null, responseHeaders, HttpStatus.FOUND); controller.startAuthorization(request, requestParams, model, headers, principal); ArgumentCaptor<HttpEntity> uaaRequest = ArgumentCaptor.forClass(HttpEntity.class); Mockito.verify(authorizationTemplate).exchange(Matchers.anyString(), Matchers.any(HttpMethod.class), uaaRequest.capture(), Matchers.any(Class.class)); MultiValueMap<String, String> uaaRequestBody = (MultiValueMap<String, String>) uaaRequest.getValue().getBody(); String requestUri = uaaRequestBody.getFirst("redirect-uri"); assertTrue(requestUri.contains("www.google.com")); assertFalse(requestUri.contains("http://www.google.com")); } private void setResponse(Map<String, Object> body, HttpHeaders headers, HttpStatus status) { if (headers == null) { headers = new HttpHeaders(); } @SuppressWarnings("rawtypes") ResponseEntity<Map> response = new ResponseEntity<Map>(body, headers, status); @SuppressWarnings({ "unchecked", "rawtypes" }) ResponseEntity<Map> exchange = authorizationTemplate.exchange(Matchers.anyString(), Matchers.any(HttpMethod.class), Matchers.any(HttpEntity.class), Matchers.any(Class.class)); Mockito.when(exchange).thenReturn(response); } }