From 7222bca6e26f2fea35745f01614f5e843e2ba2e4 Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Wed, 6 Mar 2024 17:30:13 +0100 Subject: [PATCH 01/14] added spring boot security without the login page --- backend/build.gradle.kts | 1 + backend/src/main/java/ovh/herisson/Clyde/ClydeApplication.java | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index eabd3e3..59826c5 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -21,6 +21,7 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-mail") implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-data-jpa") + implementation("org.springframework.boot:spring-boot-starter-security") // implementation("org.springframework.session:spring-session-jdbc") developmentOnly("org.springframework.boot:spring-boot-devtools") developmentOnly("org.springframework.boot:spring-boot-docker-compose") diff --git a/backend/src/main/java/ovh/herisson/Clyde/ClydeApplication.java b/backend/src/main/java/ovh/herisson/Clyde/ClydeApplication.java index aa2882d..364eba7 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/ClydeApplication.java +++ b/backend/src/main/java/ovh/herisson/Clyde/ClydeApplication.java @@ -2,8 +2,9 @@ package ovh.herisson.Clyde; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -@SpringBootApplication +@SpringBootApplication(exclude = { SecurityAutoConfiguration.class }) public class ClydeApplication { public static void main(String[] args) { From 6a39464f615a0eb90cef4879022eba60c79236db Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Wed, 6 Mar 2024 17:34:18 +0100 Subject: [PATCH 02/14] /bin/bash: line 1: q: command not found --- .../ovh/herisson/Clyde/Repositories/TokenRepository.java | 7 +++++++ .../ovh/herisson/Clyde/Repositories/UserRepository.java | 2 ++ 2 files changed, 9 insertions(+) create mode 100644 backend/src/main/java/ovh/herisson/Clyde/Repositories/TokenRepository.java diff --git a/backend/src/main/java/ovh/herisson/Clyde/Repositories/TokenRepository.java b/backend/src/main/java/ovh/herisson/Clyde/Repositories/TokenRepository.java new file mode 100644 index 0000000..2fad5f0 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Repositories/TokenRepository.java @@ -0,0 +1,7 @@ +package ovh.herisson.Clyde.Repositories; + +import org.springframework.data.repository.CrudRepository; +import ovh.herisson.Clyde.Tables.Token; + +public interface TokenRepository extends CrudRepository { +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/Repositories/UserRepository.java b/backend/src/main/java/ovh/herisson/Clyde/Repositories/UserRepository.java index 38f9ae0..af2bd08 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Repositories/UserRepository.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Repositories/UserRepository.java @@ -10,6 +10,8 @@ public interface UserRepository extends CrudRepository { User findById(long id); + User findByEmail(String email); + /** @Query(value = "select a.* from Users a ",nativeQuery = true) Iterable findAllUsers();**/ From 010f9200a76180443b130c8c0b217178d810bf47 Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Wed, 6 Mar 2024 17:35:27 +0100 Subject: [PATCH 03/14] removed useless line --- .../main/java/ovh/herisson/Clyde/EndPoints/UserController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java index affb301..03087a1 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java @@ -2,7 +2,7 @@ package ovh.herisson.Clyde.EndPoints; import org.springframework.http.HttpStatus; -import org.springframework.http.HttpStatusCode; + import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import ovh.herisson.Clyde.Repositories.UserRepository; From b050a74b75c41b1bacdebc491285f354066bcbcc Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Wed, 6 Mar 2024 17:35:49 +0100 Subject: [PATCH 04/14] added LoginController Post(/login) --- .../Clyde/EndPoints/LoginController.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 backend/src/main/java/ovh/herisson/Clyde/EndPoints/LoginController.java diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/LoginController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/LoginController.java new file mode 100644 index 0000000..863daa9 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/LoginController.java @@ -0,0 +1,45 @@ +package ovh.herisson.Clyde.EndPoints; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import ovh.herisson.Clyde.Services.TokenService; +import ovh.herisson.Clyde.Services.UserService; +import ovh.herisson.Clyde.Tables.User; + +import java.util.Date; + +@RestController +@CrossOrigin(origins = "http://localhost:5173") +public class LoginController { + private final UserService userService; + private final TokenService tokenService; + + public LoginController(UserService userService, TokenService tokenService){ + this.userService =userService; + this.tokenService = tokenService; + } + @PostMapping("/login") + public ResponseEntity login(@RequestParam String identifier, String password, Date expirationDate){ + + User user = userService.getUser(identifier); + if (user == null){ + return new ResponseEntity("wrong ID or Email", HttpStatus.BAD_REQUEST); + } + + if (!userService.checkPassword(user,password)){ + return new ResponseEntity("wrong Password",HttpStatus.BAD_REQUEST); + } + + String token = tokenService.generateNewToken(); + + + tokenService.saveToken(token,user,expirationDate); + + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.set("Set-Cookie",String.format("session_token=%s",token)); + return ResponseEntity.ok().headers(responseHeaders).build(); + } +} + + From 5acca4d10d0e4de04c7be8b1b355a9e5ebf30401 Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Wed, 6 Mar 2024 17:37:06 +0100 Subject: [PATCH 05/14] added foreign key to user --- .../java/ovh/herisson/Clyde/Tables/Token.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/Token.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/Token.java index ec59cbf..5b61cb9 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/Token.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/Token.java @@ -8,12 +8,13 @@ public class Token { @Id private int id; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name ="Users") - private int regNo; + private User user; private String token; - public Token(int regNo, String token){ - this.regNo = regNo; + public Token(User user, String token){ + this.user = user; this.token = token; } @@ -21,13 +22,12 @@ public class Token { public int getId() { return id; } - - public int getRegNo() { - return regNo; + public User getUser() { + return user; } - public void setRegNo(int regNo) { - this.regNo = regNo; + public void setUser(User regNo) { + this.user = regNo; } public String getToken(){ From 37d24c59e79675c45000100a6e6f294ad5f587b0 Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Wed, 6 Mar 2024 17:37:38 +0100 Subject: [PATCH 06/14] add generic HttpResponse --- .../Clyde/Responses/UnauthorizedResponse.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 backend/src/main/java/ovh/herisson/Clyde/Responses/UnauthorizedResponse.java diff --git a/backend/src/main/java/ovh/herisson/Clyde/Responses/UnauthorizedResponse.java b/backend/src/main/java/ovh/herisson/Clyde/Responses/UnauthorizedResponse.java new file mode 100644 index 0000000..154ecd8 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Responses/UnauthorizedResponse.java @@ -0,0 +1,12 @@ +package ovh.herisson.Clyde.Responses; + + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + + +public class UnauthorizedResponse extends ResponseEntity { + public UnauthorizedResponse(String message) { + super(message,HttpStatus.UNAUTHORIZED); + } +} From 4a85a55290b8a87bb8bad1e9f3c6fd1c620b4dc9 Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Wed, 6 Mar 2024 17:38:09 +0100 Subject: [PATCH 07/14] added Token and User Services --- .../herisson/Clyde/Services/TokenService.java | 36 +++++++++++++++++++ .../herisson/Clyde/Services/UserService.java | 36 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 backend/src/main/java/ovh/herisson/Clyde/Services/TokenService.java create mode 100644 backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/TokenService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/TokenService.java new file mode 100644 index 0000000..b427735 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/TokenService.java @@ -0,0 +1,36 @@ +package ovh.herisson.Clyde.Services; + +import org.springframework.stereotype.Service; +import ovh.herisson.Clyde.Repositories.TokenRepository; +import ovh.herisson.Clyde.Tables.Token; +import ovh.herisson.Clyde.Tables.User; + +import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; +import java.util.Date; + +@Service +public class TokenService { + + TokenRepository tokenRepo; + + public TokenService(TokenRepository tokenRepo){ + this.tokenRepo = tokenRepo; + } + + + public String generateNewToken(){ + byte[] bytes = new byte[64]; + new SecureRandom().nextBytes(bytes); + String token = new String(bytes, StandardCharsets.US_ASCII); + System.out.println(token); + return token; + } + + + //todo potentiellement return bool pour savoir si token bien add + public void saveToken(String token, User user, Date expirationDate){ + tokenRepo.save(new Token(user,token)); + } + +} \ No newline at end of file diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java new file mode 100644 index 0000000..b2c080d --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java @@ -0,0 +1,36 @@ +package ovh.herisson.Clyde.Services; + +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Service; +import ovh.herisson.Clyde.Repositories.UserRepository; +import ovh.herisson.Clyde.Tables.User; + +@Service +public class UserService { + + private final UserRepository userRepo; + private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + + + public UserService(UserRepository userRepo){ + this.userRepo = userRepo; + } + + + public User getUser(String identifier){ + if (identifier == null) return null; + try { + int id = Integer.parseInt(identifier); + return userRepo.findById(id); + } + catch (NumberFormatException nfe){ + return userRepo.findByEmail(identifier); + } + } + + + public boolean checkPassword(User user, String tryingPassword){ + return passwordEncoder.matches(tryingPassword, user.getPassword()); + } + +} From 434cc8dd2bf6e5398421e65dc3ad51c61e28ae9d Mon Sep 17 00:00:00 2001 From: LeoMoulin Date: Wed, 6 Mar 2024 20:05:24 +0100 Subject: [PATCH 08/14] - On objectise tout - Ajout des relation --- .../herisson/Clyde/Tables/CursusCourse.java | 28 +++++++++-------- .../ovh/herisson/Clyde/Tables/Secretary.java | 15 +++++----- .../Clyde/Tables/TeacherGivenCourse.java | 29 ++++++++++-------- .../ovh/herisson/Clyde/Tables/UserCursus.java | 30 +++++++++++-------- 4 files changed, 56 insertions(+), 46 deletions(-) diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/CursusCourse.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/CursusCourse.java index e48e6a3..ecdd857 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/CursusCourse.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/CursusCourse.java @@ -8,15 +8,17 @@ public class CursusCourse { @GeneratedValue(strategy = GenerationType.AUTO) private int id; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "Cursus") - private int cursusId; + private Cursus cursus; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "Course") - private int courseId; + private Course course; - public CursusCourse(int cursusId, int courseId){ - this.cursusId = cursusId; - this.courseId = courseId; + public CursusCourse(Cursus cursus, Course course){ + this.cursus = cursus; + this.course = course; } public CursusCourse() {} @@ -25,19 +27,19 @@ public class CursusCourse { return id; } - public int getCourseId() { - return courseId; + public Course getCourse() { + return course; } - public void setCourseId(int courseId){ - this.courseId = courseId; + public void setCourse(Course course){ + this.course = course; } - public int getCursusId() { - return cursusId; + public Cursus getCursus() { + return cursus; } - public void setCursusId(int cursusId) { - this.cursusId = cursusId; + public void setCursus(Cursus cursus) { + this.cursus = cursus; } } diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/Secretary.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/Secretary.java index cf533a0..cc34841 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/Secretary.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/Secretary.java @@ -8,12 +8,13 @@ public class Secretary { @GeneratedValue(strategy = GenerationType.AUTO) private int id; + @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "Users") - private int regNo; + private User user; private String faculty; - public Secretary(int regNo, String faculty){ - this.regNo = regNo; + public Secretary(User user, String faculty){ + this.user = user; this.faculty = faculty; } @@ -23,12 +24,12 @@ public class Secretary { return id; } - public int getRegNo() { - return regNo; + public User getUser() { + return user; } - public void setRegNo(int regNo) { - this.regNo = regNo; + public void setUser(User user) { + this.user = user; } public String getFaculty() { diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/TeacherGivenCourse.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/TeacherGivenCourse.java index 9cb931e..a1ee138 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/TeacherGivenCourse.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/TeacherGivenCourse.java @@ -8,18 +8,21 @@ public class TeacherGivenCourse { @GeneratedValue(strategy = GenerationType.AUTO) private int id; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "Users") - private int regNo; + private User user; + + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "Course") - private int courseId; + private Course course; //This flag helps make the difference between an assistant or a Teacher (who owns the course) private boolean owned; - public TeacherGivenCourse(int regNo, int courseId, boolean owned){ - this.regNo = regNo; - this.courseId = courseId; + public TeacherGivenCourse(User user, Course course, boolean owned){ + this.user = user; + this.course = course; this.owned = owned; } @@ -29,20 +32,20 @@ public class TeacherGivenCourse { return id; } - public int getRegNo() { - return regNo; + public User getUser() { + return user; } - public void setRegNo(int regNo) { - this.regNo = regNo; + public void setUser(User user) { + this.user = user; } - public int getCourseId() { - return courseId; + public Course getCourse() { + return course; } - public void setCourseId(int courseId) { - this.courseId = courseId; + public void setCourse(Course course) { + this.course = course; } public boolean isOwned() { diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/UserCursus.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/UserCursus.java index 4de1559..a5c5153 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/UserCursus.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/UserCursus.java @@ -7,15 +7,19 @@ public class UserCursus { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; + + //Un étudiant peut avoir plusieurs cursus + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "Users") - private int regNo; + private User user; + @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "Cursus") - private int cursusId; + private Cursus cursus; - public UserCursus(int regNo, int cursusId){ - this.regNo = regNo; - this.cursusId = cursusId; + public UserCursus(User user, Cursus cursus){ + this.user = user; + this.cursus = cursus; } public UserCursus() {} @@ -24,19 +28,19 @@ public class UserCursus { return id; } - public int getRegNo() { - return regNo; + public User getUser() { + return user; } - public void setRegNo(int regNo) { - this.regNo = regNo; + public void setUser(User user) { + this.user = user; } - public int getCursusId() { - return cursusId; + public Cursus getCursus() { + return cursus; } - public void setCursusId(int cursusId) { - this.cursusId = cursusId; + public void setCursus(Cursus cursus) { + this.cursus = cursus; } } From 2938707f0f85ce2c83cff287282287cde48531b0 Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Thu, 7 Mar 2024 00:55:07 +0100 Subject: [PATCH 09/14] added mocks users with their role as password and token --- .../Clyde/EndPoints/LoginController.java | 1 + .../Clyde/EndPoints/UserController.java | 29 +++++++++----- .../Clyde/Repositories/TokenRepository.java | 3 ++ .../Clyde/Responses/UnauthorizedResponse.java | 4 +- .../herisson/Clyde/Services/TokenService.java | 15 +++++++ .../herisson/Clyde/Services/UserService.java | 39 ++++++++++++++++++- 6 files changed, 77 insertions(+), 14 deletions(-) diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/LoginController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/LoginController.java index 863daa9..83d2f4f 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/LoginController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/LoginController.java @@ -18,6 +18,7 @@ public class LoginController { public LoginController(UserService userService, TokenService tokenService){ this.userService =userService; this.tokenService = tokenService; + } @PostMapping("/login") public ResponseEntity login(@RequestParam String identifier, String password, Date expirationDate){ diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java index 03087a1..47805d6 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java @@ -6,6 +6,9 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import ovh.herisson.Clyde.Repositories.UserRepository; +import ovh.herisson.Clyde.Responses.UnauthorizedResponse; +import ovh.herisson.Clyde.Services.TokenService; +import ovh.herisson.Clyde.Services.UserService; import ovh.herisson.Clyde.Tables.User; @@ -13,30 +16,36 @@ import ovh.herisson.Clyde.Tables.User; @CrossOrigin(origins = "http://localhost:5173") public class UserController { - private final UserRepository userRepo; + private final UserService userService; - public UserController(UserRepository userRepo){ - this.userRepo = userRepo; + private final TokenService tokenService; + public UserController(UserService userService, TokenService tokenService){ + this.userService =userService; + this.tokenService = tokenService; // todo find a way to be clearer + + tokenService.postMockToken(userService.postMockUsers());// todo find a better place to put that } @GetMapping("/user") public ResponseEntity getUsers(@RequestHeader("Authorization") String token){ - //TODO - // Get the token thru the data base - // tokenRepo.findToken(token) => User userFromToken - // si role != secretary => return error : ResponseEntity(null, HttpStatus.UNAUTHORIZED) - return new ResponseEntity(/**userRepo.findById(userFromToken.id),**/ HttpStatus.OK); + + User user = tokenService.getUserFromToken(token); + + if (user == null) { + return new UnauthorizedResponse(null); + } + return new ResponseEntity(user, HttpStatus.OK); } @PostMapping("/user") public ResponseEntity postUser(@RequestBody User user){ - userRepo.save(user); + userService.save(user); return new ResponseEntity(String.format("Account created with ID:%s",user.getRegNo()),HttpStatus.CREATED); } @GetMapping("/users") public Iterable getAllUsers(){//TODO ne l'accepter que si c'est le secrétariat - return userRepo.findAll(); + return userService.getAll(); } diff --git a/backend/src/main/java/ovh/herisson/Clyde/Repositories/TokenRepository.java b/backend/src/main/java/ovh/herisson/Clyde/Repositories/TokenRepository.java index 2fad5f0..719f11e 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Repositories/TokenRepository.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Repositories/TokenRepository.java @@ -2,6 +2,9 @@ package ovh.herisson.Clyde.Repositories; import org.springframework.data.repository.CrudRepository; import ovh.herisson.Clyde.Tables.Token; +import ovh.herisson.Clyde.Tables.User; public interface TokenRepository extends CrudRepository { + + Token getByToken(String token); } diff --git a/backend/src/main/java/ovh/herisson/Clyde/Responses/UnauthorizedResponse.java b/backend/src/main/java/ovh/herisson/Clyde/Responses/UnauthorizedResponse.java index 154ecd8..305dd4d 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Responses/UnauthorizedResponse.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Responses/UnauthorizedResponse.java @@ -5,8 +5,8 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -public class UnauthorizedResponse extends ResponseEntity { - public UnauthorizedResponse(String message) { +public class UnauthorizedResponse extends ResponseEntity { + public UnauthorizedResponse(T message) { super(message,HttpStatus.UNAUTHORIZED); } } diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/TokenService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/TokenService.java index b427735..5057007 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Services/TokenService.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/TokenService.java @@ -33,4 +33,19 @@ public class TokenService { tokenRepo.save(new Token(user,token)); } + public User getUserFromToken(String token){ + return tokenRepo.getByToken(token).getUser(); + } + + /** Take the list of mock user to save them in the Token DB + * With token being the password of the user (also his role) + * @param users an + */ + public void postMockToken(Iterable users){ + for (User user: users){ + tokenRepo.save(new Token(user,user.getPassword())); + } + } + + } \ No newline at end of file diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java index b2c080d..0482c28 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java @@ -3,15 +3,21 @@ package ovh.herisson.Clyde.Services; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import ovh.herisson.Clyde.Repositories.UserRepository; +import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.User; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + @Service public class UserService { private final UserRepository userRepo; private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); - public UserService(UserRepository userRepo){ this.userRepo = userRepo; } @@ -33,4 +39,33 @@ public class UserService { return passwordEncoder.matches(tryingPassword, user.getPassword()); } -} + /** Saves an example of : + * an Admin with id 1, email : admin@admin.com and password: admin + * a Student with id 2, email: student@student.com and password: student (no cursus yet) + * a Secretary with id 3, email: secretary@secretary.com and password: secretary + * a Teacher (same) + * and they all have silly names (hihi) + */ + public Iterable postMockUsers(){ + User herobrine = new User("brine","hero","admin@admin.com","in your WalLs","ShadowsLand",new Date(0), Role.Admin,passwordEncoder.encode("admin")); + User Joe = new User("Mama","Joe","student@student.com","roundabout","DaWarudo",new Date(0), Role.Student,passwordEncoder.encode("student")); + User Meh = new User("Inspiration","lackOf","secretary@secretary.com","a Box","the street",new Date(0), Role.Teacher,passwordEncoder.encode("secretary")); + User joke = new User("CthemBalls","Lemme","teacher@teacher.com","lab","faculty",new Date(0), Role.Teacher,passwordEncoder.encode("teacher")); + + userRepo.save(herobrine); + userRepo.save(Joe); + userRepo.save(Meh); + userRepo.save(joke); + + return new ArrayList(Arrays.asList(herobrine,Joe,Meh,joke)); + } + + public void save(User user){ + userRepo.save(user); + } + + public Iterable getAll(){ + return userRepo.findAll(); + } + +} \ No newline at end of file From 8b35b3dc014e8ae61f71b06a508241505b0c3db6 Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Thu, 7 Mar 2024 17:01:50 +0100 Subject: [PATCH 10/14] cleaned the login process --- .../Clyde/EndPoints/LoginController.java | 33 +++++-------------- .../Clyde/Services/AuthenticatorService.java | 32 ++++++++++++++++++ 2 files changed, 41 insertions(+), 24 deletions(-) create mode 100644 backend/src/main/java/ovh/herisson/Clyde/Services/AuthenticatorService.java diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/LoginController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/LoginController.java index 83d2f4f..d47885f 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/LoginController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/LoginController.java @@ -1,44 +1,29 @@ package ovh.herisson.Clyde.EndPoints; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import ovh.herisson.Clyde.Services.TokenService; -import ovh.herisson.Clyde.Services.UserService; -import ovh.herisson.Clyde.Tables.User; +import ovh.herisson.Clyde.Responses.UnauthorizedResponse; +import ovh.herisson.Clyde.Services.AuthenticatorService; import java.util.Date; @RestController @CrossOrigin(origins = "http://localhost:5173") public class LoginController { - private final UserService userService; - private final TokenService tokenService; - - public LoginController(UserService userService, TokenService tokenService){ - this.userService =userService; - this.tokenService = tokenService; - + private final AuthenticatorService authServ; + public LoginController(AuthenticatorService authServ){ + this.authServ = authServ; } @PostMapping("/login") public ResponseEntity login(@RequestParam String identifier, String password, Date expirationDate){ - User user = userService.getUser(identifier); - if (user == null){ - return new ResponseEntity("wrong ID or Email", HttpStatus.BAD_REQUEST); + String sessionToken = authServ.login(identifier,password,expirationDate); + if (sessionToken == null){ + return new UnauthorizedResponse<>("Identifier or Password incorrect"); } - if (!userService.checkPassword(user,password)){ - return new ResponseEntity("wrong Password",HttpStatus.BAD_REQUEST); - } - - String token = tokenService.generateNewToken(); - - - tokenService.saveToken(token,user,expirationDate); - HttpHeaders responseHeaders = new HttpHeaders(); - responseHeaders.set("Set-Cookie",String.format("session_token=%s",token)); + responseHeaders.set("Set-Cookie",String.format("session_token=%s",sessionToken)); return ResponseEntity.ok().headers(responseHeaders).build(); } } diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/AuthenticatorService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/AuthenticatorService.java new file mode 100644 index 0000000..f3ae072 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/AuthenticatorService.java @@ -0,0 +1,32 @@ +package ovh.herisson.Clyde.Services; + +import org.springframework.stereotype.Service; +import ovh.herisson.Clyde.Tables.User; + +import java.util.Date; + +@Service +public class AuthenticatorService { + + private final TokenService tokenService; + private final UserService userService; + + public AuthenticatorService(TokenService tokenService, UserService userService){ + this.tokenService = tokenService; + this.userService = userService; + } + + public User getUserFromToken(String token){ + return tokenService.getUserFromToken(token); + } + + + public String login(String identifier, String password, Date expirationDate){ + User user = userService.getUser(identifier); + if (user == null){return null;} + if (!userService.checkPassword(user,password)){return null;} + String token = tokenService.generateNewToken(); + tokenService.saveToken(token,user,expirationDate); + return token; + } +} From 6b58c852a2ad951e5725571e1eced694945fa546 Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Thu, 7 Mar 2024 17:02:19 +0100 Subject: [PATCH 11/14] cleaning --- .../Clyde/EndPoints/MockController.java | 55 +++++++++++++++++++ .../Clyde/EndPoints/UserController.java | 23 +++----- .../herisson/Clyde/Services/TokenService.java | 18 +----- .../herisson/Clyde/Services/UserService.java | 21 ------- 4 files changed, 66 insertions(+), 51 deletions(-) create mode 100644 backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java new file mode 100644 index 0000000..a01c7ec --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java @@ -0,0 +1,55 @@ +package ovh.herisson.Clyde.EndPoints; + +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; +import ovh.herisson.Clyde.Repositories.TokenRepository; +import ovh.herisson.Clyde.Repositories.UserRepository; +import ovh.herisson.Clyde.Tables.Role; +import ovh.herisson.Clyde.Tables.Token; +import ovh.herisson.Clyde.Tables.User; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; + +@RestController +@CrossOrigin(origins = "http://localhost:5173") + +public class MockController { + private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + + public final UserRepository userRepo; + public final TokenRepository tokenRepo; + + + public MockController(UserRepository userRepo, TokenRepository tokenRepo){ + this.tokenRepo = tokenRepo; + this.userRepo = userRepo; + } + + /** Saves an example of each user type by : + * email : FooRole@FooRole.com, password : FooRole and token : FooRole + * For example the admin as "admin@admin.com" as email and "admin" as both password and token + * They all have silly names + */ + + @PostMapping("/generateMock") + public void postMock(){ + + User herobrine = new User("brine","hero","admin@admin.com","in your WalLs","ShadowsLand",new Date(0), Role.Admin,passwordEncoder.encode("admin")); + User joe = new User("Mama","Joe","student@student.com","roundabout","DaWarudo",new Date(0), Role.Student,passwordEncoder.encode("student")); + User meh = new User("Inspiration","lackOf","secretary@secretary.com","a Box","the street",new Date(0), Role.Teacher,passwordEncoder.encode("secretary")); + User joke = new User("CthemBalls","Lemme","teacher@teacher.com","lab","faculty",new Date(0), Role.Teacher,passwordEncoder.encode("teacher")); + + + ArrayList users = new ArrayList(Arrays.asList(herobrine,joe,meh,joke)); + + userRepo.saveAll(users); + + for (User user: users){ + tokenRepo.save(new Token(user,user.getPassword())); + } + } +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java index b282ee1..ba54926 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java @@ -6,7 +6,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import ovh.herisson.Clyde.Responses.UnauthorizedResponse; -import ovh.herisson.Clyde.Services.TokenService; +import ovh.herisson.Clyde.Services.AuthenticatorService; import ovh.herisson.Clyde.Services.UserService; import ovh.herisson.Clyde.Tables.User; @@ -16,24 +16,19 @@ import ovh.herisson.Clyde.Tables.User; public class UserController { private final UserService userService; - - private final TokenService tokenService; - public UserController(UserService userService, TokenService tokenService){ + private final AuthenticatorService authServ; + public UserController(UserService userService, AuthenticatorService authServ){ this.userService = userService; - this.tokenService = tokenService; // todo find a way to be clearer - - tokenService.postMockToken(userService.postMockUsers());// todo find a better place to put that + this.authServ = authServ; } @GetMapping("/user") - public ResponseEntity getUsers(@RequestHeader("Authorization") String token){ - - User user = tokenService.getUserFromToken(token); - + public ResponseEntity getUser(@RequestHeader("Authorization") String token){ + User user = authServ.getUserFromToken(token); if (user == null) { - return new UnauthorizedResponse(null); + return new UnauthorizedResponse<>(null); } - return new ResponseEntity(user, HttpStatus.OK); + return new ResponseEntity<>(user, HttpStatus.OK); } @PostMapping("/user") @@ -43,7 +38,7 @@ public class UserController { } @GetMapping("/users") - public Iterable getAllUsers(){//TODO ne l'accepter que si c'est le secrétariat + public Iterable getAllUsers(){ return userService.getAll(); } diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/TokenService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/TokenService.java index 5057007..e619fd8 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Services/TokenService.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/TokenService.java @@ -27,25 +27,11 @@ public class TokenService { return token; } - - //todo potentiellement return bool pour savoir si token bien add - public void saveToken(String token, User user, Date expirationDate){ - tokenRepo.save(new Token(user,token)); - } - public User getUserFromToken(String token){ return tokenRepo.getByToken(token).getUser(); } - /** Take the list of mock user to save them in the Token DB - * With token being the password of the user (also his role) - * @param users an - */ - public void postMockToken(Iterable users){ - for (User user: users){ - tokenRepo.save(new Token(user,user.getPassword())); - } + public void saveToken(String token, User user, Date expirationDate){// todo faire qlq chose de l'expDate + tokenRepo.save(new Token(user,token)); } - - } \ No newline at end of file diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java index 0482c28..f16c68f 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java @@ -39,27 +39,6 @@ public class UserService { return passwordEncoder.matches(tryingPassword, user.getPassword()); } - /** Saves an example of : - * an Admin with id 1, email : admin@admin.com and password: admin - * a Student with id 2, email: student@student.com and password: student (no cursus yet) - * a Secretary with id 3, email: secretary@secretary.com and password: secretary - * a Teacher (same) - * and they all have silly names (hihi) - */ - public Iterable postMockUsers(){ - User herobrine = new User("brine","hero","admin@admin.com","in your WalLs","ShadowsLand",new Date(0), Role.Admin,passwordEncoder.encode("admin")); - User Joe = new User("Mama","Joe","student@student.com","roundabout","DaWarudo",new Date(0), Role.Student,passwordEncoder.encode("student")); - User Meh = new User("Inspiration","lackOf","secretary@secretary.com","a Box","the street",new Date(0), Role.Teacher,passwordEncoder.encode("secretary")); - User joke = new User("CthemBalls","Lemme","teacher@teacher.com","lab","faculty",new Date(0), Role.Teacher,passwordEncoder.encode("teacher")); - - userRepo.save(herobrine); - userRepo.save(Joe); - userRepo.save(Meh); - userRepo.save(joke); - - return new ArrayList(Arrays.asList(herobrine,Joe,Meh,joke)); - } - public void save(User user){ userRepo.save(user); } From 2f2a72bfa0b4f74ca45b17b79150b171160f8764 Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Thu, 7 Mar 2024 17:29:31 +0100 Subject: [PATCH 12/14] added the possibility to remove the mocks --- .../Clyde/EndPoints/MockController.java | 20 ++++++++++++++----- .../Clyde/Repositories/TokenRepository.java | 2 ++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java index a01c7ec..0fc9a24 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java @@ -2,6 +2,7 @@ package ovh.herisson.Clyde.EndPoints; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import ovh.herisson.Clyde.Repositories.TokenRepository; @@ -23,6 +24,8 @@ public class MockController { public final UserRepository userRepo; public final TokenRepository tokenRepo; + ArrayList mockUsers; + public MockController(UserRepository userRepo, TokenRepository tokenRepo){ this.tokenRepo = tokenRepo; @@ -35,7 +38,7 @@ public class MockController { * They all have silly names */ - @PostMapping("/generateMock") + @PostMapping("/mock") public void postMock(){ User herobrine = new User("brine","hero","admin@admin.com","in your WalLs","ShadowsLand",new Date(0), Role.Admin,passwordEncoder.encode("admin")); @@ -43,13 +46,20 @@ public class MockController { User meh = new User("Inspiration","lackOf","secretary@secretary.com","a Box","the street",new Date(0), Role.Teacher,passwordEncoder.encode("secretary")); User joke = new User("CthemBalls","Lemme","teacher@teacher.com","lab","faculty",new Date(0), Role.Teacher,passwordEncoder.encode("teacher")); + mockUsers = new ArrayList(Arrays.asList(herobrine,joe,meh,joke)); - ArrayList users = new ArrayList(Arrays.asList(herobrine,joe,meh,joke)); + userRepo.saveAll(mockUsers); - userRepo.saveAll(users); - - for (User user: users){ + for (User user: mockUsers){ tokenRepo.save(new Token(user,user.getPassword())); } } + + @DeleteMapping("/mock") + public void deleteMock(){ + for (User user:mockUsers){ + tokenRepo.deleteAll(tokenRepo.getByUser(user)); + } + userRepo.deleteAll(mockUsers); + } } diff --git a/backend/src/main/java/ovh/herisson/Clyde/Repositories/TokenRepository.java b/backend/src/main/java/ovh/herisson/Clyde/Repositories/TokenRepository.java index 719f11e..d375e7a 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Repositories/TokenRepository.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Repositories/TokenRepository.java @@ -7,4 +7,6 @@ import ovh.herisson.Clyde.Tables.User; public interface TokenRepository extends CrudRepository { Token getByToken(String token); + + Iterable getByUser(User user); } From c33b73a1145d109b6c9cd61442d7c567a2a3efe1 Mon Sep 17 00:00:00 2001 From: LeoMoulin Date: Thu, 7 Mar 2024 19:12:48 +0100 Subject: [PATCH 13/14] - Ajout de "l'url" de l'image dans User --- .../src/main/java/ovh/herisson/Clyde/Tables/User.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java index 746ac3b..95467a4 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java @@ -20,15 +20,17 @@ public class User { private String address; private String country; private Date birthDate; + private String profilePictureUrl; private ovh.herisson.Clyde.Tables.Role role; private String password; - public User(String lastName, String firstName, String email, String address, String country, Date birthDate, Role role, String password){ + public User(String lastName, String firstName, String email, String address, String country, Date birthDate, String profilePictureUrl, Role role, String password){ this.lastName = lastName; this.firstName = firstName; this.email = email; this.address = address; this.country = country; this.birthDate = birthDate; + this.profilePictureUrl = profilePictureUrl; this.role = role; this.password = password; } @@ -86,6 +88,11 @@ public class User { this.birthDate = birthDate; } + public String getProfilePictureUrl(){return this.profilePictureUrl;} + + public void setProfilePictureUrl(String profilePictureUrl){ + this.profilePictureUrl = profilePictureUrl; + } public ovh.herisson.Clyde.Tables.Role getRole() { return role; } From acfd366fc83793b750392fed10d9c02391cec975 Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Fri, 8 Mar 2024 12:00:56 +0100 Subject: [PATCH 14/14] fixed the user constructor issue --- .../java/ovh/herisson/Clyde/EndPoints/MockController.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java index 0fc9a24..f7825f6 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java @@ -41,10 +41,10 @@ public class MockController { @PostMapping("/mock") public void postMock(){ - User herobrine = new User("brine","hero","admin@admin.com","in your WalLs","ShadowsLand",new Date(0), Role.Admin,passwordEncoder.encode("admin")); - User joe = new User("Mama","Joe","student@student.com","roundabout","DaWarudo",new Date(0), Role.Student,passwordEncoder.encode("student")); - User meh = new User("Inspiration","lackOf","secretary@secretary.com","a Box","the street",new Date(0), Role.Teacher,passwordEncoder.encode("secretary")); - User joke = new User("CthemBalls","Lemme","teacher@teacher.com","lab","faculty",new Date(0), Role.Teacher,passwordEncoder.encode("teacher")); + User herobrine = new User("brine","hero","admin@admin.com","in your WalLs","ShadowsLand",new Date(0), "none",Role.Admin,passwordEncoder.encode("admin")); + User joe = new User("Mama","Joe","student@student.com","roundabout","DaWarudo",new Date(0), "None",Role.Student,passwordEncoder.encode("student")); + User meh = new User("Inspiration","lackOf","secretary@secretary.com","a Box","the street",new Date(0),"none", Role.Teacher,passwordEncoder.encode("secretary")); + User joke = new User("CthemBalls","Lemme","teacher@teacher.com","lab","faculty",new Date(0), "none",Role.Teacher,passwordEncoder.encode("teacher")); mockUsers = new ArrayList(Arrays.asList(herobrine,joe,meh,joke));