Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.cloudfoundry.identity.uaa.account.EmailAccountCreationService Maven / Gradle / Ivy
package org.cloudfoundry.identity.uaa.account;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.message.MessageService;
import org.cloudfoundry.identity.uaa.message.MessageType;
import org.cloudfoundry.identity.uaa.scim.ScimUser;
import org.cloudfoundry.identity.uaa.scim.ScimUserProvisioning;
import org.cloudfoundry.identity.uaa.scim.exception.ScimResourceAlreadyExistsException;
import org.cloudfoundry.identity.uaa.scim.util.ScimUtils;
import org.cloudfoundry.identity.uaa.scim.validate.PasswordValidator;
import org.cloudfoundry.identity.uaa.util.JsonUtils;
import org.cloudfoundry.identity.uaa.zone.ClientServicesExtension;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
import org.springframework.http.HttpStatus;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.NoSuchClientException;
import org.springframework.util.StringUtils;
import org.springframework.web.client.HttpClientErrorException;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring4.SpringTemplateEngine;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import static org.cloudfoundry.identity.uaa.codestore.ExpiringCodeType.REGISTRATION;
import static org.cloudfoundry.identity.uaa.util.UaaUrlUtils.findMatchingRedirectUri;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
public class EmailAccountCreationService implements AccountCreationService {
private final Log logger = LogFactory.getLog(getClass());
public static final String SIGNUP_REDIRECT_URL = "signup_redirect_url";
private final SpringTemplateEngine templateEngine;
private final MessageService messageService;
private final ExpiringCodeStore codeStore;
private final ScimUserProvisioning scimUserProvisioning;
private final ClientServicesExtension clientDetailsService;
private final PasswordValidator passwordValidator;
public EmailAccountCreationService(
SpringTemplateEngine templateEngine,
MessageService messageService,
ExpiringCodeStore codeStore,
ScimUserProvisioning scimUserProvisioning,
ClientServicesExtension clientDetailsService,
PasswordValidator passwordValidator) {
this.templateEngine = templateEngine;
this.messageService = messageService;
this.codeStore= codeStore;
this.scimUserProvisioning = scimUserProvisioning;
this.clientDetailsService = clientDetailsService;
this.passwordValidator = passwordValidator;
}
@Override
public void beginActivation(String email, String password, String clientId, String redirectUri) {
passwordValidator.validate(password);
String subject = buildSubjectText();
try {
ScimUser scimUser = createUser(email, password, OriginKeys.UAA);
generateAndSendCode(email, clientId, subject, scimUser.getId(), redirectUri);
} catch (ScimResourceAlreadyExistsException e) {
List users = scimUserProvisioning.query("userName eq \""+email+"\" and origin eq \""+ OriginKeys.UAA+"\"", IdentityZoneHolder.get().getId());
try {
if (users.size()>0) {
if (users.get(0).isVerified()) {
throw new UaaException("User already active.", HttpStatus.CONFLICT.value());
} else {
generateAndSendCode(email, clientId, subject, users.get(0).getId(), redirectUri);
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
} catch (IOException e) {
logger.error("Exception raised while creating account activation email for " + email, e);
}
}
private void generateAndSendCode(String email, String clientId, String subject, String userId, String redirectUri) throws IOException {
ExpiringCode expiringCode = ScimUtils.getExpiringCode(codeStore, userId, email, clientId, redirectUri, REGISTRATION);
String htmlContent = getEmailHtml(expiringCode.getCode(), email);
messageService.sendMessage(email, MessageType.CREATE_ACCOUNT_CONFIRMATION, subject, htmlContent);
}
@Override
public AccountCreationResponse completeActivation(String code) throws IOException {
ExpiringCode expiringCode = codeStore.retrieveCode(code, IdentityZoneHolder.get().getId());
if ((null == expiringCode) || ((null != expiringCode.getIntent()) && !REGISTRATION.name().equals(expiringCode.getIntent()))) {
throw new HttpClientErrorException(BAD_REQUEST);
}
Map data = JsonUtils.readValue(expiringCode.getData(), new TypeReference>() {});
ScimUser user = scimUserProvisioning.retrieve(data.get("user_id"), IdentityZoneHolder.get().getId());
user = scimUserProvisioning.verifyUser(user.getId(), user.getVersion(), IdentityZoneHolder.get().getId());
String clientId = data.get("client_id");
String redirectUri = data.get("redirect_uri") != null ? data.get("redirect_uri") : "";
String redirectLocation = getRedirect(clientId, redirectUri);
return new AccountCreationResponse(user.getId(), user.getUserName(), user.getUserName(), redirectLocation);
}
private String getRedirect(String clientId, String redirectUri) throws IOException {
if (clientId != null) {
try {
ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId, IdentityZoneHolder.get().getId());
Set registeredRedirectUris = clientDetails.getRegisteredRedirectUri() == null ? Collections.emptySet() :
clientDetails.getRegisteredRedirectUri();
String signupRedirectUrl = (String) clientDetails.getAdditionalInformation().get(SIGNUP_REDIRECT_URL);
String matchingRedirectUri = findMatchingRedirectUri(registeredRedirectUris, redirectUri, Optional.ofNullable(signupRedirectUrl).orElse("home"));
if (matchingRedirectUri != null) {
return matchingRedirectUri;
}
} catch (NoSuchClientException nsce) {
logger.debug(String.format("Unable to find client with ID:%s for account activation redirect", clientId), nsce);
}
}
return getDefaultRedirect();
}
@Override
public String getDefaultRedirect() throws IOException {
return "home";
}
@Override
public ScimUser createUser(String username, String password, String origin) {
ScimUser scimUser = new ScimUser();
scimUser.setUserName(username);
ScimUser.Email email = new ScimUser.Email();
email.setPrimary(true);
email.setValue(username);
scimUser.setEmails(Arrays.asList(email));
scimUser.setOrigin(origin);
scimUser.setPassword(password);
scimUser.setVerified(false);
try {
ScimUser userResponse = scimUserProvisioning.createUser(scimUser, password, IdentityZoneHolder.get().getId());
return userResponse;
} catch (RuntimeException x) {
if (x instanceof ScimResourceAlreadyExistsException) {
throw x;
}
throw new UaaException("Couldn't create user:"+username, x);
}
}
private String buildSubjectText() {
String companyName = IdentityZoneHolder.resolveBranding().getCompanyName();
boolean addBranding = StringUtils.hasText(companyName) && IdentityZoneHolder.isUaa();
if(addBranding) {
return String.format("Activate your %s account", companyName);
} else {
return "Activate your account";
}
}
private String getEmailHtml(String code, String email) {
String accountsUrl = ScimUtils.getVerificationURL(null).toString();
final Context ctx = new Context();
String companyName = IdentityZoneHolder.resolveBranding().getCompanyName();
if (IdentityZoneHolder.isUaa()) {
ctx.setVariable("serviceName", StringUtils.hasText(companyName) ? companyName : "Cloud Foundry");
} else {
ctx.setVariable("serviceName", IdentityZoneHolder.get().getName());
}
ctx.setVariable("servicePhrase", StringUtils.hasText(companyName) && IdentityZoneHolder.isUaa() ? companyName + " account" : "an account");
ctx.setVariable("code", code);
ctx.setVariable("email", email);
ctx.setVariable("accountsUrl", accountsUrl);
return templateEngine.process("activate", ctx);
}
}