Merge branch 'email-username-login-feature' into 'dev'

Added email support to login

See merge request sa4-2020/the-sanmarinoes/backend!19
This commit is contained in:
Claudio Maggioni 2020-03-03 11:01:00 +01:00
commit c6d4a7e698
5 changed files with 39 additions and 28 deletions

View file

@ -4,6 +4,7 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.config.JWTTokenUtil;
import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.JWTRequest; import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.JWTRequest;
import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.JWTResponse; import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.JWTResponse;
import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.UserUpdateRequest; import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.UserUpdateRequest;
import ch.usi.inf.sa4.sanmarinoes.smarthut.error.UserNotFoundException;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*;
import io.swagger.annotations.Authorization; import io.swagger.annotations.Authorization;
import java.security.Principal; import java.security.Principal;
@ -35,8 +36,7 @@ public class AuthenticationController {
AuthenticationManager authenticationManager, AuthenticationManager authenticationManager,
UserRepository userRepository, UserRepository userRepository,
JWTTokenUtil jwtTokenUtil, JWTTokenUtil jwtTokenUtil,
JWTUserDetailsService userDetailsService, JWTUserDetailsService userDetailsService) {
UserRepository users) {
this.authenticationManager = authenticationManager; this.authenticationManager = authenticationManager;
this.userRepository = userRepository; this.userRepository = userRepository;
this.jwtTokenUtil = jwtTokenUtil; this.jwtTokenUtil = jwtTokenUtil;
@ -45,9 +45,25 @@ public class AuthenticationController {
@PostMapping("/login") @PostMapping("/login")
public JWTResponse login(@RequestBody JWTRequest authenticationRequest) throws Exception { public JWTResponse login(@RequestBody JWTRequest authenticationRequest) throws Exception {
authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword()); if (authenticationRequest.getUsernameOrEmail().contains("@")) {
// usernameOrEmail contains an email, so fetch the corresponding username
final User user =
userRepository.findByEmailIgnoreCase(
authenticationRequest.getUsernameOrEmail());
if (user == null) {
throw new UserNotFoundException();
}
authenticate(user.getUsername(), authenticationRequest.getPassword());
} else {
// usernameOrEmail contains a username, authenticate with that then
authenticate(
authenticationRequest.getUsernameOrEmail(),
authenticationRequest.getPassword());
}
final UserDetails userDetails = final UserDetails userDetails =
userDetailsService.loadUserByUsername(authenticationRequest.getUsername()); userDetailsService.loadUserByUsername(authenticationRequest.getUsernameOrEmail());
final String token = jwtTokenUtil.generateToken(userDetails); final String token = jwtTokenUtil.generateToken(userDetails);
return new JWTResponse(token); return new JWTResponse(token);
} }

View file

@ -1,15 +1,15 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.dto; package ch.usi.inf.sa4.sanmarinoes.smarthut.dto;
public class JWTRequest { public class JWTRequest {
private String username; private String usernameOrEmail;
private String password; private String password;
public String getUsername() { public String getUsernameOrEmail() {
return this.username; return this.usernameOrEmail;
} }
public void setUsername(String username) { public void setUsernameOrEmail(String usernameOrEmail) {
this.username = username; this.usernameOrEmail = usernameOrEmail;
} }
public String getPassword() { public String getPassword() {

View file

@ -12,6 +12,9 @@ public class UserRegistrationRequest {
/** The full name of the user */ /** The full name of the user */
@NotNull @NotNull
@NotEmpty(message = "Please provide a username") @NotEmpty(message = "Please provide a username")
@Pattern(
regexp = "[A-Za-z0-9_\\-]+",
message = "Username can contain only letters, numbers, '_' and '-'")
private String username; private String username;
/** A properly salted way to store the password */ /** A properly salted way to store the password */

View file

@ -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 UserNotFoundException extends Exception {
public UserNotFoundException() {
super("No user found with given email");
}
}

View file

@ -2,11 +2,6 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
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")
@ -19,25 +14,15 @@ public class User {
private Long id; private Long id;
/** The full name of the user */ /** The full name of the user */
@NotNull
@Column(nullable = false) @Column(nullable = false)
@NotEmpty(message = "Please provide a full name")
private String name; private String name;
/** The full name of the user */ /** The full name of the user */
@NotNull
@Column(nullable = false) @Column(nullable = false)
@NotEmpty(message = "Please provide a username")
private String username; private String username;
/** A properly salted way to store the password */ /** A properly salted way to store the password */
@NotNull
@Column(nullable = false) @Column(nullable = false)
@NotEmpty(message = "Please provide a password")
@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;
/** /**
@ -45,10 +30,6 @@ public class User {
* </code>, technically not RFC 5322 compliant * </code>, technically not RFC 5322 compliant
*/ */
@Column(nullable = false, unique = true) @Column(nullable = false, unique = true)
@NotNull
@NotEmpty(message = "Please provide an email")
@Email(message = "Please provide a valid email address")
@Pattern(regexp = ".+@.+\\..+", message = "Please provide a valid email address")
private String email; private String email;
@Column(nullable = false) @Column(nullable = false)