From 5760c7d30c546450a3d0c389fc37e28bf57e93e6 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 5 Oct 2025 13:15:26 +0200 Subject: [PATCH] - implemented simulated user in dev profile --- .../layout/bulkedit/BulkEditRow.vue | 6 +- .../components/layout/edit/MaterialEdit.vue | 2 +- .../components/layout/edit/PackagingEdit.vue | 8 +- .../components/layout/edit/SupplierView.vue | 4 +- .../src/pages/CalculationSingleEdit.vue | 55 ++++++--- .../lcc/config/DevUserEmulationFilter.java | 115 ++++++++++++++++++ .../de/avatic/lcc/config/SecurityConfig.java | 8 +- .../bulk/BulkOperationController.java | 6 +- .../lcc/controller/dev/DevController.java | 13 +- .../users/ActiveUserController.java | 20 ++- .../lcc/repositories/MaterialRepository.java | 21 ---- .../authorization/AuthorizationService.java | 12 -- .../DefaultAuthorizationService.java | 15 --- .../SimulatedAuthorizationService.java | 36 ------ 14 files changed, 196 insertions(+), 125 deletions(-) create mode 100644 src/main/java/de/avatic/lcc/config/DevUserEmulationFilter.java delete mode 100644 src/main/java/de/avatic/lcc/service/users/authorization/AuthorizationService.java delete mode 100644 src/main/java/de/avatic/lcc/service/users/authorization/DefaultAuthorizationService.java delete mode 100644 src/main/java/de/avatic/lcc/service/users/authorization/SimulatedAuthorizationService.java diff --git a/src/frontend/src/components/layout/bulkedit/BulkEditRow.vue b/src/frontend/src/components/layout/bulkedit/BulkEditRow.vue index 6d7902a..9a1f5c9 100644 --- a/src/frontend/src/components/layout/bulkedit/BulkEditRow.vue +++ b/src/frontend/src/components/layout/bulkedit/BulkEditRow.vue @@ -6,9 +6,9 @@
{{ premise.material.part_number }}
-
- {{ premise.material.name }} -
+ + +
HS Code: {{ premise.material.hs_code }} diff --git a/src/frontend/src/components/layout/edit/MaterialEdit.vue b/src/frontend/src/components/layout/edit/MaterialEdit.vue index b2f1f14..30856e2 100644 --- a/src/frontend/src/components/layout/edit/MaterialEdit.vue +++ b/src/frontend/src/components/layout/edit/MaterialEdit.vue @@ -8,7 +8,7 @@ - +
diff --git a/src/frontend/src/components/layout/edit/PackagingEdit.vue b/src/frontend/src/components/layout/edit/PackagingEdit.vue index 731f35f..b319ecf 100644 --- a/src/frontend/src/components/layout/edit/PackagingEdit.vue +++ b/src/frontend/src/components/layout/edit/PackagingEdit.vue @@ -1,7 +1,7 @@ diff --git a/src/frontend/src/pages/CalculationSingleEdit.vue b/src/frontend/src/pages/CalculationSingleEdit.vue index 5077ddd..9e2ff29 100644 --- a/src/frontend/src/pages/CalculationSingleEdit.vue +++ b/src/frontend/src/pages/CalculationSingleEdit.vue @@ -3,7 +3,8 @@
- {{ fromMassEdit ? 'Back' : 'Close' }} + {{ fromMassEdit ? 'Back' : 'Close' }}
- +
@@ -40,7 +41,18 @@
-

Master data

+ +
+

Material

+

Price

+

Handling unit

+
+ + +
+

Master data

