diff --git a/README.md b/README.md index 1b35090..aa53ec8 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ Course Exercice : Application to help others ### APIs -- [ ] `Rest` Create user -- [ ] `Rest` Login with user and password +- [X] `Rest` Create user +- [X] `Rest` Login with user and password - [ ] `Rest` Make sure admin can do everything and users don't - [ ] `Rest` Create a Help Request - [ ] `Rest` Modify the Help Request status diff --git a/helpapp-backend/administration-service/pom.xml b/helpapp-backend/administration-service/pom.xml index 963e9af..014095e 100644 --- a/helpapp-backend/administration-service/pom.xml +++ b/helpapp-backend/administration-service/pom.xml @@ -6,24 +6,27 @@ 4.0.0 administration-service + jar - org.springframework.boot - spring-boot-starter-web + spring-boot-starter-data-jpa + + + jakarta.persistence + jakarta.persistence-api + 3.1.0 + + + mysql + mysql-connector-java + 8.0.33 - - - org.springframework.boot - spring-boot-maven-plugin - 3.1.4 - - org.apache.maven.plugins diff --git a/helpapp-backend/administration-service/src/main/java/insa/application/helpapp/rest/AdministrationService.java b/helpapp-backend/administration-service/src/main/java/insa/application/helpapp/rest/AdministrationService.java new file mode 100644 index 0000000..6c3ea52 --- /dev/null +++ b/helpapp-backend/administration-service/src/main/java/insa/application/helpapp/rest/AdministrationService.java @@ -0,0 +1,23 @@ +package insa.application.helpapp.rest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class AdministrationService { + + @Autowired + private ConnectionRepository connectionRepository; + + public boolean checkToken(int idUser, String token) { + List connections = connectionRepository.findByIdUser(idUser); + + if (connections.isEmpty()) { + return false; + } + Connection c = connections.getFirst(); + return c.getToken().equals(token) && c.getExpiresAt().isAfter(java.time.LocalDateTime.now()); + } +} diff --git a/helpapp-backend/administration-service/src/main/java/insa/application/helpapp/rest/AdministrationServiceApplication.java b/helpapp-backend/administration-service/src/main/java/insa/application/helpapp/rest/AdministrationServiceApplication.java deleted file mode 100644 index e0ac220..0000000 --- a/helpapp-backend/administration-service/src/main/java/insa/application/helpapp/rest/AdministrationServiceApplication.java +++ /dev/null @@ -1,39 +0,0 @@ -package insa.application.helpapp.rest; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.web.bind.annotation.*; - -import java.util.*; - -@SpringBootApplication -@RestController -@RequestMapping("/admin/requests") -public class AdministrationServiceApplication { - - private final Map requestStatusDatabase = new HashMap<>(); - - public static void main(String[] args) { - SpringApplication.run(AdministrationServiceApplication.class, args); - } - - // Validate a request - @PutMapping("/{id}/validate") - public String validateRequest(@PathVariable Long id) { - requestStatusDatabase.put(id, "Validated"); - return "Request " + id + " validated."; - } - - // Reject a request with justification - @PutMapping("/{id}/reject") - public String rejectRequest(@PathVariable Long id, @RequestParam String reason) { - requestStatusDatabase.put(id, "Rejected: " + reason); - return "Request " + id + " rejected for reason: " + reason; - } - - // View request statuses - @GetMapping - public Map viewAllStatuses() { - return requestStatusDatabase; - } -} diff --git a/helpapp-backend/user-service/src/main/java/insa/application/helpapp/rest/Connection.java b/helpapp-backend/administration-service/src/main/java/insa/application/helpapp/rest/Connection.java similarity index 100% rename from helpapp-backend/user-service/src/main/java/insa/application/helpapp/rest/Connection.java rename to helpapp-backend/administration-service/src/main/java/insa/application/helpapp/rest/Connection.java diff --git a/helpapp-backend/user-service/src/main/java/insa/application/helpapp/rest/ConnectionRepository.java b/helpapp-backend/administration-service/src/main/java/insa/application/helpapp/rest/ConnectionRepository.java similarity index 100% rename from helpapp-backend/user-service/src/main/java/insa/application/helpapp/rest/ConnectionRepository.java rename to helpapp-backend/administration-service/src/main/java/insa/application/helpapp/rest/ConnectionRepository.java diff --git a/helpapp-backend/feedback-service/pom.xml b/helpapp-backend/feedback-service/pom.xml deleted file mode 100644 index 9d440c1..0000000 --- a/helpapp-backend/feedback-service/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - insa.application.helpapp - helpapp - 1.0-SNAPSHOT - - 4.0.0 - feedback-service - - - - - org.springframework.boot - spring-boot-starter-web - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - 3.1.4 - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 21 - 21 - - - - - - diff --git a/helpapp-backend/feedback-service/src/main/java/insa/application/helpapp/rest/FeedbackServiceApplication.java b/helpapp-backend/feedback-service/src/main/java/insa/application/helpapp/rest/FeedbackServiceApplication.java deleted file mode 100644 index 89f29f1..0000000 --- a/helpapp-backend/feedback-service/src/main/java/insa/application/helpapp/rest/FeedbackServiceApplication.java +++ /dev/null @@ -1,83 +0,0 @@ -package insa.application.helpapp.rest; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.web.bind.annotation.*; - -import java.util.*; -import java.util.concurrent.atomic.AtomicLong; - -@SpringBootApplication -@RestController -@RequestMapping("/feedbacks") -public class FeedbackServiceApplication { - - private final Map feedbackDatabase = new HashMap<>(); - private final AtomicLong idGenerator = new AtomicLong(1); - - public static void main(String[] args) { - SpringApplication.run(FeedbackServiceApplication.class, args); - } - - // Add feedback - @PostMapping - public Feedback addFeedback(@RequestBody Feedback feedback) { - long id = idGenerator.getAndIncrement(); - feedback.setId(id); - feedbackDatabase.put(id, feedback); - return feedback; - } - - // Get feedback by request ID - @GetMapping("/request/{requestId}") - public List getFeedbackByRequest(@PathVariable Long requestId) { - List feedbackList = new ArrayList<>(); - for (Feedback feedback : feedbackDatabase.values()) { - if (feedback.getRequestId().equals(requestId)) { - feedbackList.add(feedback); - } - } - return feedbackList; - } - - // Feedback entity - static class Feedback { - private Long id; - private Long requestId; - private String comment; - private Integer rating; // 1 to 5 - - // Getters and setters - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public Long getRequestId() { - return requestId; - } - - public void setRequestId(Long requestId) { - this.requestId = requestId; - } - - public String getComment() { - return comment; - } - - public void setComment(String comment) { - this.comment = comment; - } - - public Integer getRating() { - return rating; - } - - public void setRating(Integer rating) { - this.rating = rating; - } - } -} diff --git a/helpapp-backend/pom.xml b/helpapp-backend/pom.xml index f436f20..df77397 100644 --- a/helpapp-backend/pom.xml +++ b/helpapp-backend/pom.xml @@ -7,12 +7,12 @@ pom - user-service - request-service - volunteer-service - feedback-service + administration-service + request-service role-service + user-service + diff --git a/helpapp-backend/request-service/pom.xml b/helpapp-backend/request-service/pom.xml index 6c195a1..d3b2782 100644 --- a/helpapp-backend/request-service/pom.xml +++ b/helpapp-backend/request-service/pom.xml @@ -13,6 +13,22 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-data-jpa + + + mysql + mysql-connector-java + 8.0.33 + runtime + + + + insa.application.helpapp + administration-service + 1.0-SNAPSHOT + diff --git a/helpapp-backend/request-service/src/main/java/insa/application/helpapp/rest/RequestRepository.java b/helpapp-backend/request-service/src/main/java/insa/application/helpapp/rest/RequestRepository.java new file mode 100644 index 0000000..f0c5c80 --- /dev/null +++ b/helpapp-backend/request-service/src/main/java/insa/application/helpapp/rest/RequestRepository.java @@ -0,0 +1,7 @@ +package insa.application.helpapp.rest; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface RequestRepository extends JpaRepository { + +} \ No newline at end of file diff --git a/helpapp-backend/request-service/src/main/java/insa/application/helpapp/rest/RequestServiceApplication.java b/helpapp-backend/request-service/src/main/java/insa/application/helpapp/rest/RequestServiceApplication.java index 6906969..47536ef 100644 --- a/helpapp-backend/request-service/src/main/java/insa/application/helpapp/rest/RequestServiceApplication.java +++ b/helpapp-backend/request-service/src/main/java/insa/application/helpapp/rest/RequestServiceApplication.java @@ -1,35 +1,28 @@ package insa.application.helpapp.rest; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +// import org.springframework.http.HttpStatus; +// import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import org.springframework.web.client.RestTemplate; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -import java.util.*; -import java.util.concurrent.atomic.AtomicLong; +// import org.springframework.beans.factory.annotation.Autowired; @SpringBootApplication @RestController -@RequestMapping("/requests") public class RequestServiceApplication { - - private final Map requestDatabase = new HashMap<>(); - private final AtomicLong idGenerator = new AtomicLong(1); - + @Autowired + private AdministrationService administrationService; public static void main(String[] args) { SpringApplication.run(RequestServiceApplication.class, args); } - @Bean - public RestTemplate restTemplate() { - return new RestTemplate(); - } - - private final RestTemplate restTemplate = new RestTemplate(); - + // CORS Configuration @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @@ -42,91 +35,11 @@ public class RequestServiceApplication { }; } - // Create a new help request - @PostMapping - public HelpRequest createRequest(@RequestBody HelpRequest request) { - if (request.getUserId() == null || request.getDetails() == null) { - throw new RuntimeException("User ID and details are required"); - } - // Validate user via UserService - if (!isUserValid(request.getUserId())) { - throw new RuntimeException("Invalid user ID"); - } - long id = idGenerator.getAndIncrement(); - request.setId(id); - request.setStatus("Pending"); - requestDatabase.put(id, request); - return request; - } - - // Get requests for a specific user - @GetMapping("/user/{userId}") - public List getRequestsByUser(@PathVariable Long userId) { - List userRequests = new ArrayList<>(); - for (HelpRequest request : requestDatabase.values()) { - if (request.getUserId().equals(userId)) { - userRequests.add(request); - } - } - return userRequests; - } - - // Get all help requests - @GetMapping - public List getAllRequests() { - return new ArrayList<>(requestDatabase.values()); - } - - // Simulate user validation (integration with UserService) - private boolean isUserValid(Long userId) { - try { - // Call UserService to check if the user exists - String url = "http://localhost:8083/users/" + userId; - restTemplate.getForObject(url, Object.class); // Throws exception if user doesn't exist - return true; - } catch (Exception e) { - return false; - } - } - - // HelpRequest entity - static class HelpRequest { - private Long id; - private Long userId; - private String details; - private String status; // Pending, Validated, Rejected, Completed - - // Getters and setters - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public Long getUserId() { - return userId; - } - - public void setUserId(Long userId) { - this.userId = userId; - } - - public String getDetails() { - return details; - } - - public void setDetails(String details) { - this.details = details; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } + @PostMapping("/post_message") + public ResponseEntity postMessage(@RequestParam int idUser,@RequestParam String token, @RequestParam String message) { + if(!administrationService.checkToken(idUser, token)) { + return ResponseEntity.status(HttpStatus.FORBIDDEN).body("User or token invalid."); + }; + return ResponseEntity.ok("yessay"); } } diff --git a/helpapp-backend/request-service/src/main/java/insa/application/helpapp/rest/Requests.java b/helpapp-backend/request-service/src/main/java/insa/application/helpapp/rest/Requests.java new file mode 100644 index 0000000..8eb04eb --- /dev/null +++ b/helpapp-backend/request-service/src/main/java/insa/application/helpapp/rest/Requests.java @@ -0,0 +1,72 @@ +package insa.application.helpapp.rest; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; + +import java.time.LocalDate; + +@Entity +@Table(name = "requests", schema = "service-architecture") +public class Requests { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @Column(name = "id_status", nullable = false) + private int idStatus; + + @Column(name = "id_user", nullable = false) + private int idUser; + + @Column(name = "created_at", nullable = false, columnDefinition = "DATE DEFAULT CURRENT_DATE") + private LocalDate createdAt; + + @Column(name = "message", nullable = false) + private String message; + + // Getters and Setters + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getIdStatus() { + return idStatus; + } + + public void setIdStatus(int idStatus) { + this.idStatus = idStatus; + } + + public int getIdUser() { + return idUser; + } + + public void setIdUser(int idUser) { + this.idUser = idUser; + } + + public LocalDate getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(LocalDate createdAt) { + this.createdAt = createdAt; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/helpapp-backend/user-service/pom.xml b/helpapp-backend/user-service/pom.xml index 76b4bee..1f191ed 100644 --- a/helpapp-backend/user-service/pom.xml +++ b/helpapp-backend/user-service/pom.xml @@ -23,6 +23,12 @@ 8.0.33 runtime + + + insa.application.helpapp + administration-service + 1.0-SNAPSHOT + diff --git a/helpapp-backend/user-service/src/main/java/insa/application/helpapp/rest/UserService.java b/helpapp-backend/user-service/src/main/java/insa/application/helpapp/rest/UserService.java new file mode 100644 index 0000000..18698af --- /dev/null +++ b/helpapp-backend/user-service/src/main/java/insa/application/helpapp/rest/UserService.java @@ -0,0 +1,23 @@ +package insa.application.helpapp.rest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class UserService { + + @Autowired + private ConnectionRepository connectionRepository; + + public boolean checkToken(int idUser, String token) { + List connections = connectionRepository.findByIdUser(idUser); + + if (connections.isEmpty()) { + return false; + } + Connection c = connections.getFirst(); + return c.getToken().equals(token) && c.getExpiresAt().isAfter(java.time.LocalDateTime.now()); + } +} diff --git a/helpapp-backend/user-service/src/main/java/insa/application/helpapp/rest/UserServiceApplication.java b/helpapp-backend/user-service/src/main/java/insa/application/helpapp/rest/UserServiceApplication.java index b7083fc..a073cef 100644 --- a/helpapp-backend/user-service/src/main/java/insa/application/helpapp/rest/UserServiceApplication.java +++ b/helpapp-backend/user-service/src/main/java/insa/application/helpapp/rest/UserServiceApplication.java @@ -8,14 +8,13 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.hibernate.type.descriptor.java.LocalDateTimeJavaType; import org.springframework.beans.factory.annotation.Autowired; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.List; import java.time.LocalDateTime; -import java.math.BigInteger; import java.security.SecureRandom; import java.util.Base64; @@ -31,9 +30,9 @@ public class UserServiceApplication { // https://stackoverflow.com/users/774398/patrick public static String generateRandomBase64Token(int byteLength) { SecureRandom secureRandom = new SecureRandom(); - byte[] token = new byte[byteLength-32]; + byte[] token = new byte[byteLength - 32]; secureRandom.nextBytes(token); - return Base64.getUrlEncoder().withoutPadding().encodeToString(token); //base64 encoding + return Base64.getUrlEncoder().withoutPadding().encodeToString(token); // base64 encoding } public static void main(String[] args) { @@ -54,6 +53,7 @@ public class UserServiceApplication { } // Post should be : /create_user?idRole=1&username=toto&password=1234 + // Response: created user @PostMapping("/create_user") public User createUser(@RequestParam int idRole, @RequestParam String username, @RequestParam String password) { User user = new User(); @@ -64,30 +64,49 @@ public class UserServiceApplication { return userRepository.save(user); } + // Post should be : /get_user?id=1 + // Response: idRole (int), username (string) + @GetMapping("/get_user") + public ResponseEntity getUser(@RequestParam int id) { + Optional userOptional = userRepository.findById(id); + + if (userOptional.isEmpty()) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("User ID not known."); + } + User user = userOptional.get(); + Map response = new HashMap<>(); + + // Reponse to client + response.put("username", user.getUsername()); + response.put("idRole", user.getIdRole()); + return ResponseEntity.ok(response); + } + // Post should be : /connect?username=toto&password=1234 // Response can vary: Error if username/password doesn't exist/match // Response if success: userId (int), expiresAt (time), token (varchar(128)) @PostMapping("/connect") - public ResponseEntity connect(@RequestParam String username, @RequestParam String password) - { + public ResponseEntity connect(@RequestParam String username, @RequestParam String password) { List users = userRepository.findByUsername(username); // Checks username - if(users.isEmpty()) { - return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Username not known."); + if (users.isEmpty()) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Username not known."); } User user = users.getFirst(); // Checks password - if(!user.getPassword().equals(password)) { + if (!user.getPassword().equals(password)) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid password."); } // Checks if token already exists List connections = connectionRepository.findByIdUser(user.getId()); Map response = new HashMap<>(); Connection connection = new Connection(); - if(!connections.isEmpty() && (connections.getFirst().getExpiresAt().isBefore(LocalDateTime.now()))) - { + if (connections.isEmpty() + || (!connections.isEmpty() && (connections.getFirst().getExpiresAt().isBefore(LocalDateTime.now())))) { // Remove the old token - connectionRepository.delete(connections.getFirst()); + if (!connections.isEmpty()) { + connectionRepository.delete(connections.getFirst()); + } // Create new token if password & username is correct // Get User ID connection.setidUser(user.getId()); @@ -109,5 +128,4 @@ public class UserServiceApplication { return ResponseEntity.ok(response); } - } diff --git a/helpapp-backend/volunteer-service/pom.xml b/helpapp-backend/volunteer-service/pom.xml deleted file mode 100644 index 298515b..0000000 --- a/helpapp-backend/volunteer-service/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - insa.application.helpapp - helpapp - 1.0-SNAPSHOT - - 4.0.0 - volunteer-service - - - - - org.springframework.boot - spring-boot-starter-web - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - 3.1.4 - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 21 - 21 - - - - - - diff --git a/helpapp-backend/volunteer-service/src/main/java/insa/application/helpapp/rest/VolunteerServiceApplication.java b/helpapp-backend/volunteer-service/src/main/java/insa/application/helpapp/rest/VolunteerServiceApplication.java deleted file mode 100644 index 65897e5..0000000 --- a/helpapp-backend/volunteer-service/src/main/java/insa/application/helpapp/rest/VolunteerServiceApplication.java +++ /dev/null @@ -1,38 +0,0 @@ -package insa.application.helpapp.rest; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.web.bind.annotation.*; - -import java.util.*; - -@SpringBootApplication -@RestController -@RequestMapping("/volunteers") -public class VolunteerServiceApplication { - - private final Map volunteerActions = new HashMap<>(); - - public static void main(String[] args) { - SpringApplication.run(VolunteerServiceApplication.class, args); - } - - // View available requests (simulating) - @GetMapping("/requests") - public List viewAvailableRequests() { - return List.of("Request 1: Grocery delivery", "Request 2: Medical help"); - } - - // Respond to a specific request - @PostMapping("/{volunteerId}/help") - public String respondToRequest(@PathVariable Long volunteerId, @RequestParam Long requestId) { - volunteerActions.put(requestId, "Volunteer " + volunteerId + " responded."); - return "Volunteer " + volunteerId + " responded to request " + requestId; - } - - // View all volunteer actions - @GetMapping("/actions") - public Map viewActions() { - return volunteerActions; - } -}