Skip to content
This repository was archived by the owner on Nov 23, 2025. It is now read-only.

Commit d05ee64

Browse files
authored
Merge pull request #3 from TechTorque-2025/integration_bug_fixes
feat: Enhance role-based access control for project and service listings
2 parents 5b3306b + 766ca0e commit d05ee64

5 files changed

Lines changed: 63 additions & 7 deletions

File tree

project-service/src/main/java/com/techtorque/project_service/config/GatewayHeaderFilter.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,19 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
2626
if (userId != null && !userId.isEmpty()) {
2727
List<SimpleGrantedAuthority> authorities = rolesHeader == null ? Collections.emptyList() :
2828
Arrays.stream(rolesHeader.split(","))
29-
.map(role -> new SimpleGrantedAuthority("ROLE_" + role.trim().toUpperCase()))
29+
.map(role -> {
30+
String roleUpper = role.trim().toUpperCase();
31+
// Treat SUPER_ADMIN as ADMIN for authorization purposes
32+
if ("SUPER_ADMIN".equals(roleUpper)) {
33+
// Add both SUPER_ADMIN and ADMIN roles
34+
return Arrays.asList(
35+
new SimpleGrantedAuthority("ROLE_SUPER_ADMIN"),
36+
new SimpleGrantedAuthority("ROLE_ADMIN")
37+
);
38+
}
39+
return Collections.singletonList(new SimpleGrantedAuthority("ROLE_" + roleUpper));
40+
})
41+
.flatMap(List::stream)
3042
.collect(Collectors.toList());
3143

3244
UsernamePasswordAuthenticationToken authentication =

project-service/src/main/java/com/techtorque/project_service/controller/ProjectController.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,21 @@ public ResponseEntity<ApiResponse> requestModification(
4343

4444
@Operation(summary = "List projects for the current customer")
4545
@GetMapping
46-
@PreAuthorize("hasRole('CUSTOMER')")
47-
public ResponseEntity<ApiResponse> listCustomerProjects(@RequestHeader("X-User-Subject") String customerId) {
48-
List<Project> projects = projectService.getProjectsForCustomer(customerId);
46+
@PreAuthorize("hasAnyRole('CUSTOMER', 'ADMIN', 'EMPLOYEE')")
47+
public ResponseEntity<ApiResponse> listCustomerProjects(
48+
@RequestHeader("X-User-Subject") String userId,
49+
@RequestHeader("X-User-Roles") String roles) {
50+
51+
List<Project> projects;
52+
53+
// Admin and Employee can see all projects
54+
if (roles.contains("ADMIN") || roles.contains("EMPLOYEE")) {
55+
projects = projectService.getAllProjects();
56+
} else {
57+
// Customer sees only their own projects
58+
projects = projectService.getProjectsForCustomer(userId);
59+
}
60+
4961
List<ProjectResponseDto> response = projects.stream()
5062
.map(this::mapToResponseDto)
5163
.collect(Collectors.toList());

project-service/src/main/java/com/techtorque/project_service/controller/ServiceController.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,34 @@ public ResponseEntity<ApiResponse> createService(
4242

4343
@Operation(summary = "List services for the current customer")
4444
@GetMapping
45-
@PreAuthorize("hasRole('CUSTOMER')")
45+
@PreAuthorize("hasAnyRole('CUSTOMER', 'ADMIN', 'EMPLOYEE')")
4646
public ResponseEntity<ApiResponse> listCustomerServices(
47-
@RequestHeader("X-User-Subject") String customerId,
47+
@RequestHeader("X-User-Subject") String userId,
48+
@RequestHeader("X-User-Roles") String roles,
4849
@RequestParam(required = false) String status) {
49-
List<StandardService> services = standardServiceService.getServicesForCustomer(customerId, status);
50+
51+
List<StandardService> services;
52+
53+
// Admin and Employee can see all services
54+
if (roles.contains("ADMIN") || roles.contains("EMPLOYEE")) {
55+
services = standardServiceService.getAllServices();
56+
// Apply status filter if provided
57+
if (status != null && !status.isEmpty()) {
58+
try {
59+
com.techtorque.project_service.entity.ServiceStatus statusEnum =
60+
com.techtorque.project_service.entity.ServiceStatus.valueOf(status.toUpperCase());
61+
services = services.stream()
62+
.filter(s -> s.getStatus() == statusEnum)
63+
.collect(Collectors.toList());
64+
} catch (IllegalArgumentException e) {
65+
// Invalid status, ignore filter
66+
}
67+
}
68+
} else {
69+
// Customer sees only their own services
70+
services = standardServiceService.getServicesForCustomer(userId, status);
71+
}
72+
5073
List<ServiceResponseDto> response = services.stream()
5174
.map(this::mapToServiceResponseDto)
5275
.collect(Collectors.toList());

project-service/src/main/java/com/techtorque/project_service/service/StandardServiceService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public interface StandardServiceService {
1313
StandardService createServiceFromAppointment(CreateServiceDto dto, String employeeId);
1414

1515
List<StandardService> getServicesForCustomer(String customerId, String status);
16+
17+
List<StandardService> getAllServices(); // For admin/employee to see all services
1618

1719
Optional<StandardService> getServiceDetails(String serviceId, String userId, String userRole);
1820

project-service/src/main/java/com/techtorque/project_service/service/impl/StandardServiceServiceImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ public List<StandardService> getServicesForCustomer(String customerId, String st
7777
return services;
7878
}
7979

80+
@Override
81+
@Transactional(readOnly = true)
82+
public List<StandardService> getAllServices() {
83+
log.info("Fetching all services (admin/employee access)");
84+
return serviceRepository.findAll();
85+
}
86+
8087
@Override
8188
public Optional<StandardService> getServiceDetails(String serviceId, String userId, String userRole) {
8289
log.info("Fetching service {} for user: {} with role: {}", serviceId, userId, userRole);

0 commit comments

Comments
 (0)