Skip to content

Commit

Permalink
Merge branch 'master' into develop
Browse files Browse the repository at this point in the history
Signed-off-by: Priyata Agrawal <pagrawal@pivotal.io>
  • Loading branch information
mbhave authored and Priyata25 committed May 4, 2016
2 parents 30756b3 + 5c23774 commit 4a119d3
Show file tree
Hide file tree
Showing 17 changed files with 89 additions and 44 deletions.
Expand Up @@ -80,20 +80,22 @@ private ResetPasswordResponse changePasswordCodeAuthenticated(String code, Strin
throw new InvalidCodeException("invalid_code", "Sorry, your reset password link is no longer valid. Please request a new one", 422);
}
String userId;
String userName = null;
Date passwordLastModified = null;
String clientId = null;
String redirectUri = null;
String userName;
Date passwordLastModified;
String clientId;
String redirectUri;
PasswordChange change;
try {
PasswordChange change = JsonUtils.readValue(expiringCode.getData(), PasswordChange.class);
userId = change.getUserId();
userName = change.getUsername();
passwordLastModified = change.getPasswordModifiedTime();
clientId = change.getClientId();
redirectUri = change.getRedirectUri();
change = JsonUtils.readValue(expiringCode.getData(), PasswordChange.class);
} catch (JsonUtils.JsonUtilException x) {
userId = expiringCode.getData();
throw new InvalidCodeException("invalid_code", "Sorry, your reset password link is no longer valid. Please request a new one", 422);
}
userId = change.getUserId();
userName = change.getUsername();
passwordLastModified = change.getPasswordModifiedTime();
clientId = change.getClientId();
redirectUri = change.getRedirectUri();

