Email Verifcation Works
This commit is contained in:
parent
990f1bd6d4
commit
2271f4a5b9
10 changed files with 106 additions and 20 deletions
|
@ -17,6 +17,7 @@ dependencies {
|
||||||
implementation 'org.springframework.boot:spring-boot-starter'
|
implementation 'org.springframework.boot:spring-boot-starter'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||||
|
implementation 'org.springframework.boot:spring-boot-starter-mail'
|
||||||
implementation 'io.jsonwebtoken:jjwt:0.9.1'
|
implementation 'io.jsonwebtoken:jjwt:0.9.1'
|
||||||
implementation 'org.springframework.security:spring-security-web'
|
implementation 'org.springframework.security:spring-security-web'
|
||||||
implementation 'org.postgresql:postgresql'
|
implementation 'org.postgresql:postgresql'
|
||||||
|
|
|
@ -54,6 +54,10 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
.permitAll()
|
.permitAll()
|
||||||
.antMatchers("/auth/register")
|
.antMatchers("/auth/register")
|
||||||
.permitAll()
|
.permitAll()
|
||||||
|
.antMatchers("/register")
|
||||||
|
.permitAll()
|
||||||
|
.antMatchers("/register/confirm-account")
|
||||||
|
.permitAll()
|
||||||
.
|
.
|
||||||
// all other requests need to be authenticated
|
// all other requests need to be authenticated
|
||||||
anyRequest()
|
anyRequest()
|
||||||
|
|
|
@ -42,13 +42,6 @@ public class AuthenticationController {
|
||||||
return new JWTResponse(token);
|
return new JWTResponse(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/register")
|
|
||||||
public User register(@Valid @RequestBody User user) {
|
|
||||||
user.setPassword(encoder.encode(user.getPassword()));
|
|
||||||
users.save(user);
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
@PatchMapping("/update")
|
@PatchMapping("/update")
|
||||||
public User update(@Valid @RequestBody final UserUpdateRequest u, final Principal principal) {
|
public User update(@Valid @RequestBody final UserUpdateRequest u, final Principal principal) {
|
||||||
final User oldUser = userRepository.findByUsername(principal.getName());
|
final User oldUser = userRepository.findByUsername(principal.getName());
|
||||||
|
|
|
@ -1,16 +1,24 @@
|
||||||
package ch.usi.inf.sa4.sanmarinoes.smarthut.controller;
|
package ch.usi.inf.sa4.sanmarinoes.smarthut.controller;
|
||||||
|
|
||||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.Service.EmailSenderService;
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.Service.EmailSenderService;
|
||||||
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.OkResponse;
|
||||||
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.error.DuplicateEmailRegistrationException;
|
||||||
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.error.EmailTokenNotFoundException;
|
||||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ConfirmationToken;
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ConfirmationToken;
|
||||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ConfirmationTokenRepository;
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ConfirmationTokenRepository;
|
||||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.User;
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.User;
|
||||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.UserRepository;
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.UserRepository;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.mail.SimpleMailMessage;
|
import org.springframework.mail.SimpleMailMessage;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
@ -25,6 +33,8 @@ public class UserAccountController {
|
||||||
|
|
||||||
@Autowired private EmailSenderService emailSenderService;
|
@Autowired private EmailSenderService emailSenderService;
|
||||||
|
|
||||||
|
@Autowired private BCryptPasswordEncoder encoder;
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public ModelAndView displayRegistration(ModelAndView modelAndView, User user) {
|
public ModelAndView displayRegistration(ModelAndView modelAndView, User user) {
|
||||||
modelAndView.addObject("user", user);
|
modelAndView.addObject("user", user);
|
||||||
|
@ -33,14 +43,17 @@ public class UserAccountController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public ModelAndView registerUser(ModelAndView modelAndView, User user) {
|
public OkResponse registerUser(@Valid @RequestBody User user)
|
||||||
|
throws DuplicateEmailRegistrationException {
|
||||||
|
System.out.println(user);
|
||||||
User existingUser = userRepository.findByEmailIgnoreCase(user.getEmail());
|
User existingUser = userRepository.findByEmailIgnoreCase(user.getEmail());
|
||||||
|
|
||||||
// Check if an User with the same email already exists
|
// Check if an User with the same email already exists
|
||||||
if (existingUser != null) {
|
if (existingUser != null) {
|
||||||
modelAndView.addObject("message", "This email already exists!");
|
throw new DuplicateEmailRegistrationException();
|
||||||
modelAndView.setViewName("error");
|
|
||||||
} else {
|
} else {
|
||||||
|
// encode user's password
|
||||||
|
user.setPassword(encoder.encode(user.getPassword()));
|
||||||
userRepository.save(user);
|
userRepository.save(user);
|
||||||
|
|
||||||
ConfirmationToken confirmationToken = new ConfirmationToken(user);
|
ConfirmationToken confirmationToken = new ConfirmationToken(user);
|
||||||
|
@ -53,16 +66,28 @@ public class UserAccountController {
|
||||||
mailMessage.setFrom("smarthut.sm@gmail.com");
|
mailMessage.setFrom("smarthut.sm@gmail.com");
|
||||||
mailMessage.setText(
|
mailMessage.setText(
|
||||||
"To confirm your account, please click here : "
|
"To confirm your account, please click here : "
|
||||||
+ "http://localhost:8082/confirm-account?token="
|
+ "http://localhost:8080/register/confirm-account?token="
|
||||||
+ confirmationToken.getConfirmationToken());
|
+ confirmationToken.getConfirmationToken());
|
||||||
|
|
||||||
emailSenderService.sendEmail(mailMessage);
|
emailSenderService.sendEmail(mailMessage);
|
||||||
|
|
||||||
modelAndView.addObject("emailId", user.getEmail());
|
return new OkResponse();
|
||||||
|
|
||||||
modelAndView.setViewName("successfulRegisteration");
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return modelAndView;
|
@GetMapping(value = "/confirm-account")
|
||||||
|
public OkResponse confirmUserAccount(@RequestParam("token") @NotNull String confirmationToken)
|
||||||
|
throws EmailTokenNotFoundException {
|
||||||
|
final ConfirmationToken token =
|
||||||
|
confirmationTokenRepository.findByConfirmationToken(confirmationToken);
|
||||||
|
|
||||||
|
if (token != null) {
|
||||||
|
final User user = userRepository.findByEmailIgnoreCase(token.getUser().getEmail());
|
||||||
|
user.setEnabled(true);
|
||||||
|
userRepository.save(user);
|
||||||
|
return new OkResponse();
|
||||||
|
} else {
|
||||||
|
throw new EmailTokenNotFoundException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package ch.usi.inf.sa4.sanmarinoes.smarthut.dto;
|
||||||
|
|
||||||
|
/** A dummy DTO to return when there is no data to return */
|
||||||
|
public class OkResponse {
|
||||||
|
private boolean success = true;
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package ch.usi.inf.sa4.sanmarinoes.smarthut.error;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
|
||||||
|
@ResponseStatus(code = HttpStatus.BAD_REQUEST)
|
||||||
|
public class DuplicateEmailRegistrationException extends Exception {
|
||||||
|
public DuplicateEmailRegistrationException() {
|
||||||
|
super("Email already belonging to another user");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package ch.usi.inf.sa4.sanmarinoes.smarthut.error;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
|
||||||
|
@ResponseStatus(code = HttpStatus.BAD_REQUEST)
|
||||||
|
public class EmailTokenNotFoundException extends Exception {
|
||||||
|
public EmailTokenNotFoundException() {
|
||||||
|
super("Email verification token not found in DB");
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,6 +37,9 @@ public class ConfirmationToken {
|
||||||
confirmationToken = UUID.randomUUID().toString();
|
confirmationToken = UUID.randomUUID().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Constructor for hibernate reflective stuff things whatever */
|
||||||
|
public ConfirmationToken() {}
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import javax.validation.constraints.Email;
|
import javax.validation.constraints.Email;
|
||||||
import javax.validation.constraints.Min;
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import javax.validation.constraints.Pattern;
|
import javax.validation.constraints.Pattern;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
/** A user of the Smarthut application */
|
/** A user of the Smarthut application */
|
||||||
@Entity(name = "smarthutuser")
|
@Entity(name = "smarthutuser")
|
||||||
|
@ -33,7 +33,10 @@ public class User {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
@NotEmpty(message = "Please provide a password")
|
@NotEmpty(message = "Please provide a password")
|
||||||
@Min(value = 6, message = "Your password should be at least 6 characters long")
|
@Size(
|
||||||
|
min = 6,
|
||||||
|
max = 255,
|
||||||
|
message = "Your password should be at least 6 characters long and up to 255 chars long")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,6 +54,9 @@ public class User {
|
||||||
@OneToMany(mappedBy = "user")
|
@OneToMany(mappedBy = "user")
|
||||||
private Set<Room> rooms;
|
private Set<Room> rooms;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private Boolean isEnabled = false;
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -95,6 +101,14 @@ public class User {
|
||||||
return rooms;
|
return rooms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean getEnabled() {
|
||||||
|
return isEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(Boolean enabled) {
|
||||||
|
isEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "User{"
|
return "User{"
|
||||||
|
@ -103,11 +117,17 @@ public class User {
|
||||||
+ ", name='"
|
+ ", name='"
|
||||||
+ name
|
+ name
|
||||||
+ '\''
|
+ '\''
|
||||||
|
+ ", username='"
|
||||||
|
+ username
|
||||||
|
+ '\''
|
||||||
+ ", password='"
|
+ ", password='"
|
||||||
+ password
|
+ password
|
||||||
+ '\''
|
+ '\''
|
||||||
+ ", email='"
|
+ ", email='"
|
||||||
+ email
|
+ email
|
||||||
+ "\'}";
|
+ '\''
|
||||||
|
+ ", isEnabled="
|
||||||
|
+ isEnabled
|
||||||
|
+ '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,3 +11,15 @@ spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.Im
|
||||||
spring.jpa.properties.hibernate.format_sql=true
|
spring.jpa.properties.hibernate.format_sql=true
|
||||||
|
|
||||||
jwt.secret=thiskeymustbeverylongorthethingcomplainssoiamjustgoingtowritehereabunchofgarbageciaomamma
|
jwt.secret=thiskeymustbeverylongorthethingcomplainssoiamjustgoingtowritehereabunchofgarbageciaomamma
|
||||||
|
|
||||||
|
spring.mail.test-connection=true
|
||||||
|
spring.mail.host=smtp.gmail.com
|
||||||
|
spring.mail.port=587
|
||||||
|
spring.mail.properties.mail.smtp.starttls.enable=true
|
||||||
|
spring.mail.username=smarthut.sm@gmail.com
|
||||||
|
spring.mail.password=dcadvbagqfkwbfts
|
||||||
|
spring.mail.properties.mail.smtp.starttls.required=true
|
||||||
|
spring.mail.properties.mail.smtp.auth=true
|
||||||
|
spring.mail.properties.mail.smtp.connectiontimeout=5000
|
||||||
|
spring.mail.properties.mail.smtp.timeout=5000
|
||||||
|
spring.mail.properties.mail.smtp.writetimeout=5000
|
Loading…
Reference in a new issue