From 82fb91a3d5d6b0baeabda63d30fad57f5cf0ed2a Mon Sep 17 00:00:00 2001 From: Martin Karlsson Date: Thu, 23 Apr 2026 20:48:00 +0200 Subject: [PATCH 01/23] Feature: - Added header to all templates where relevant - Removed dashboard/applicant and redirected directly to visas/dashboard - Added sign out logic to UserViewController and SecurityConfig --- .../config/SecurityConfig.java | 8 +- .../user/controller/UserViewController.java | 44 ++-- .../templates/dashboard/applicant.html | 188 ------------------ src/main/resources/templates/error/error.html | 50 ++++- .../resources/templates/fragments/header.html | 26 ++- .../resources/templates/visa/apply-form.html | 9 +- .../resources/templates/visa/dashboard.html | 12 +- .../resources/templates/visa/details.html | 9 +- .../resources/templates/visa/edit-form.html | 9 +- 9 files changed, 126 insertions(+), 229 deletions(-) delete mode 100644 src/main/resources/templates/dashboard/applicant.html diff --git a/src/main/java/org/example/visacasemanagementsystem/config/SecurityConfig.java b/src/main/java/org/example/visacasemanagementsystem/config/SecurityConfig.java index 208e14b..4b27895 100644 --- a/src/main/java/org/example/visacasemanagementsystem/config/SecurityConfig.java +++ b/src/main/java/org/example/visacasemanagementsystem/config/SecurityConfig.java @@ -7,6 +7,7 @@ import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.factory.PasswordEncoderFactories; @@ -32,20 +33,21 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .requestMatchers("/").permitAll() .requestMatchers("/user/signup").permitAll() .requestMatchers("/user/login").permitAll() - .requestMatchers("/logout").permitAll() + .requestMatchers("/user/logout").authenticated() .requestMatchers("/dashboard").authenticated() .requestMatchers("/profile/**").authenticated() .requestMatchers("/visas/**").authenticated() .requestMatchers("/api/comments/**").authenticated() .requestMatchers("/**/admin").hasRole("ADMIN") - .requestMatchers("/**/applicant").hasRole("USER") + // /dashboard/applicant was removed — USERs now land on /visas/dashboard + // (covered by the /visas/** authenticated matcher above). .anyRequest().hasRole("SYSADMIN") ) .headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)) .formLogin(l -> l .defaultSuccessUrl("/dashboard", true) .loginPage("/user/login")) - .logout(withDefaults()) //TODO: Custom logout page required + .logout(AbstractHttpConfigurer::disable) .httpBasic(withDefaults()); return http.build(); diff --git a/src/main/java/org/example/visacasemanagementsystem/user/controller/UserViewController.java b/src/main/java/org/example/visacasemanagementsystem/user/controller/UserViewController.java index 1d310a4..48330c6 100644 --- a/src/main/java/org/example/visacasemanagementsystem/user/controller/UserViewController.java +++ b/src/main/java/org/example/visacasemanagementsystem/user/controller/UserViewController.java @@ -1,6 +1,8 @@ package org.example.visacasemanagementsystem.user.controller; import jakarta.persistence.EntityNotFoundException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.example.visacasemanagementsystem.audit.service.UserLogService; import org.example.visacasemanagementsystem.audit.service.VisaLogService; import org.example.visacasemanagementsystem.exception.UnauthorizedException; @@ -13,7 +15,10 @@ import org.example.visacasemanagementsystem.visa.dto.VisaDTO; import org.example.visacasemanagementsystem.visa.service.VisaService; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @@ -41,16 +46,16 @@ public UserViewController(VisaService visaService, this.userLogService = userLogService; } - // Signup form for new users, accessible to all + // Signup form for new users, accessible to all. @PreAuthorize("permitAll()") @GetMapping("/user/signup") - public String userSignupForm(Model model) { + public String userSignupForm(@AuthenticationPrincipal UserPrincipal principal, Model model) { + if (principal != null) { + return "redirect:/dashboard"; + } return "user/signup"; } - // Posting a successful user creation then redirecting to the applicant dashboard since only applicants can be - // created through the signup process. Admins or Sysadmins are created from applicant users by given authorization - // from a sysadmin. @PreAuthorize("permitAll()") @PostMapping("/user/signup") public String createUser(@RequestParam String fullName, @@ -69,15 +74,26 @@ public String createUser(@RequestParam String fullName, } } - // Login page + // Login page. @PreAuthorize("permitAll()") @GetMapping("/user/login") - public String userLoginForm(){ + public String userLoginForm(@AuthenticationPrincipal UserPrincipal principal) { + if (principal != null) { + return "redirect:/dashboard"; + } return "user/login"; } - // Uneditable profile view from where the user themselves or a sysadmin can access the profile edit view through a - // button only available to them + // Sign-out endpoint. + @PreAuthorize("isAuthenticated()") + @PostMapping("/user/logout") + public String logout(HttpServletRequest request, HttpServletResponse response) { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + new SecurityContextLogoutHandler().logout(request, response, auth); + return "redirect:/user/login?logout"; + } + + // Uneditable profile view @GetMapping("/profile/view/{userId}") public String viewProfile(@AuthenticationPrincipal UserPrincipal principal, @PathVariable Long userId, @@ -179,16 +195,6 @@ public String userListView(@AuthenticationPrincipal UserPrincipal principal, return "user/list"; } - @PreAuthorize("hasRole('USER')") - @GetMapping("/dashboard/applicant") - public String applicantDashboard(@AuthenticationPrincipal UserPrincipal principal, - Model model) { - List visas = visaService.findVisasByApplicantId(principal.getUserId()); - model.addAttribute("name", principal.getFullName()); - model.addAttribute("visas", visas); - return "dashboard/applicant"; - } - @PreAuthorize("hasRole('ADMIN')") @GetMapping("/dashboard/admin") public String adminDashboard(@AuthenticationPrincipal UserPrincipal principal, diff --git a/src/main/resources/templates/dashboard/applicant.html b/src/main/resources/templates/dashboard/applicant.html deleted file mode 100644 index 35fbb41..0000000 --- a/src/main/resources/templates/dashboard/applicant.html +++ /dev/null @@ -1,188 +0,0 @@ - - - - - Dashboard - - - - - - - -
-
-
-
-

