package org.cloudfoundry.identity.uaa.login;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.cloudfoundry.identity.uaa.codestore.ExpiringCode;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring4.SpringTemplateEngine;
import javax.mail.MessagingException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;
public class EmailAccountCreationService implements AccountCreationService {
private final Log logger = LogFactory.getLog(getClass());
private final SpringTemplateEngine templateEngine;
private final EmailService emailService;
private final RestTemplate uaaTemplate;
private final String uaaBaseUrl;
private final String brand;
private final ObjectMapper objectMapper;
public EmailAccountCreationService(ObjectMapper objectMapper, SpringTemplateEngine templateEngine, EmailService emailService, RestTemplate uaaTemplate, String uaaBaseUrl, String brand) {
this.objectMapper = objectMapper;
this.templateEngine = templateEngine;
this.emailService = emailService;
this.uaaTemplate = uaaTemplate;
this.uaaBaseUrl = uaaBaseUrl;
this.brand = brand;
}
@Override
public void beginActivation(String email, String clientId) {
String subject = getSubjectText();
try {
Timestamp expiresAt = new Timestamp(System.currentTimeMillis() + (60 * 60 * 1000)); // 1 hour
ExpiringCode expiringCodeForPost = getExpiringCode(email, clientId, expiresAt);
ExpiringCode expiringCode = uaaTemplate.postForObject(uaaBaseUrl + "/Codes", expiringCodeForPost, ExpiringCode.class);
String htmlContent = getEmailHtml(expiringCode.getCode(), email);
try {
emailService.sendMimeMessage(email, subject, htmlContent);
} catch (MessagingException e) {
logger.error("Exception raised while sending message to " + email, e);
} catch (UnsupportedEncodingException e) {
logger.error("Exception raised while sending message to " + email, e);
}
} catch (RestClientException e) {
logger.info("Exception raised while creating account activation email for " + email, e);
} catch (IOException e) {
logger.info("Exception raised while creating account activation email for " + email, e);
}
}
private ExpiringCode getExpiringCode(String username, String clientId, Timestamp expiresAt) throws IOException {
Map<String, String> codeData = new HashMap<>();
codeData.put("username", username);
codeData.put("client_id", clientId);
String codeDataString = objectMapper.writeValueAsString(codeData);
return new ExpiringCode(null, expiresAt, codeDataString);
}
@Override
public AccountCreation completeActivation(String code, String password) {
Map<String, String> accountCreationRequest = new HashMap<>();
accountCreationRequest.put("code", code);
accountCreationRequest.put("password", password);
return uaaTemplate.postForObject(uaaBaseUrl + "/create_account", accountCreationRequest, AccountCreation.class);
}
private String getSubjectText() {
return brand.equals("pivotal") ? "Activate your Pivotal ID" : "Activate your account";
}
private String getEmailHtml(String code, String email) {
String accountsUrl = ServletUriComponentsBuilder.fromCurrentContextPath().path("/accounts/new").build().toUriString();
final Context ctx = new Context();
ctx.setVariable("serviceName", brand.equals("pivotal") ? "Pivotal" : "Cloud Foundry");
ctx.setVariable("servicePhrase", brand.equals("pivotal") ? "a Pivotal ID" : "an account");
ctx.setVariable("code", code);
ctx.setVariable("email", email);
ctx.setVariable("accountsUrl", accountsUrl);
return templateEngine.process("activate", ctx);
}
}