Skip to content

Commit

Permalink
Merge pull request #20 from TAMULib/email-users
Browse files Browse the repository at this point in the history
Implement User Email login/registration
  • Loading branch information
wwelling committed Mar 14, 2019
2 parents ab94d2a + 97023e1 commit b0b2750
Show file tree
Hide file tree
Showing 35 changed files with 933 additions and 238 deletions.
18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,31 @@
"ng-csv": "0.3.6",
"ng-file-upload": "12.2.13",
"ng-table": "3.0.1",
"weaver-ui-core": "git+https://github.com/TAMULib/Weaver-UI-Core.git#2.x"
"weaver-ui-core": "git+https://github.com/TAMULib/Weaver-UI-Core.git#v2.0.0"
},
"devDependencies": {
"grunt": "1.0.3",
"grunt-cli": "1.3.1",
"grunt-cli": "1.3.2",
"grunt-contrib-clean": "2.0.0",
"grunt-contrib-concat": "1.0.1",
"grunt-contrib-copy": "1.0.0",
"grunt-contrib-jshint": "1.1.0",
"grunt-contrib-jshint": "2.0.0",
"grunt-contrib-symlink": "1.0.0",
"grunt-contrib-uglify": "4.0.0",
"grunt-contrib-watch": "1.1.0",
"grunt-karma-coveralls": "2.5.4",
"grunt-ngdocs": "0.2.10",
"grunt-ngdocs": "0.2.11",
"grunt-usemin": "3.1.1",
"http-server": "0.10.0",
"jasmine-promise-matchers": "2.5.0",
"http-server": "0.11.1",
"jasmine-promise-matchers": "2.6.0",
"jshint-stylish": "2.2.1",
"karma": "3.0.0",
"karma": "3.1.4",
"karma-coverage": "1.1.2",
"karma-chrome-launcher": "2.2.0",
"karma-firefox-launcher": "1.1",
"karma-jasmine": "1.1.2",
"karma-jasmine": "2.0.1",
"karma-junit-reporter": "1.2.0",
"karma-ng-html2js-preprocessor": "1.0.0",
"protractor": "5.4.1"
"protractor": "5.4.2"
}
}
44 changes: 25 additions & 19 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@

<groupId>edu.tamu</groupId>
<artifactId>sage</artifactId>
<version>0.0.1-SNAPSHOT</version>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>

<name>Sage</name>
<description>Weaver Solr Aggregation Engine</description>

<parent>
<groupId>edu.tamu.framework</groupId>
<artifactId>weaver-webservice-parent</artifactId>
<version>2.0.0-SNAPSHOT</version>
<groupId>edu.tamu.weaver</groupId>
<artifactId>webservice-parent</artifactId>
<version>2.0.0</version>
</parent>

<properties>
Expand All @@ -29,33 +29,39 @@
<dependencies>

<dependency>
<groupId>edu.tamu.framework</groupId>
<artifactId>weaver-auth</artifactId>
<version>2.0.0-SNAPSHOT</version>
<groupId>edu.tamu.weaver</groupId>
<artifactId>auth</artifactId>
<version>2.0.0</version>
</dependency>

<dependency>
<groupId>edu.tamu.framework</groupId>
<artifactId>weaver-token-provider</artifactId>
<version>2.0.0-SNAPSHOT</version>
<groupId>edu.tamu.weaver</groupId>
<artifactId>token-provider</artifactId>
<version>2.0.0</version>
</dependency>

<dependency>
<groupId>edu.tamu.framework</groupId>
<artifactId>weaver-validation</artifactId>
<version>2.0.0-SNAPSHOT</version>
<groupId>edu.tamu.weaver</groupId>
<artifactId>validation</artifactId>
<version>2.0.0</version>
</dependency>

<dependency>
<groupId>edu.tamu.framework</groupId>
<artifactId>weaver-wro</artifactId>
<version>2.0.0-SNAPSHOT</version>
<groupId>edu.tamu.weaver</groupId>
<artifactId>wro</artifactId>
<version>2.0.0</version>
</dependency>

<dependency>
<groupId>edu.tamu.framework</groupId>
<artifactId>weaver-reporting</artifactId>
<version>2.0.0-SNAPSHOT</version>
<groupId>edu.tamu.weaver</groupId>
<artifactId>reporting</artifactId>
<version>2.0.0</version>
</dependency>

<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>

<dependency>
Expand Down
19 changes: 0 additions & 19 deletions src/main/java/edu/tamu/app/auth/service/UserDetailsService.java

This file was deleted.

182 changes: 182 additions & 0 deletions src/main/java/edu/tamu/sage/auth/controller/AuthController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package edu.tamu.sage.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.sage.auth.service.AppUserCredentialsService;
import edu.tamu.sage.model.EmailTemplate;
import edu.tamu.sage.model.User;
import edu.tamu.sage.model.repo.UserRepo;
import edu.tamu.sage.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;

@Override
@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);
}

@Override
@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!");
}
}

}

0 comments on commit b0b2750

Please sign in to comment.