Your Applications

-

Welcome back, Applicant

-
-
- -
- -
-

You haven't submitted any visa applications yet.

- Apply for a Visa -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDVisa TypeNationalityStatusHandler
1Work VisaSweden - SUBMITTED - - 1 - Unassigned - - View → -
- Rejection reason: - -
-
-
-
- - - \ No newline at end of file diff --git a/src/main/resources/templates/error/error.html b/src/main/resources/templates/error/error.html index 41dd767..143a6f0 100644 --- a/src/main/resources/templates/error/error.html +++ b/src/main/resources/templates/error/error.html @@ -1,8 +1,11 @@ - + System Error - Visa Management + + + @@ -217,4 +127,4 @@

Unassigned Cases

- \ No newline at end of file + diff --git a/src/main/resources/templates/dashboard/sysadmin.html b/src/main/resources/templates/dashboard/sysadmin.html index 2ce0184..b4730e0 100644 --- a/src/main/resources/templates/dashboard/sysadmin.html +++ b/src/main/resources/templates/dashboard/sysadmin.html @@ -3,19 +3,12 @@ Sysadmin Dashboard - + + @@ -274,4 +168,4 @@

User Log

- \ No newline at end of file + diff --git a/src/main/resources/templates/error/error.html b/src/main/resources/templates/error/error.html index 143a6f0..0f0ab57 100644 --- a/src/main/resources/templates/error/error.html +++ b/src/main/resources/templates/error/error.html @@ -5,22 +5,9 @@ System Error - Visa Management - + + @@ -98,7 +74,7 @@
-
+
⚠️Error.

Something went wrong

The action could not be completed. Please verify your request or return to the dashboard.

diff --git a/src/main/resources/templates/fragments/header.html b/src/main/resources/templates/fragments/header.html index dcc9566..1214f09 100644 --- a/src/main/resources/templates/fragments/header.html +++ b/src/main/resources/templates/fragments/header.html @@ -3,64 +3,11 @@ xmlns:sec="http://www.thymeleaf.org/extras/spring-security" lang="en"> - +