Changeset 946877f
- Timestamp:
- 05/23/26 19:27:12 (4 months ago)
- Branches:
- master
- Children:
- ccb5a6b
- Parents:
- 43e476a
- Files:
-
- 1 added
- 11 edited
-
backend/src/main/java/medora/controller/AppointmentController.java (modified) (8 diffs)
-
backend/src/main/java/medora/controller/BillingController.java (modified) (9 diffs)
-
backend/src/main/java/medora/controller/DepartmentController.java (modified) (6 diffs)
-
backend/src/main/java/medora/controller/DoctorController.java (modified) (4 diffs)
-
backend/src/main/java/medora/controller/LabController.java (modified) (6 diffs)
-
backend/src/main/java/medora/controller/PatientController.java (modified) (4 diffs)
-
backend/src/main/java/medora/controller/ProcedureController.java (modified) (7 diffs)
-
backend/src/main/java/medora/controller/ReferralController.java (modified) (3 diffs)
-
backend/src/main/java/medora/dto/BillingDetailDTO.java (modified) (3 diffs)
-
backend/src/main/java/medora/util/JwtUtil.java (modified) (2 diffs)
-
backend/src/main/java/medora/util/SecurityUtil.java (added)
-
pom.xml (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
backend/src/main/java/medora/controller/AppointmentController.java
r43e476a r946877f 3 3 import medora.dto.AppointmentDTO; 4 4 import medora.dto.CreateAppointmentRequest; 5 import medora.dto.PatientDTO; 5 6 import medora.dto.DoctorDTO; 6 import medora.dto.PatientDTO;7 7 import medora.models.domain.Appointment; 8 import medora.models.domain.Patient; 9 import medora.models.domain.Doctors; 8 10 import medora.service.AppointmentService; 11 import medora.util.SecurityUtil; 9 12 import org.slf4j.Logger; 10 13 import org.slf4j.LoggerFactory; … … 13 16 import org.springframework.http.ResponseEntity; 14 17 import org.springframework.web.bind.annotation.*; 18 import jakarta.servlet.http.HttpServletRequest; 15 19 16 20 import java.time.LocalDate; … … 26 30 27 31 private final AppointmentService appointmentService; 28 29 public AppointmentController(AppointmentService appointmentService) { 32 private final SecurityUtil securityUtil; 33 34 public AppointmentController(AppointmentService appointmentService, SecurityUtil securityUtil) { 30 35 this.appointmentService = appointmentService; 36 this.securityUtil = securityUtil; 31 37 } 32 38 33 39 @PostMapping 34 public ResponseEntity<?> createAppointment(@RequestBody CreateAppointmentRequest request) { 35 try { 40 public ResponseEntity<?> createAppointment(@RequestBody CreateAppointmentRequest request, HttpServletRequest httpRequest) { 41 try { 42 String role = securityUtil.getRoleFromRequest(httpRequest); 43 if (role == null) { 44 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 45 .body(Map.of("error", "Unauthorized")); 46 } 47 36 48 if (request.getPatientId() == null || request.getPatientId() <= 0) { 37 49 return ResponseEntity.badRequest() … … 49 61 return ResponseEntity.badRequest() 50 62 .body(Map.of("error", "Appointment time is required")); 63 } 64 65 // Patients can only create appointments for themselves 66 if (role.equals("PATIENT")) { 67 Long patientIdFromToken = securityUtil.getPatientIdFromRequest(httpRequest); 68 if (patientIdFromToken == null || !patientIdFromToken.equals(request.getPatientId())) { 69 return ResponseEntity.status(HttpStatus.FORBIDDEN) 70 .body(Map.of("error", "You can only create appointments for yourself")); 71 } 51 72 } 52 73 … … 90 111 91 112 @GetMapping 92 public ResponseEntity<?> getAllAppointments() { 93 try { 94 logger.info("Fetching all appointments"); 95 List<Appointment> appointments = appointmentService.getAllAppointments(); 113 public ResponseEntity<?> getAllAppointments(HttpServletRequest httpRequest) { 114 try { 115 String role = securityUtil.getRoleFromRequest(httpRequest); 116 if (role == null) { 117 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 118 .body(Map.of("error", "Unauthorized")); 119 } 120 121 // Patients cannot view all appointments 122 if (role.equals("PATIENT")) { 123 return ResponseEntity.status(HttpStatus.FORBIDDEN) 124 .body(Map.of("error", "Patients cannot view all appointments")); 125 } 126 127 List<Appointment> appointments; 128 129 // Doctors can only view their own appointments 130 if (role.equals("DOCTOR")) { 131 Long doctorIdFromToken = securityUtil.getDoctorIdFromRequest(httpRequest); 132 if (doctorIdFromToken == null || doctorIdFromToken <= 0) { 133 return ResponseEntity.status(HttpStatus.FORBIDDEN) 134 .body(Map.of("error", "Doctor ID not found in token")); 135 } 136 logger.info("Fetching appointments for doctor ID: {}", doctorIdFromToken); 137 appointments = appointmentService.getAppointmentsForDoctor(doctorIdFromToken); 138 } else { 139 // ADMIN and other roles can view all appointments 140 logger.info("Fetching all appointments"); 141 appointments = appointmentService.getAllAppointments(); 142 } 143 96 144 List<AppointmentDTO> dtos = appointments.stream() 97 145 .map(this::convertToDTO) … … 110 158 111 159 @GetMapping("/patient/{patientId}") 112 public ResponseEntity<?> getAppointmentsForPatient(@PathVariable Long patientId) { 113 try { 160 public ResponseEntity<?> getAppointmentsForPatient(@PathVariable Long patientId, HttpServletRequest httpRequest) { 161 try { 162 String role = securityUtil.getRoleFromRequest(httpRequest); 163 if (role == null) { 164 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 165 .body(Map.of("error", "Unauthorized")); 166 } 167 168 // Patients can only view their own appointments 169 if (role.equals("PATIENT")) { 170 Long patientIdFromToken = securityUtil.getPatientIdFromRequest(httpRequest); 171 if (patientIdFromToken == null || !patientIdFromToken.equals(patientId)) { 172 return ResponseEntity.status(HttpStatus.FORBIDDEN) 173 .body(Map.of("error", "You can only view your own appointments")); 174 } 175 } 176 114 177 logger.info("Fetching appointments for patient ID: {}", patientId); 115 178 List<Appointment> appointments = appointmentService.getAppointmentsForPatient(patientId); … … 172 235 173 236 @PatchMapping("/{appointmentId}/cancel") 174 public ResponseEntity<?> cancelAppointment(@PathVariable Long appointmentId) { 175 try { 237 public ResponseEntity<?> cancelAppointment(@PathVariable Long appointmentId, HttpServletRequest httpRequest) { 238 try { 239 String role = securityUtil.getRoleFromRequest(httpRequest); 240 if (role == null) { 241 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 242 .body(Map.of("error", "Unauthorized")); 243 } 244 245 // Verify appointment exists and check permissions for patients 246 Appointment appointment = appointmentService.getAppointmentById(appointmentId) 247 .orElseThrow(() -> new RuntimeException("Appointment not found")); 248 249 if (role.equals("PATIENT")) { 250 Long patientIdFromToken = securityUtil.getPatientIdFromRequest(httpRequest); 251 Long appointmentPatientId = appointment.getPatient() != null ? appointment.getPatient().getPatientId() : null; 252 if (patientIdFromToken == null || !patientIdFromToken.equals(appointmentPatientId)) { 253 return ResponseEntity.status(HttpStatus.FORBIDDEN) 254 .body(Map.of("error", "You can only cancel your own appointments")); 255 } 256 } 257 176 258 logger.info("Cancelling appointment with ID: {}", appointmentId); 177 Appointmentappointment = appointmentService.cancelAppointment(appointmentId);259 appointment = appointmentService.cancelAppointment(appointmentId); 178 260 AppointmentDTO dto = convertToDTO(appointment); 179 261 return ResponseEntity.ok(dto); … … 190 272 191 273 @PatchMapping("/{appointmentId}/complete") 192 public ResponseEntity<?> completeAppointment(@PathVariable Long appointmentId) { 193 try { 274 public ResponseEntity<?> completeAppointment(@PathVariable Long appointmentId, HttpServletRequest httpRequest) { 275 try { 276 String role = securityUtil.getRoleFromRequest(httpRequest); 277 if (role == null) { 278 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 279 .body(Map.of("error", "Unauthorized")); 280 } 281 282 // Only ADMIN and DOCTOR can complete appointments 283 if (role.equals("PATIENT")) { 284 return ResponseEntity.status(HttpStatus.FORBIDDEN) 285 .body(Map.of("error", "Patients cannot complete appointments")); 286 } 287 194 288 logger.info("Completing appointment with ID: {}", appointmentId); 195 289 Appointment appointment = appointmentService.completeAppointment(appointmentId); -
backend/src/main/java/medora/controller/BillingController.java
r43e476a r946877f 9 9 import medora.service.BillingService; 10 10 import medora.util.BillingPDFGenerator; 11 import medora.util.SecurityUtil; 11 12 import org.slf4j.Logger; 12 13 import org.slf4j.LoggerFactory; … … 16 17 import org.springframework.http.ResponseEntity; 17 18 import org.springframework.web.bind.annotation.*; 19 import jakarta.servlet.http.HttpServletRequest; 18 20 19 21 import java.time.LocalDate; … … 29 31 30 32 private final BillingService billingService; 31 32 public BillingController(BillingService billingService) { 33 private final SecurityUtil securityUtil; 34 35 public BillingController(BillingService billingService, SecurityUtil securityUtil) { 33 36 this.billingService = billingService; 37 this.securityUtil = securityUtil; 34 38 } 35 39 36 40 @PostMapping 37 public ResponseEntity<?> generateBillingRecord(@RequestBody CreateBillingRequest request) { 38 try { 41 public ResponseEntity<?> generateBillingRecord(@RequestBody CreateBillingRequest request, HttpServletRequest httpRequest) { 42 try { 43 String role = securityUtil.getRoleFromRequest(httpRequest); 44 if (role == null) { 45 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 46 .body(Map.of("error", "Unauthorized")); 47 } 48 49 // Only ADMIN can generate billing records (doctors cannot access billing) 50 if (!role.equals("ADMIN")) { 51 return ResponseEntity.status(HttpStatus.FORBIDDEN) 52 .body(Map.of("error", "Only administrators can generate billing records")); 53 } 54 39 55 if (request.getMedicalRecordId() == null || request.getMedicalRecordId() <= 0) { 40 56 return ResponseEntity.badRequest() … … 70 86 71 87 @GetMapping("/{billId}") 72 public ResponseEntity<?> getBillingById(@PathVariable Long billId) { 73 try { 88 public ResponseEntity<?> getBillingById(@PathVariable Long billId, HttpServletRequest httpRequest) { 89 try { 90 String role = securityUtil.getRoleFromRequest(httpRequest); 91 if (role == null) { 92 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 93 .body(Map.of("error", "Unauthorized")); 94 } 95 96 // Doctors cannot access billing 97 if (role.equals("DOCTOR")) { 98 return ResponseEntity.status(HttpStatus.FORBIDDEN) 99 .body(Map.of("error", "Doctors cannot access billing records")); 100 } 101 74 102 logger.info("Fetching billing record with ID: {}", billId); 75 return billingService.getBillingById(billId) 76 .map(b -> ResponseEntity.ok(convertToDTO(b))) 77 .orElse(ResponseEntity.notFound().build()); 103 var billing = billingService.getBillingById(billId); 104 if (billing.isEmpty()) { 105 return ResponseEntity.notFound().build(); 106 } 107 108 // Patients can only view their own billing records 109 if (role.equals("PATIENT")) { 110 Long patientIdFromToken = securityUtil.getPatientIdFromRequest(httpRequest); 111 Long billPatientId = billing.get().getMedicalRecord() != null && billing.get().getMedicalRecord().getPatient() != null 112 ? billing.get().getMedicalRecord().getPatient().getPatientId() 113 : null; 114 if (patientIdFromToken == null || !patientIdFromToken.equals(billPatientId)) { 115 return ResponseEntity.status(HttpStatus.FORBIDDEN) 116 .body(Map.of("error", "You can only view your own billing records")); 117 } 118 } 119 120 return ResponseEntity.ok(convertToDTO(billing.get())); 78 121 } catch (RuntimeException e) { 79 122 logger.error("Error fetching billing record: {}", e.getMessage()); … … 88 131 89 132 @GetMapping("/{billId}/detail") 90 public ResponseEntity<?> getBillingDetail(@PathVariable Long billId) { 91 try { 133 public ResponseEntity<?> getBillingDetail(@PathVariable Long billId, HttpServletRequest httpRequest) { 134 try { 135 String role = securityUtil.getRoleFromRequest(httpRequest); 136 if (role == null) { 137 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 138 .body(Map.of("error", "Unauthorized")); 139 } 140 141 // Doctors cannot access billing 142 if (role.equals("DOCTOR")) { 143 return ResponseEntity.status(HttpStatus.FORBIDDEN) 144 .body(Map.of("error", "Doctors cannot access billing records")); 145 } 146 92 147 logger.info("Fetching detailed billing information for bill ID: {}", billId); 93 148 BillingDetailDTO detail = billingService.getBillingDetail(billId); 149 150 // Patients can only view their own billing details 151 if (role.equals("PATIENT")) { 152 Long patientIdFromToken = securityUtil.getPatientIdFromRequest(httpRequest); 153 if (patientIdFromToken == null || detail == null || !patientIdFromToken.equals(detail.getPatientId())) { 154 return ResponseEntity.status(HttpStatus.FORBIDDEN) 155 .body(Map.of("error", "You can only view your own billing records")); 156 } 157 } 158 94 159 return ResponseEntity.ok(detail); 95 160 } catch (RuntimeException e) { … … 105 170 106 171 @GetMapping 107 public ResponseEntity<?> getAllBillings() { 108 try { 172 public ResponseEntity<?> getAllBillings(HttpServletRequest httpRequest) { 173 try { 174 String role = securityUtil.getRoleFromRequest(httpRequest); 175 if (role == null) { 176 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 177 .body(Map.of("error", "Unauthorized")); 178 } 179 180 // Doctors and Patients cannot view all billing records 181 if (role.equals("PATIENT") || role.equals("DOCTOR")) { 182 return ResponseEntity.status(HttpStatus.FORBIDDEN) 183 .body(Map.of("error", "You cannot view all billing records")); 184 } 185 109 186 logger.info("Fetching all billing records"); 110 187 List<Billing> billings = billingService.getAllBillingRecords(); … … 125 202 126 203 @GetMapping("/patient/{patientId}") 127 public ResponseEntity<?> getBillingHistoryForPatient(@PathVariable Long patientId) { 128 try { 204 public ResponseEntity<?> getBillingHistoryForPatient(@PathVariable Long patientId, HttpServletRequest httpRequest) { 205 try { 206 String role = securityUtil.getRoleFromRequest(httpRequest); 207 if (role == null) { 208 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 209 .body(Map.of("error", "Unauthorized")); 210 } 211 212 // Doctors cannot access billing 213 if (role.equals("DOCTOR")) { 214 return ResponseEntity.status(HttpStatus.FORBIDDEN) 215 .body(Map.of("error", "Doctors cannot access billing records")); 216 } 217 218 // Patients can only view their own billing history 219 if (role.equals("PATIENT")) { 220 Long patientIdFromToken = securityUtil.getPatientIdFromRequest(httpRequest); 221 if (patientIdFromToken == null || !patientIdFromToken.equals(patientId)) { 222 return ResponseEntity.status(HttpStatus.FORBIDDEN) 223 .body(Map.of("error", "You can only view your own billing records")); 224 } 225 } 226 129 227 logger.info("Fetching billing history for patient ID: {}", patientId); 130 228 List<Billing> billings = billingService.getBillingHistoryForPatient(patientId); … … 146 244 @PatchMapping("/{billId}/payment-status") 147 245 public ResponseEntity<?> updatePaymentStatus(@PathVariable Long billId, 148 @RequestBody UpdateBillingRequest request) { 149 try { 246 @RequestBody UpdateBillingRequest request, 247 HttpServletRequest httpRequest) { 248 try { 249 String role = securityUtil.getRoleFromRequest(httpRequest); 250 if (role == null) { 251 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 252 .body(Map.of("error", "Unauthorized")); 253 } 254 255 // Only ADMIN can update payment status 256 if (!role.equals("ADMIN")) { 257 return ResponseEntity.status(HttpStatus.FORBIDDEN) 258 .body(Map.of("error", "Only administrators can update payment status")); 259 } 260 150 261 if (request.getPaymentStatus() == null) { 151 262 return ResponseEntity.badRequest() … … 170 281 171 282 @GetMapping("/{billId}/invoice-pdf") 172 public ResponseEntity<?> downloadInvoicePDF(@PathVariable Long billId) { 173 try { 283 public ResponseEntity<?> downloadInvoicePDF(@PathVariable Long billId, HttpServletRequest httpRequest) { 284 try { 285 String role = securityUtil.getRoleFromRequest(httpRequest); 286 if (role == null) { 287 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 288 .body(Map.of("error", "Unauthorized")); 289 } 290 291 // Doctors cannot access billing 292 if (role.equals("DOCTOR")) { 293 return ResponseEntity.status(HttpStatus.FORBIDDEN) 294 .body(Map.of("error", "Doctors cannot access billing records")); 295 } 296 174 297 logger.info("Generating PDF invoice for bill ID: {}", billId); 175 298 BillingDetailDTO billingDetail = billingService.getBillingDetail(billId); 299 300 // Patients can only download their own invoices 301 if (role.equals("PATIENT")) { 302 Long patientIdFromToken = securityUtil.getPatientIdFromRequest(httpRequest); 303 if (patientIdFromToken == null || !patientIdFromToken.equals(billingDetail.getPatientId())) { 304 return ResponseEntity.status(HttpStatus.FORBIDDEN) 305 .body(Map.of("error", "You can only download your own invoices")); 306 } 307 } 308 176 309 byte[] pdfContent = BillingPDFGenerator.generateInvoicePDF(billingDetail); 177 310 -
backend/src/main/java/medora/controller/DepartmentController.java
r43e476a r946877f 4 4 import medora.models.domain.Doctors; 5 5 import medora.service.DepartmentService; 6 import medora.util.SecurityUtil; 6 7 import org.slf4j.Logger; 7 8 import org.slf4j.LoggerFactory; … … 9 10 import org.springframework.http.ResponseEntity; 10 11 import org.springframework.web.bind.annotation.*; 12 import jakarta.servlet.http.HttpServletRequest; 11 13 12 14 import java.util.List; … … 21 23 22 24 private final DepartmentService departmentService; 23 24 public DepartmentController(DepartmentService departmentService) { 25 private final SecurityUtil securityUtil; 26 27 public DepartmentController(DepartmentService departmentService, SecurityUtil securityUtil) { 25 28 this.departmentService = departmentService; 29 this.securityUtil = securityUtil; 26 30 } 27 31 … … 67 71 } 68 72 69 73 /** 74 * Get department by name 75 */ 70 76 @GetMapping("/name/{departmentName}") 71 77 public ResponseEntity<?> getDepartmentByName(@PathVariable String departmentName) { … … 110 116 } 111 117 112 118 /** 119 * Create a new department 120 */ 113 121 @PostMapping 114 public ResponseEntity<?> createDepartment(@RequestBody Map<String, String> request) { 115 try { 122 public ResponseEntity<?> createDepartment(@RequestBody Map<String, String> request, HttpServletRequest httpRequest) { 123 try { 124 String role = securityUtil.getRoleFromRequest(httpRequest); 125 if (role == null) { 126 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 127 .body(Map.of("error", "Unauthorized")); 128 } 129 130 // Only ADMIN can create departments 131 if (!role.equals("ADMIN")) { 132 return ResponseEntity.status(HttpStatus.FORBIDDEN) 133 .body(Map.of("error", "Only administrators can create departments")); 134 } 135 116 136 String departmentName = request.get("departmentName"); 117 137 if (departmentName == null || departmentName.isBlank()) { … … 137 157 } 138 158 139 159 /** 160 * Update a department 161 */ 140 162 @PutMapping("/{departmentId}") 141 163 public ResponseEntity<?> updateDepartment(@PathVariable Long departmentId, 142 @RequestBody Map<String, String> request) { 143 try { 164 @RequestBody Map<String, String> request, 165 HttpServletRequest httpRequest) { 166 try { 167 String role = securityUtil.getRoleFromRequest(httpRequest); 168 if (role == null) { 169 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 170 .body(Map.of("error", "Unauthorized")); 171 } 172 173 // Only ADMIN can update departments 174 if (!role.equals("ADMIN")) { 175 return ResponseEntity.status(HttpStatus.FORBIDDEN) 176 .body(Map.of("error", "Only administrators can update departments")); 177 } 178 144 179 String departmentName = request.get("departmentName"); 145 180 if (departmentName == null || departmentName.isBlank()) { -
backend/src/main/java/medora/controller/DoctorController.java
r43e476a r946877f 1 1 package medora.controller; 2 2 3 import medora.dto.*; 4 import medora.models.domain.Departments; 3 import medora.dto.DoctorDTO; 4 import medora.dto.CreateDoctorRequest; 5 import medora.dto.DoctorLevelDTO; 6 import medora.dto.DoctorSpecializationDTO; 7 import medora.dto.DepartmentDTO; 8 import medora.models.domain.Doctors; 5 9 import medora.models.domain.DoctorLevel; 6 10 import medora.models.domain.DoctorSpecialization; 7 import medora.models.domain.D octors;11 import medora.models.domain.Departments; 8 12 import medora.service.DoctorService; 13 import medora.util.SecurityUtil; 9 14 import org.slf4j.Logger; 10 15 import org.slf4j.LoggerFactory; … … 12 17 import org.springframework.http.ResponseEntity; 13 18 import org.springframework.web.bind.annotation.*; 19 import jakarta.servlet.http.HttpServletRequest; 14 20 15 21 import java.util.List; … … 24 30 25 31 private final DoctorService doctorService; 26 27 public DoctorController(DoctorService doctorService) { 32 private final SecurityUtil securityUtil; 33 34 public DoctorController(DoctorService doctorService, SecurityUtil securityUtil) { 28 35 this.doctorService = doctorService; 36 this.securityUtil = securityUtil; 29 37 } 30 38 31 39 @PostMapping 32 public ResponseEntity<?> createDoctor(@RequestBody CreateDoctorRequest request) { 33 try { 40 public ResponseEntity<?> createDoctor(@RequestBody CreateDoctorRequest request, HttpServletRequest httpRequest) { 41 try { 42 String role = securityUtil.getRoleFromRequest(httpRequest); 43 if (role == null) { 44 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 45 .body(Map.of("error", "Unauthorized")); 46 } 47 48 // Only ADMIN can create doctors 49 if (!role.equals("ADMIN")) { 50 return ResponseEntity.status(HttpStatus.FORBIDDEN) 51 .body(Map.of("error", "Only administrators can create doctors")); 52 } 34 53 if (request.getFirstName() == null || request.getFirstName().isBlank()) { 35 54 return ResponseEntity.badRequest() … … 193 212 @PutMapping("/{doctorId}") 194 213 public ResponseEntity<?> updateDoctor(@PathVariable Long doctorId, 195 @RequestBody CreateDoctorRequest request) { 196 try { 214 @RequestBody CreateDoctorRequest request, 215 HttpServletRequest httpRequest) { 216 try { 217 String role = securityUtil.getRoleFromRequest(httpRequest); 218 if (role == null) { 219 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 220 .body(Map.of("error", "Unauthorized")); 221 } 222 223 // Only ADMIN can update doctors 224 if (!role.equals("ADMIN")) { 225 return ResponseEntity.status(HttpStatus.FORBIDDEN) 226 .body(Map.of("error", "Only administrators can update doctors")); 227 } 228 197 229 logger.info("Updating doctor with ID: {}", doctorId); 198 230 -
backend/src/main/java/medora/controller/LabController.java
r43e476a r946877f 2 2 3 3 import medora.dto.*; 4 import medora.models.domain.LabResults; 5 import medora.models.domain.LabTests; 6 import medora.models.domain.MedicalRecordLabResults; 7 import medora.models.domain.PerformedLabTests; 4 import medora.models.domain.*; 8 5 import medora.service.LabService; 6 import medora.util.SecurityUtil; 9 7 import org.slf4j.Logger; 10 8 import org.slf4j.LoggerFactory; … … 12 10 import org.springframework.http.ResponseEntity; 13 11 import org.springframework.web.bind.annotation.*; 12 import jakarta.servlet.http.HttpServletRequest; 14 13 15 14 import java.util.List; … … 24 23 25 24 private final LabService labService; 26 27 public LabController(LabService labService) { 25 private final SecurityUtil securityUtil; 26 27 public LabController(LabService labService, SecurityUtil securityUtil) { 28 28 this.labService = labService; 29 this.securityUtil = securityUtil; 29 30 } 30 31 31 32 @PostMapping 32 public ResponseEntity<?> createLabTest(@RequestBody CreateLabTestRequest request) { 33 try { 33 public ResponseEntity<?> createLabTest(@RequestBody CreateLabTestRequest request, HttpServletRequest httpRequest) { 34 try { 35 String role = securityUtil.getRoleFromRequest(httpRequest); 36 if (role == null) { 37 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 38 .body(Map.of("error", "Unauthorized")); 39 } 40 41 // Only ADMIN can create lab tests 42 if (!role.equals("ADMIN")) { 43 return ResponseEntity.status(HttpStatus.FORBIDDEN) 44 .body(Map.of("error", "Only administrators can create lab tests")); 45 } 46 34 47 if (request.getTestName() == null || request.getTestName().isBlank()) { 35 48 return ResponseEntity.badRequest() … … 100 113 @PutMapping("/{testId}") 101 114 public ResponseEntity<?> updateLabTest(@PathVariable Long testId, 102 @RequestBody CreateLabTestRequest request) {115 @RequestBody CreateLabTestRequest request) { 103 116 try { 104 117 logger.info("Updating lab test with ID: {}", testId); … … 123 136 124 137 @PostMapping("/request") 125 public ResponseEntity<?> requestLabTest(@RequestBody RequestLabTestRequest request) { 126 try { 138 public ResponseEntity<?> requestLabTest(@RequestBody RequestLabTestRequest request, HttpServletRequest httpRequest) { 139 try { 140 String role = securityUtil.getRoleFromRequest(httpRequest); 141 if (role == null) { 142 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 143 .body(Map.of("error", "Unauthorized")); 144 } 145 146 // Patients cannot request lab tests 147 if (role.equals("PATIENT")) { 148 return ResponseEntity.status(HttpStatus.FORBIDDEN) 149 .body(Map.of("error", "Patients cannot request lab tests")); 150 } 151 127 152 logger.info("Requesting lab test {} for patient {}", request.getTestId(), request.getPatientId()); 128 153 … … 193 218 194 219 @PostMapping("/results") 195 public ResponseEntity<?> submitLabResult(@RequestBody SubmitLabResultRequest request) { 196 try { 220 public ResponseEntity<?> submitLabResult(@RequestBody SubmitLabResultRequest request, HttpServletRequest httpRequest) { 221 try { 222 String role = securityUtil.getRoleFromRequest(httpRequest); 223 if (role == null) { 224 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 225 .body(Map.of("error", "Unauthorized")); 226 } 227 228 // Only LAB_TECHNICIAN can submit lab results (not DOCTOR) 229 if (!role.equals("LAB_TECHNICIAN")) { 230 return ResponseEntity.status(HttpStatus.FORBIDDEN) 231 .body(Map.of("error", "Only lab technicians can submit lab results")); 232 } 233 197 234 logger.info("Submitting lab result for medical record {}", request.getMedicalRecordId()); 198 235 -
backend/src/main/java/medora/controller/PatientController.java
r43e476a r946877f 1 1 package medora.controller; 2 2 3 import medora.dto.PatientDTO; 3 4 import medora.dto.CreatePatientRequest; 4 import medora.dto.PatientDTO;5 5 import medora.models.domain.Patient; 6 6 import medora.service.PatientService; 7 import medora.util.SecurityUtil; 7 8 import org.slf4j.Logger; 8 9 import org.slf4j.LoggerFactory; … … 10 11 import org.springframework.http.ResponseEntity; 11 12 import org.springframework.web.bind.annotation.*; 13 import jakarta.servlet.http.HttpServletRequest; 12 14 13 15 import java.util.List; … … 22 24 23 25 private final PatientService patientService; 24 25 public PatientController(PatientService patientService) { 26 private final SecurityUtil securityUtil; 27 28 public PatientController(PatientService patientService, SecurityUtil securityUtil) { 26 29 this.patientService = patientService; 30 this.securityUtil = securityUtil; 27 31 } 28 32 29 33 @PostMapping 30 public ResponseEntity<?> createPatient(@RequestBody CreatePatientRequest request) { 31 try { 34 public ResponseEntity<?> createPatient(@RequestBody CreatePatientRequest request, HttpServletRequest httpRequest) { 35 try { 36 String role = securityUtil.getRoleFromRequest(httpRequest); 37 if (role == null) { 38 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 39 .body(Map.of("error", "Unauthorized")); 40 } 41 42 // Only ADMIN can create patients 43 if (!role.equals("ADMIN")) { 44 return ResponseEntity.status(HttpStatus.FORBIDDEN) 45 .body(Map.of("error", "Only administrators can create patients")); 46 } 32 47 if (request.getFirstName() == null || request.getFirstName().isBlank()) { 33 48 return ResponseEntity.badRequest() … … 144 159 @PutMapping("/{patientId}") 145 160 public ResponseEntity<?> updatePatient(@PathVariable Long patientId, 146 @RequestBody CreatePatientRequest request) { 147 try { 161 @RequestBody CreatePatientRequest request, 162 HttpServletRequest httpRequest) { 163 try { 164 String role = securityUtil.getRoleFromRequest(httpRequest); 165 if (role == null) { 166 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 167 .body(Map.of("error", "Unauthorized")); 168 } 169 170 // Only ADMIN can update patients 171 if (!role.equals("ADMIN")) { 172 return ResponseEntity.status(HttpStatus.FORBIDDEN) 173 .body(Map.of("error", "Only administrators can update patients")); 174 } 175 148 176 logger.info("Updating patient with ID: {}", patientId); 149 177 -
backend/src/main/java/medora/controller/ProcedureController.java
r43e476a r946877f 5 5 import medora.dto.SubmitProcedureResultRequest; 6 6 import medora.models.domain.PerformedProcedures; 7 import medora.models.domain.Procedure; 7 8 import medora.models.domain.ProcedureResults; 8 9 import medora.service.ProcedureService; 10 import medora.util.SecurityUtil; 9 11 import org.slf4j.Logger; 10 12 import org.slf4j.LoggerFactory; … … 13 15 import org.springframework.http.ResponseEntity; 14 16 import org.springframework.web.bind.annotation.*; 17 import jakarta.servlet.http.HttpServletRequest; 15 18 16 19 import java.time.LocalDate; … … 26 29 27 30 private final ProcedureService procedureService; 28 29 public ProcedureController(ProcedureService procedureService) { 31 private final SecurityUtil securityUtil; 32 33 public ProcedureController(ProcedureService procedureService, SecurityUtil securityUtil) { 30 34 this.procedureService = procedureService; 35 this.securityUtil = securityUtil; 31 36 } 32 37 … … 48 53 49 54 @PostMapping("/request") 50 public ResponseEntity<?> requestProcedure(@RequestBody RequestProcedureRequest request) { 51 try { 55 public ResponseEntity<?> requestProcedure(@RequestBody RequestProcedureRequest request, HttpServletRequest httpRequest) { 56 try { 57 String role = securityUtil.getRoleFromRequest(httpRequest); 58 if (role == null) { 59 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 60 .body(Map.of("error", "Unauthorized")); 61 } 62 63 // Patients cannot request procedures 64 if (role.equals("PATIENT")) { 65 return ResponseEntity.status(HttpStatus.FORBIDDEN) 66 .body(Map.of("error", "Patients cannot request procedures")); 67 } 68 52 69 logger.info("Requesting procedure {} for patient {}", request.getProcedureId(), request.getPatientId()); 53 70 … … 207 224 public ResponseEntity<?> recordProcedureOutcome( 208 225 @PathVariable Long procedureId, 209 @RequestParam String notes) { 210 try { 226 @RequestParam String notes, 227 HttpServletRequest httpRequest) { 228 try { 229 String role = securityUtil.getRoleFromRequest(httpRequest); 230 if (role == null) { 231 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 232 .body(Map.of("error", "Unauthorized")); 233 } 234 235 // Only DOCTOR and ADMIN can record procedure outcomes 236 if (role.equals("PATIENT")) { 237 return ResponseEntity.status(HttpStatus.FORBIDDEN) 238 .body(Map.of("error", "Patients cannot record procedure outcomes")); 239 } 240 211 241 logger.info("Recording procedure outcome for ID: {}", procedureId); 212 242 PerformedProcedures procedure = procedureService.recordProcedureOutcome(procedureId, notes); … … 232 262 233 263 @PostMapping("/results") 234 public ResponseEntity<?> submitProcedureResult(@RequestBody SubmitProcedureResultRequest request) { 235 try { 264 public ResponseEntity<?> submitProcedureResult(@RequestBody SubmitProcedureResultRequest request, HttpServletRequest httpRequest) { 265 try { 266 String role = securityUtil.getRoleFromRequest(httpRequest); 267 if (role == null) { 268 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 269 .body(Map.of("error", "Unauthorized")); 270 } 271 272 // Only DOCTOR can submit procedure results 273 if (!role.equals("DOCTOR")) { 274 return ResponseEntity.status(HttpStatus.FORBIDDEN) 275 .body(Map.of("error", "Only doctors can submit procedure results")); 276 } 277 236 278 logger.info("Submitting procedure result for medical record {}", request.getMedicalRecordId()); 237 279 … … 292 334 private Map<String, Object> convertResultToDTO(ProcedureResults result) { 293 335 return Map.of( 294 "resultId", result.getResultId(),295 "procedureId", result.getProcedure().getProcedureId(),296 "procedureType", result.getProcedure().getProcedureType(),297 "resultDescription", result.getResultDescription() != null ? result.getResultDescription() : "",298 "resultDate", result.getResultDate()336 "resultId", result.getResultId(), 337 "procedureId", result.getProcedure().getProcedureId(), 338 "procedureType", result.getProcedure().getProcedureType(), 339 "resultDescription", result.getResultDescription() != null ? result.getResultDescription() : "", 340 "resultDate", result.getResultDate() 299 341 ); 300 342 } 301 343 } 344 -
backend/src/main/java/medora/controller/ReferralController.java
r43e476a r946877f 5 5 import medora.models.domain.Referrals; 6 6 import medora.service.ReferralService; 7 import medora.util.SecurityUtil; 7 8 import org.slf4j.Logger; 8 9 import org.slf4j.LoggerFactory; … … 10 11 import org.springframework.http.ResponseEntity; 11 12 import org.springframework.web.bind.annotation.*; 13 import jakarta.servlet.http.HttpServletRequest; 12 14 13 15 import java.util.List; … … 22 24 23 25 private final ReferralService referralService; 24 25 public ReferralController(ReferralService referralService) { 26 private final SecurityUtil securityUtil; 27 28 public ReferralController(ReferralService referralService, SecurityUtil securityUtil) { 26 29 this.referralService = referralService; 30 this.securityUtil = securityUtil; 27 31 } 28 32 29 33 @PostMapping 30 public ResponseEntity<?> createReferral(@RequestBody CreateReferralRequest request) { 31 try { 34 public ResponseEntity<?> createReferral(@RequestBody CreateReferralRequest request, HttpServletRequest httpRequest) { 35 try { 36 String role = securityUtil.getRoleFromRequest(httpRequest); 37 if (role == null) { 38 return ResponseEntity.status(HttpStatus.UNAUTHORIZED) 39 .body(Map.of("error", "Unauthorized")); 40 } 41 42 // Patients cannot create referrals 43 if (role.equals("PATIENT")) { 44 return ResponseEntity.status(HttpStatus.FORBIDDEN) 45 .body(Map.of("error", "Patients cannot create referrals")); 46 } 47 32 48 if (request.getMedicalRecordId() == null || request.getMedicalRecordId() <= 0) { 33 49 return ResponseEntity.badRequest() -
backend/src/main/java/medora/dto/BillingDetailDTO.java
r43e476a r946877f 7 7 public class BillingDetailDTO { 8 8 private Long billId; 9 private Long patientId; 9 10 private String patientName; 10 11 private String patientEmbg; … … 19 20 public BillingDetailDTO() {} 20 21 21 public BillingDetailDTO(Long billId, String patientName, String patientEmbg, String patientPhone,22 public BillingDetailDTO(Long billId, Long patientId, String patientName, String patientEmbg, String patientPhone, 22 23 BigDecimal totalCost, String paymentStatus, LocalDate paymentDate, 23 24 LocalDate billDate, List<BillingItemDTO> procedures, List<BillingItemDTO> labTests) { 24 25 this.billId = billId; 26 this.patientId = patientId; 25 27 this.patientName = patientName; 26 28 this.patientEmbg = patientEmbg; … … 37 39 public Long getBillId() { return billId; } 38 40 public void setBillId(Long billId) { this.billId = billId; } 41 42 public Long getPatientId() { return patientId; } 43 public void setPatientId(Long patientId) { this.patientId = patientId; } 39 44 40 45 public String getPatientName() { return patientName; } -
backend/src/main/java/medora/util/JwtUtil.java
r43e476a r946877f 1 1 package medora.util; 2 2 3 import io.jsonwebtoken.Claims; 3 4 import io.jsonwebtoken.Jwts; 4 5 import io.jsonwebtoken.SignatureAlgorithm; … … 9 10 import javax.crypto.SecretKey; 10 11 import java.util.Date; 12 import java.util.HashMap; 13 import java.util.Map; 11 14 12 15 @Component 13 16 public class JwtUtil { 14 17 15 @Value("${jwt.secret: your-secret-key-change-this-in-production}")18 @Value("${jwt.secret:MyVerySecretKeyForJWTTokenGenerationAndValidationPurposesOnly12345}") 16 19 private String jwtSecret; 17 20 18 @Value("${jwt.expiration:86400000}") 21 @Value("${jwt.expiration:86400000}") // 24 hours in milliseconds 19 22 private long jwtExpirationMs; 20 23 24 private SecretKey getSigningKey() { 25 return Keys.hmacShaKeyFor(jwtSecret.getBytes()); 26 } 27 21 28 public String generateToken(String username, String role, Long userId, Long patientId) { 22 SecretKey key = Keys.hmacShaKeyFor(jwtSecret.getBytes()); 29 return generateTokenWithDoctorId(username, role, userId, patientId, null); 30 } 23 31 32 public String generateTokenWithDoctorId(String username, String role, Long userId, Long patientId, Long doctorId) { 33 Map<String, Object> claims = new HashMap<>(); 34 claims.put("role", role); 35 claims.put("userId", userId); 36 if (patientId != null) { 37 claims.put("patientId", patientId); 38 } 39 if (doctorId != null) { 40 claims.put("doctorId", doctorId); 41 } 42 return createToken(claims, username); 43 } 44 45 private String createToken(Map<String, Object> claims, String subject) { 24 46 return Jwts.builder() 25 .subject(username) 26 .claim("role", role) 27 .claim("userId", userId) 28 .claim("patientId", patientId) 29 .issuedAt(new Date()) 30 .expiration(new Date(System.currentTimeMillis() + jwtExpirationMs)) 31 .signWith(key, SignatureAlgorithm.HS256) 47 .setClaims(claims) 48 .setSubject(subject) 49 .setIssuedAt(new Date()) 50 .setExpiration(new Date(System.currentTimeMillis() + jwtExpirationMs)) 51 .signWith(getSigningKey(), SignatureAlgorithm.HS256) 32 52 .compact(); 33 53 } 54 55 public String extractUsername(String token) { 56 return extractClaim(token, Claims::getSubject); 57 } 58 59 public String extractRole(String token) { 60 return extractClaim(token, claims -> (String) claims.get("role")); 61 } 62 63 public Long extractUserId(String token) { 64 return extractClaim(token, claims -> ((Number) claims.get("userId")).longValue()); 65 } 66 67 public Long extractPatientId(String token) { 68 return extractClaim(token, claims -> { 69 Object patientId = claims.get("patientId"); 70 return patientId != null ? ((Number) patientId).longValue() : null; 71 }); 72 } 73 74 public Long extractDoctorId(String token) { 75 return extractClaim(token, claims -> { 76 Object doctorId = claims.get("doctorId"); 77 return doctorId != null ? ((Number) doctorId).longValue() : null; 78 }); 79 } 80 81 public <T> T extractClaim(String token, java.util.function.Function<Claims, T> claimsResolver) { 82 final Claims claims = extractAllClaims(token); 83 return claimsResolver.apply(claims); 84 } 85 86 private Claims extractAllClaims(String token) { 87 return Jwts.parser() 88 .verifyWith(getSigningKey()) 89 .build() 90 .parseSignedClaims(token) 91 .getPayload(); 92 } 93 94 public boolean isTokenValid(String token) { 95 try { 96 Jwts.parser() 97 .verifyWith(getSigningKey()) 98 .build() 99 .parseSignedClaims(token); 100 return true; 101 } catch (Exception e) { 102 return false; 103 } 104 } 105 106 public boolean isTokenExpired(String token) { 107 return extractClaim(token, Claims::getExpiration).before(new Date()); 108 } 34 109 } -
pom.xml
r43e476a r946877f 10 10 </parent> 11 11 <groupId>medora</groupId> 12 <artifactId>medora 4</artifactId>12 <artifactId>medora5</artifactId> 13 13 <version>0.0.1-SNAPSHOT</version> 14 14 <name>medora5</name>
Note:
See TracChangeset
for help on using the changeset viewer.