ScimUser user = scimUserProvisioning.retrieve(userId);
try {
if (isUserModified(user, expiringCode.getExpiresAt(), userName, passwordLastModified)) {
Expand Down
Expand Up @@ -43,7 +43,7 @@ public class JdbcExpiringCodeStore implements ExpiringCodeStore {

private Log logger = LogFactory.getLog(getClass());

private RandomValueStringGenerator generator = new RandomValueStringGenerator(6);
private RandomValueStringGenerator generator = new RandomValueStringGenerator(10);

private JdbcTemplate jdbcTemplate;

Expand Down
Expand Up @@ -54,7 +54,7 @@ public AcceptedInvitation acceptInvitation(String code, String password) {
user = scimUserProvisioning.verifyUser(userId, user.getVersion());


if (OriginKeys.UAA.equals(user.getOrigin())) {
if (OriginKeys.UAA.equals(user.getOrigin()) && StringUtils.hasText(password)) {
PasswordChangeRequest request = new PasswordChangeRequest();
request.setPassword(password);
scimUserProvisioning.changePassword(userId, null, password);
Expand Down
@@ -1,11 +1,9 @@
package org.cloudfoundry.identity.uaa.scim.endpoints;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.Date;

@JsonIgnoreProperties(ignoreUnknown = true)
public class PasswordChange {
public PasswordChange() {}

Expand Down
2 changes: 1 addition & 1 deletion server/src/main/resources/login-ui.xml
Expand Up @@ -151,7 +151,7 @@
entry-point-ref="loginEntryPoint"
use-expressions="false"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
<csrf disabled="false"/>
<access-denied-handler ref="loginEntryPoint"/>
</http>
Expand Down
Expand Up @@ -51,7 +51,7 @@ public void testGenerateCode() throws Exception {
assertNotNull(result);

assertNotNull(result.getCode());
assertTrue(result.getCode().trim().length() > 0);
assertTrue(result.getCode().trim().length() == 10);

assertEquals(expiresAt, result.getExpiresAt());

Expand Down
Expand Up @@ -306,7 +306,7 @@ public void acceptInvitePage_for_verifiedUser() throws Exception {

when(expiringCodeStore.retrieveCode("the_secret_code")).thenReturn(new ExpiringCode("code", new Timestamp(System.currentTimeMillis()), JsonUtils.writeValueAsString(codeData), null));
when(expiringCodeStore.generateCode(anyString(), anyObject(), eq(null))).thenReturn(new ExpiringCode("code", new Timestamp(System.currentTimeMillis()), JsonUtils.writeValueAsString(codeData), null));
when(invitationsService.acceptInvitation(anyString(), anyString())).thenReturn(new InvitationsService.AcceptedInvitation("blah.test.com", new ScimUser()));
when(invitationsService.acceptInvitation(anyString(), eq(""))).thenReturn(new InvitationsService.AcceptedInvitation("blah.test.com", new ScimUser()));
IdentityProvider provider = new IdentityProvider();
provider.setType(OriginKeys.UAA);
when(providerProvisioning.retrieveByOrigin(anyString(), anyString())).thenReturn(provider);
Expand Down
Expand Up @@ -14,7 +14,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
Expand All @@ -32,7 +31,6 @@
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.thymeleaf.spring4.SpringTemplateEngine;

import java.sql.Timestamp;
import java.util.HashMap;
Expand All @@ -48,6 +46,7 @@
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.security.oauth2.common.util.OAuth2Utils.CLIENT_ID;
Expand Down Expand Up @@ -108,6 +107,23 @@ public void acceptInvitationNoClientId() throws Exception {
assertEquals("/home", redirectLocation);
}

@Test
public void acceptInvitation_withoutPasswordUpdate() throws Exception {
ScimUser user = new ScimUser("user-id-001", "user@example.com", "first", "last");
user.setOrigin(UAA);
when(scimUserProvisioning.retrieve(eq("user-id-001"))).thenReturn(user);
when(scimUserProvisioning.verifyUser(anyString(), anyInt())).thenReturn(user);

Map<String,String> userData = new HashMap<>();
userData.put(USER_ID, "user-id-001");
userData.put(EMAIL, "user@example.com");
when(expiringCodeStore.retrieveCode(anyString())).thenReturn(new ExpiringCode("code", new Timestamp(System.currentTimeMillis()), JsonUtils.writeValueAsString(userData), null));

emailInvitationsService.acceptInvitation("code", "").getRedirectUri();
verify(scimUserProvisioning).verifyUser(user.getId(), user.getVersion());
verify(scimUserProvisioning, never()).changePassword(anyString(), anyString(), anyString());
}

@Test
public void acceptInvitationWithClientNotFound() throws Exception {
ScimUser user = new ScimUser("user-id-001", "user@example.com", "first", "last");
Expand Down
Expand Up @@ -127,7 +127,7 @@ public void forgotPassword_PublishesResetPasswordRequestEvent() throws Exception
ArgumentCaptor<ResetPasswordRequestEvent> captor = ArgumentCaptor.forClass(ResetPasswordRequestEvent.class);
verify(publisher).publishEvent(captor.capture());
ResetPasswordRequestEvent event = captor.getValue();
assertThat((String) event.getSource(), equalTo("user@example.com"));
assertThat(event.getSource(), equalTo("user@example.com"));
assertThat(event.getCode(), equalTo("code"));
assertThat(event.getAuthentication(), sameInstance(authentication));
}
Expand Down Expand Up @@ -191,7 +191,7 @@ public void resetPassword_InvalidPasswordException_NewPasswordSameAsOld() {
user.setMeta(new ScimMeta(new Date(), new Date(), 0));
user.setPrimaryEmail("foo@example.com");
ExpiringCode expiringCode = new ExpiringCode("good_code",
new Timestamp(System.currentTimeMillis() + UaaResetPasswordService.PASSWORD_RESET_LIFETIME), "user-id", null);
new Timestamp(System.currentTimeMillis() + UaaResetPasswordService.PASSWORD_RESET_LIFETIME), "{\"user_id\":\"user-id\",\"username\":\"username\",\"passwordModifiedTime\":null,\"client_id\":\"\",\"redirect_uri\":\"\"}", null);
when(codeStore.retrieveCode("good_code")).thenReturn(expiringCode);
when(scimUserProvisioning.retrieve("user-id")).thenReturn(user);
when(scimUserProvisioning.checkPasswordMatches("user-id", "Passwo3dAsOld"))
Expand All @@ -208,6 +208,22 @@ public void resetPassword_InvalidPasswordException_NewPasswordSameAsOld() {
}
}

@Test
public void resetPassword_InvalidCodeData() {
ExpiringCode expiringCode = new ExpiringCode("good_code",
new Timestamp(System.currentTimeMillis() + UaaResetPasswordService.PASSWORD_RESET_LIFETIME), "user-id", null);
when(codeStore.retrieveCode("good_code")).thenReturn(expiringCode);
SecurityContext securityContext = mock(SecurityContext.class);
when(securityContext.getAuthentication()).thenReturn(new MockAuthentication());
SecurityContextHolder.setContext(securityContext);
try {
emailResetPasswordService.resetPassword("good_code", "password");
fail();
} catch (InvalidCodeException e) {
assertEquals("Sorry, your reset password link is no longer valid. Please request a new one", e.getMessage());
}
}

@Test
public void resetPassword_WithInvalidClientId() {
setupResetPassword("invalid_client", "redirect.example.com");
Expand Down
Expand Up @@ -237,7 +237,8 @@ public void testCreatingAPasswordResetWithAUsernameContainingSpecialCharacters()
@Test
public void testChangingAPasswordWithAValidCode() throws Exception {
when(expiringCodeStore.retrieveCode("secret_code"))
.thenReturn(new ExpiringCode("secret_code", new Timestamp(System.currentTimeMillis() + UaaResetPasswordService.PASSWORD_RESET_LIFETIME), "eyedee", null));
.thenReturn(new ExpiringCode("secret_code", new Timestamp(System.currentTimeMillis() + UaaResetPasswordService.PASSWORD_RESET_LIFETIME),
"{\"user_id\":\"eyedee\",\"username\":\"user@example.com\",\"passwordModifiedTime\":null,\"client_id\":\"\",\"redirect_uri\":\"\"}", null));

ScimUser scimUser = new ScimUser("eyedee", "user@example.com", "User", "Man");
scimUser.setMeta(new ScimMeta(new Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24)), new Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24)), 0));
Expand Down Expand Up @@ -281,7 +282,9 @@ public void changing_password_with_invalid_code() throws Exception {
@Test
public void testChangingAPasswordForUnverifiedUser() throws Exception {
when(expiringCodeStore.retrieveCode("secret_code"))
.thenReturn(new ExpiringCode("secret_code", new Timestamp(System.currentTimeMillis() + UaaResetPasswordService.PASSWORD_RESET_LIFETIME), "eyedee", null));
.thenReturn(new ExpiringCode("secret_code", new Timestamp(System.currentTimeMillis() + UaaResetPasswordService.PASSWORD_RESET_LIFETIME),
"{\"user_id\":\"eyedee\",\"username\":\"user@example.com\",\"passwordModifiedTime\":null,\"client_id\":\"\",\"redirect_uri\":\"\"}",
null));

ScimUser scimUser = new ScimUser("eyedee", "user@example.com", "User", "Man");
scimUser.setMeta(new ScimMeta(new Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24)), new Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24)), 0));
Expand Down Expand Up @@ -338,7 +341,9 @@ public void changePassword_Returns422UnprocessableEntity_NewPasswordSameAsOld()
Mockito.reset(passwordValidator);

when(expiringCodeStore.retrieveCode("emailed_code"))
.thenReturn(new ExpiringCode("emailed_code", new Timestamp(System.currentTimeMillis()+ UaaResetPasswordService.PASSWORD_RESET_LIFETIME), "eyedee", null));
.thenReturn(new ExpiringCode("emailed_code", new Timestamp(System.currentTimeMillis()+ UaaResetPasswordService.PASSWORD_RESET_LIFETIME),
"{\"user_id\":\"eyedee\",\"username\":\"user@example.com\",\"passwordModifiedTime\":null,\"client_id\":\"\",\"redirect_uri\":\"\"}",
null));

ScimUser scimUser = new ScimUser("eyedee", "user@example.com", "User", "Man");
scimUser.setMeta(new ScimMeta(new Date(System.currentTimeMillis()-(1000*60*60*24)), new Date(System.currentTimeMillis()-(1000*60*60*24)), 0));
Expand Down
2 changes: 1 addition & 1 deletion uaa/src/main/webapp/WEB-INF/spring/codestore-endpoints.xml
Expand Up @@ -26,7 +26,7 @@
<http name="codeStoreSecurity" pattern="/Codes/**" create-session="stateless" authentication-manager-ref="emptyAuthenticationManager"
entry-point-ref="oauthAuthenticationEntryPoint"
xmlns="http://www.springframework.org/schema/security" use-expressions="true">
<intercept-url pattern="/**" access="#oauth2.hasAnyScope('scim.create','scim.write','password.write')"/>
<intercept-url pattern="/**" access="#oauth2.hasAnyScope('oauth.login')"/>
<custom-filter ref="resourceAgnosticAuthenticationFilter" position="PRE_AUTH_FILTER" />
<anonymous enabled="false" />
<expression-handler ref="oauthWebExpressionHandler" />
Expand Down
Expand Up @@ -249,7 +249,7 @@ public void testFormEncodedAutologinRequest() throws Exception {
Map.class);

String autologinCode = (String) autologinResponseEntity.getBody().get("code");
assertEquals(6, autologinCode.length());
assertEquals(10, autologinCode.length());
}

@Test
Expand Down
Expand Up @@ -90,6 +90,7 @@ public void setUp() throws Exception {

@Test
public void testChangePassword() throws Exception {
webDriver.get(baseUrl + "/change_password");
signIn(userEmail, PASSWORD);

changePassword(PASSWORD, NEW_PASSWORD, "new");
Expand All @@ -108,7 +109,7 @@ public void displaysErrorWhenPasswordContravenesPolicy() {
//the only policy we can contravene by default is the length

String newPassword = new RandomValueStringGenerator(260).generate();

webDriver.get(baseUrl + "/change_password");
signIn(userEmail, PASSWORD);

changePassword(PASSWORD, newPassword, newPassword);
Expand All @@ -134,11 +135,8 @@ private void signOut() {
}

private void signIn(String userName, String password) {
webDriver.get(baseUrl + "/logout.do");
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?"));
}
}
Expand Up @@ -91,7 +91,7 @@ public class InvitationsIT {
@Before
public void setup() throws Exception {
scimToken = testClient.getOAuthAccessToken("admin", "adminsecret", "client_credentials", "scim.read,scim.write");
loginToken = testClient.getOAuthAccessToken("login", "loginsecret", "client_credentials", "password.write,scim.write");
loginToken = testClient.getOAuthAccessToken("login", "loginsecret", "client_credentials", "oauth.login");
screenShootRule.setWebDriver(webDriver);
}

Expand Down Expand Up @@ -199,9 +199,9 @@ private String createInvitation(String username, String userEmail, String redire
return createInvitation(baseUrl, uaaUrl, username, userEmail, origin, redirectUri, loginToken, scimToken);
}

public static String createInvitation(String baseUrl, String uaaUrl, String username, String userEmail, String origin, String redirectUri, String scimWriteToken, String scimReadToken) {
public static String createInvitation(String baseUrl, String uaaUrl, String username, String userEmail, String origin, String redirectUri, String loginToken, String scimToken) {
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + scimWriteToken);
headers.add("Authorization", "Bearer " + scimToken);
RestTemplate uaaTemplate = new RestTemplate();
ScimUser scimUser = new ScimUser();
scimUser.setUserName(username);
Expand All @@ -211,8 +211,8 @@ public static String createInvitation(String baseUrl, String uaaUrl, String user

String userId = null;
try {
userId = IntegrationTestUtils.getUserIdByField(scimReadToken, baseUrl, origin, "email", userEmail);
scimUser = IntegrationTestUtils.getUser(scimReadToken, baseUrl, userId);
userId = IntegrationTestUtils.getUserIdByField(scimToken, baseUrl, origin, "email", userEmail);
scimUser = IntegrationTestUtils.getUser(scimToken, baseUrl, userId);
} catch (RuntimeException x) {
}
if (userId == null) {
Expand All @@ -224,12 +224,15 @@ public static String createInvitation(String baseUrl, String uaaUrl, String user
userId = response.getBody().getId();
} else {
scimUser.setVerified(false);
IntegrationTestUtils.updateUser(scimWriteToken, uaaUrl, scimUser);
IntegrationTestUtils.updateUser(scimToken, uaaUrl, scimUser);
}

HttpHeaders invitationHeaders = new HttpHeaders();
invitationHeaders.add("Authorization", "Bearer " + loginToken);

Timestamp expiry = new Timestamp(System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(System.currentTimeMillis() + 24 * 3600, TimeUnit.MILLISECONDS));
ExpiringCode expiringCode = new ExpiringCode(null, expiry, "{\"origin\":\"" + origin + "\", \"client_id\":\"app\", \"redirect_uri\":\"" + redirectUri + "\", \"user_id\":\"" + userId + "\", \"email\":\"" + userEmail + "\"}", null);
HttpEntity<ExpiringCode> expiringCodeRequest = new HttpEntity<>(expiringCode, headers);
HttpEntity<ExpiringCode> expiringCodeRequest = new HttpEntity<>(expiringCode, invitationHeaders);
ResponseEntity<ExpiringCode> expiringCodeResponse = uaaTemplate.exchange(uaaUrl + "/Codes", HttpMethod.POST, expiringCodeRequest, ExpiringCode.class);
expiringCode = expiringCodeResponse.getBody();
return expiringCode.getCode();
Expand Down

0 comments on commit 4a119d3

Please sign in to comment.