-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
minimal service side implementation of user registration by email
- Loading branch information
Showing
10 changed files
with
436 additions
and
29 deletions.
There are no files selected for viewing
180 changes: 180 additions & 0 deletions
180
src/main/java/edu/tamu/cap/auth/controller/AuthController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
package edu.tamu.cap.auth.controller; | ||
|
||
import static edu.tamu.weaver.response.ApiStatus.ERROR; | ||
import static edu.tamu.weaver.response.ApiStatus.INVALID; | ||
import static edu.tamu.weaver.response.ApiStatus.SUCCESS; | ||
import static org.springframework.web.bind.annotation.RequestMethod.GET; | ||
import static org.springframework.web.bind.annotation.RequestMethod.POST; | ||
|
||
import java.security.InvalidKeyException; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.util.Date; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
import javax.crypto.BadPaddingException; | ||
import javax.crypto.IllegalBlockSizeException; | ||
import javax.crypto.NoSuchPaddingException; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import edu.tamu.cap.auth.service.AppUserCredentialsService; | ||
import edu.tamu.cap.model.EmailTemplate; | ||
import edu.tamu.cap.model.User; | ||
import edu.tamu.cap.model.repo.UserRepo; | ||
import edu.tamu.cap.service.EmailTemplateService; | ||
import edu.tamu.weaver.auth.controller.WeaverAuthController; | ||
import edu.tamu.weaver.response.ApiResponse; | ||
import edu.tamu.weaver.validation.results.ValidationResults; | ||
import edu.tamu.weaver.validation.utility.ValidationUtility; | ||
|
||
@RestController | ||
@RequestMapping("/auth") | ||
public class AuthController extends WeaverAuthController { | ||
|
||
private Logger logger = LoggerFactory.getLogger(this.getClass()); | ||
|
||
private final static String EMAIL_VERIFICATION_TYPE = "EMAIL_VERIFICATION"; | ||
|
||
public static final String REGISTRATION_TEMPLATE = "SYSTEM New User Registration"; | ||
|
||
@Value("${app.url}") | ||
private String url; | ||
|
||
@Autowired | ||
private UserRepo userRepo; | ||
|
||
@Autowired | ||
EmailTemplateService emailTemplateService; | ||
|
||
@Autowired | ||
private AppUserCredentialsService appUserCredentialsService; | ||
|
||
@RequestMapping(value = "/register", method = { POST, GET }) | ||
public ApiResponse registration(@RequestBody(required = false) Map<String, String> data, @RequestParam Map<String, String> parameters) { | ||
|
||
if (parameters.get("email") != null) { | ||
|
||
String email = parameters.get("email"); | ||
|
||
if (userRepo.findByEmail(email) != null) { | ||
logger.debug("Account with email " + email + " already exists!"); | ||
ValidationResults invalidEmail = new ValidationResults(); | ||
invalidEmail.addMessage(ValidationUtility.BUSINESS_MESSAGE_KEY, "verify", "Account with email " + email + " already exists!"); | ||
return new ApiResponse(INVALID, invalidEmail); | ||
} | ||
|
||
HashMap<String,String> emailData = new HashMap<String,String>(); | ||
try { | ||
emailData.put("REGISTRATION_URL", url + "/register?token=" + cryptoService.generateGenericToken(email, EMAIL_VERIFICATION_TYPE)); | ||
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | ||
| BadPaddingException e) { | ||
logger.debug("Unable to generate token! " + email); | ||
return new ApiResponse(ERROR, "Unable to generate token! " + email); | ||
} | ||
EmailTemplate finalEmail = emailTemplateService.buildEmail("user_registration",emailData); | ||
|
||
try { | ||
emailSender.sendEmail(email, finalEmail.getSubject(), finalEmail.getMessage()); | ||
} catch (javax.mail.MessagingException e) { | ||
logger.debug("Unable to send email! " + email); | ||
return new ApiResponse(ERROR, "Unable to send email! " + email); | ||
} | ||
|
||
return new ApiResponse(SUCCESS, "An email has been sent to " + email + ". Please confirm email to continue registration.", parameters); | ||
} | ||
|
||
String token = data.get("token"); | ||
String firstName = data.get("firstName"); | ||
String lastName = data.get("lastName"); | ||
String password = data.get("userPassword"); | ||
String confirm = data.get("confirm"); | ||
|
||
if ((firstName == null || firstName.trim().length() == 0) && (lastName == null || lastName.trim().length() == 0)) { | ||
logger.debug("Either a first or last name is required!"); | ||
return new ApiResponse(ERROR, "Either a first or last name is required!"); | ||
} | ||
|
||
if (password == null || password.trim().length() == 0) { | ||
logger.debug("Registration requires a password!"); | ||
return new ApiResponse(ERROR, "Registration requires a password!"); | ||
} | ||
|
||
if (password != null && !password.equals(confirm)) { | ||
logger.debug("The passwords do not match!"); | ||
return new ApiResponse(ERROR, "The passwords do not match!"); | ||
} | ||
|
||
if (password != null && password.trim().length() < 6) { | ||
logger.debug("Password must be greater than 6 characters!"); | ||
return new ApiResponse(ERROR, "Password must be greater than 6 characters!"); | ||
} | ||
|
||
String[] content = null; | ||
try { | ||
content = cryptoService.validateGenericToken(token, EMAIL_VERIFICATION_TYPE); | ||
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e) { | ||
logger.debug("Unable to validate token!"); | ||
return new ApiResponse(ERROR, "Unable to generate token!"); | ||
} | ||
|
||
String tokenCreateTime = content[0]; | ||
String email = content[1]; | ||
|
||
Long tokenDaysOld = TimeUnit.MILLISECONDS.toDays(Long.valueOf(tokenCreateTime) - new Date().getTime()); | ||
|
||
if (tokenDaysOld >= 2) { | ||
logger.debug("Token has expired!"); | ||
return new ApiResponse(ERROR, "Token has expired! Please begin registration again."); | ||
} | ||
|
||
User user = appUserCredentialsService.createUserFromRegistration(email, firstName, lastName, cryptoService.encodePassword(password)); | ||
|
||
return new ApiResponse(SUCCESS, "Registration was successful. Please login.", user); | ||
} | ||
|
||
@RequestMapping(value = "/login", method = POST) | ||
public ApiResponse login(@RequestBody Map<String, String> data) { | ||
|
||
String email = data.get("email"); | ||
String password = data.get("userPassword"); | ||
|
||
User user = userRepo.findByEmail(email); | ||
|
||
if (user == null) { | ||
logger.debug("No user found with email " + email + "!"); | ||
ValidationResults invalidEmail = new ValidationResults(); | ||
invalidEmail.addMessage(ValidationUtility.BUSINESS_MESSAGE_KEY, "login", "No user found with email " + email + "!"); | ||
return new ApiResponse(INVALID, invalidEmail); | ||
} | ||
|
||
if (!cryptoService.validatePassword(password, user.getPassword())) { | ||
logger.debug("Authentication failed!"); | ||
ValidationResults failedAuthenticationResults = new ValidationResults(); | ||
failedAuthenticationResults.addMessage(ValidationUtility.BUSINESS_MESSAGE_KEY, "login", "Authentication failed!"); | ||
return new ApiResponse(INVALID, failedAuthenticationResults); | ||
} | ||
|
||
try { | ||
Map<String, Object> claims = new HashMap<String, Object>(); | ||
claims.put("lastName", user.getLastName()); | ||
claims.put("firstName", user.getFirstName()); | ||
claims.put("username", user.getUsername()); | ||
claims.put("email", user.getEmail()); | ||
String subject = user.getEmail(); | ||
return new ApiResponse(SUCCESS, "Login successful", tokenService.createToken(subject, claims)); | ||
} catch (Exception e) { | ||
logger.debug("Unable to generate token!"); | ||
return new ApiResponse(ERROR, "Unable to generate token!"); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package edu.tamu.cap.model; | ||
|
||
public class EmailTemplate { | ||
|
||
private String name; | ||
|
||
private String subject; | ||
|
||
private String message; | ||
|
||
/** | ||
* Create a new EmailTemplate | ||
* | ||
* @param name | ||
* The new template's name. | ||
* @param subject | ||
* The new template's subject. | ||
* @param message | ||
* The new template's message | ||
*/ | ||
public EmailTemplate(String name, String subject, String message) { | ||
setName(name); | ||
setSubject(subject); | ||
setMessage(message); | ||
} | ||
|
||
/** | ||
* @return the name | ||
*/ | ||
public String getName() { | ||
return name; | ||
} | ||
|
||
/** | ||
* @param name | ||
* the name to set | ||
*/ | ||
public void setName(String name) { | ||
this.name = name; | ||
} | ||
|
||
/** | ||
* @return the subject | ||
*/ | ||
public String getSubject() { | ||
return subject; | ||
} | ||
|
||
/** | ||
* @param subject | ||
* the subject to set | ||
*/ | ||
public void setSubject(String subject) { | ||
this.subject = subject; | ||
} | ||
|
||
/** | ||
* @return the message | ||
*/ | ||
public String getMessage() { | ||
return message; | ||
} | ||
|
||
/** | ||
* @param message | ||
* the message to set | ||
*/ | ||
public void setMessage(String message) { | ||
this.message = message; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.