From e013c13087f6b74ddb18e7a1afacafc8867591b0 Mon Sep 17 00:00:00 2001
From: Jessie Ragot <jessie.ragot@hotmail.com>
Date: Mon, 3 Mar 2025 11:59:59 +0100
Subject: [PATCH] Authentication and registration fully functional, merge and
 conflict resolved with Aichatou's code, statistic removed from the doctors'
 dashboard, PatientController created but not implemented (Aichatou's task),
 patient-dashboard template added, admin user not yet implemented but present
 in the list when registering (we'll see if we keep this one).  We need to
 resolve the fact that one doctor can retrieve appointments from all the
 doctors and that we can access the medical records of all the patients, no
 matter who is connected, by changing the URL directly.

---
 .../projetIndu/ProjetInduApplication.java     | 28 ++++------
 .../projetIndu/config/SecurityConfig.java     | 40 -------------
 .../controllers/AuthController.java           | 56 +++++++++++++++----
 .../controllers/DashboardController.java      | 36 ------------
 .../controllers/LoginController.java          |  2 +-
 .../controllers/PatientController.java        | 10 ++++
 .../controllers/UserController.java           | 35 ------------
 .../projetIndu/dto/RegisterRequest.java       | 13 -----
 .../projetIndu/security/SecurityConfig.java   | 10 ++--
 .../projetIndu/services/UserService.java      | 48 ++++++++--------
 .../resources/templates/doctor-dashboard.html | 17 +++---
 src/main/resources/templates/register.html    | 37 ++++++++++++
 12 files changed, 142 insertions(+), 190 deletions(-)
 delete mode 100644 src/main/java/com/projet/projetIndu/config/SecurityConfig.java
 delete mode 100644 src/main/java/com/projet/projetIndu/controllers/DashboardController.java
 create mode 100644 src/main/java/com/projet/projetIndu/controllers/PatientController.java
 delete mode 100644 src/main/java/com/projet/projetIndu/controllers/UserController.java
 delete mode 100644 src/main/java/com/projet/projetIndu/dto/RegisterRequest.java

diff --git a/src/main/java/com/projet/projetIndu/ProjetInduApplication.java b/src/main/java/com/projet/projetIndu/ProjetInduApplication.java
index ab5f191..a7037d5 100644
--- a/src/main/java/com/projet/projetIndu/ProjetInduApplication.java
+++ b/src/main/java/com/projet/projetIndu/ProjetInduApplication.java
@@ -1,27 +1,21 @@
 package com.projet.projetIndu;
 
-import com.projet.projetIndu.entities.Role;
-import com.projet.projetIndu.entities.User;
-import com.projet.projetIndu.services.UserService;
-import jakarta.annotation.PostConstruct;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.AutoConfigureOrder;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 
 @SpringBootApplication
 public class ProjetInduApplication {
-	@Autowired
-	private UserService userService;
+//	@Autowired
+//	private UserService userService;
+//
+//	@PostConstruct
+//	public void init() {
+//		User aichatou = userService.registerUser("aichatou", "test", Role.ADMIN);
+//		System.out.println(aichatou);
+//	}
 
-	@PostConstruct
-	public void init() {
-		User aichatou = userService.registerUser("aichatou", "test", Role.ADMIN);
-		System.out.println(aichatou);
-	}
-
-	public static void main(String[] args) {
-		SpringApplication.run(ProjetInduApplication.class, args);
-	}
+    public static void main(String[] args) {
+        SpringApplication.run(ProjetInduApplication.class, args);
+    }
 
 }
diff --git a/src/main/java/com/projet/projetIndu/config/SecurityConfig.java b/src/main/java/com/projet/projetIndu/config/SecurityConfig.java
deleted file mode 100644
index 4811941..0000000
--- a/src/main/java/com/projet/projetIndu/config/SecurityConfig.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.projet.projetIndu.config;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.security.web.SecurityFilterChain;
-
-@Configuration
-public class SecurityConfig {
-
-    @Bean
-    public BCryptPasswordEncoder passwordEncoder() {
-        return new BCryptPasswordEncoder();
-    }
-    @Bean
-    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
-        http
-                .csrf(csrf -> csrf.disable())  // Désactiver CSRF pour les tests (à activer en prod)
-                .authorizeHttpRequests(auth -> auth
-                        .requestMatchers("/", "/register", "/login", "/css/**", "/js/**").permitAll() // Pages publiques
-                        .requestMatchers("/dashboard/patient").hasAuthority("PATIENT") // Tableau de bord patient
-                        .requestMatchers("/dashboard/doctor").hasAuthority("DOCTOR") // Tableau de bord médecin
-                        .requestMatchers("/medical-files/**").authenticated() // Tout utilisateur connecté peut voir ses dossiers médicaux
-                        .anyRequest().authenticated()
-                )
-                .formLogin(form -> form
-                        .loginPage("/login")
-                        .defaultSuccessUrl("/dashboard", true) // Redirection après connexion
-                        .permitAll()
-                )
-                .logout(logout -> logout
-                        .logoutUrl("/logout")
-                        .logoutSuccessUrl("/login?logout")
-                        .permitAll()
-                );
-
-        return http.build();
-    }
-}
diff --git a/src/main/java/com/projet/projetIndu/controllers/AuthController.java b/src/main/java/com/projet/projetIndu/controllers/AuthController.java
index 4c7a21e..8a20b5d 100644
--- a/src/main/java/com/projet/projetIndu/controllers/AuthController.java
+++ b/src/main/java/com/projet/projetIndu/controllers/AuthController.java
@@ -1,11 +1,15 @@
 package com.projet.projetIndu.controllers;
 
+import com.projet.projetIndu.dto.UserRegistrationDTO;
 import com.projet.projetIndu.entities.Role;
-import com.projet.projetIndu.entities.User;
 import com.projet.projetIndu.services.UserService;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.time.LocalDate;
 
 @Controller
 public class AuthController {
@@ -24,24 +28,52 @@ public class AuthController {
     // Traite l'inscription
     @PostMapping("/register")
     public String registerUser(
-            @RequestParam String username,
+            @RequestParam String firstName,
+            @RequestParam String lastName,
+            @RequestParam String email,
             @RequestParam String password,
-            @RequestParam Role role,
+            @RequestParam String role,
+            @RequestParam(required = false) String dateOfBirth, // Facultatif
+            @RequestParam(required = false) String address,    // Facultatif
+            @RequestParam(required = false) String speciality, // Facultatif
             Model model) {
 
-        if (userService.getUserByUsername(username).isPresent()) {
+        if (userService.getUserByUsername(email).isPresent()) {
             model.addAttribute("error", "L'utilisateur existe déjà !");
             return "register";
         }
 
-        // Enregistrer l'utilisateur
-        User newUser = userService.registerUser(username, password, role);
+        Role userRole;
+        try {
+            userRole = Role.valueOf(role.toUpperCase());
+        } catch (IllegalArgumentException e) {
+            model.addAttribute("error", "Rôle invalide !");
+            return "register";
+        }
+
+        UserRegistrationDTO dto = new UserRegistrationDTO();
+        dto.setFirstName(firstName);
+        dto.setLastName(lastName);
+        dto.setEmail(email);
+        dto.setPassword(password);
+        dto.setRole(userRole);
 
-        // Redirection selon le rôle
-        if (newUser.getRole() == Role.DOCTOR) {
-            return "redirect:/doctor-dashboard";
-        } else {
-            return "redirect:/patient-dashboard";
+        if (userRole == Role.PATIENT) {
+            dto.setDateOfBirth(dateOfBirth != null ? LocalDate.parse(dateOfBirth) : null);
+            dto.setAddress(address);
+        } else if (userRole == Role.DOCTOR) {
+            dto.setSpeciality(speciality);
         }
+
+        // Enregistrer l'utilisateur
+        try {
+            userService.registerUser(dto);
+        } catch (IllegalArgumentException e) {
+            model.addAttribute("error", e.getMessage());
+            return "register";
+        }
+
+        return "redirect:/login?registered=true";
+
     }
 }
diff --git a/src/main/java/com/projet/projetIndu/controllers/DashboardController.java b/src/main/java/com/projet/projetIndu/controllers/DashboardController.java
deleted file mode 100644
index 37d97da..0000000
--- a/src/main/java/com/projet/projetIndu/controllers/DashboardController.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.projet.projetIndu.controllers;
-
-import org.springframework.security.core.Authentication;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-
-@Controller
-@RequestMapping("/dashboard")
-public class DashboardController {
-
-    @GetMapping
-    public String redirectDashboard(Authentication authentication) {
-        System.out.println("Roles de l'utilisateur: " + authentication.getAuthorities());
-
-        if (authentication.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ROLE_DOCTOR"))) {
-            return "redirect:/dashboard/doctor";
-        } else if (authentication.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ROLE_PATIENT"))) {
-            return "redirect:/dashboard/patient";
-        }
-        return "redirect:/login";
-    }
-
-
-    @GetMapping("/patient")
-    public String patientDashboard() {
-        System.out.println("Redirection vers le dashboard patient...");
-        return "patient-dashboard";
-    }
-
-    @GetMapping("/doctor")
-    public String doctorDashboard() {
-        return "doctor-dashboard";  // Vue pour le médecin
-    }
-}
-
diff --git a/src/main/java/com/projet/projetIndu/controllers/LoginController.java b/src/main/java/com/projet/projetIndu/controllers/LoginController.java
index c444a66..c543594 100644
--- a/src/main/java/com/projet/projetIndu/controllers/LoginController.java
+++ b/src/main/java/com/projet/projetIndu/controllers/LoginController.java
@@ -7,7 +7,7 @@ import org.springframework.web.bind.annotation.GetMapping;
 public class LoginController {
 
     @GetMapping("/login")
-    public String login() {
+    public String loginPage() {
         return "login";
     }
 }
diff --git a/src/main/java/com/projet/projetIndu/controllers/PatientController.java b/src/main/java/com/projet/projetIndu/controllers/PatientController.java
new file mode 100644
index 0000000..ceb65ab
--- /dev/null
+++ b/src/main/java/com/projet/projetIndu/controllers/PatientController.java
@@ -0,0 +1,10 @@
+package com.projet.projetIndu.controllers;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@RequestMapping("/patients") // doit concorder avec la route dans le SecurityConfig
+@Controller
+public class PatientController {
+
+}
diff --git a/src/main/java/com/projet/projetIndu/controllers/UserController.java b/src/main/java/com/projet/projetIndu/controllers/UserController.java
deleted file mode 100644
index beeefe3..0000000
--- a/src/main/java/com/projet/projetIndu/controllers/UserController.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.projet.projetIndu.controllers;
-
-import com.projet.projetIndu.dto.UserRegistrationDTO;
-import com.projet.projetIndu.services.UserService;
-import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.ModelAttribute;
-import org.springframework.web.bind.annotation.PostMapping;
-
-@Controller
-public class UserController {
-    private final UserService userService;
-
-    public UserController(UserService userService) {
-        this.userService = userService;
-    }
-
-    @GetMapping("/register")
-    public String showRegistrationForm(Model model) {
-        model.addAttribute("userDTO", new UserRegistrationDTO());
-        return "register";
-    }
-
-    @PostMapping("/register")
-    public String registerUser(@ModelAttribute("userDTO") UserRegistrationDTO userDTO, Model model) {
-        try {
-            userService.registerUser(userDTO);
-            return "redirect:/login";
-        } catch (IllegalArgumentException e) {
-            model.addAttribute("error", e.getMessage());
-            return "register";
-        }
-    }
-}
diff --git a/src/main/java/com/projet/projetIndu/dto/RegisterRequest.java b/src/main/java/com/projet/projetIndu/dto/RegisterRequest.java
deleted file mode 100644
index e5a363d..0000000
--- a/src/main/java/com/projet/projetIndu/dto/RegisterRequest.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.projet.projetIndu.dto;
-
-import com.projet.projetIndu.entities.Role;
-import lombok.Getter;
-import lombok.Setter;
-
-@Getter
-@Setter
-public class RegisterRequest {
-    private String username;
-    private String password;
-    private Role role;
-}
diff --git a/src/main/java/com/projet/projetIndu/security/SecurityConfig.java b/src/main/java/com/projet/projetIndu/security/SecurityConfig.java
index 51f4368..da719e5 100644
--- a/src/main/java/com/projet/projetIndu/security/SecurityConfig.java
+++ b/src/main/java/com/projet/projetIndu/security/SecurityConfig.java
@@ -21,17 +21,16 @@ public class SecurityConfig {
         return new BCryptPasswordEncoder();
     }
 
-
     @Bean
     public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
-        http.authorizeHttpRequests(auth -> auth
-                        .requestMatchers("/", "/login", "/register", "/css/**", "/js/**").permitAll()
+        http
+                .authorizeHttpRequests(auth -> auth
+                        .requestMatchers("/", "/register", "/login", "/css/**", "/js/**").permitAll() // Pages publiques
                         .requestMatchers("/admin/**").hasAuthority("ADMIN")
                         .requestMatchers("/doctors/**").hasAuthority("DOCTOR")
                         .requestMatchers("/patients/**").hasAuthority("PATIENT")
                         .anyRequest().authenticated()
                 )
-
                 .formLogin(form -> form
                         .loginPage("/login")
                         .usernameParameter("email")
@@ -89,5 +88,4 @@ public class SecurityConfig {
         return new GrantedAuthorityDefaults("");
     }
 
-
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/projet/projetIndu/services/UserService.java b/src/main/java/com/projet/projetIndu/services/UserService.java
index e731fcb..ba62a2d 100644
--- a/src/main/java/com/projet/projetIndu/services/UserService.java
+++ b/src/main/java/com/projet/projetIndu/services/UserService.java
@@ -1,7 +1,10 @@
 package com.projet.projetIndu.services;
 
 import com.projet.projetIndu.dto.UserRegistrationDTO;
-import com.projet.projetIndu.entities.*;
+import com.projet.projetIndu.entities.Admin;
+import com.projet.projetIndu.entities.Doctor;
+import com.projet.projetIndu.entities.Patient;
+import com.projet.projetIndu.entities.User;
 import com.projet.projetIndu.repositories.UserRepository;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.core.userdetails.UserDetails;
@@ -53,29 +56,31 @@ public class UserService implements UserDetailsService {
         String encodedPassword = passwordEncoder.encode(userDTO.getPassword());
         User user;
 
-        Role role;
-        try {
-            role = Role.valueOf(String.valueOf(userDTO.getRole()));
-
-            switch (role) {
-                case DOCTOR -> {
-                    Doctor doctor = new Doctor();
-                    doctor.setSpeciality(userDTO.getSpeciality());
-                    user = doctor;
+        switch (userDTO.getRole()) {
+            case DOCTOR -> {
+                if (userDTO.getSpeciality() == null || userDTO.getSpeciality().isEmpty()) {
+                    throw new IllegalArgumentException("Speciality is required for doctors");
                 }
-                case PATIENT -> {
-                    Patient patient = new Patient();
-                    patient.setDateOfBirth(userDTO.getDateOfBirth());
-                    patient.setAddress(userDTO.getAddress());
-                    user = patient;
+                Doctor doctor = new Doctor();
+                doctor.setSpeciality(userDTO.getSpeciality());
+                user = doctor;
+            }
+            case PATIENT -> {
+                if (userDTO.getDateOfBirth() == null) {
+                    throw new IllegalArgumentException("Date of birth is required for patients");
                 }
-                case ADMIN -> {
-                    user = new Admin();
+                if (userDTO.getAddress() == null || userDTO.getAddress().isBlank()) {
+                    throw new IllegalArgumentException("Address is required for patients");
                 }
-                default -> throw new IllegalArgumentException("Invalid role");
+                Patient patient = new Patient();
+                patient.setDateOfBirth(userDTO.getDateOfBirth());
+                patient.setAddress(userDTO.getAddress());
+                user = patient;
             }
-        } catch (IllegalArgumentException e) {
-            throw new IllegalArgumentException("Invalid role provided: " + userDTO.getRole());
+            case ADMIN -> {
+                user = new Admin();
+            }
+            default -> throw new IllegalArgumentException("Invalid role");
         }
 
         user.setFirstName(userDTO.getFirstName());
@@ -83,8 +88,7 @@ public class UserService implements UserDetailsService {
         user.setPhoneNumber(userDTO.getPhoneNumber());
         user.setEmail(userDTO.getEmail());
         user.setPassword(encodedPassword);
-        user.setRole(role);
-
+        user.setRole(userDTO.getRole());
 
         return userRepository.save(user);
     }
diff --git a/src/main/resources/templates/doctor-dashboard.html b/src/main/resources/templates/doctor-dashboard.html
index b511557..b6c86c3 100644
--- a/src/main/resources/templates/doctor-dashboard.html
+++ b/src/main/resources/templates/doctor-dashboard.html
@@ -22,7 +22,8 @@
 <main class="mt-12">
     <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
         <h2 class="text-3xl font-bold text-gray-800 text-center">Bienvenue sur votre tableau de bord</h2>
-        <p class="mt-4 text-lg text-gray-600 text-center">Consultez vos dossiers médicaux et gérez vos patients efficacement.</p>
+        <p class="mt-4 text-lg text-gray-600 text-center">Consultez vos dossiers médicaux et gérez vos patients
+            efficacement.</p>
 
         <div class="mt-8 grid grid-cols-1 md:grid-cols-2 gap-6">
             <a href="#" class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition">
@@ -35,15 +36,15 @@
                 <p class="mt-2 text-gray-600">Accéder aux dossiers médicaux de vos patients.</p>
             </a>
 
-            <a href="/appointments" class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition">
-                <h3 class="text-xl font-semibold text-gray-800">Rendez-vous</h3>
-                <p class="mt-2 text-gray-600">Gérer votre planning et vos rendez-vous.</p>
+            <a href="/appointments"
+               class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition md:col-span-2 flex items-center justify-center text-center">
+                <div class="space-y-2">
+                    <h3 class="text-xl font-semibold text-gray-800">Rendez-vous</h3>
+                    <p class="text-gray-600">Gérer votre planning et vos rendez-vous.</p>
+                </div>
             </a>
 
-            <a href="#" class="p-6 bg-white shadow-md rounded-lg hover:shadow-lg transition">
-                <h3 class="text-xl font-semibold text-gray-800">Statistiques</h3>
-                <p class="mt-2 text-gray-600">Voir vos consultations et performances.</p>
-            </a>
+
         </div>
     </div>
 </main>
diff --git a/src/main/resources/templates/register.html b/src/main/resources/templates/register.html
index 5dbff8b..df68dc5 100644
--- a/src/main/resources/templates/register.html
+++ b/src/main/resources/templates/register.html
@@ -6,6 +6,13 @@
     <link rel="stylesheet" th:href="@{/css/styles.css}">
     <link rel="stylesheet"
           href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
+    <script>
+        function toggleFields() {
+            var role = document.getElementById("role").value;
+            document.getElementById("doctorFields").style.display = (role === "DOCTOR") ? "block" : "none";
+            document.getElementById("patientFields").style.display = (role === "PATIENT") ? "block" : "none";
+        }
+    </script>
 </head>
 <body class="bg-light">
 <div class="container d-flex justify-content-center align-items-center vh-100">
@@ -28,6 +35,36 @@
                 <label for="password" class="form-label">Mot de passe</label>
                 <input type="password" class="form-control" id="password" name="password" required>
             </div>
+            <div class="mb-3">
+                <label for="role" class="form-label">Rôle</label>
+                <select class="form-control" id="role" name="role" required onchange="toggleFields()">
+                    <option value="PATIENT">Patient</option>
+                    <option value="DOCTOR">Médecin</option>
+                    <option value="ADMIN">Administrateur</option>
+                </select>
+            </div>
+
+            <!-- Champs spécifiques pour Médecin -->
+            <div id="doctorFields" style="display: none;">
+                <div class="mb-3">
+                    <label for="speciality" class="form-label">Spécialité</label>
+                    <input type="text" class="form-control" id="speciality" name="speciality">
+                </div>
+            </div>
+
+            <!-- Champs spécifiques pour Patient -->
+            <div id="patientFields">
+                <div class="mb-3">
+                    <label for="dateOfBirth" class="form-label">Date de naissance</label>
+                    <input type="date" class="form-control" id="dateOfBirth" name="dateOfBirth">
+                </div>
+                <div class="mb-3">
+                    <label for="address" class="form-label">Adresse</label>
+                    <input type="text" class="form-control" id="address" name="address">
+                </div>
+            </div>
+
+
             <button type="submit" class="btn btn-success w-100">S'inscrire</button>
         </form>
         <div class="text-center mt-3">
-- 
GitLab