package org.cloudfoundry.identity.uaa.login;
import com.dumbster.smtp.SimpleSmtpServer;
import org.cloudfoundry.identity.uaa.authentication.Origin;
import org.cloudfoundry.identity.uaa.authentication.UaaPrincipal;
import org.cloudfoundry.identity.uaa.login.test.UaaRestTemplateBeanFactoryPostProcessor;
import org.cloudfoundry.identity.uaa.test.YamlServletProfileInitializerContextInitializer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.http.HttpMethod;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.support.XmlWebApplicationContext;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.not;
import static org.springframework.http.HttpMethod.*;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.jsonPath;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.xpath;
public class AccountsControllerIntegrationTest {
XmlWebApplicationContext webApplicationContext;
private MockMvc mockMvc;
private MockRestServiceServer mockUaaServer;
private static SimpleSmtpServer mailServer;
@BeforeClass
public static void startMailServer() throws Exception {
mailServer = SimpleSmtpServer.start(2525);
}
@Before
public void setUp() throws Exception {
webApplicationContext = new XmlWebApplicationContext();
webApplicationContext.setEnvironment(new MockEnvironment());
new YamlServletProfileInitializerContextInitializer().initializeContext(webApplicationContext, "login.yml");
webApplicationContext.setConfigLocation("file:./src/main/webapp/WEB-INF/spring-servlet.xml");
webApplicationContext.addBeanFactoryPostProcessor(new UaaRestTemplateBeanFactoryPostProcessor("authorizationTemplate"));
webApplicationContext.refresh();
FilterChainProxy springSecurityFilterChain = webApplicationContext.getBean("springSecurityFilterChain", FilterChainProxy.class);
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.addFilter(springSecurityFilterChain)
.build();
mockUaaServer = MockRestServiceServer.createServer(webApplicationContext.getBean("authorizationTemplate", RestTemplate.class));
}
@AfterClass
public static void stopMailServer() throws Exception {
mailServer.stop();
}
@Test
public void testCreateActivationEmailPage() throws Exception {
((MockEnvironment) webApplicationContext.getEnvironment()).setProperty("login.brand", "oss");
mockMvc.perform(get("/create_account.do"))
.andExpect(content().string(containsString("Create your account")))
.andExpect(content().string(not(containsString("Pivotal ID"))));
}
@Test
public void testCreateActivationEmailPageWithPivotalBrand() throws Exception {
((MockEnvironment) webApplicationContext.getEnvironment()).setProperty("login.brand", "pivotal");
mockMvc.perform(get("/create_account.do"))
.andExpect(content().string(containsString("Create your Pivotal ID")))
.andExpect(content().string(not(containsString("Create your account"))));
}
@Test
public void testActivationEmailSentPage() throws Exception {
((MockEnvironment) webApplicationContext.getEnvironment()).setProperty("login.brand", "oss");
mockMvc.perform(get("/accounts/email_sent"))
.andExpect(status().isOk())
.andExpect(content().string(containsString("Create your account")))
.andExpect(xpath("//input[@disabled='disabled']/@value").string("Email successfully sent"))
.andExpect(content().string(not(containsString("Pivotal ID"))));
}
@Test
public void testActivationEmailSentPageWithPivotalBrand() throws Exception {
((MockEnvironment) webApplicationContext.getEnvironment()).setProperty("login.brand", "pivotal");
mockMvc.perform(get("/accounts/email_sent"))
.andExpect(status().isOk())
.andExpect(content().string(containsString("Create your Pivotal ID")))
.andExpect(xpath("//input[@disabled='disabled']/@value").string("Email successfully sent"))
.andExpect(content().string(not(containsString("Create your account"))));
}
@Test
public void testCreatingAnAccount() throws Exception {
String scimUserJSONString = "{" +
"\"userName\": \"user@example.com\"," +
"\"id\": \"newly-created-user-id\"," +
"\"emails\": [{\"value\":\"user@example.com\"}]" +
"}";
mockUaaServer.expect(requestTo("http://localhost:8080/uaa/Users"))
.andExpect(method(POST))
.andExpect(jsonPath("$.userName").value("user@example.com"))
.andExpect(jsonPath("$.password").value("secret"))
.andExpect(jsonPath("$.origin").value("uaa"))
.andExpect(jsonPath("$.verified").value(false))
.andExpect(jsonPath("$.emails[0].value").value("user@example.com"))
.andRespond(withSuccess(scimUserJSONString, APPLICATION_JSON));
mockUaaServer.expect(requestTo("http://localhost:8080/uaa/Codes"))
.andExpect(method(HttpMethod.POST))
.andRespond(withSuccess("{\"code\":\"the_secret_code\"," +
"\"expiresAt\":1406152741265," +
"\"data\":\"{\\\"user_id\\\":\\\"newly-created-user-id\\\",\\\"client_id\\\":\\\"app\\\"}\"}",
APPLICATION_JSON));
String uaaResponseJson = "{" +
" \"code\":\"the_secret_code\"," +
" \"expiresAt\":1406152741265," +
" \"data\":\"{\\\"user_id\\\":\\\"newly-created-user-id\\\",\\\"client_id\\\":\\\"app\\\"}\"" +
"}";
mockUaaServer.expect(requestTo("http://localhost:8080/uaa/Codes/the_secret_code"))
.andExpect(method(GET))
.andRespond(withSuccess(uaaResponseJson, APPLICATION_JSON));
mockUaaServer.expect(requestTo("http://localhost:8080/uaa/Users/newly-created-user-id/verify"))
.andExpect(method(GET))
.andRespond(withSuccess(scimUserJSONString, APPLICATION_JSON));
Map<String,Object> additionalInformation = new HashMap<>();
additionalInformation.put("signup_redirect_url", "http://example.com/redirect");
String clientDetails = "{" +
"\"client_id\": \"app\"," +
"\"signup_redirect_url\": \"http://example.com/redirect\"" +
"}";
mockUaaServer.expect(requestTo("http://localhost:8080/uaa/oauth/clients/app"))
.andExpect(method(GET))
.andRespond(withSuccess(clientDetails, APPLICATION_JSON));
mockMvc.perform(post("/create_account.do")
.param("email", "user@example.com")
.param("password", "secret")
.param("password_confirmation", "secret")
.param("client_id", "app"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("accounts/email_sent"));
MvcResult mvcResult = mockMvc.perform(get("/verify_user")
.param("code", "the_secret_code"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("http://example.com/redirect"))
.andReturn();
SecurityContext securityContext = (SecurityContext) mvcResult.getRequest().getSession().getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
Authentication authentication = securityContext.getAuthentication();
Assert.assertThat(authentication.getPrincipal(), instanceOf(UaaPrincipal.class));
UaaPrincipal principal = (UaaPrincipal) authentication.getPrincipal();
Assert.assertThat(principal.getId(), equalTo("newly-created-user-id"));
Assert.assertThat(principal.getEmail(), equalTo("user@example.com"));
Assert.assertThat(principal.getOrigin(), equalTo(Origin.UAA));
}
}