formatting and fixes

This commit is contained in:
Anthony Stirling 2025-08-06 16:35:09 +01:00
parent d1c8802890
commit 0dd0e0c71e
9 changed files with 50 additions and 66 deletions

View File

@ -221,42 +221,49 @@ public class InitialSecuritySetup {
private void migrateDeprecatedRolesToUser() { private void migrateDeprecatedRolesToUser() {
String[] deprecatedRoles = { String[] deprecatedRoles = {
"ROLE_WEB_ONLY_USER", "ROLE_WEB_ONLY_USER", "ROLE_EXTRA_LIMITED_API_USER", "ROLE_LIMITED_API_USER"
"ROLE_EXTRA_LIMITED_API_USER",
"ROLE_LIMITED_API_USER"
}; };
int totalMigrated = 0; int totalMigrated = 0;
for (String deprecatedRole : deprecatedRoles) { for (String deprecatedRole : deprecatedRoles) {
List<User> usersWithDeprecatedRole = userService.findByRole(deprecatedRole); List<User> usersWithDeprecatedRole = userService.findByRole(deprecatedRole);
if (!usersWithDeprecatedRole.isEmpty()) { if (!usersWithDeprecatedRole.isEmpty()) {
log.info("Found {} users with role {}. Converting to USER...", log.info(
usersWithDeprecatedRole.size(), deprecatedRole); "Found {} users with role {}. Converting to USER...",
usersWithDeprecatedRole.size(),
deprecatedRole);
int migratedCount = 0; int migratedCount = 0;
for (User user : usersWithDeprecatedRole) { for (User user : usersWithDeprecatedRole) {
try { try {
user.setUserRole(Role.USER); user.setUserRole(Role.USER);
userService.saveUser(user); userService.saveUser(user);
log.debug("Converted user '{}' from {} to USER", log.debug(
user.getUsername(), deprecatedRole); "Converted user '{}' from {} to USER",
user.getUsername(),
deprecatedRole);
migratedCount++; migratedCount++;
} catch (Exception e) { } catch (Exception e) {
log.error("Failed to migrate user '{}' from {} to USER: {}", log.error(
user.getUsername(), deprecatedRole, e.getMessage()); "Failed to migrate user '{}' from {} to USER: {}",
user.getUsername(),
deprecatedRole,
e.getMessage());
} }
} }
if (migratedCount > 0) { if (migratedCount > 0) {
log.info("Successfully migrated {} users from {} to USER", log.info(
migratedCount, deprecatedRole); "Successfully migrated {} users from {} to USER",
migratedCount,
deprecatedRole);
totalMigrated += migratedCount; totalMigrated += migratedCount;
} }
} }
} }
if (totalMigrated == 0) { if (totalMigrated == 0) {
log.debug("No users with deprecated roles found - migration not needed"); log.debug("No users with deprecated roles found - migration not needed");
} else { } else {

View File

@ -220,15 +220,13 @@ public class AccountWebController {
List<User> allUsers = userRepository.findAllWithTeam(); List<User> allUsers = userRepository.findAllWithTeam();
Iterator<User> iterator = allUsers.iterator(); Iterator<User> iterator = allUsers.iterator();
Map<String, String> roleDetails = Role.getAllRoleDetails(); Map<String, String> roleDetails = Role.getAllRoleDetails();
// Filter role details to only show SYSTEM_ADMIN, USER, and DEMO_USER in UI // Filter role details to only show SYSTEM_ADMIN, USER, and DEMO_USER in UI
Map<String, String> filteredRoleDetails = new LinkedHashMap<>(); Map<String, String> filteredRoleDetails = new LinkedHashMap<>();
String[] allowedRoles = { String[] allowedRoles = {
Role.SYSTEM_ADMIN.getRoleId(), Role.SYSTEM_ADMIN.getRoleId(), Role.USER.getRoleId(), Role.DEMO_USER.getRoleId()
Role.USER.getRoleId(),
Role.DEMO_USER.getRoleId()
}; };
for (String roleId : allowedRoles) { for (String roleId : allowedRoles) {
if (roleDetails.containsKey(roleId)) { if (roleDetails.containsKey(roleId)) {
filteredRoleDetails.put(roleId, roleDetails.get(roleId)); filteredRoleDetails.put(roleId, roleDetails.get(roleId));

View File

@ -30,7 +30,8 @@ import stirling.software.proprietary.security.service.RoleBasedAuthorizationServ
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@PremiumEndpoint @PremiumEndpoint
@PreAuthorize("@roleBasedAuthorizationService.canManageOrgUsers() or @roleBasedAuthorizationService.canManageOrgTeams()") @PreAuthorize(
"@roleBasedAuthorizationService.canManageOrgUsers() or @roleBasedAuthorizationService.canManageOrgTeams()")
public class OrgAdminController { public class OrgAdminController {
private final TeamRepository teamRepository; private final TeamRepository teamRepository;

View File

@ -34,7 +34,8 @@ public class OrganizationController {
} }
@GetMapping("/{id}") @GetMapping("/{id}")
@PreAuthorize("@roleBasedAuthorizationService.canViewOrganization(@organizationRepository.findById(#id).orElse(null))") @PreAuthorize(
"@roleBasedAuthorizationService.canViewOrganization(@organizationRepository.findById(#id).orElse(null))")
public ResponseEntity<Organization> getOrganization(@PathVariable Long id) { public ResponseEntity<Organization> getOrganization(@PathVariable Long id) {
Optional<Organization> organizationOpt = organizationRepository.findById(id); Optional<Organization> organizationOpt = organizationRepository.findById(id);
if (organizationOpt.isEmpty()) { if (organizationOpt.isEmpty()) {

View File

@ -62,7 +62,8 @@ public class TeamController {
} }
@PostMapping("/rename") @PostMapping("/rename")
@PreAuthorize("@roleBasedAuthorizationService.canManageTeam(@teamRepository.findById(#teamId).orElse(null))") @PreAuthorize(
"@roleBasedAuthorizationService.canManageTeam(@teamRepository.findById(#teamId).orElse(null))")
public RedirectView renameTeam( public RedirectView renameTeam(
@RequestParam("teamId") Long teamId, @RequestParam("newName") String newName) { @RequestParam("teamId") Long teamId, @RequestParam("newName") String newName) {
Optional<Team> existing = teamRepository.findById(teamId); Optional<Team> existing = teamRepository.findById(teamId);
@ -88,7 +89,8 @@ public class TeamController {
@PostMapping("/delete") @PostMapping("/delete")
@Transactional @Transactional
@PreAuthorize("@roleBasedAuthorizationService.canManageTeam(@teamRepository.findById(#teamId).orElse(null))") @PreAuthorize(
"@roleBasedAuthorizationService.canManageTeam(@teamRepository.findById(#teamId).orElse(null))")
public RedirectView deleteTeam(@RequestParam("teamId") Long teamId) { public RedirectView deleteTeam(@RequestParam("teamId") Long teamId) {
Optional<Team> teamOpt = teamRepository.findById(teamId); Optional<Team> teamOpt = teamRepository.findById(teamId);
if (teamOpt.isEmpty()) { if (teamOpt.isEmpty()) {
@ -113,7 +115,8 @@ public class TeamController {
@PostMapping("/addUser") @PostMapping("/addUser")
@Transactional @Transactional
@PreAuthorize("@roleBasedAuthorizationService.canAddUserToTeam(#userId, @teamRepository.findById(#teamId).orElse(null))") @PreAuthorize(
"@roleBasedAuthorizationService.canAddUserToTeam(#userId, @teamRepository.findById(#teamId).orElse(null))")
public RedirectView addUserToTeam( public RedirectView addUserToTeam(
@RequestParam("teamId") Long teamId, @RequestParam("userId") Long userId) { @RequestParam("teamId") Long teamId, @RequestParam("userId") Long userId) {

View File

@ -116,26 +116,6 @@ public class TeamLeadController {
return ResponseEntity.ok().body("User removed from team successfully"); return ResponseEntity.ok().body("User removed from team successfully");
} }
/** Get users that can be added to the team (within same organization, not in any team) */
@GetMapping("/available-users")
public ResponseEntity<List<User>> getAvailableUsers() {
if (!authorizationService.canManageTeamUsers()) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
User currentUser = authorizationService.getCurrentUser();
if (currentUser == null || currentUser.getOrganization() == null) {
return ResponseEntity.badRequest().build();
}
// Find users in the same organization who are not in any team
List<User> availableUsers =
userRepository.findUsersInOrganizationWithoutTeam(
currentUser.getOrganization().getId());
return ResponseEntity.ok(availableUsers);
}
/** Update a team member's role (team leads can only assign USER role) */ /** Update a team member's role (team leads can only assign USER role) */
@PostMapping("/update-member-role") @PostMapping("/update-member-role")
@Transactional @Transactional

View File

@ -24,9 +24,6 @@ public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByAuthenticationTypeIgnoreCase(String authenticationType); List<User> findByAuthenticationTypeIgnoreCase(String authenticationType);
@Query("SELECT u FROM User u WHERE u.team IS NULL")
List<User> findAllWithoutTeam();
@Query(value = "SELECT u FROM User u LEFT JOIN FETCH u.team") @Query(value = "SELECT u FROM User u LEFT JOIN FETCH u.team")
List<User> findAllWithTeam(); List<User> findAllWithTeam();
@ -38,8 +35,8 @@ public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByTeam(Team team); List<User> findByTeam(Team team);
@Query("SELECT u FROM User u WHERE u.team IS NULL AND u.organization.id = :organizationId") @Query("SELECT u FROM User u WHERE u.team IS NULL")
List<User> findUsersInOrganizationWithoutTeam(@Param("organizationId") Long organizationId); List<User> findUsersWithoutTeam();
@Query("SELECT u FROM User u JOIN u.authorities a WHERE a.authority = :role") @Query("SELECT u FROM User u JOIN u.authorities a WHERE a.authority = :role")
List<User> findByRole(@Param("role") String role); List<User> findByRole(@Param("role") String role);

View File

@ -624,7 +624,7 @@ public class UserService implements UserServiceInterface {
} }
public List<User> getUsersWithoutTeam() { public List<User> getUsersWithoutTeam() {
return userRepository.findAllWithoutTeam(); return userRepository.findUsersWithoutTeam();
} }
public void saveAll(List<User> users) { public void saveAll(List<User> users) {

View File

@ -11,25 +11,19 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import stirling.software.proprietary.model.Organization; import stirling.software.proprietary.model.Organization;
import stirling.software.proprietary.model.Team; import stirling.software.proprietary.model.Team;
import stirling.software.proprietary.security.repository.TeamRepository; import stirling.software.proprietary.security.repository.TeamRepository;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
class TeamServiceTest { class TeamServiceTest {
@Mock private TeamRepository teamRepository; @Mock private TeamRepository teamRepository;
@Mock @Mock private OrganizationService organizationService;
private OrganizationService organizationService;
@InjectMocks @InjectMocks private TeamService teamService;
private TeamService teamService;
@Test @Test
void getDefaultTeam() { void getDefaultTeam() {
@ -42,7 +36,8 @@ class TeamServiceTest {
team.setOrganization(organization); team.setOrganization(organization);
when(organizationService.getOrCreateDefaultOrganization()).thenReturn(organization); when(organizationService.getOrCreateDefaultOrganization()).thenReturn(organization);
when(teamRepository.findByNameAndOrganizationId(TeamService.DEFAULT_TEAM_NAME, organization.getId())) when(teamRepository.findByNameAndOrganizationId(
TeamService.DEFAULT_TEAM_NAME, organization.getId()))
.thenReturn(Optional.of(team)); .thenReturn(Optional.of(team));
Team result = teamService.getOrCreateDefaultTeam(); Team result = teamService.getOrCreateDefaultTeam();
@ -83,8 +78,9 @@ class TeamServiceTest {
team.setOrganization(organization); team.setOrganization(organization);
when(organizationService.getOrCreateInternalOrganization()).thenReturn(organization); when(organizationService.getOrCreateInternalOrganization()).thenReturn(organization);
when(teamRepository.findByNameAndOrganizationId(TeamService.INTERNAL_TEAM_NAME, organization.getId())) when(teamRepository.findByNameAndOrganizationId(
.thenReturn(Optional.of(team)); TeamService.INTERNAL_TEAM_NAME, organization.getId()))
.thenReturn(Optional.of(team));
Team result = teamService.getOrCreateInternalTeam(); Team result = teamService.getOrCreateInternalTeam();
@ -104,8 +100,9 @@ class TeamServiceTest {
internalTeam.setOrganization(organization); internalTeam.setOrganization(organization);
when(organizationService.getOrCreateInternalOrganization()).thenReturn(organization); when(organizationService.getOrCreateInternalOrganization()).thenReturn(organization);
when(teamRepository.findByNameAndOrganizationId(TeamService.INTERNAL_TEAM_NAME, organization.getId())) when(teamRepository.findByNameAndOrganizationId(
.thenReturn(Optional.empty()); TeamService.INTERNAL_TEAM_NAME, organization.getId()))
.thenReturn(Optional.empty());
when(teamRepository.save(any(Team.class))).thenReturn(internalTeam); when(teamRepository.save(any(Team.class))).thenReturn(internalTeam);
Team result = teamService.getOrCreateInternalTeam(); Team result = teamService.getOrCreateInternalTeam();