Skip to content

Commit

Permalink
Merge pull request #20 from CodeURJC-DAW-2022-23/feat/functional_logi…
Browse files Browse the repository at this point in the history
…n_register

Feat/functional login register
  • Loading branch information
franchescoURJC committed Feb 28, 2023
2 parents 09d164b + 66c4062 commit e5dc5dd
Show file tree
Hide file tree
Showing 24 changed files with 756 additions and 37 deletions.
4 changes: 4 additions & 0 deletions back/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,48 @@
package net.daw.alist.controllers;

import lombok.AllArgsConstructor;
import net.daw.alist.security.RegistrationRequest;
import net.daw.alist.services.RegistrationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.http.HttpResponse;
import java.util.Optional;

@AllArgsConstructor
@Controller
public class RegisterController {
@Autowired
private final RegistrationService registrationService;

@GetMapping("/register")
public String register() {
return "register";
}

@PostMapping("/register")
public String registerPost(Model model, RegistrationRequest request) {
String result = registrationService.register(request);
if (result.equals("Success")){
model.addAttribute("notVerified", true);
model.addAttribute("verifyMSG", "Please check your inbox to verify your email address");
return "/register";
} else{
model.addAttribute("error", true);
model.addAttribute("errorMSG", result);
return "/register";
}
}

@GetMapping("/registration/confirm")
public String confirm(@RequestParam("token") String token, HttpServletResponse httpResponse) throws IOException {
registrationService.confirmToken(token);
httpResponse.sendRedirect("/sign-in");
return "/sign-in";
}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package net.daw.alist.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Optional;

@Controller
public class SignInController {

@GetMapping("/sign-in")
public String signIn() {
public String login(Model model, @RequestParam Optional<String> error) {
error.ifPresent(e -> model.addAttribute("error", true));
return "sign-in";
}

Expand Down
82 changes: 71 additions & 11 deletions back/src/main/java/net/daw/alist/models/User.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
package net.daw.alist.models;

import java.sql.Blob;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.*;
import java.util.*;

import javax.persistence.*;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.EqualsAndHashCode;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

@EqualsAndHashCode
@Entity
public class User {
public class User implements UserDetails {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
Expand All @@ -20,7 +25,24 @@ public class User {
private String username;
private String password;
private String email;
private Boolean admin;
@Enumerated(EnumType.STRING)
private UserRole role;

private boolean enabled; //For email verification

private boolean locked; //For banning

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

public boolean isLocked() {
return locked;
}

public void setLocked(boolean locked) {
this.locked = locked;
}

@Lob
@JsonIgnore
Expand All @@ -45,13 +67,20 @@ public User(
String username,
String password,
String email,
Boolean admin
UserRole role
) {
this.date = new Date();
this.username = username;
this.password = password;
this.email = email;
this.admin = admin;
this.role = role;
enabled = false; //Change this if you want to turn off email verification
locked = false;
this.image = image;

if(role.equals(UserRole.ADMIN)){
enabled = true;
}
}

public void setUsername(String username) {
Expand All @@ -66,8 +95,8 @@ public void setEmail(String email) {
this.email = email;
}

public void setAdmin(Boolean admin) {
this.admin = admin;
public void setRole(UserRole role) {
this.role = role;
}

public void setImage(Blob imageFile, String image) {
Expand Down Expand Up @@ -95,10 +124,13 @@ public Date getDate() {
return date;
}

@Override
public String getUsername() {
return username;
}


@Override
public String getPassword() {
return password;
}
Expand All @@ -107,8 +139,8 @@ public String getEmail() {
return email;
}

public Boolean getAdmin() {
return admin;
public UserRole getRole() {
return role;
}

public Blob getImageFile() {
Expand All @@ -135,4 +167,32 @@ public List<Comment> getComments() {
return comments;
}

@Override
public boolean isAccountNonExpired() {
return true;
}

@Override
public boolean isAccountNonLocked() {
return !locked;
}

@Override
public boolean isCredentialsNonExpired() {
return true;
}

@Override
public boolean isEnabled() {
return enabled;
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
SimpleGrantedAuthority authority =
new SimpleGrantedAuthority("ROLE_" + role.name());
return Collections.singletonList(authority);
}


}
6 changes: 6 additions & 0 deletions back/src/main/java/net/daw/alist/models/UserRole.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package net.daw.alist.models;

public enum UserRole {
USER,
ADMIN
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package net.daw.alist.repositories;

import net.daw.alist.security.ConfirmationToken;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Optional;

@Repository
@Transactional(readOnly = true)
public interface ConfirmationTokenRepository
extends JpaRepository<ConfirmationToken, Long> {

Optional<ConfirmationToken> findByToken(String token);

@Transactional
@Modifying
@Query("UPDATE ConfirmationToken c " +
"SET c.confirmedAt = ?2 " +
"WHERE c.token = ?1")
int updateConfirmedAt(String token,
LocalDateTime confirmedAt);
}
16 changes: 16 additions & 0 deletions back/src/main/java/net/daw/alist/repositories/UserRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

import net.daw.alist.models.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import javax.transaction.Transactional;
import java.util.Optional;

@Repository
@Transactional
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
Optional<User> findByEmail(String email);

@Transactional
@Modifying
@Query("UPDATE User a " +
"SET a.enabled = TRUE WHERE a.email = ?1")
public int enableUser(String email);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package net.daw.alist.security;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CSRFHandlerConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CSRFHandlerInterceptor());
}
}

class CSRFHandlerInterceptor implements HandlerInterceptor {

@Override
public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler,
final ModelAndView modelAndView) throws Exception {

if (modelAndView != null) {
CsrfToken token = (CsrfToken) request.getAttribute("_csrf");
if (token != null) {
modelAndView.addObject("token", token.getToken());
}
}
}
}
56 changes: 56 additions & 0 deletions back/src/main/java/net/daw/alist/security/ConfirmationToken.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package net.daw.alist.security;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import net.daw.alist.models.User;

import javax.persistence.*;
import java.time.LocalDateTime;

@Getter
@Setter
@NoArgsConstructor
@Entity
public class ConfirmationToken {

@SequenceGenerator(
name = "confirmation_token_sequence",
sequenceName = "confirmation_token_sequence",
allocationSize = 1
)
@Id
@GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "confirmation_token_sequence"
)
private Long id;

@Column(nullable = false)
private String token;

@Column(nullable = false)
private LocalDateTime createdAt;

@Column(nullable = false)
private LocalDateTime expiresAt;

private LocalDateTime confirmedAt;

@ManyToOne
@JoinColumn(
nullable = false,
name = "app_user_id"
)
private User user;

public ConfirmationToken(String token,
LocalDateTime createdAt,
LocalDateTime expiresAt,
User appUser) {
this.token = token;
this.createdAt = createdAt;
this.expiresAt = expiresAt;
this.user = appUser;
}
}
Loading

0 comments on commit e5dc5dd

Please sign in to comment.