Red-6659 - Don't allow users with lower rank roles to activate/deactivate users with higher rank roles
This commit is contained in:
parent
1272d91e74
commit
5c0679f1fc
@ -120,7 +120,8 @@ public interface UserResource {
|
|||||||
|
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@Operation(summary = "Activate/deactivate a user profile", description = "None")
|
@Operation(summary = "Activate/deactivate a user profile", description = "None")
|
||||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Failed to activate/deactivate profile")})
|
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Failed to activate/deactivate profile"),
|
||||||
|
@ApiResponse(responseCode = "403", description = "Cannot activate/deactivate users with higher rank roles")})
|
||||||
@PostMapping(value = ACTIVATE_USER_PROFILE_PATH + USER_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
|
@PostMapping(value = ACTIVATE_USER_PROFILE_PATH + USER_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
User activateProfile(@PathVariable(USER_ID) String userId, @RequestParam(IS_ACTIVE_PARAM) boolean isActive);
|
User activateProfile(@PathVariable(USER_ID) String userId, @RequestParam(IS_ACTIVE_PARAM) boolean isActive);
|
||||||
|
|
||||||
|
|||||||
@ -438,6 +438,12 @@ public class UserService {
|
|||||||
|
|
||||||
public User activateProfile(String userId, boolean isActive) {
|
public User activateProfile(String userId, boolean isActive) {
|
||||||
|
|
||||||
|
var executionValid = isExecutionRankValid(KeycloakSecurity.getUserId(), userId);
|
||||||
|
|
||||||
|
if (!executionValid) {
|
||||||
|
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "It is not allowed to activate/deactivate a user with higher ranking roles");
|
||||||
|
}
|
||||||
|
|
||||||
var user = this.getUserResource(userId);
|
var user = this.getUserResource(userId);
|
||||||
var userRepresentation = user.toRepresentation();
|
var userRepresentation = user.toRepresentation();
|
||||||
|
|
||||||
@ -445,6 +451,7 @@ public class UserService {
|
|||||||
user.update(userRepresentation);
|
user.update(userRepresentation);
|
||||||
|
|
||||||
var currentRoles = getRoles(userId);
|
var currentRoles = getRoles(userId);
|
||||||
|
|
||||||
if (isActive && currentRoles.isEmpty()) { // add RED_USER role
|
if (isActive && currentRoles.isEmpty()) { // add RED_USER role
|
||||||
setRoles(userId, tenantUserManagementProperties.getKcRoleMapping().getDefaultRoles());
|
setRoles(userId, tenantUserManagementProperties.getKcRoleMapping().getDefaultRoles());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,27 +3,29 @@ package com.knecon.fforesight.tenantusermanagement.tests;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.fail;
|
import static org.assertj.core.api.Assertions.fail;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import lombok.SneakyThrows;
|
import com.knecon.fforesight.tenantcommons.TenantContext;
|
||||||
import feign.FeignException;
|
|
||||||
|
|
||||||
import com.knecon.fforesight.tenantusermanagement.AbstractTenantUserManagementIntegrationTest;
|
import com.knecon.fforesight.tenantusermanagement.AbstractTenantUserManagementIntegrationTest;
|
||||||
import com.knecon.fforesight.tenantusermanagement.feigntestclients.external.UserClient;
|
import com.knecon.fforesight.tenantusermanagement.feigntestclients.external.UserClient;
|
||||||
import com.knecon.fforesight.tenantcommons.TenantContext;
|
|
||||||
import com.knecon.fforesight.tenantusermanagement.model.CreateUserRequest;
|
import com.knecon.fforesight.tenantusermanagement.model.CreateUserRequest;
|
||||||
import com.knecon.fforesight.tenantusermanagement.model.ResetPasswordRequest;
|
import com.knecon.fforesight.tenantusermanagement.model.ResetPasswordRequest;
|
||||||
import com.knecon.fforesight.tenantusermanagement.model.UpdateMyProfileRequest;
|
import com.knecon.fforesight.tenantusermanagement.model.UpdateMyProfileRequest;
|
||||||
import com.knecon.fforesight.tenantusermanagement.model.UpdateProfileRequest;
|
import com.knecon.fforesight.tenantusermanagement.model.UpdateProfileRequest;
|
||||||
import com.knecon.fforesight.tenantusermanagement.properties.TenantUserManagementProperties;
|
import com.knecon.fforesight.tenantusermanagement.properties.TenantUserManagementProperties;
|
||||||
|
|
||||||
|
import feign.FeignException;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
public class UserTest extends AbstractTenantUserManagementIntegrationTest {
|
public class UserTest extends AbstractTenantUserManagementIntegrationTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -37,6 +39,7 @@ public class UserTest extends AbstractTenantUserManagementIntegrationTest {
|
|||||||
public void testUsers() {
|
public void testUsers() {
|
||||||
|
|
||||||
TenantContext.setTenantId(AbstractTenantUserManagementIntegrationTest.TEST_TENANT_ID);
|
TenantContext.setTenantId(AbstractTenantUserManagementIntegrationTest.TEST_TENANT_ID);
|
||||||
|
tokenService.setUser("test@fforesight.com", "secret");
|
||||||
|
|
||||||
var allUsers = userClient.getAllUsers(true);
|
var allUsers = userClient.getAllUsers(true);
|
||||||
var testUserFound = allUsers.stream().anyMatch(u -> u.getEmail().equalsIgnoreCase("test@fforesight.com"));
|
var testUserFound = allUsers.stream().anyMatch(u -> u.getEmail().equalsIgnoreCase("test@fforesight.com"));
|
||||||
@ -93,6 +96,8 @@ public class UserTest extends AbstractTenantUserManagementIntegrationTest {
|
|||||||
|
|
||||||
allUsers = userClient.getAllUsers(true);
|
allUsers = userClient.getAllUsers(true);
|
||||||
assertThat(allUsers).hasSize(1);
|
assertThat(allUsers).hasSize(1);
|
||||||
|
|
||||||
|
TenantContext.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -138,6 +143,123 @@ public class UserTest extends AbstractTenantUserManagementIntegrationTest {
|
|||||||
assertThat(e.status()).isEqualTo(403);
|
assertThat(e.status()).isEqualTo(403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TenantContext.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SneakyThrows
|
||||||
|
public void testActivateUserWithLowerRole() {
|
||||||
|
|
||||||
|
TenantContext.setTenantId(AbstractTenantUserManagementIntegrationTest.TEST_TENANT_ID);
|
||||||
|
tokenService.setUser("test@fforesight.com", "secret");
|
||||||
|
|
||||||
|
var redAdminUserRequest = new CreateUserRequest();
|
||||||
|
redAdminUserRequest.setEmail("red-admin@knecon.com");
|
||||||
|
redAdminUserRequest.setUsername(redAdminUserRequest.getEmail());
|
||||||
|
redAdminUserRequest.setRoles(Set.of("SUPER_USER"));
|
||||||
|
var redAdmin = userClient.createUser(redAdminUserRequest);
|
||||||
|
|
||||||
|
var redUserAdminUserRequest = new CreateUserRequest();
|
||||||
|
redUserAdminUserRequest.setEmail("red-user-admin@knecon.com");
|
||||||
|
redUserAdminUserRequest.setUsername(redUserAdminUserRequest.getEmail());
|
||||||
|
redUserAdminUserRequest.setRoles(Set.of("LESS_SUPER_USER"));
|
||||||
|
var redUserAdmin = userClient.createUser(redUserAdminUserRequest);
|
||||||
|
|
||||||
|
userClient.resetPassword(redAdmin.getUserId(), ResetPasswordRequest.builder().password("Secret@secured!23").build());
|
||||||
|
userClient.resetPassword(redUserAdmin.getUserId(), ResetPasswordRequest.builder().password("Secret@secured!23").build());
|
||||||
|
|
||||||
|
// authenticate as red-admin
|
||||||
|
tokenService.setUser("red-admin@knecon.com", "Secret@secured!23");
|
||||||
|
|
||||||
|
// activate red-user-admin should work since the user has a lower rank
|
||||||
|
var user = userClient.activateProfile(redUserAdmin.getUserId(), true);
|
||||||
|
assertTrue(user.isActive());
|
||||||
|
|
||||||
|
// deactivate red-user-admin should work since the user has a lower rank
|
||||||
|
user = userClient.activateProfile(redUserAdmin.getUserId(), false);
|
||||||
|
assertFalse(user.isActive());
|
||||||
|
|
||||||
|
tokenService.setUser("test@fforesight.com", "secret");
|
||||||
|
userClient.deleteUser(redUserAdmin.getUserId());
|
||||||
|
userClient.deleteUser(redAdmin.getUserId());
|
||||||
|
TenantContext.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SneakyThrows
|
||||||
|
public void testActivateUserWithHigherRole() {
|
||||||
|
|
||||||
|
TenantContext.setTenantId(AbstractTenantUserManagementIntegrationTest.TEST_TENANT_ID);
|
||||||
|
tokenService.setUser("test@fforesight.com", "secret");
|
||||||
|
|
||||||
|
var redAdminUserRequest = new CreateUserRequest();
|
||||||
|
redAdminUserRequest.setEmail("red-admin@knecon.com");
|
||||||
|
redAdminUserRequest.setUsername(redAdminUserRequest.getEmail());
|
||||||
|
redAdminUserRequest.setRoles(Set.of("SUPER_USER"));
|
||||||
|
var redAdmin = userClient.createUser(redAdminUserRequest);
|
||||||
|
|
||||||
|
var redUserAdminUserRequest = new CreateUserRequest();
|
||||||
|
redUserAdminUserRequest.setEmail("red-user-admin@knecon.com");
|
||||||
|
redUserAdminUserRequest.setUsername(redUserAdminUserRequest.getEmail());
|
||||||
|
redUserAdminUserRequest.setRoles(Set.of("LESS_SUPER_USER"));
|
||||||
|
var redUserAdmin = userClient.createUser(redUserAdminUserRequest);
|
||||||
|
|
||||||
|
userClient.resetPassword(redAdmin.getUserId(), ResetPasswordRequest.builder().password("Secret@secured!23").build());
|
||||||
|
userClient.resetPassword(redUserAdmin.getUserId(), ResetPasswordRequest.builder().password("Secret@secured!23").build());
|
||||||
|
|
||||||
|
// authenticate as red-user-admin
|
||||||
|
tokenService.setUser("red-user-admin@knecon.com", "Secret@secured!23");
|
||||||
|
|
||||||
|
// activate red-admin should not work since the user has a higher rank
|
||||||
|
FeignException feignException = assertThrows(FeignException.class, () -> userClient.activateProfile(redAdmin.getUserId(), true));
|
||||||
|
assertEquals(feignException.status(), 403);
|
||||||
|
assertTrue(feignException.getMessage().contains("It is not allowed to activate/deactivate a user with higher ranking role"));
|
||||||
|
|
||||||
|
tokenService.setUser("test@fforesight.com", "secret");
|
||||||
|
userClient.deleteUser(redUserAdmin.getUserId());
|
||||||
|
userClient.deleteUser(redAdmin.getUserId());
|
||||||
|
TenantContext.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SneakyThrows
|
||||||
|
public void testActivateUserWithSameRole() {
|
||||||
|
|
||||||
|
TenantContext.setTenantId(AbstractTenantUserManagementIntegrationTest.TEST_TENANT_ID);
|
||||||
|
tokenService.setUser("test@fforesight.com", "secret");
|
||||||
|
|
||||||
|
var redAdminUserRequest = new CreateUserRequest();
|
||||||
|
redAdminUserRequest.setEmail("red-admin@knecon.com");
|
||||||
|
redAdminUserRequest.setUsername(redAdminUserRequest.getEmail());
|
||||||
|
redAdminUserRequest.setRoles(Set.of("SUPER_USER"));
|
||||||
|
var redAdmin = userClient.createUser(redAdminUserRequest);
|
||||||
|
|
||||||
|
var redUserAdminUserRequest = new CreateUserRequest();
|
||||||
|
redUserAdminUserRequest.setEmail("red-user-admin@knecon.com");
|
||||||
|
redUserAdminUserRequest.setUsername(redUserAdminUserRequest.getEmail());
|
||||||
|
redUserAdminUserRequest.setRoles(Set.of("SUPER_USER"));
|
||||||
|
var redUserAdmin = userClient.createUser(redUserAdminUserRequest);
|
||||||
|
|
||||||
|
userClient.resetPassword(redAdmin.getUserId(), ResetPasswordRequest.builder().password("Secret@secured!23").build());
|
||||||
|
userClient.resetPassword(redUserAdmin.getUserId(), ResetPasswordRequest.builder().password("Secret@secured!23").build());
|
||||||
|
|
||||||
|
// authenticate as red-user-admin
|
||||||
|
tokenService.setUser("red-admin@knecon.com", "Secret@secured!23");
|
||||||
|
|
||||||
|
// activate red-user-admin should work since the user has the same rank
|
||||||
|
var user = userClient.activateProfile(redUserAdmin.getUserId(), true);
|
||||||
|
assertTrue(user.isActive());
|
||||||
|
|
||||||
|
// deactivate red-user-admin should work since the user has the same rank
|
||||||
|
user = userClient.activateProfile(redUserAdmin.getUserId(), false);
|
||||||
|
assertFalse(user.isActive());
|
||||||
|
|
||||||
|
tokenService.setUser("test@fforesight.com", "secret");
|
||||||
|
userClient.deleteUser(redUserAdmin.getUserId());
|
||||||
|
userClient.deleteUser(redAdmin.getUserId());
|
||||||
|
TenantContext.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user