+
+
authorities = new HashSet<>(); + user.getGroups().forEach(group -> + authorities.add(new SimpleGrantedAuthority("ROLE_" + group.getName().toUpperCase())) + ); + + // Create a mock OIDC user + Map claims = new HashMap<>(); + claims.put("sub", user.getId().toString()); + claims.put("email", user.getEmail()); + claims.put("preferred_username", user.getEmail()); + claims.put("name", user.getFirstName() + " " + user.getLastName()); + if (user.getWorkdayId() != null) { + claims.put("workday_id", user.getWorkdayId()); + } + + OidcIdToken idToken = new OidcIdToken( + "mock-token", + Instant.now(), + Instant.now().plusSeconds(3600), + claims + ); + + OidcUserInfo userInfo = new OidcUserInfo(claims); + + LccOidcUser oidcUser = new LccOidcUser( + authorities, + idToken, + userInfo, + "preferred_username", + user.getId() + ); + + Authentication authentication = new PreAuthenticatedAuthenticationToken( + oidcUser, + null, + authorities + ); + + SecurityContext context = SecurityContextHolder.createEmptyContext(); + context.setAuthentication(authentication); + SecurityContextHolder.setContext(context); + } + + public static void setEmulatedUserId(HttpSession session, Integer userId) { + if (userId == null) { + session.removeAttribute(DEV_USER_ID_SESSION_KEY); + } else { + session.setAttribute(DEV_USER_ID_SESSION_KEY, userId); + } + } + + public static Integer getEmulatedUserId(HttpSession session) { + return (Integer) session.getAttribute(DEV_USER_ID_SESSION_KEY); + } +} \ No newline at end of file diff --git a/src/main/java/de/avatic/lcc/config/SecurityConfig.java b/src/main/java/de/avatic/lcc/config/SecurityConfig.java index b88713c..67e65bb 100644 --- a/src/main/java/de/avatic/lcc/config/SecurityConfig.java +++ b/src/main/java/de/avatic/lcc/config/SecurityConfig.java @@ -58,14 +58,18 @@ public class SecurityConfig { @Bean @Profile("dev | test") - public SecurityFilterChain devSecurityFilterChain(HttpSecurity http) throws Exception { + public SecurityFilterChain devSecurityFilterChain(HttpSecurity http, UserRepository userRepository) throws Exception { return http - .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()) + .authorizeHttpRequests(auth -> auth + .requestMatchers("/api/**").permitAll() + .requestMatchers("/api/dev/**").permitAll() + .anyRequest().permitAll()) .csrf(csrf -> csrf .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) .csrfTokenRequestHandler(new LccCsrfTokenRequestHandler()) ) .addFilterAfter(new CsrfCookieFilter(), BasicAuthenticationFilter.class) + .addFilterBefore(new DevUserEmulationFilter(userRepository), BasicAuthenticationFilter.class) .build(); } diff --git a/src/main/java/de/avatic/lcc/controller/bulk/BulkOperationController.java b/src/main/java/de/avatic/lcc/controller/bulk/BulkOperationController.java index 18278d6..e457ea1 100644 --- a/src/main/java/de/avatic/lcc/controller/bulk/BulkOperationController.java +++ b/src/main/java/de/avatic/lcc/controller/bulk/BulkOperationController.java @@ -7,11 +7,13 @@ import de.avatic.lcc.dto.bulk.BulkOperationDTO; import de.avatic.lcc.service.bulk.BulkOperationService; import de.avatic.lcc.service.bulk.TemplateExportService; import de.avatic.lcc.util.exception.base.BadRequestException; +import jakarta.annotation.security.RolesAllowed; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.InputStreamResource; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -24,6 +26,7 @@ import java.util.List; */ @RestController @RequestMapping("/api/bulk") +@RolesAllowed({"ROLE_SUPER", "ROLE_FREIGHT", "ROLE_PACKAGING"}) public class BulkOperationController { private final BulkOperationService bulkOperationService; @@ -34,20 +37,17 @@ public class BulkOperationController { this.templateExportService = templateExportService; } - @GetMapping({"/status/", "/status"}) public ResponseEntity> getBulkStatus() { return ResponseEntity.ok(bulkOperationService.getStatus()); } - @PostMapping({"/upload/{type}", "/upload/{type}/"}) public ResponseEntity uploadFile(@PathVariable BulkFileType type, @BodyParam("file") MultipartFile file) { bulkOperationService.processFileImport(type, file); return ResponseEntity.ok().build(); } - @GetMapping({"/templates/{type}", "/templates/{type}/"}) public ResponseEntity generateTemplate(@PathVariable BulkFileType type) { HttpHeaders headers = new HttpHeaders(); diff --git a/src/main/java/de/avatic/lcc/controller/dev/DevController.java b/src/main/java/de/avatic/lcc/controller/dev/DevController.java index d580bab..fe699ea 100644 --- a/src/main/java/de/avatic/lcc/controller/dev/DevController.java +++ b/src/main/java/de/avatic/lcc/controller/dev/DevController.java @@ -1,6 +1,6 @@ package de.avatic.lcc.controller.dev; -import com.azure.core.annotation.BodyParam; +import de.avatic.lcc.config.DevUserEmulationFilter; import de.avatic.lcc.dto.error.CalculationJobDumpDTO; import de.avatic.lcc.dto.users.UserDTO; import de.avatic.lcc.repositories.error.DumpRepository; @@ -8,7 +8,7 @@ import de.avatic.lcc.repositories.pagination.SearchQueryPagination; import de.avatic.lcc.repositories.pagination.SearchQueryResult; import de.avatic.lcc.repositories.users.UserRepository; import de.avatic.lcc.service.transformer.users.UserTransformer; -import de.avatic.lcc.service.users.authorization.AuthorizationService; +import jakarta.servlet.http.HttpSession; import jakarta.validation.constraints.Min; import org.springframework.context.annotation.Profile; import org.springframework.http.ResponseEntity; @@ -21,13 +21,12 @@ import java.util.List; @RequestMapping({"/api/dev", "/api/dev/"}) public class DevController { - private final AuthorizationService authorizationService; private final DumpRepository dumpRepository; private final UserRepository userRepository; private final UserTransformer userTransformer; - public DevController(AuthorizationService authorizationService, DumpRepository dumpRepository, UserRepository userRepository, UserTransformer userTransformer) { - this.authorizationService = authorizationService; + public DevController(DumpRepository dumpRepository, UserRepository userRepository, UserTransformer userTransformer) { + this.dumpRepository = dumpRepository; this.userRepository = userRepository; this.userTransformer = userTransformer; @@ -67,8 +66,8 @@ public class DevController { } @PostMapping({"/user", "/user/"}) - public ResponseEntity setActiveUser(@RequestBody UserDTO user) { - authorizationService.setActiveUser(user.getEmail()); + public ResponseEntity setActiveUser(@RequestBody UserDTO user, HttpSession session) { + DevUserEmulationFilter.setEmulatedUserId(session, userRepository.getByEmail(user.getEmail()).getId()); return ResponseEntity.ok().build(); } diff --git a/src/main/java/de/avatic/lcc/controller/users/ActiveUserController.java b/src/main/java/de/avatic/lcc/controller/users/ActiveUserController.java index 243e909..a28a314 100644 --- a/src/main/java/de/avatic/lcc/controller/users/ActiveUserController.java +++ b/src/main/java/de/avatic/lcc/controller/users/ActiveUserController.java @@ -1,9 +1,12 @@ package de.avatic.lcc.controller.users; +import de.avatic.lcc.config.LccOidcUser; import de.avatic.lcc.dto.users.UserDTO; +import de.avatic.lcc.repositories.users.UserRepository; import de.avatic.lcc.service.transformer.users.UserTransformer; -import de.avatic.lcc.service.users.authorization.AuthorizationService; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -13,17 +16,24 @@ import org.springframework.web.bind.annotation.RestController; public class ActiveUserController { - private final AuthorizationService authorizationService; private final UserTransformer userTransformer; + private final UserRepository userRepository; + + public ActiveUserController(UserTransformer userTransformer, UserRepository userRepository) { - public ActiveUserController(AuthorizationService authorizationService, UserTransformer userTransformer) { - this.authorizationService = authorizationService; this.userTransformer = userTransformer; + this.userRepository = userRepository; } @GetMapping public ResponseEntity getActiveUser() { - return ResponseEntity.ok(userTransformer.toUserDTO(authorizationService.getActiveUser())); + + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + if(auth.getPrincipal() instanceof LccOidcUser) { + LccOidcUser user = (LccOidcUser) auth.getPrincipal(); + return ResponseEntity.ok(userTransformer.toUserDTO(userRepository.getById(user.getSqlUserId()))); + } + return ResponseEntity.internalServerError().build(); } } diff --git a/src/main/java/de/avatic/lcc/repositories/MaterialRepository.java b/src/main/java/de/avatic/lcc/repositories/MaterialRepository.java index 2fdfad8..8845bff 100644 --- a/src/main/java/de/avatic/lcc/repositories/MaterialRepository.java +++ b/src/main/java/de/avatic/lcc/repositories/MaterialRepository.java @@ -159,27 +159,6 @@ public class MaterialRepository { return Optional.ofNullable(jdbcTemplate.update(updateQuery, material.getName(), material.getPartNumber(), material.getNormalizedPartNumber(), material.getHsCode(), material.getId()) == 0 ? null : material.getId()); } - @Transactional - public Optional create(Material material) { - - //todo if there is a deprecated, reuse this - - KeyHolder keyHolder = new GeneratedKeyHolder(); - - jdbcTemplate.update(connection -> { - PreparedStatement ps = connection.prepareStatement("INSERT INTO material (name, part_number, normalized_part_number, hs_code) VALUES (?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS); - ps.setString(1, material.getName()); // - ps.setString(2, material.getPartNumber()); - ps.setString(3, material.getNormalizedPartNumber()); - ps.setString(4, material.getHsCode()); - return ps; - }, keyHolder); - - - return Optional.ofNullable(!Objects.requireNonNull(keyHolder.getKeys()).isEmpty() ? ((Integer) keyHolder.getKeys().values().iterator().next()) : null); - - } - /** * Returns all IDs from the input list that don't exist in the material table * @param ids List of integers to check diff --git a/src/main/java/de/avatic/lcc/service/users/authorization/AuthorizationService.java b/src/main/java/de/avatic/lcc/service/users/authorization/AuthorizationService.java deleted file mode 100644 index 3370564..0000000 --- a/src/main/java/de/avatic/lcc/service/users/authorization/AuthorizationService.java +++ /dev/null @@ -1,12 +0,0 @@ -package de.avatic.lcc.service.users.authorization; - -import de.avatic.lcc.dto.users.UserDTO; -import de.avatic.lcc.model.users.User; -import org.springframework.stereotype.Service; - -@Service -public interface AuthorizationService { - default void setActiveUser(String id) { throw new UnsupportedOperationException(); } - - User getActiveUser(); -} diff --git a/src/main/java/de/avatic/lcc/service/users/authorization/DefaultAuthorizationService.java b/src/main/java/de/avatic/lcc/service/users/authorization/DefaultAuthorizationService.java deleted file mode 100644 index 54f8f6f..0000000 --- a/src/main/java/de/avatic/lcc/service/users/authorization/DefaultAuthorizationService.java +++ /dev/null @@ -1,15 +0,0 @@ -package de.avatic.lcc.service.users.authorization; - - -import de.avatic.lcc.model.users.User; -import org.springframework.context.annotation.Profile; -import org.springframework.stereotype.Service; - -@Service -@Profile("!dev & !test") -public class DefaultAuthorizationService implements AuthorizationService{ - @Override - public User getActiveUser() { - return null; - } -} diff --git a/src/main/java/de/avatic/lcc/service/users/authorization/SimulatedAuthorizationService.java b/src/main/java/de/avatic/lcc/service/users/authorization/SimulatedAuthorizationService.java deleted file mode 100644 index fb866fe..0000000 --- a/src/main/java/de/avatic/lcc/service/users/authorization/SimulatedAuthorizationService.java +++ /dev/null @@ -1,36 +0,0 @@ -package de.avatic.lcc.service.users.authorization; - -import de.avatic.lcc.dto.users.UserDTO; -import de.avatic.lcc.model.users.User; -import de.avatic.lcc.repositories.users.UserRepository; -import org.springframework.context.annotation.Profile; -import org.springframework.stereotype.Service; - - -@Service -@Profile("dev | test") -public class SimulatedAuthorizationService implements AuthorizationService { - - private final UserRepository userRepository; - private User activeUser; - - public SimulatedAuthorizationService(UserRepository userRepository) { - this.userRepository = userRepository; - } - - @Override - public void setActiveUser(String mail) { - this.activeUser = userRepository.getByEmail(mail); - System.out.println(activeUser); - } - - @Override - public User getActiveUser() { - if(activeUser == null){ - activeUser = userRepository.getById(1); - } - - return activeUser; - } - -}