From ab91a39a63ce37dcc9985423aa6b6be7ffa19b50 Mon Sep 17 00:00:00 2001 From: LeoMoulin Date: Mon, 11 Mar 2024 20:23:45 +0100 Subject: [PATCH 01/25] Create exception for file deletion. Add user/inscriptionrequest connection to StorageFile entity. Create a prototype of the delete for file function --- .../Clyde/EndPoints/StorageController.java | 2 +- .../CouldntDeleteFileException.java | 4 +++ .../Clyde/Services/StorageService.java | 23 ++++++++++--- .../Clyde/Tables/InscriptionRequest.java | 3 ++ .../Clyde/Tables/ReinscriptionRequest.java | 2 +- .../herisson/Clyde/Tables/StorageFile.java | 34 ++++++++++++++++--- 6 files changed, 57 insertions(+), 11 deletions(-) create mode 100644 backend/src/main/java/ovh/herisson/Clyde/Exceptions/CouldntDeleteFileException.java diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/StorageController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/StorageController.java index 2a36657..be58f17 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/StorageController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/StorageController.java @@ -23,7 +23,7 @@ public class StorageController { @PostMapping("/upload/{fileType}") public ResponseEntity handleFileUpload(@RequestParam("file") MultipartFile file, @PathVariable FileType fileType) { - String path = storageServ.store(file,fileType); + String path = storageServ.store(file,fileType, null, null); if (path == null) return new ResponseEntity<>("issue with the file storage", HttpStatus.BAD_REQUEST); diff --git a/backend/src/main/java/ovh/herisson/Clyde/Exceptions/CouldntDeleteFileException.java b/backend/src/main/java/ovh/herisson/Clyde/Exceptions/CouldntDeleteFileException.java new file mode 100644 index 0000000..ce0d637 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Exceptions/CouldntDeleteFileException.java @@ -0,0 +1,4 @@ +package ovh.herisson.Clyde.Exceptions; + +public class CouldntDeleteFileException extends Exception{ +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/StorageService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/StorageService.java index 77dff70..eeea9e3 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Services/StorageService.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/StorageService.java @@ -3,11 +3,14 @@ package ovh.herisson.Clyde.Services; import org.springframework.core.io.UrlResource; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import ovh.herisson.Clyde.Exceptions.CouldntDeleteFileException; import ovh.herisson.Clyde.Repositories.FileRepository; -import ovh.herisson.Clyde.Tables.FileType; -import ovh.herisson.Clyde.Tables.StorageFile; +import ovh.herisson.Clyde.Tables.*; + +import java.io.File; import java.io.IOException; import org.springframework.core.io.Resource; + import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -27,7 +30,7 @@ public class StorageService { } - public String store(MultipartFile file, FileType fileType) { + public String store(MultipartFile file, FileType fileType, User user, InscriptionRequest request) { if (file.getOriginalFilename().isEmpty()){return null;} @@ -49,8 +52,20 @@ public class StorageService { String url = this.rootLocation.resolve(Paths.get(Objects.requireNonNull(stringUuid))) .normalize().toString(); - fileRepo.save(new StorageFile(file.getName(),url, fileType)); + fileRepo.save(new StorageFile(file.getName(),url, fileType, user, request)); return url; } + + public void delete(StorageFile file) throws CouldntDeleteFileException { + File f = new File(file.getUrl()); + //Delete le fichier + try{ + f.delete(); + } catch (Exception e) { + throw new CouldntDeleteFileException(); + } + //Delete l'entité + fileRepo.delete(file); + } } diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/InscriptionRequest.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/InscriptionRequest.java index 2e5bf0d..fa853b1 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/InscriptionRequest.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/InscriptionRequest.java @@ -4,7 +4,10 @@ import jakarta.persistence.*; import java.util.Date; + +@Entity public class InscriptionRequest { + @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; private String firstName; diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/ReinscriptionRequest.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/ReinscriptionRequest.java index 8a56f88..0a4db64 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/ReinscriptionRequest.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/ReinscriptionRequest.java @@ -20,7 +20,7 @@ public class ReinscriptionRequest { //Permet de différencier les demandes de changement et une réinscription dans le même cursus //Pour la réinscription on va le mettre a 0 - private boolean type; + private boolean type = false; public ReinscriptionRequest(){} diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/StorageFile.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/StorageFile.java index a96d0ec..4124231 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/StorageFile.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/StorageFile.java @@ -1,9 +1,6 @@ package ovh.herisson.Clyde.Tables; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; @Entity @@ -20,10 +17,21 @@ public class StorageFile { private FileType fileType; - public StorageFile(String name, String url, FileType fileType){ + //Pour lier un user ou une demande d'inscription au fichier + @ManyToOne + @JoinColumn(name = "user") + private User user; + + @ManyToOne + @JoinColumn(name = "inscriptionrequest") + private InscriptionRequest request; + + public StorageFile(String name, String url, FileType fileType, User user, InscriptionRequest request){ this.name = name; this.url = url; this.fileType = fileType; + this.user = user; + this.request = request; } public StorageFile(){} @@ -60,4 +68,20 @@ public class StorageFile { public void setFileType(FileType fileType) { this.fileType = fileType; } + + public void setUser(User user) { + this.user = user; + } + + public User getUser() { + return user; + } + + public void setRequest(InscriptionRequest request) { + this.request = request; + } + + public InscriptionRequest getRequest() { + return request; + } } From 28d252279a83dad0c0b4f8f0ddd06fdda826c56d Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Mon, 11 Mar 2024 22:33:53 +0100 Subject: [PATCH 02/25] added a small description --- .../java/ovh/herisson/Clyde/Tables/User.java | 26 ++++++++++++++++++- 1 file changed, 25 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 101ec9e..5ba70ab 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java @@ -8,7 +8,6 @@ import java.util.Date; //et l'attribut tokenApi doit encore être ajouté vu qu'il faut en discuter @Entity -//Je rajoute un s au nom de la table pour éviter les conflits avec les mots réservés @Table(name = "Users") public class User { @Id @@ -37,6 +36,31 @@ public class User { this.password = password; } + + /** Constructor for the first registration request from a student (can't specify a Role) + * + * @param lastName + * @param firstName + * @param email + * @param address + * @param country + * @param birthDate + * @param profilePictureUrl + * @param password + */ + public User(String lastName, String firstName, String email, String address, + String country, Date birthDate, String profilePictureUrl, String password) + { + this.lastName = lastName; + this.firstName = firstName; + this.email = email; + this.address = address; + this.country = country; + this.birthDate = birthDate; + this.profilePictureUrl = profilePictureUrl; + this.password = password; + this.role = Role.Student; + } public User() {} public int getRegNo(){ From 5c728098dff85db2dc61fcf4153d7d6269614ffe Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Tue, 12 Mar 2024 00:03:32 +0100 Subject: [PATCH 03/25] protected post /user and get/users and return without password --- .../Clyde/EndPoints/UserController.java | 47 ++++++++++++++++--- 1 file changed, 41 insertions(+), 6 deletions(-) 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 43bcd0c..4a20058 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java @@ -8,8 +8,11 @@ import org.springframework.web.bind.annotation.*; import ovh.herisson.Clyde.Responses.UnauthorizedResponse; import ovh.herisson.Clyde.Services.AuthenticatorService; import ovh.herisson.Clyde.Services.UserService; +import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.User; +import java.util.ArrayList; + @RestController @CrossOrigin(origins = "http://localhost:5173") @@ -23,25 +26,57 @@ public class UserController { } @GetMapping("/user") - public ResponseEntity getUser(@RequestHeader("Cookie") String authorization){ + public ResponseEntity getUser(@RequestHeader("Authorization") String authorization){ if (authorization == null) return new UnauthorizedResponse<>(null); User user = authServ.getUserFromToken(authorization); if (user == null) return new UnauthorizedResponse<>(null); - return new ResponseEntity<>(user, HttpStatus.OK); + + return new ResponseEntity<>(userWithoutPassword(user), HttpStatus.OK); } - @PostMapping("/user") //todo check role - public ResponseEntity postUser(@RequestBody User user){ + @PostMapping("/user") + public ResponseEntity postUser(@RequestBody User user,@RequestHeader("Authorization") String authorization){ + + if (authorization == null) return new UnauthorizedResponse<>(null); + User poster = authServ.getUserFromToken(authorization); + + if (poster.getRole() != Role.Secretary || poster.getRole() != Role.Admin) + return new UnauthorizedResponse<>(null); + + userService.save(user); return new ResponseEntity<>(String.format("Account created with ID:%s",user.getRegNo()),HttpStatus.CREATED); } @GetMapping("/users") - public Iterable getAllUsers(){ - return userService.getAll(); + public ResponseEntity> getAllUsers(@RequestHeader("Authorization") String authorization){ + + if (authorization == null) return new UnauthorizedResponse<>(null); + User poster = authServ.getUserFromToken(authorization); + + if (poster == null) return new UnauthorizedResponse<>(null); + + if (poster.getRole() != Role.Secretary || poster.getRole() != Role.Admin) + return new UnauthorizedResponse<>(null); + + Iterable users = userService.getAll(); + ArrayList withoutPassword = new ArrayList<>(); + + for (User u :users){ + withoutPassword.add(userWithoutPassword(u)); + } + return new ResponseEntity<>(withoutPassword, HttpStatus.OK); } + + /** return user's data except password + * @param user the user to return + * @return all the user data without the password + */ + private Object[] userWithoutPassword(User user){ + return new Object[] {user.getRegNo(),user.getFirstName(),user.getLastName(),user.getBirthDate(),user.getCountry(),user.getAddress(),user.getRole()}; + } } From 8fbfb3695811756250bceed5efc3e5ec66995d27 Mon Sep 17 00:00:00 2001 From: LeoMoulin Date: Tue, 12 Mar 2024 10:48:13 +0100 Subject: [PATCH 04/25] Remove the bad link between users and file. Add a delete function for storageFile entities and clean things. --- .../Clyde/EndPoints/MockController.java | 12 +++----- .../Clyde/EndPoints/StorageController.java | 2 +- .../Clyde/Services/StorageService.java | 4 +-- .../herisson/Clyde/Tables/StorageFile.java | 29 +------------------ 4 files changed, 8 insertions(+), 39 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 b140057..787a534 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java @@ -1,20 +1,14 @@ 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 org.springframework.web.bind.annotation.*; import ovh.herisson.Clyde.Repositories.TokenRepository; import ovh.herisson.Clyde.Repositories.UserRepository; import ovh.herisson.Clyde.Services.TokenService; -import ovh.herisson.Clyde.Tables.Role; -import ovh.herisson.Clyde.Tables.Token; -import ovh.herisson.Clyde.Tables.User; +import ovh.herisson.Clyde.Tables.*; import java.util.ArrayList; import java.util.Arrays; -import java.util.Calendar; import java.util.Date; @RestController @@ -26,6 +20,7 @@ public class MockController { public final UserRepository userRepo; public final TokenRepository tokenRepo; public final TokenService tokenService; + ArrayList mockUsers; @@ -62,3 +57,4 @@ public class MockController { userRepo.deleteAll(mockUsers); } } + diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/StorageController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/StorageController.java index be58f17..2a36657 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/StorageController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/StorageController.java @@ -23,7 +23,7 @@ public class StorageController { @PostMapping("/upload/{fileType}") public ResponseEntity handleFileUpload(@RequestParam("file") MultipartFile file, @PathVariable FileType fileType) { - String path = storageServ.store(file,fileType, null, null); + String path = storageServ.store(file,fileType); if (path == null) return new ResponseEntity<>("issue with the file storage", HttpStatus.BAD_REQUEST); diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/StorageService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/StorageService.java index eeea9e3..36e39ca 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Services/StorageService.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/StorageService.java @@ -30,7 +30,7 @@ public class StorageService { } - public String store(MultipartFile file, FileType fileType, User user, InscriptionRequest request) { + public String store(MultipartFile file, FileType fileType) { if (file.getOriginalFilename().isEmpty()){return null;} @@ -52,7 +52,7 @@ public class StorageService { String url = this.rootLocation.resolve(Paths.get(Objects.requireNonNull(stringUuid))) .normalize().toString(); - fileRepo.save(new StorageFile(file.getName(),url, fileType, user, request)); + fileRepo.save(new StorageFile(file.getName(),url, fileType)); return url; } diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/StorageFile.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/StorageFile.java index 4124231..afa7985 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/StorageFile.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/StorageFile.java @@ -16,22 +16,10 @@ public class StorageFile { private FileType fileType; - - //Pour lier un user ou une demande d'inscription au fichier - @ManyToOne - @JoinColumn(name = "user") - private User user; - - @ManyToOne - @JoinColumn(name = "inscriptionrequest") - private InscriptionRequest request; - - public StorageFile(String name, String url, FileType fileType, User user, InscriptionRequest request){ + public StorageFile(String name, String url, FileType fileType){ this.name = name; this.url = url; this.fileType = fileType; - this.user = user; - this.request = request; } public StorageFile(){} @@ -69,19 +57,4 @@ public class StorageFile { this.fileType = fileType; } - public void setUser(User user) { - this.user = user; - } - - public User getUser() { - return user; - } - - public void setRequest(InscriptionRequest request) { - this.request = request; - } - - public InscriptionRequest getRequest() { - return request; - } } From 66282bce9ff0e386228689a88db78efc34e950c1 Mon Sep 17 00:00:00 2001 From: LeoMoulin Date: Tue, 12 Mar 2024 17:53:41 +0100 Subject: [PATCH 05/25] Create new constructor for ReinscriptionRequest so you don't have to worry about the type of the request --- .../ovh/herisson/Clyde/Tables/ReinscriptionRequest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/ReinscriptionRequest.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/ReinscriptionRequest.java index 0a4db64..c7c5569 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/ReinscriptionRequest.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/ReinscriptionRequest.java @@ -31,6 +31,12 @@ public class ReinscriptionRequest { this.type = type; } + public ReinscriptionRequest(User user, Cursus newCursus, RequestState state){ + this.user = user; + this.newCursus = newCursus; + this.state = state; + } + public int getId() { return id; } From dae59f67ce08e7fabc1d86684d4a1cb00c69aef3 Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Tue, 12 Mar 2024 22:35:25 +0100 Subject: [PATCH 06/25] encoding the password before saving it oups I Forgor --- .../herisson/Clyde/EndPoints/MockController.java | 8 ++++---- .../ovh/herisson/Clyde/Services/UserService.java | 14 ++++++-------- 2 files changed, 10 insertions(+), 12 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 18fea23..7a57013 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), "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")); + User herobrine = new User("brine","hero","admin@admin.com","in your WalLs","ShadowsLand",new Date(0), "none",Role.Admin,"admin"); + User joe = new User("Mama","Joe","student@student.com","roundabout","DaWarudo",new Date(0), "None",Role.Student,"student"); + User meh = new User("Inspiration","lackOf","secretary@secretary.com","a Box","the street",new Date(0),"none", Role.Teacher,"secretary"); + User joke = new User("CthemBalls","Lemme","teacher@teacher.com","lab","faculty",new Date(0), "none",Role.Teacher,"teacher"); mockUsers = new ArrayList(Arrays.asList(herobrine,joe,meh,joke)); 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 f16c68f..ca04fff 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java @@ -5,16 +5,10 @@ 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; +import java.util.*; @Service public class UserService { - private final UserRepository userRepo; private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); @@ -35,16 +29,20 @@ public class UserService { } + public boolean checkPassword(User user, String tryingPassword){ return passwordEncoder.matches(tryingPassword, user.getPassword()); } public void save(User user){ + user.setPassword(encodePassword(user.getPassword())); userRepo.save(user); } public Iterable getAll(){ return userRepo.findAll(); } - + public String encodePassword(String rawPassword){ + return passwordEncoder.encode(rawPassword); + } } \ No newline at end of file From 4b0ea8cf4060b04608d78717b5955f676c78a37e Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Tue, 12 Mar 2024 23:08:18 +0100 Subject: [PATCH 07/25] added the post /user Endpoint --- .../Clyde/EndPoints/MockController.java | 8 +-- .../Clyde/EndPoints/UserController.java | 49 ++++++++++----- .../herisson/Clyde/Services/UserService.java | 62 +++++++++++++++++++ .../java/ovh/herisson/Clyde/Tables/User.java | 4 +- 4 files changed, 101 insertions(+), 22 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 7a57013..8ae4217 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), "none",Role.Admin,"admin"); - User joe = new User("Mama","Joe","student@student.com","roundabout","DaWarudo",new Date(0), "None",Role.Student,"student"); - User meh = new User("Inspiration","lackOf","secretary@secretary.com","a Box","the street",new Date(0),"none", Role.Teacher,"secretary"); - User joke = new User("CthemBalls","Lemme","teacher@teacher.com","lab","faculty",new Date(0), "none",Role.Teacher,"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)); 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 4a20058..0ca4d47 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java @@ -1,8 +1,10 @@ package ovh.herisson.Clyde.EndPoints; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import ovh.herisson.Clyde.Responses.UnauthorizedResponse; @@ -11,7 +13,9 @@ import ovh.herisson.Clyde.Services.UserService; import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.User; +import java.io.IOException; import java.util.ArrayList; +import java.util.Map; @RestController @@ -38,13 +42,9 @@ public class UserController { @PostMapping("/user") public ResponseEntity postUser(@RequestBody User user,@RequestHeader("Authorization") String authorization){ - if (authorization == null) return new UnauthorizedResponse<>(null); - User poster = authServ.getUserFromToken(authorization); - - if (poster.getRole() != Role.Secretary || poster.getRole() != Role.Admin) + if (!isSecretaryOrAdmin(authorization)) return new UnauthorizedResponse<>(null); - userService.save(user); return new ResponseEntity<>(String.format("Account created with ID:%s",user.getRegNo()),HttpStatus.CREATED); } @@ -52,12 +52,7 @@ public class UserController { @GetMapping("/users") public ResponseEntity> getAllUsers(@RequestHeader("Authorization") String authorization){ - if (authorization == null) return new UnauthorizedResponse<>(null); - User poster = authServ.getUserFromToken(authorization); - - if (poster == null) return new UnauthorizedResponse<>(null); - - if (poster.getRole() != Role.Secretary || poster.getRole() != Role.Admin) + if (!isSecretaryOrAdmin(authorization)) return new UnauthorizedResponse<>(null); Iterable users = userService.getAll(); @@ -68,15 +63,37 @@ public class UserController { } return new ResponseEntity<>(withoutPassword, HttpStatus.OK); } + @PatchMapping("/user") + public ResponseEntity patchUser(@RequestBody Map updates, @RequestHeader("Authorization") String authorization) { + + if (authorization == null) return new UnauthorizedResponse<>(null); + + User poster = authServ.getUserFromToken(authorization); + if (poster == null) {return new UnauthorizedResponse<>("bad authorization");} + + if (!userService.modifyData(poster, updates, poster)) + return new UnauthorizedResponse<>("there was an issue with the updates requested"); + + return new ResponseEntity<>("data modified", HttpStatus.OK); + } - - /** return user's data except password - * @param user the user to return - * @return all the user data without the password - */ + /** return user's data except password + * @param user the user to return + * @return all the user data without the password + */ private Object[] userWithoutPassword(User user){ return new Object[] {user.getRegNo(),user.getFirstName(),user.getLastName(),user.getBirthDate(),user.getCountry(),user.getAddress(),user.getRole()}; } + + private boolean isSecretaryOrAdmin(String authorization){ + if (authorization ==null) + return false; + + User poster = authServ.getUserFromToken(authorization); + if (poster == null) return false; + + return poster.getRole() == Role.Secretary && poster.getRole() == Role.Admin; + } } 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 ca04fff..79ec04a 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java @@ -28,6 +28,68 @@ public class UserService { } } + /** modify the target data + * verify the permission of modifying from the poster + * + * @param poster the user wanting to modify target's data + * @param updates the changes to be made + * @param target the user to update + * @return if the changes were done or not + */ + public boolean modifyData(User poster, Map updates, User target){ + + System.out.printf("%s and %s",poster.getRegNo(),target.getRegNo()); + if (poster.getRegNo().equals(target.getRegNo())){ + for (Map.Entry entry : updates.entrySet()){ + + if ( entry.getKey().equals("regNo") || entry.getKey().equals("role")) {return false;} + + switch (entry.getKey()){ + case "firstName": + target.setFirstName((String) entry.getValue()); + break; + case "lastName": + target.setLastName((String) entry.getValue()); + break; + case "email": + target.setEmail((String) entry.getValue()); + break; + case "address": + target.setAddress((String) entry.getValue()); + break; + case "country": + target.setCountry((String) entry.getValue()); + break; + case "birthDate": + target.setBirthDate((Date) entry.getValue()); + break; + case "profilePictureUrl": + target.setProfilePictureUrl((String) entry.getValue()); + break; + case "password": + target.setPassword(encodePassword((String) entry.getValue())); + break; + } + } + userRepo.save(target); + return true; + } + // the secretary can change roles (for example if a student becomes a teacher) + else if (poster.getRole() == Role.Secretary) + { + for (Map.Entry entry : updates.entrySet()){ + + if ( !entry.getKey().equals("role")) {return false;} + + if (entry.getValue() == Role.Admin){return false;} + + target.setRole((Role) entry.getValue()); + userRepo.save(target); + return true; + } + } + return false; + } public boolean checkPassword(User user, String tryingPassword){ 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 5ba70ab..7a2c51d 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java @@ -12,7 +12,7 @@ import java.util.Date; public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) - private int regNo; + private Long regNo; private String lastName; private String firstName; private String email; @@ -63,7 +63,7 @@ public class User { } public User() {} - public int getRegNo(){ + public Long getRegNo(){ return this.regNo; } public String getLastName() { From 4b1db883e25afb3ed780d8f9f837857cb58aaf00 Mon Sep 17 00:00:00 2001 From: Bartha Maxime <231026@umons.ac.be> Date: Wed, 13 Mar 2024 15:28:17 +0100 Subject: [PATCH 08/25] updated tonitch's reviews --- .../Clyde/EndPoints/UserController.java | 21 ++++++++++++++----- .../herisson/Clyde/Services/UserService.java | 8 ++----- 2 files changed, 18 insertions(+), 11 deletions(-) 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 0ca4d47..63df79f 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java @@ -15,6 +15,7 @@ import ovh.herisson.Clyde.Tables.User; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.Map; @@ -30,7 +31,7 @@ public class UserController { } @GetMapping("/user") - public ResponseEntity getUser(@RequestHeader("Authorization") String authorization){ + public ResponseEntity> getUser(@RequestHeader("Authorization") String authorization){ if (authorization == null) return new UnauthorizedResponse<>(null); User user = authServ.getUserFromToken(authorization); @@ -50,13 +51,13 @@ public class UserController { } @GetMapping("/users") - public ResponseEntity> getAllUsers(@RequestHeader("Authorization") String authorization){ + public ResponseEntity>> getAllUsers(@RequestHeader("Authorization") String authorization){ if (!isSecretaryOrAdmin(authorization)) return new UnauthorizedResponse<>(null); Iterable users = userService.getAll(); - ArrayList withoutPassword = new ArrayList<>(); + ArrayList> withoutPassword = new ArrayList<>(); for (User u :users){ withoutPassword.add(userWithoutPassword(u)); @@ -82,8 +83,18 @@ public class UserController { * @param user the user to return * @return all the user data without the password */ - private Object[] userWithoutPassword(User user){ - return new Object[] {user.getRegNo(),user.getFirstName(),user.getLastName(),user.getBirthDate(),user.getCountry(),user.getAddress(),user.getRole()}; + private HashMap userWithoutPassword(User user){ + HashMap toReturn = new HashMap<>(); + + toReturn.put("regNo",user.getRegNo()); + toReturn.put("firstName",user.getFirstName()); + toReturn.put("lastName",user.getLastName()); + toReturn.put("birthDate",user.getBirthDate()); + toReturn.put("country",user.getCountry()); + toReturn.put("address",user.getAddress()); + toReturn.put("role",user.getRole()); + + return toReturn; } private boolean isSecretaryOrAdmin(String authorization){ 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 79ec04a..55a2f92 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java @@ -38,7 +38,6 @@ public class UserService { */ public boolean modifyData(User poster, Map updates, User target){ - System.out.printf("%s and %s",poster.getRegNo(),target.getRegNo()); if (poster.getRegNo().equals(target.getRegNo())){ for (Map.Entry entry : updates.entrySet()){ @@ -67,7 +66,7 @@ public class UserService { target.setProfilePictureUrl((String) entry.getValue()); break; case "password": - target.setPassword(encodePassword((String) entry.getValue())); + target.setPassword(passwordEncoder.encode((String) entry.getValue())); break; } } @@ -97,14 +96,11 @@ public class UserService { } public void save(User user){ - user.setPassword(encodePassword(user.getPassword())); + user.setPassword(passwordEncoder.encode(user.getPassword())); userRepo.save(user); } public Iterable getAll(){ return userRepo.findAll(); } - public String encodePassword(String rawPassword){ - return passwordEncoder.encode(rawPassword); - } } \ No newline at end of file From 2a58c335f2fa5893d33dae15ae91c7dca046ce35 Mon Sep 17 00:00:00 2001 From: LeoMoulin Date: Wed, 13 Mar 2024 15:48:28 +0100 Subject: [PATCH 09/25] Apply les trucs de l'exception --- backend/build.gradle.kts | 1 + .../Clyde/Exceptions/CouldntDeleteFileException.java | 4 ---- .../java/ovh/herisson/Clyde/Services/StorageService.java | 7 ++----- 3 files changed, 3 insertions(+), 9 deletions(-) delete mode 100644 backend/src/main/java/ovh/herisson/Clyde/Exceptions/CouldntDeleteFileException.java diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index f105250..6557b82 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -41,3 +41,4 @@ tasks.register("run") { tasks.withType { useJUnitPlatform() } + diff --git a/backend/src/main/java/ovh/herisson/Clyde/Exceptions/CouldntDeleteFileException.java b/backend/src/main/java/ovh/herisson/Clyde/Exceptions/CouldntDeleteFileException.java deleted file mode 100644 index ce0d637..0000000 --- a/backend/src/main/java/ovh/herisson/Clyde/Exceptions/CouldntDeleteFileException.java +++ /dev/null @@ -1,4 +0,0 @@ -package ovh.herisson.Clyde.Exceptions; - -public class CouldntDeleteFileException extends Exception{ -} diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/StorageService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/StorageService.java index 36e39ca..cb3ceb0 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Services/StorageService.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/StorageService.java @@ -1,15 +1,12 @@ package ovh.herisson.Clyde.Services; -import org.springframework.core.io.UrlResource; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; -import ovh.herisson.Clyde.Exceptions.CouldntDeleteFileException; import ovh.herisson.Clyde.Repositories.FileRepository; import ovh.herisson.Clyde.Tables.*; import java.io.File; import java.io.IOException; -import org.springframework.core.io.Resource; import java.nio.file.Files; import java.nio.file.Path; @@ -57,13 +54,13 @@ public class StorageService { return url; } - public void delete(StorageFile file) throws CouldntDeleteFileException { + public void delete(StorageFile file) throws SecurityException { File f = new File(file.getUrl()); //Delete le fichier try{ f.delete(); } catch (Exception e) { - throw new CouldntDeleteFileException(); + throw new SecurityException(); } //Delete l'entité fileRepo.delete(file); From d5b1df32b6e435a6716ecb9230d4f425db32d08f Mon Sep 17 00:00:00 2001 From: Wawilski Date: Tue, 12 Mar 2024 11:10:14 +0100 Subject: [PATCH 10/25] course management --- frontend/src/App.vue | 17 ++++--- frontend/src/Apps/ManageCourses.vue | 78 +++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 frontend/src/Apps/ManageCourses.vue diff --git a/frontend/src/App.vue b/frontend/src/App.vue index ef68173..114cacc 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -8,11 +8,13 @@ import LoginPage from './Apps/Login.vue' import Inscription from "./Apps/Inscription.vue" import Profil from "./Apps/Profil.vue" + import Courses from "./Apps/ManageCourses.vue" const apps = { '/login': LoginPage, '/inscription': Inscription, - '/profil': Profil + '/profil': Profil, + '/manage-courses' : Courses, } const currentPath = ref(window.location.hash) @@ -97,8 +99,12 @@
{{i18n("app.forum")}}
  • -
    -
    {{i18n("app.inscription.requests")}}
  • +
    +
    {{i18n("app.inscription.requests")}}
    + +
  • +
    +
    Manage courses
  • @@ -246,7 +252,6 @@ } .text { - position: absolute; right: 0%; width: 0%; opacity: 0; @@ -258,9 +263,9 @@ ul.vertical:hover .text { opacity: 1; - width: 70%; + width: 60%; transition-duration: .3s; - padding-left: 5px; + padding-left: 15px; } diff --git a/frontend/src/Apps/ManageCourses.vue b/frontend/src/Apps/ManageCourses.vue new file mode 100644 index 0000000..d006f32 --- /dev/null +++ b/frontend/src/Apps/ManageCourses.vue @@ -0,0 +1,78 @@ + + + + From 354793a29fca86f69ae397d35e16157c9e8e8c04 Mon Sep 17 00:00:00 2001 From: Wawilski Date: Wed, 13 Mar 2024 15:07:17 +0100 Subject: [PATCH 11/25] Create Course --- frontend/src/Apps/Login.vue | 1 - frontend/src/Apps/ManageCourses.vue | 159 +++++++++++++++++++++++++++- 2 files changed, 156 insertions(+), 4 deletions(-) diff --git a/frontend/src/Apps/Login.vue b/frontend/src/Apps/Login.vue index 786c786..1927230 100644 --- a/frontend/src/Apps/Login.vue +++ b/frontend/src/Apps/Login.vue @@ -165,7 +165,6 @@ .inputBox input,button,select { width:100%; - background:rgb(255, 0 255); border: none; margin-right: 50px; padding-left: 10px; diff --git a/frontend/src/Apps/ManageCourses.vue b/frontend/src/Apps/ManageCourses.vue index d006f32..6925685 100644 --- a/frontend/src/Apps/ManageCourses.vue +++ b/frontend/src/Apps/ManageCourses.vue @@ -1,4 +1,6 @@ @@ -75,4 +164,68 @@ const cursus=[ border-radius:20px; margin-bottom:10px; } + +.modify{ + font-size:25px; + padding:10px 10px 10px 10px; + background-color: rgb(239,60,168); + cursor: pointer; + border:none; + border-radius:15px; +} + + input, select{ + + font-size:25px; + cursor: pointer; + border:none; + border-radius:15px; + } + button{ + font-size:15px; + height:50px; + width:100px; + border:none; + border-radius:20px; + + } + + .buttonGrid{ + display:grid; + grid-template-columns: auto auto; + column-gap:50px; + grid-template-areas: + "create delete"; + } + + .create{ + grid-area:create; + + background-color:rgb(0,200,0); + + } + + .delete{ + grid-area:delete; + background-color:rgb(200,0,0); + } + + .listTitle{ + display: flex; + justify-content: center; + align-items: center; + width:400px; + margin-left:auto; + margin-right:auto; + border:2px solid black; + font-size:25px; + color:white; + padding:20px; + background-color:rgb(50,50,50); + border-radius:20px;margin-bottom:10px; + + button:hover{ + opacity:0.8; + } +} From 7d8e1113ccd5c594fa484b55a0e3be1b22bec3aa Mon Sep 17 00:00:00 2001 From: Wawilski Date: Wed, 13 Mar 2024 17:48:48 +0100 Subject: [PATCH 12/25] Remove course --- frontend/src/Apps/ManageCourses.vue | 100 ++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 27 deletions(-) diff --git a/frontend/src/Apps/ManageCourses.vue b/frontend/src/Apps/ManageCourses.vue index 6925685..d92fcf9 100644 --- a/frontend/src/Apps/ManageCourses.vue +++ b/frontend/src/Apps/ManageCourses.vue @@ -14,18 +14,30 @@ const cursus=[ "name": "Operating Systems", "credits": 8, "faculty": "science", - "teacher": 14, + "teacher": 62, "Assistants": []}, { "id": 52, "name": "Fonctionnement des ordinateurs", "credits": 11, "faculty": "science", - "teacher": 42, + "teacher": 59, "Assistants": []}, ] + const profList=[42,45,62,84,59] + + const createMod = ref(false) + const deleteMod = ref(false) + + const editElementID = ref(""); + + function editItem(id){ + editElementID = id; + } + + //Juste pour montrer le Create Mode const pattern = { "id": 0, @@ -35,73 +47,107 @@ const cursus=[ "teacher": null, "Assistants": []} -const profList=[42,45,62,84,59] - - const createMod = ref(false) - const deleteMod = ref(false) - - const editElementID = ref(""); - let toAdd = Object.assign({}, pattern); function addToCourse (){ - toAdd.id=(cursus[cursus.length-1].id)-1; + if (cursus.length>0){ + toAdd.id=(cursus[cursus.length-1].id)-1;} + else{ + toAdd.id=0; + } let isnull= false; for(const [key, value] of Object.entries(toAdd)){ - console.log(value) if(value === null){ isnull=true; } - console.log(isnull) } - console.log(toAdd) if (!isnull){ cursus.push(toAdd); } - toAdd= Object.assign({},pattern); } + - function editItem(id){ - editElementID = id; + //Juste pour montrer le Delete Mode + let toRemove; + + function removeCourse() { + console.log("ok"); + console.log(toRemove); + let rem=-1; + for(const [key, value] of Object.entries(cursus)){ + console.log(key); + console.log(value) + if(value.name === toRemove){ + rem = key; + break; + } + } + console.log(rem) + if (rem > -1){ + cursus.splice(rem, 1);} + console.log(cursus); }