org.cloudfoundry.identity.uaa.scim.endpoints.ChangeEmailEndpoints Maven / Gradle / Ivy
package org.cloudfoundry.identity.uaa.scim.endpoints;
import com.fasterxml.jackson.core.type.TypeReference;
import org.cloudfoundry.identity.uaa.account.EmailChange;
import org.cloudfoundry.identity.uaa.account.EmailChangeResponse;
import org.cloudfoundry.identity.uaa.codestore.ExpiringCode;
import org.cloudfoundry.identity.uaa.codestore.ExpiringCodeStore;
import org.cloudfoundry.identity.uaa.constants.OriginKeys;
import org.cloudfoundry.identity.uaa.error.UaaException;
import org.cloudfoundry.identity.uaa.resources.QueryableResourceManager;
import org.cloudfoundry.identity.uaa.scim.ScimUser;
import org.cloudfoundry.identity.uaa.scim.ScimUserProvisioning;
import org.cloudfoundry.identity.uaa.scim.event.UserModifiedEvent;
import org.cloudfoundry.identity.uaa.util.JsonUtils;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import static org.cloudfoundry.identity.uaa.codestore.ExpiringCodeType.EMAIL;
import static org.springframework.http.HttpStatus.CONFLICT;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY;
@Controller
public class ChangeEmailEndpoints implements ApplicationEventPublisherAware {
private final ScimUserProvisioning scimUserProvisioning;
private final ExpiringCodeStore expiringCodeStore;
private ApplicationEventPublisher publisher;
private final QueryableResourceManager clientDetailsService;
private static final int EMAIL_CHANGE_LIFETIME = 30 * 60 * 1000;
public static final String CHANGE_EMAIL_REDIRECT_URL = "change_email_redirect_url";
public ChangeEmailEndpoints(ScimUserProvisioning scimUserProvisioning, ExpiringCodeStore expiringCodeStore, QueryableResourceManager clientDetailsService) {
this.scimUserProvisioning = scimUserProvisioning;
this.expiringCodeStore = expiringCodeStore;
this.clientDetailsService = clientDetailsService;
}
@RequestMapping(value="/email_verifications", method = RequestMethod.POST)
public ResponseEntity generateEmailVerificationCode(@RequestBody EmailChange emailChange) {
String userId = emailChange.getUserId();
String email = emailChange.getEmail();
ScimUser user = scimUserProvisioning.retrieve(userId, IdentityZoneHolder.get().getId());
if (user.getUserName().equals(user.getPrimaryEmail())) {
List results = scimUserProvisioning.query("userName eq \"" + email + "\" and origin eq \"" + OriginKeys.UAA + "\"", IdentityZoneHolder.get().getId());
if (!results.isEmpty()) {
return new ResponseEntity<>(CONFLICT);
}
}
String code;
try {
code = expiringCodeStore.generateCode(JsonUtils.writeValueAsString(emailChange), new Timestamp(System.currentTimeMillis() + EMAIL_CHANGE_LIFETIME), EMAIL.name(), IdentityZoneHolder.get().getId()).getCode();
} catch (JsonUtils.JsonUtilException e) {
throw new UaaException("Error while generating change email code", e);
}
return new ResponseEntity<>(code, CREATED);
}
@RequestMapping(value="/email_changes", method = RequestMethod.POST)
public ResponseEntity changeEmail(@RequestBody String code) throws IOException {
ExpiringCode expiringCode = expiringCodeStore.retrieveCode(code, IdentityZoneHolder.get().getId());
if ((null != expiringCode) && ((null == expiringCode.getIntent()) || EMAIL.name().equals(expiringCode.getIntent()))) {
Map data = JsonUtils.readValue(expiringCode.getData(), new TypeReference