/*******************************************************************************
* 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.feature;
import com.dumbster.smtp.SimpleSmtpServer;
import com.dumbster.smtp.SmtpMessage;
import org.cloudfoundry.identity.uaa.authentication.Origin;
import org.cloudfoundry.identity.uaa.codestore.ExpiringCode;
import org.cloudfoundry.identity.uaa.login.test.DefaultIntegrationTestConfig;
import org.cloudfoundry.identity.uaa.login.test.IntegrationTestRule;
import org.cloudfoundry.identity.uaa.login.test.TestClient;
import org.cloudfoundry.identity.uaa.scim.ScimUser;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.test.TestAccounts;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.client.RestTemplate;
import java.security.SecureRandom;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import static junit.framework.TestCase.assertNotNull;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.springframework.http.HttpStatus.FOUND;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = DefaultIntegrationTestConfig.class)
public class InvitationsIT {
@Autowired
TestAccounts testAccounts;
@Autowired @Rule
public IntegrationTestRule integrationTestRule;
@Autowired
WebDriver webDriver;
@Autowired
SimpleSmtpServer simpleSmtpServer;
@Autowired
TestClient testClient;
@Value("${integration.test.uaa_url}")
String uaaUrl;
@Value("${integration.test.base_url}")
String baseUrl;
@Value("${integration.test.app_url}")
String appUrl;
@Test
public void testSendInvite() throws Exception {
int randomInt = new SecureRandom().nextInt();
String userEmail = "user" + randomInt + "@example.com";
int receivedEmailSize = simpleSmtpServer.getReceivedEmailSize();
signIn(testAccounts.getUserName(), testAccounts.getPassword());
webDriver.findElement(By.linkText("Invite Users")).click();
assertEquals("Send an invite", webDriver.findElement(By.tagName("h1")).getText());
webDriver.findElement(By.name("email")).sendKeys(userEmail);
webDriver.findElement(By.xpath("//input[@value='Send invite']")).click();
assertEquals("Invite sent", webDriver.findElement(By.tagName("h1")).getText());
assertEquals(receivedEmailSize + 1, simpleSmtpServer.getReceivedEmailSize());
Iterator receivedEmail = simpleSmtpServer.getReceivedEmail();
SmtpMessage message = (SmtpMessage) receivedEmail.next();
receivedEmail.remove();
assertEquals(userEmail, message.getHeaderValue("To"));
assertThat(message.getBody(), containsString("Accept Invite"));
String link = testClient.extractLink(message.getBody());
assertTrue(link.contains("/invitations/accept"));
webDriver.get(link);
assertEquals("Create your account", webDriver.findElement(By.tagName("h1")).getText());
webDriver.findElement(By.name("password")).sendKeys("secret");
webDriver.findElement(By.name("password_confirmation")).sendKeys("secret");
webDriver.findElement(By.xpath("//input[@value='Create account']")).click();
assertThat(webDriver.findElement(By.cssSelector("h1")).getText(), containsString("Where to?"));
webDriver.findElement(By.xpath("//*[text()='"+userEmail+"']")).click();
webDriver.findElement(By.linkText("Sign Out")).click();
webDriver.findElement(By.name("username")).sendKeys(userEmail);
webDriver.findElement(By.name("password")).sendKeys("secret");
webDriver.findElement(By.xpath("//input[@value='Sign in']")).click();
assertThat(webDriver.findElement(By.cssSelector("h1")).getText(), containsString("Where to?"));
}
@Test
public void testClientRedirectInviteUser() throws Exception {
String code = generateCode();
webDriver.get(baseUrl + "/invitations/accept?code=" + code);
assertEquals("Create your account", webDriver.findElement(By.tagName("h1")).getText());
webDriver.findElement(By.name("password")).sendKeys("secret");
webDriver.findElement(By.name("password_confirmation")).sendKeys("secret");
webDriver.findElement(By.xpath("//input[@value='Create account']")).click();
Assert.assertThat(webDriver.findElement(By.cssSelector("h1")).getText(), not(containsString("Where to?")));
}
private String generateCode() {
String token = testClient.getOAuthAccessToken("login", "loginsecret", "client_credentials", "password.write,scim.write");
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + token);
RestTemplate uaaTemplate = new RestTemplate();
String userEmail = "user" + new SecureRandom().nextInt() + "@example.com";
ScimUser scimUser = new ScimUser();
scimUser.setUserName(userEmail);
ScimUser.Email email = new ScimUser.Email();
email.setPrimary(true);
email.setValue(userEmail);
scimUser.setEmails(Arrays.asList(email));
scimUser.setOrigin(Origin.UAA);
HttpEntity<ScimUser> request = new HttpEntity<>(scimUser, headers);
ResponseEntity<ScimUser> response = uaaTemplate.exchange(uaaUrl + "/Users", HttpMethod.POST, request, ScimUser.class);
Timestamp expiry = new Timestamp(System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(System.currentTimeMillis() + 24 * 3600, TimeUnit.MILLISECONDS));
ExpiringCode expiringCode = new ExpiringCode(null, expiry, "{\"client_id\":\"app\", \"user_id\":\"" + response.getBody().getId() + "\", \"email\":\"user@example.com\"}");
HttpEntity<ExpiringCode> expiringCodeRequest = new HttpEntity<>(expiringCode, headers);
ResponseEntity<ExpiringCode> expiringCodeResponse = uaaTemplate.exchange(uaaUrl + "/Codes", HttpMethod.POST, expiringCodeRequest, ExpiringCode.class);
expiringCode = expiringCodeResponse.getBody();
return expiringCode.getCode();
}
private void signIn(String userName, String password) {
webDriver.get(baseUrl + "/login");
webDriver.findElement(By.name("username")).sendKeys(userName);
webDriver.findElement(By.name("password")).sendKeys(password);
webDriver.findElement(By.xpath("//input[@value='Sign in']")).click();
assertThat(webDriver.findElement(By.cssSelector("h1")).getText(), containsString("Where to?"));
}
}