import org.sonar.db.DbSession;
import org.sonar.db.permission.GroupPermissionDto;
import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.organization.DefaultOrganizationProvider;
import static java.lang.String.format;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
public class GroupPermissionChanger {
private final DbClient dbClient;
+ private final DefaultOrganizationProvider defaultOrganizationProvider;
- public GroupPermissionChanger(DbClient dbClient) {
+ public GroupPermissionChanger(DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider) {
this.dbClient = dbClient;
+ this.defaultOrganizationProvider = defaultOrganizationProvider;
}
public boolean apply(DbSession dbSession, GroupPermissionChange change) {
.setGroupId(change.getGroupIdOrAnyone().getId())
.setResourceId(change.getNullableProjectId());
dbClient.groupPermissionDao().insert(dbSession, addedDto);
+ updateRootFlag(dbSession, change);
return true;
}
change.getOrganizationUuid(),
change.getGroupIdOrAnyone().getId(),
change.getNullableProjectId());
+ updateRootFlag(dbSession, change);
return true;
}
+ private void updateRootFlag(DbSession dbSession, GroupPermissionChange change) {
+ if (SYSTEM_ADMIN.equals(change.getPermission()) && !change.getGroupIdOrAnyone().isAnyone() && !change.getProjectId().isPresent()) {
+ dbClient.groupDao().updateRootFlagOfUsersInGroupFromPermissions(dbSession, change.getGroupIdOrAnyone().getId(), defaultOrganizationProvider.get().getUuid());
+ }
+ }
+
private List<String> loadExistingPermissions(DbSession dbSession, GroupPermissionChange change) {
Optional<ProjectId> projectId = change.getProjectId();
if (projectId.isPresent()) {
import java.util.Optional;
import java.util.Set;
-import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.permission.UserPermissionDto;
import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.permission.PermissionChange.Operation;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
+
public class UserPermissionChanger {
private final DbClient dbClient;
+ private final DefaultOrganizationProvider defaultOrganizationProvider;
- public UserPermissionChanger(DbClient dbClient) {
+ public UserPermissionChanger(DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider) {
this.dbClient = dbClient;
+ this.defaultOrganizationProvider = defaultOrganizationProvider;
}
public boolean apply(DbSession dbSession, UserPermissionChange change) {
default:
throw new UnsupportedOperationException("Unsupported permission change: " + change.getOperation());
}
+ if (SYSTEM_ADMIN.equals(change.getPermission()) && !change.getProjectId().isPresent()) {
+ dbClient.userDao().updateRootFlagFromPermissions(dbSession, change.getUserId().getId(), defaultOrganizationProvider.get().getUuid());
+ }
return true;
}
}
private void checkOtherAdminUsersExist(DbSession session, PermissionChange change) {
- if (GlobalPermissions.SYSTEM_ADMIN.equals(change.getPermission()) &&
+ if (SYSTEM_ADMIN.equals(change.getPermission()) &&
!change.getProjectId().isPresent() &&
dbClient.roleDao().countUserPermissions(session, change.getPermission(), null) <= 1) {
- throw new BadRequestException(String.format("Last user with '%s' permission. Permission cannot be removed.", GlobalPermissions.SYSTEM_ADMIN));
+ throw new BadRequestException(String.format("Last user with '%s' permission. Permission cannot be removed.", SYSTEM_ADMIN));
}
}
}
import org.sonar.db.DbSession;
import org.sonar.db.user.UserDto;
import org.sonar.db.user.UserGroupDto;
+import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.user.UserSession;
import static java.lang.String.format;
private final DbClient dbClient;
private final UserSession userSession;
private final GroupWsSupport support;
+ private final DefaultOrganizationProvider defaultOrganizationProvider;
- public AddUserAction(DbClient dbClient, UserSession userSession, GroupWsSupport support) {
+ public AddUserAction(DbClient dbClient, UserSession userSession, GroupWsSupport support, DefaultOrganizationProvider defaultOrganizationProvider) {
this.dbClient = dbClient;
this.userSession = userSession;
this.support = support;
+ this.defaultOrganizationProvider = defaultOrganizationProvider;
}
@Override
if (!isMemberOf(dbSession, user, groupId)) {
UserGroupDto membershipDto = new UserGroupDto().setGroupId(groupId.getId()).setUserId(user.getId());
dbClient.userGroupDao().insert(dbSession, membershipDto);
+ dbClient.userDao().updateRootFlagFromPermissions(dbSession, user.getId(), defaultOrganizationProvider.get().getUuid());
dbSession.commit();
}
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.user.UserDto;
+import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.user.UserSession;
import static java.lang.String.format;
private final DbClient dbClient;
private final UserSession userSession;
private final GroupWsSupport support;
+ private final DefaultOrganizationProvider defaultOrganizationProvider;
- public RemoveUserAction(DbClient dbClient, UserSession userSession, GroupWsSupport support) {
+ public RemoveUserAction(DbClient dbClient, UserSession userSession, GroupWsSupport support, DefaultOrganizationProvider defaultOrganizationProvider) {
this.dbClient = dbClient;
this.userSession = userSession;
this.support = support;
+ this.defaultOrganizationProvider = defaultOrganizationProvider;
}
@Override
UserDto user = getUser(dbSession, login);
dbClient.userGroupDao().delete(dbSession, group.getId(), user.getId());
+ dbClient.userDao().updateRootFlagFromPermissions(dbSession, user.getId(), defaultOrganizationProvider.get().getUuid());
dbSession.commit();
response.noContent();
import org.sonar.db.user.GroupDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.usergroups.ws.GroupIdOrAnyone;
import static org.assertj.core.api.Assertions.assertThat;
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
-
@Rule
public ExpectedException expectedException = ExpectedException.none();
- private GroupPermissionChanger underTest = new GroupPermissionChanger(db.getDbClient());
+ private GroupPermissionChanger underTest = new GroupPermissionChanger(db.getDbClient(), TestDefaultOrganizationProvider.from(db));
private OrganizationDto org;
private GroupDto group;
private ComponentDto project;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.user.GroupDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
expectedException.expect(BadRequestException.class);
- newRequest()
- .setParam(PARAM_GROUP_NAME, group.getName())
- .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN)
- .execute();
+ executeRequest(group, UserRole.ISSUE_ADMIN);
}
@Test
expectedException.expect(IllegalArgumentException.class);
newRequest()
- .setParam(PARAM_GROUP_NAME, group.getName())
- .execute();
+ .setParam(PARAM_GROUP_NAME, group.getName())
+ .execute();
}
@Test
assertThat(db.users().selectGroupPermissions(group, project)).containsOnly(ISSUE_ADMIN);
}
+ @Test
+ public void set_root_flag_to_true_on_all_users_in_group_when_admin_permission_to_group_of_default_organization_without_org_param() throws Exception {
+ GroupDto group = db.users().insertGroup(db.getDefaultOrganization());
+ UserDto rootByUserPermissionUser = db.users().insertRootByUserPermission();
+ UserDto rootByGroupPermissionUser = db.users().insertRootByGroupPermission();
+ UserDto notRootUser = db.users().insertUser();
+ UserDto notInGroupUser = db.users().insertUser();
+ db.users().insertMembers(group, rootByUserPermissionUser, rootByGroupPermissionUser, notRootUser);
+ loginAsAdminOnDefaultOrganization();
+
+ executeRequest(group, SYSTEM_ADMIN);
+
+ db.rootFlag().verify(rootByUserPermissionUser, true);
+ db.rootFlag().verify(rootByGroupPermissionUser, true);
+ db.rootFlag().verify(notRootUser, true);
+ db.rootFlag().verifyUnchanged(notInGroupUser);
+ }
+
+ @Test
+ public void set_root_flag_to_true_on_all_users_in_group_when_admin_permission_to_group_of_default_organization_with_org_param() throws Exception {
+ GroupDto group = db.users().insertGroup(db.getDefaultOrganization());
+ UserDto rootByUserPermissionUser = db.users().insertRootByUserPermission();
+ UserDto rootByGroupPermissionUser = db.users().insertRootByGroupPermission();
+ UserDto notRootUser = db.users().insertUser();
+ UserDto notInGroupUser = db.users().insertUser();
+ db.users().insertMembers(group, rootByUserPermissionUser, rootByGroupPermissionUser, notRootUser);
+ loginAsAdminOnDefaultOrganization();
+
+ executeRequest(group, db.getDefaultOrganization(), SYSTEM_ADMIN);
+
+ db.rootFlag().verify(rootByUserPermissionUser, true);
+ db.rootFlag().verify(rootByGroupPermissionUser, true);
+ db.rootFlag().verify(notRootUser, true);
+ db.rootFlag().verifyUnchanged(notInGroupUser);
+ }
+
+ @Test
+ public void does_not_set_root_flag_to_true_on_all_users_in_group_when_admin_permission_to_group_of_default_organization() throws Exception {
+ OrganizationDto otherOrganization = db.organizations().insert();
+ GroupDto group = db.users().insertGroup(otherOrganization);
+ UserDto rootByUserPermissionUser = db.users().insertRootByUserPermission();
+ UserDto rootByGroupPermissionUser = db.users().insertRootByGroupPermission();
+ UserDto notRootUser = db.users().insertUser();
+ UserDto notInGroupUser = db.users().insertUser();
+ db.users().insertMembers(group, rootByUserPermissionUser, rootByGroupPermissionUser, notRootUser);
+ loginAsAdmin(otherOrganization);
+
+ executeRequest(group, otherOrganization, SYSTEM_ADMIN);
+
+ db.rootFlag().verify(rootByUserPermissionUser, true);
+ db.rootFlag().verify(rootByGroupPermissionUser, true);
+ db.rootFlag().verify(notRootUser, false);
+ db.rootFlag().verifyUnchanged(notInGroupUser);
+ }
+
+ private void executeRequest(GroupDto groupDto, OrganizationDto organizationDto, String permission) throws Exception {
+ newRequest()
+ .setParam(PARAM_GROUP_NAME, groupDto.getName())
+ .setParam(PARAM_PERMISSION, permission)
+ .setParam(PARAM_ORGANIZATION_KEY, organizationDto.getKey())
+ .execute();
+ }
+
+ private void executeRequest(GroupDto groupDto, String permission) throws Exception {
+ newRequest()
+ .setParam(PARAM_GROUP_NAME, groupDto.getName())
+ .setParam(PARAM_PERMISSION, permission)
+ .execute();
+ }
+
private WsTester.TestRequest newRequest() {
return wsTester.newPostRequest(CONTROLLER, ACTION);
}
*/
package org.sonar.server.permission.ws;
+import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.web.UserRole;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.ServerException;
+import org.sonar.server.ws.WsTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
import static org.sonar.db.component.ComponentTesting.newView;
import static org.sonar.server.permission.ws.AddUserAction.ACTION;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.CONTROLLER;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION_KEY;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY;
assertThat(db.users().selectUserPermissions(user, project)).containsOnly(ISSUE_ADMIN);
}
+
+ @Test
+ public void sets_root_flag_to_true_when_adding_user_admin_permission_without_org_parameter() throws Exception {
+ UserDto rootByUserPermissionUser = db.users().insertRootByUserPermission();
+ UserDto rootByGroupPermissionUser = db.users().insertRootByGroupPermission();
+ UserDto notRootUser = db.users().insertUser();
+ loginAsAdminOnDefaultOrganization();
+
+ executeRequest(notRootUser, SYSTEM_ADMIN);
+ db.rootFlag().verify(notRootUser, true);
+ db.rootFlag().verifyUnchanged(rootByUserPermissionUser);
+ db.rootFlag().verifyUnchanged(rootByGroupPermissionUser);
+
+ executeRequest(rootByUserPermissionUser, SYSTEM_ADMIN);
+ db.rootFlag().verify(notRootUser, true);
+ db.rootFlag().verifyUnchanged(rootByUserPermissionUser); // because already has specified user permission
+ db.rootFlag().verifyUnchanged(rootByGroupPermissionUser);
+
+ executeRequest(rootByGroupPermissionUser, SYSTEM_ADMIN);
+ db.rootFlag().verify(notRootUser, true);
+ db.rootFlag().verifyUnchanged(rootByUserPermissionUser);
+ db.rootFlag().verify(rootByGroupPermissionUser, true);
+ }
+
+ @Test
+ public void sets_root_flag_to_true_when_adding_user_admin_permission_with_default_organization_uuid() throws Exception {
+ UserDto rootByUserPermissionUser = db.users().insertRootByUserPermission();
+ UserDto rootByGroupPermissionUser = db.users().insertRootByGroupPermission();
+ UserDto notRootUser = db.users().insertUser();
+ loginAsAdminOnDefaultOrganization();
+
+ executeRequest(notRootUser, SYSTEM_ADMIN, db.getDefaultOrganization());
+ db.rootFlag().verify(notRootUser, true);
+ db.rootFlag().verifyUnchanged(rootByUserPermissionUser);
+ db.rootFlag().verifyUnchanged(rootByGroupPermissionUser);
+
+ executeRequest(rootByUserPermissionUser, SYSTEM_ADMIN, db.getDefaultOrganization());
+ db.rootFlag().verify(notRootUser, true);
+ db.rootFlag().verifyUnchanged(rootByUserPermissionUser); // because already has specified user permission
+ db.rootFlag().verifyUnchanged(rootByGroupPermissionUser);
+
+ executeRequest(rootByGroupPermissionUser, SYSTEM_ADMIN, db.getDefaultOrganization());
+ db.rootFlag().verify(notRootUser, true);
+ db.rootFlag().verifyUnchanged(rootByUserPermissionUser);
+ db.rootFlag().verify(rootByGroupPermissionUser, true);
+ }
+
+ @Test
+ public void does_not_set_root_flag_when_adding_user_admin_permission_with_other_organization_uuid() throws Exception {
+ OrganizationDto otherOrganization = db.organizations().insert();
+ UserDto rootByUserPermissionUser = db.users().insertRootByUserPermission();
+ UserDto rootByGroupPermissionUser = db.users().insertRootByGroupPermission();
+ UserDto notRootUser = db.users().insertUser();
+ loginAsAdmin(otherOrganization);
+
+ executeRequest(notRootUser, SYSTEM_ADMIN, otherOrganization);
+ db.rootFlag().verify(notRootUser, false);
+ db.rootFlag().verifyUnchanged(rootByUserPermissionUser);
+ db.rootFlag().verifyUnchanged(rootByGroupPermissionUser);
+
+ executeRequest(rootByUserPermissionUser, SYSTEM_ADMIN, otherOrganization);
+ db.rootFlag().verify(notRootUser, false);
+ db.rootFlag().verifyUnchanged(rootByUserPermissionUser); // because already has specified permission
+ db.rootFlag().verifyUnchanged(rootByGroupPermissionUser);
+
+ executeRequest(rootByGroupPermissionUser, SYSTEM_ADMIN, otherOrganization);
+ db.rootFlag().verify(notRootUser, false);
+ db.rootFlag().verifyUnchanged(rootByUserPermissionUser);
+ db.rootFlag().verify(rootByGroupPermissionUser, true);
+ }
+
+ private void executeRequest(UserDto userDto, String permission) throws Exception {
+ executeRequest(userDto, permission, null);
+ }
+
+ private void executeRequest(UserDto userDto, String permission, @Nullable OrganizationDto organizationDto) throws Exception {
+ WsTester.TestRequest request = wsTester.newPostRequest(CONTROLLER, ACTION)
+ .setParam(PARAM_USER_LOGIN, userDto.getLogin())
+ .setParam(PARAM_PERMISSION, permission);
+ if (organizationDto != null) {
+ request.setParam(PARAM_ORGANIZATION_KEY, organizationDto.getKey());
+ }
+ request.execute();
+ }
+
}
protected PermissionUpdater newPermissionUpdater() {
return new PermissionUpdater(db.getDbClient(),
mock(IssueAuthorizationIndexer.class),
- new UserPermissionChanger(db.getDbClient()),
- new GroupPermissionChanger(db.getDbClient()));
+ new UserPermissionChanger(db.getDbClient(), defaultOrganizationProvider),
+ new GroupPermissionChanger(db.getDbClient(), defaultOrganizationProvider));
}
protected PermissionTemplateDto insertTemplate() {
import org.junit.Test;
import org.sonar.api.web.UserRole;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.user.GroupDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.CONTROLLER;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_ID;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_NAME;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION_KEY;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY;
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Last group with permission 'admin'. Permission cannot be removed.");
- newRequest()
- .setParam(PARAM_GROUP_NAME, aGroup.getName())
- .setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
- .execute();
+ executeRequest(aGroup, SYSTEM_ADMIN);
}
@Test
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Invalid global permission 'issueadmin'. Valid values are [admin, profileadmin, gateadmin, scan, provisioning]");
- newRequest()
- .setParam(PARAM_GROUP_NAME, aGroup.getName())
- .setParam(PARAM_PERMISSION, ISSUE_ADMIN)
- .execute();
+ executeRequest(aGroup, ISSUE_ADMIN);
}
@Test
.execute();
}
+ @Test
+ public void sets_root_flag_to_false_on_all_users_in_group_when_removing_admin_permission_from_group_of_default_organization_without_org_param() throws Exception {
+ UserDto lastAdminUser = db.users().insertRootByUserPermission();
+ GroupDto adminGroup = db.users().insertAdminGroup();
+ UserDto user1 = db.users().insertRootByGroupPermission("user1", adminGroup);
+ UserDto user2 = db.users().insertRootByGroupPermission("user2", adminGroup);
+ loginAsAdminOnDefaultOrganization();
+
+ executeRequest(adminGroup, SYSTEM_ADMIN);
+
+ db.rootFlag().verify(user1, false);
+ db.rootFlag().verify(user2, false);
+ db.rootFlag().verifyUnchanged(lastAdminUser);
+ }
+
+ @Test
+ public void sets_root_flag_to_false_on_all_users_in_group_when_removing_admin_permission_from_group_of_default_organization_with_org_param() throws Exception {
+ UserDto lastAdminUser = db.users().insertRootByUserPermission();
+ GroupDto adminGroup = db.users().insertAdminGroup();
+ UserDto user1 = db.users().insertRootByGroupPermission("user1", adminGroup);
+ UserDto user2 = db.users().insertRootByGroupPermission("user2", adminGroup);
+ loginAsAdminOnDefaultOrganization();
+
+ executeRequest(adminGroup, db.getDefaultOrganization(), SYSTEM_ADMIN);
+
+ db.rootFlag().verify(user1, false);
+ db.rootFlag().verify(user2, false);
+ db.rootFlag().verifyUnchanged(lastAdminUser);
+ }
+
+ @Test
+ public void does_not_set_root_flag_to_false_on_all_users_in_group_when_removing_admin_permission_from_group_of_other_organization() throws Exception {
+ OrganizationDto otherOrganization = db.organizations().insert();
+ UserDto lastAdmin = db.users().insertUser();
+ db.users().insertPermissionOnUser(otherOrganization, lastAdmin, SYSTEM_ADMIN);
+ GroupDto adminGroup = db.users().insertAdminGroup(otherOrganization);
+ UserDto rootByUserPermissionUser = db.users().insertRootByUserPermission();
+ UserDto rootByGroupPermissionUser = db.users().insertRootByGroupPermission();
+ UserDto inAdminGroupUser = db.users().insertUser();
+ UserDto notInGroupUser = db.users().insertUser();
+ db.users().insertMembers(adminGroup, rootByUserPermissionUser, rootByGroupPermissionUser, inAdminGroupUser);
+ loginAsAdmin(otherOrganization);
+
+ executeRequest(adminGroup, otherOrganization, SYSTEM_ADMIN);
+
+ db.rootFlag().verify(rootByUserPermissionUser, true);
+ db.rootFlag().verify(rootByGroupPermissionUser, true);
+ db.rootFlag().verify(inAdminGroupUser, false);
+ db.rootFlag().verifyUnchanged(notInGroupUser);
+ }
+
+ private void executeRequest(GroupDto groupDto, String permission) throws Exception {
+ newRequest()
+ .setParam(PARAM_GROUP_NAME, groupDto.getName())
+ .setParam(PARAM_PERMISSION, permission)
+ .execute();
+ }
+
+ private void executeRequest(GroupDto groupDto, OrganizationDto organizationDto, String permission) throws Exception {
+ newRequest()
+ .setParam(PARAM_GROUP_NAME, groupDto.getName())
+ .setParam(PARAM_PERMISSION, permission)
+ .setParam(PARAM_ORGANIZATION_KEY, organizationDto.getKey())
+ .execute();
+ }
+
@Test
public void removing_global_permission_fails_if_not_administrator_of_organization() throws Exception {
userSession.login();
import static org.sonar.db.component.ComponentTesting.newView;
import static org.sonar.server.permission.ws.RemoveUserAction.ACTION;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.CONTROLLER;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION_KEY;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY;
public void remove_permission_from_user() throws Exception {
db.users().insertPermissionOnUser(user, PROVISIONING);
db.users().insertPermissionOnUser(user, QUALITY_GATE_ADMIN);
- loginAsAdmin();
+ loginAsAdminOnDefaultOrganization();
wsTester.newPostRequest(CONTROLLER, ACTION)
.setParam(PARAM_USER_LOGIN, user.getLogin())
public void fail_to_remove_admin_permission_if_last_admin() throws Exception {
db.users().insertPermissionOnUser(user, CODEVIEWER);
db.users().insertPermissionOnUser(user, ADMIN);
- loginAsAdmin();
+ loginAsAdminOnDefaultOrganization();
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Last user with 'admin' permission. Permission cannot be removed.");
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY));
db.users().insertProjectPermissionOnUser(user, CODEVIEWER, project);
db.users().insertProjectPermissionOnUser(user, ISSUE_ADMIN, project);
- loginAsAdmin();
+ loginAsAdminOnDefaultOrganization();
wsTester.newPostRequest(CONTROLLER, ACTION)
.setParam(PARAM_USER_LOGIN, user.getLogin())
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY));
db.users().insertProjectPermissionOnUser(user, ISSUE_ADMIN, project);
db.users().insertProjectPermissionOnUser(user, CODEVIEWER, project);
- loginAsAdmin();
+ loginAsAdminOnDefaultOrganization();
wsTester.newPostRequest(CONTROLLER, ACTION)
.setParam(PARAM_USER_LOGIN, user.getLogin())
ComponentDto view = db.components().insertComponent(newView("view-uuid").setKey("view-key"));
db.users().insertProjectPermissionOnUser(user, ISSUE_ADMIN, view);
db.users().insertProjectPermissionOnUser(user, CODEVIEWER, view);
- loginAsAdmin();
+ loginAsAdminOnDefaultOrganization();
wsTester.newPostRequest(CONTROLLER, ACTION)
.setParam(PARAM_USER_LOGIN, user.getLogin())
@Test
public void fail_when_project_does_not_exist() throws Exception {
- loginAsAdmin();
+ loginAsAdminOnDefaultOrganization();
expectedException.expect(NotFoundException.class);
@Test
public void fail_when_project_permission_without_permission() throws Exception {
- loginAsAdmin();
+ loginAsAdminOnDefaultOrganization();
expectedException.expect(BadRequestException.class);
@Test
public void fail_when_component_is_not_a_project() throws Exception {
db.components().insertComponent(newFileDto(newProjectDto(), null, "file-uuid"));
- loginAsAdmin();
+ loginAsAdminOnDefaultOrganization();
expectedException.expect(BadRequestException.class);
@Test
public void fail_when_get_request() throws Exception {
- loginAsAdmin();
+ loginAsAdminOnDefaultOrganization();
expectedException.expect(ServerException.class);
@Test
public void fail_when_user_login_is_missing() throws Exception {
- loginAsAdmin();
+ loginAsAdminOnDefaultOrganization();
expectedException.expect(IllegalArgumentException.class);
@Test
public void fail_when_permission_is_missing() throws Exception {
- loginAsAdmin();
+ loginAsAdminOnDefaultOrganization();
expectedException.expect(IllegalArgumentException.class);
@Test
public void fail_when_project_uuid_and_project_key_are_provided() throws Exception {
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY));
- loginAsAdmin();
+ loginAsAdminOnDefaultOrganization();
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Project id or project key can be provided, not both.");
.execute();
}
+ @Test
+ public void sets_root_flag_to_false_when_removing_user_admin_permission_of_default_organization_without_org_parameter() throws Exception {
+ UserDto lastAdminUser = db.users().insertRootByUserPermission();
+ UserDto adminUser = db.users().insertRootByUserPermission();
+ loginAsAdminOnDefaultOrganization();
+
+ executeRequest(adminUser, SYSTEM_ADMIN);
+
+ db.rootFlag().verify(adminUser, false);
+ }
+
+ @Test
+ public void sets_root_flag_to_false_when_removing_user_admin_permission_of_default_organization_with_org_parameter() throws Exception {
+ UserDto lastAdminUser = db.users().insertRootByUserPermission();
+ UserDto adminUser = db.users().insertRootByUserPermission();
+ loginAsAdminOnDefaultOrganization();
+
+ executeRequest(adminUser, db.getDefaultOrganization(), SYSTEM_ADMIN);
+
+ db.rootFlag().verify(adminUser, false);
+ }
+
+ @Test
+ public void does_not_set_root_flag_to_false_when_removing_user_admin_permission_of_other_organization() throws Exception {
+ UserDto rootUser = db.users().insertRootByUserPermission();
+ UserDto notRootUser = db.users().insertUser();
+ OrganizationDto otherOrganization = db.organizations().insert();
+ db.users().insertPermissionOnUser(otherOrganization, rootUser, SYSTEM_ADMIN);
+ db.users().insertPermissionOnUser(otherOrganization, notRootUser, SYSTEM_ADMIN);
+ loginAsAdmin(otherOrganization);
+
+ executeRequest(rootUser, otherOrganization, SYSTEM_ADMIN);
+ db.rootFlag().verify(rootUser, true);
+ db.rootFlag().verifyUnchanged(notRootUser);
+
+ executeRequest(notRootUser, otherOrganization, SYSTEM_ADMIN);
+ db.rootFlag().verify(rootUser, true);
+ db.rootFlag().verify(notRootUser, false);
+ }
+
+ private void executeRequest(UserDto userDto, OrganizationDto organizationDto, String permission) throws Exception {
+ wsTester.newPostRequest(CONTROLLER, ACTION)
+ .setParam(PARAM_USER_LOGIN, userDto.getLogin())
+ .setParam(PARAM_PERMISSION, permission)
+ .setParam(PARAM_ORGANIZATION_KEY, organizationDto.getKey())
+ .execute();
+ }
+
+ private void executeRequest(UserDto userDto, String permission) throws Exception {
+ wsTester.newPostRequest(CONTROLLER, ACTION)
+ .setParam(PARAM_USER_LOGIN, userDto.getLogin())
+ .setParam(PARAM_PERMISSION, permission)
+ .execute();
+ }
+
@Test
public void removing_global_permission_fails_if_not_administrator_of_organization() throws Exception {
userSession.login();
assertThat(db.users().selectUserPermissions(user, project)).containsOnly(CODEVIEWER);
}
- private void loginAsAdmin() {
- loginAsOrganizationAdmin(db.getDefaultOrganization());
- }
-
- private void loginAsOrganizationAdmin(OrganizationDto org) {
- userSession.login().addOrganizationPermission(org.getUuid(), SYSTEM_ADMIN);
- }
}
*/
package org.sonar.server.usergroups.ws;
+import java.util.List;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
-import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.user.GroupDto;
import org.sonar.db.user.UserDto;
+import org.sonar.db.user.UserMembershipDto;
+import org.sonar.db.user.UserMembershipQuery;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.ws.WsTester;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_GROUP_NAME;
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_LOGIN;
import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_ORGANIZATION_KEY;
@Before
public void setUp() {
- ws = new WsTester(new UserGroupsWs(new AddUserAction(db.getDbClient(), userSession, newGroupWsSupport())));
+ ws = new WsTester(new UserGroupsWs(new AddUserAction(db.getDbClient(), userSession, newGroupWsSupport(), defaultOrganizationProvider)));
}
@Test
UserDto user1 = db.users().insertUser();
UserDto user2 = db.users().insertUser();
db.users().insertMember(users, user1);
-
loginAsAdminOnDefaultOrganization();
+
newRequest()
.setParam("id", users.getId().toString())
.setParam("login", user2.getLogin())
@Test
public void fail_if_group_does_not_exist() throws Exception {
UserDto user = db.users().insertUser();
+ loginAsAdminOnDefaultOrganization();
expectedException.expect(NotFoundException.class);
- loginAsAdminOnDefaultOrganization();
newRequest()
.setParam("id", "42")
.setParam("login", user.getLogin())
@Test
public void fail_if_user_does_not_exist() throws Exception {
GroupDto group = db.users().insertGroup(db.getDefaultOrganization(), "admins");
+ loginAsAdminOnDefaultOrganization();
expectedException.expect(NotFoundException.class);
- loginAsAdminOnDefaultOrganization();
newRequest()
.setParam("id", group.getId().toString())
.setParam("login", "my-admin")
expectedException.expect(UnauthorizedException.class);
+ executeRequest(group, user);
+ }
+
+ @Test
+ public void set_root_flag_to_true_when_adding_user_to_group_of_default_organization_with_admin_permission() throws Exception {
+ GroupDto group = db.users().insertAdminGroup();
+ UserDto falselyRootUser = db.users().makeRoot(db.users().insertUser("falselyRootUser"));
+ UserDto notRootUser = db.users().insertUser("notRootUser");
+ loginAsAdminOnDefaultOrganization();
+
+ executeRequest(group, falselyRootUser);
+ verifyUserInGroup(falselyRootUser, group);
+ db.rootFlag().verify(falselyRootUser, true);
+ verifyUserNotInGroup(notRootUser, group);
+ db.rootFlag().verifyUnchanged(notRootUser);
+
+ executeRequest(group, notRootUser);
+ verifyUserInGroup(falselyRootUser, group);
+ db.rootFlag().verify(falselyRootUser, true);
+ verifyUserInGroup(notRootUser, group);
+ db.rootFlag().verify(notRootUser, true);
+ }
+
+ @Test
+ public void does_not_set_root_flag_to_true_when_adding_user_to_group_of_other_organization_with_admin_permission() throws Exception {
+ OrganizationDto otherOrganization = db.organizations().insert();
+ GroupDto group = db.users().insertAdminGroup(otherOrganization);
+ UserDto falselyRootUser = db.users().makeRoot(db.users().insertUser("falselyRootUser"));
+ UserDto notRootUser = db.users().insertUser("notRootUser");
+ loginAsAdmin(otherOrganization);
+
+ executeRequest(group, falselyRootUser);
+ verifyUserInGroup(falselyRootUser, group);
+ db.rootFlag().verify(falselyRootUser, false);
+ verifyUserNotInGroup(notRootUser, group);
+ db.rootFlag().verifyUnchanged(notRootUser);
+
+ executeRequest(group, notRootUser);
+ verifyUserInGroup(falselyRootUser, group);
+ db.rootFlag().verify(falselyRootUser, false);
+ verifyUserInGroup(notRootUser, group);
+ db.rootFlag().verify(notRootUser, false);
+ }
+
+ private void executeRequest(GroupDto groupDto, UserDto userDto) throws Exception {
newRequest()
- .setParam("id", group.getId().toString())
- .setParam("login", user.getLogin())
+ .setParam("id", groupDto.getId().toString())
+ .setParam("login", userDto.getLogin())
.execute();
}
}
private void loginAsAdmin(OrganizationDto org) {
- userSession.login().addOrganizationPermission(org.getUuid(), GlobalPermissions.SYSTEM_ADMIN);
+ userSession.login().addOrganizationPermission(org.getUuid(), SYSTEM_ADMIN);
}
private GroupWsSupport newGroupWsSupport() {
return new GroupWsSupport(db.getDbClient(), defaultOrganizationProvider);
}
+ private void verifyUserInGroup(UserDto userDto, GroupDto groupDto) {
+ assertThat(isUserInGroup(userDto, groupDto))
+ .as("user '%s' is a member of group '%s' of organization '%s'", userDto.getLogin(), groupDto.getName(), groupDto.getOrganizationUuid())
+ .isTrue();
+ }
+
+ private void verifyUserNotInGroup(UserDto userDto, GroupDto groupDto) {
+ assertThat(isUserInGroup(userDto, groupDto))
+ .as("user '%s' is not a member of group '%s' of organization '%s'", userDto.getLogin(), groupDto.getName(), groupDto.getOrganizationUuid())
+ .isFalse();
+ }
+
+ private boolean isUserInGroup(UserDto userDto, GroupDto groupDto) {
+ List<UserMembershipDto> members = db.getDbClient().groupMembershipDao()
+ .selectMembers(db.getSession(), UserMembershipQuery.builder().groupId(groupDto.getId()).membership(UserMembershipQuery.IN).build(), 0, Integer.MAX_VALUE);
+ return members
+ .stream()
+ .anyMatch(dto -> dto.getLogin().equals(userDto.getLogin()));
+ }
+
}
*/
package org.sonar.server.usergroups.ws;
+import java.util.List;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.user.GroupDto;
import org.sonar.db.user.UserDto;
+import org.sonar.db.user.UserMembershipDto;
+import org.sonar.db.user.UserMembershipQuery;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.tester.UserSessionRule;
@Before
public void setUp() {
GroupWsSupport groupSupport = new GroupWsSupport(db.getDbClient(), defaultOrganizationProvider);
- ws = new WsTester(new UserGroupsWs(new RemoveUserAction(db.getDbClient(), userSession, groupSupport)));
+ ws = new WsTester(new UserGroupsWs(new RemoveUserAction(db.getDbClient(), userSession, groupSupport, defaultOrganizationProvider)));
}
@Test
.execute();
}
+ @Test
+ public void sets_root_flag_to_false_when_removing_user_from_group_of_default_organization_with_admin_permission() throws Exception {
+ GroupDto adminGroup = db.users().insertAdminGroup();
+ UserDto user1 = db.users().insertRootByGroupPermission(adminGroup);
+ UserDto user2 = db.users().insertRootByGroupPermission(adminGroup);
+ loginAsAdmin();
+
+ executeRequest(adminGroup, user1);
+ verifyUserNotInGroup(user1, adminGroup);
+ verifyRootFlagUpdated(user1, false);
+ verifyUserInGroup(user2, adminGroup);
+ verifyUnchanged(user2);
+
+ executeRequest(adminGroup, user2);
+ verifyUserNotInGroup(user1, adminGroup);
+ verifyRootFlag(user1, false);
+ verifyUserNotInGroup(user2, adminGroup);
+ verifyRootFlagUpdated(user2, false);
+ }
+
+ @Test
+ public void does_not_set_root_flag_to_false_when_removing_user_from_group_of_default_organization_and_user_is_admin_of_default_organization_another_way()
+ throws Exception {
+ GroupDto adminGroup1 = db.users().insertAdminGroup();
+ UserDto adminUserByUserPermission = db.users().insertRootByUserPermission("adminUserByUserPermission");
+ UserDto adminUserByTwoGroups = db.users().insertRootByGroupPermission("adminUserByTwoGroups", adminGroup1);
+ UserDto adminUserBySingleGroup = db.users().insertUser("adminUserBySingleGroup");
+ GroupDto adminGroup2 = db.users().insertAdminGroup();
+ db.users().insertMembers(adminGroup2, adminUserByUserPermission, adminUserByTwoGroups, adminUserBySingleGroup);
+ loginAsAdmin();
+
+ executeRequest(adminGroup2, adminUserByUserPermission);
+ verifyUserNotInGroup(adminUserByUserPermission, adminGroup2);
+ verifyRootFlagUpdated(adminUserByUserPermission, true);
+ verifyUserInGroup(adminUserByTwoGroups, adminGroup2);
+ verifyUserInGroup(adminUserByTwoGroups, adminGroup1);
+ verifyUnchanged(adminUserByTwoGroups);
+ verifyUserInGroup(adminUserBySingleGroup, adminGroup2);
+ verifyUnchanged(adminUserBySingleGroup);
+
+ executeRequest(adminGroup2, adminUserByTwoGroups);
+ verifyUserNotInGroup(adminUserByUserPermission, adminGroup2);
+ verifyRootFlag(adminUserByUserPermission, true);
+ verifyUserNotInGroup(adminUserByTwoGroups, adminGroup2);
+ verifyUserInGroup(adminUserByTwoGroups, adminGroup1);
+ verifyRootFlagUpdated(adminUserByTwoGroups, true);
+ verifyUserInGroup(adminUserBySingleGroup, adminGroup2);
+ verifyUnchanged(adminUserBySingleGroup);
+
+ executeRequest(adminGroup2, adminUserBySingleGroup);
+ verifyUserNotInGroup(adminUserByUserPermission, adminGroup2);
+ verifyRootFlag(adminUserByUserPermission, true);
+ verifyUserNotInGroup(adminUserByTwoGroups, adminGroup2);
+ verifyUserInGroup(adminUserByTwoGroups, adminGroup1);
+ verifyRootFlagUpdated(adminUserByTwoGroups, true);
+ verifyUserNotInGroup(adminUserBySingleGroup, adminGroup2);
+ verifyRootFlagUpdated(adminUserBySingleGroup, false);
+ }
+
+ private void executeRequest(GroupDto group, UserDto user) throws Exception {
+ newRequest()
+ .setParam("id", group.getId().toString())
+ .setParam("login", user.getLogin())
+ .execute();
+ }
+
private WsTester.TestRequest newRequest() {
return ws.newPostRequest("api/user_groups", "remove_user");
}
userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
}
+ private void verifyUnchanged(UserDto user) {
+ db.rootFlag().verifyUnchanged(user);
+ }
+
+ private void verifyRootFlagUpdated(UserDto userDto, boolean root) {
+ db.rootFlag().verify(userDto, root);
+ }
+
+ private void verifyRootFlag(UserDto userDto, boolean root) {
+ db.rootFlag().verify(userDto, root);
+ }
+
+ private void verifyUserInGroup(UserDto userDto, GroupDto groupDto) {
+ assertThat(isUserInGroup(userDto, groupDto))
+ .as("user '%s' is a member of group '%s' of organization '%s'", userDto.getLogin(), groupDto.getName(), groupDto.getOrganizationUuid())
+ .isTrue();
+ }
+
+ private void verifyUserNotInGroup(UserDto userDto, GroupDto groupDto) {
+ assertThat(isUserInGroup(userDto, groupDto))
+ .as("user '%s' is not a member of group '%s' of organization '%s'", userDto.getLogin(), groupDto.getName(), groupDto.getOrganizationUuid())
+ .isFalse();
+ }
+
+ private boolean isUserInGroup(UserDto userDto, GroupDto groupDto) {
+ List<UserMembershipDto> members = db.getDbClient().groupMembershipDao()
+ .selectMembers(db.getSession(), UserMembershipQuery.builder().groupId(groupDto.getId()).membership(UserMembershipQuery.IN).build(), 0, Integer.MAX_VALUE);
+ return members
+ .stream()
+ .anyMatch(dto -> dto.getLogin().equals(userDto.getLogin()));
+ }
+
}
return mapper(dbSession).selectByOrganizationUuid(organizationUuid);
}
+ /**
+ * Ensures all users of the specified group have its root flag set or unset depending on whether each of them have the
+ * 'admin' permission in the default organization or not.
+ */
+ public void updateRootFlagOfUsersInGroupFromPermissions(DbSession dbSession, long groupId, String defaultOrganizationUuid) {
+ long now = system.now();
+ GroupMapper mapper = mapper(dbSession);
+ mapper.updateRootUsersOfGroup(groupId, defaultOrganizationUuid, now);
+ mapper.updateNonRootUsersOfGroup(groupId, defaultOrganizationUuid, now);
+ }
+
private static GroupMapper mapper(DbSession session) {
return session.getMapper(GroupMapper.class);
}
GroupDto selectByName(@Param("organizationUuid") String organizationUuid, @Param("name") String name);
List<GroupDto> selectByOrganizationUuid(@Param("organizationUuid") String organizationUuid);
+
+ int updateRootUsersOfGroup(@Param("groupId") long groupId,
+ @Param("defaultOrganizationUuid") String defaultOrganizationUuid,
+ @Param("now") long now);
+
+ int updateNonRootUsersOfGroup(@Param("groupId") long groupId,
+ @Param("defaultOrganizationUuid") String defaultOrganizationUuid,
+ @Param("now") long now);
}
}
public UserDto selectUserById(DbSession session, long userId) {
- return getMapper(session).selectUser(userId);
+ return mapper(session).selectUser(userId);
}
/**
* Used by the Governance plugin
*/
public List<UserDto> selectByIds(DbSession session, Collection<Long> ids) {
- return executeLargeInputs(ids, getMapper(session)::selectByIds);
+ return executeLargeInputs(ids, mapper(session)::selectByIds);
}
/**
@CheckForNull
public UserDto selectActiveUserByLogin(DbSession session, String login) {
- UserMapper mapper = getMapper(session);
+ UserMapper mapper = mapper(session);
return mapper.selectUserByLogin(login);
}
* if list of logins is empty, without any db round trips.
*/
public List<UserDto> selectByLogins(DbSession session, Collection<String> logins) {
- return executeLargeInputs(logins, getMapper(session)::selectByLogins);
+ return executeLargeInputs(logins, mapper(session)::selectByLogins);
}
/**
}
public List<UserDto> selectUsers(DbSession dbSession, UserQuery query) {
- return getMapper(dbSession).selectUsers(query);
+ return mapper(dbSession).selectUsers(query);
}
public long countRootUsersButLogin(DbSession dbSession, String login) {
- return getMapper(dbSession).countRootUsersButLogin(login);
+ return mapper(dbSession).countRootUsersButLogin(login);
}
public UserDto insert(DbSession session, UserDto dto) {
- getMapper(session).insert(dto);
+ mapper(session).insert(dto);
return dto;
}
public UserDto update(DbSession session, UserDto dto) {
- getMapper(session).update(dto);
+ mapper(session).update(dto);
return dto;
}
public void setRoot(DbSession session, String login, boolean root) {
- getMapper(session).setRoot(login, root, system2.now());
+ mapper(session).setRoot(login, root, system2.now());
}
/**
* @return false if the user does not exist, true if the existing user has been deactivated
*/
public boolean deactivateUserByLogin(DbSession dbSession, String login) {
- UserMapper mapper = getMapper(dbSession);
+ UserMapper mapper = mapper(dbSession);
UserDto dto = mapper.selectUserByLogin(login);
if (dto == null) {
return false;
@CheckForNull
public UserDto selectByLogin(DbSession session, String login) {
- return getMapper(session).selectByLogin(login);
+ return mapper(session).selectByLogin(login);
}
public UserDto selectOrFailByLogin(DbSession session, String login) {
String like = new StringBuilder().append("%")
.append(UserDto.SCM_ACCOUNTS_SEPARATOR).append(scmAccountOrLoginOrEmail)
.append(UserDto.SCM_ACCOUNTS_SEPARATOR).append("%").toString();
- return getMapper(session).selectNullableByScmAccountOrLoginOrEmail(scmAccountOrLoginOrEmail, like);
+ return mapper(session).selectNullableByScmAccountOrLoginOrEmail(scmAccountOrLoginOrEmail, like);
}
/**
* Please note that email is case insensitive, result for searching 'mail@email.com' or 'Mail@Email.com' will be the same
*/
public boolean doesEmailExist(DbSession dbSession, String email) {
- return getMapper(dbSession).countByEmail(email.toLowerCase(Locale.ENGLISH)) > 0;
+ return mapper(dbSession).countByEmail(email.toLowerCase(Locale.ENGLISH)) > 0;
}
- private static UserMapper getMapper(DbSession session) {
+ /**
+ * Ensures the specified user has its root flag set or unset depending on whether the user has the 'admin' permission
+ * in the default organization or not.
+ */
+ public void updateRootFlagFromPermissions(DbSession dbSession, long userId, String defaultOrganizationUuid) {
+ long now = system2.now();
+ UserMapper mapper = mapper(dbSession);
+ mapper.updateRootUser(userId, defaultOrganizationUuid, now);
+ mapper.updateNonRootUser(userId, defaultOrganizationUuid, now);
+ }
+
+ protected UserMapper mapper(DbSession session) {
return session.getMapper(UserMapper.class);
}
void deletePropertiesMatchingLogin(@Param("propertyKeys") List<String> propertyKeys, @Param("login") String login);
void deactivateUser(@Param("id") long userId, @Param("now") long now);
+
+ int updateRootUser(@Param("userId") long userId, @Param("defaultOrganizationUuid") String defaultOrganizationUuid, @Param("now") long now);
+
+ int updateNonRootUser(@Param("userId") long userId, @Param("defaultOrganizationUuid") String defaultOrganizationUuid, @Param("now") long now);
+
}
order by upper(g.name)
</select>
+ <update id="updateRootUsersOfGroup">
+ update users u set
+ is_root = ${_true},
+ updated_at = #{now,jdbcType=BIGINT}
+ where
+ u.id in (<include refid="userIdsForGroupId"/>)
+ and exists (
+ <include refid="userPermissionAdminInDefaultOrganizationForUser"/>
+ union
+ <include refid="groupPermissionAdminInDefaultOrganizationForUser"/>
+ )
+ </update>
+ <update id="updateRootUsersOfGroup" databaseId="mssql">
+ update u set
+ is_root = ${_true},
+ updated_at = #{now,jdbcType=BIGINT}
+ from users u
+ where
+ u.id in (<include refid="userIdsForGroupId"/>)
+ and exists (
+ <include refid="userPermissionAdminInDefaultOrganizationForUser"/>
+ union
+ <include refid="groupPermissionAdminInDefaultOrganizationForUser"/>
+ )
+ </update>
+ <update id="updateNonRootUsersOfGroup">
+ update users u set
+ is_root = ${_false},
+ updated_at = #{now,jdbcType=BIGINT}
+ where
+ u.id in (<include refid="userIdsForGroupId"/>)
+ and not exists (
+ <include refid="userPermissionAdminInDefaultOrganizationForUser"/>
+ union
+ <include refid="groupPermissionAdminInDefaultOrganizationForUser"/>
+ )
+ </update>
+
+ <update id="updateNonRootUsersOfGroup" databaseId="mssql">
+ update u set
+ is_root = ${_false},
+ updated_at = #{now,jdbcType=BIGINT}
+ from users u
+ where
+ u.id in (<include refid="userIdsForGroupId"/>)
+ and not exists (
+ <include refid="userPermissionAdminInDefaultOrganizationForUser"/>
+ union
+ <include refid="groupPermissionAdminInDefaultOrganizationForUser"/>
+ )
+ </update>
+
+ <sql id="userIdsForGroupId">
+ select
+ gu.user_id
+ from
+ groups_users gu
+ where
+ gu.group_id = #{groupId,jdbcType=BIGINT}
+ </sql>
+
+ <sql id="userPermissionAdminInDefaultOrganizationForUser">
+ select
+ 1
+ from
+ user_roles ur
+ where
+ ur.user_id = u.id
+ and ur.role = 'admin'
+ and ur.resource_id is null
+ and ur.organization_uuid = #{defaultOrganizationUuid,jdbcType=VARCHAR}
+ </sql>
+
+ <sql id="groupPermissionAdminInDefaultOrganizationForUser">
+ select
+ 1
+ from
+ groups_users gu,
+ group_roles gr
+ where
+ gu.user_id = u.id
+ and gu.group_id = gr.group_id
+ and gr.role = 'admin'
+ and gr.resource_id is null
+ and gr.organization_uuid = #{defaultOrganizationUuid,jdbcType=VARCHAR}
+ </sql>
</mapper>
login = #{login}
</insert>
+ <update id="updateRootUser">
+ update users u set
+ is_root = ${_true},
+ updated_at = #{now,jdbcType=BIGINT}
+ where
+ u.id = #{userId,jdbcType=BIGINT}
+ and exists (
+ <include refid="userPermissionAdminInDefaultOrganizationForUser"/>
+ union
+ <include refid="groupPermissionAdminInDefaultOrganizationForUser"/>
+ )
+ </update>
+
+ <update id="updateRootUser" databaseId="mssql">
+ update u set
+ is_root = ${_true},
+ updated_at = #{now,jdbcType=BIGINT}
+ from users u
+ where
+ u.id = #{userId,jdbcType=BIGINT}
+ and exists (
+ <include refid="userPermissionAdminInDefaultOrganizationForUser"/>
+ union
+ <include refid="groupPermissionAdminInDefaultOrganizationForUser"/>
+ )
+ </update>
+
+ <update id="updateNonRootUser">
+ update users u set
+ is_root = ${_false},
+ updated_at = #{now,jdbcType=BIGINT}
+ where
+ u.id = #{userId,jdbcType=BIGINT}
+ and not exists (
+ <include refid="userPermissionAdminInDefaultOrganizationForUser"/>
+ union
+ <include refid="groupPermissionAdminInDefaultOrganizationForUser"/>
+ )
+ </update>
+
+ <update id="updateNonRootUser" databaseId="mssql">
+ update u set
+ is_root = ${_false},
+ updated_at = #{now,jdbcType=BIGINT}
+ from users u
+ where
+ u.id = #{userId,jdbcType=BIGINT}
+ and not exists (
+ <include refid="userPermissionAdminInDefaultOrganizationForUser"/>
+ union
+ <include refid="groupPermissionAdminInDefaultOrganizationForUser"/>
+ )
+ </update>
+
+ <sql id="userPermissionAdminInDefaultOrganizationForUser">
+ select
+ 1
+ from
+ user_roles ur
+ where
+ ur.user_id = u.id
+ and ur.role = 'admin'
+ and ur.resource_id is null
+ and ur.organization_uuid = #{defaultOrganizationUuid,jdbcType=VARCHAR}
+ </sql>
+
+ <sql id="groupPermissionAdminInDefaultOrganizationForUser">
+ select
+ 1
+ from
+ groups_users gu,
+ group_roles gr
+ where
+ gu.user_id = u.id
+ and gu.group_id = gr.group_id
+ and gr.role = 'admin'
+ and gr.resource_id is null
+ and gr.organization_uuid = #{defaultOrganizationUuid,jdbcType=VARCHAR}
+ </sql>
+
</mapper>
import org.sonar.db.organization.OrganizationDbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.organization.OrganizationTesting;
+import org.sonar.db.user.RootFlagAssertions;
import org.sonar.db.user.UserDbTester;
import static com.google.common.base.Preconditions.checkArgument;
private final UserDbTester userTester;
private final ComponentDbTester componentTester;
private final OrganizationDbTester organizationTester;
+ private final RootFlagAssertions rootFlagAssertions;
private DbTester(System2 system2, @Nullable String schemaPath) {
this.system2 = system2;
this.userTester = new UserDbTester(this);
this.componentTester = new ComponentDbTester(this);
this.organizationTester = new OrganizationDbTester(this);
+ this.rootFlagAssertions = new RootFlagAssertions(this);
}
public static DbTester create(System2 system2) {
return organizationTester;
}
+ public RootFlagAssertions rootFlag() {
+ return rootFlagAssertions;
+ }
+
@Override
protected void after() {
if (session != null) {
import org.sonar.db.organization.OrganizationDto;
import static java.util.Arrays.asList;
+import static java.util.Arrays.stream;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
import static org.sonar.db.user.GroupTesting.newGroupDto;
public class GroupDaoTest {
.setKey("an-org")
.setName("An Org")
.setUuid("abcde");
+ private static final long DATE_1 = 8_776_543L;
+ private static final long DATE_2 = 4_776_898L;
private System2 system2 = mock(System2.class);
@Rule
public DbTester db = DbTester.create(system2);
+
private final DbSession dbSession = db.getSession();
private GroupDao underTest = new GroupDao(system2);
assertThat(db.countRowsOfTable(dbSession, "groups")).isEqualTo(0);
}
+ @Test
+ public void updateRootFlagOfUsersInGroupFromPermissions_sets_root_flag_to_false_if_users_have_no_permission_at_all() {
+ UserDto[] usersInGroup1 = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser()
+ };
+ UserDto[] usersInGroup2 = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser()
+ };
+ UserDto[] usersNotInGroup = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser()
+ };
+ GroupDto group1 = db.users().insertGroup();
+ stream(usersInGroup1).forEach(user -> db.users().insertMember(group1, user));
+ GroupDto group2 = db.users().insertGroup();
+ stream(usersInGroup2).forEach(user -> db.users().insertMember(group2, user));
+
+ call_updateRootFlagFromPermissions(group1, DATE_1);
+ stream(usersInGroup1).forEach(user -> db.rootFlag().verify(user, false, DATE_1));
+ stream(usersInGroup2).forEach(db.rootFlag()::verifyUnchanged);
+ stream(usersNotInGroup).forEach(db.rootFlag()::verifyUnchanged);
+
+ call_updateRootFlagFromPermissions(group2, DATE_2);
+ stream(usersInGroup2).forEach(user -> db.rootFlag().verify(user, false, DATE_2));
+ stream(usersInGroup1).forEach(user -> db.rootFlag().verify(user, false, DATE_1));
+ stream(usersNotInGroup).forEach(db.rootFlag()::verifyUnchanged);
+ }
+
+ @Test
+ public void updateRootFlagOfUsersInGroupFromPermissions_sets_root_flag_to_true_if_users_has_admin_user_permission_on_default_organization() {
+ UserDto[] usersWithAdminInGroup1 = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser(),
+ };
+ UserDto[] usersWithoutAdminInGroup1 = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser(),
+ };
+ UserDto[] usersWithAdminInGroup2 = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser()
+ };
+ UserDto[] usersWithoutAdminInGroup2 = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser()
+ };
+ UserDto[] usersNotInGroup = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser()
+ };
+ GroupDto group1 = db.users().insertGroup();
+ stream(usersWithAdminInGroup1).forEach(user -> db.users().insertMember(group1, user));
+ stream(usersWithoutAdminInGroup1).forEach(user -> db.users().insertMember(group1, user));
+ stream(usersWithAdminInGroup1).forEach(user -> db.users().insertPermissionOnUser(db.getDefaultOrganization(), user, SYSTEM_ADMIN));
+ GroupDto group2 = db.users().insertGroup();
+ stream(usersWithAdminInGroup2).forEach(user -> db.users().insertMember(group2, user));
+ stream(usersWithoutAdminInGroup2).forEach(user -> db.users().insertMember(group2, user));
+ stream(usersWithAdminInGroup2).forEach(user -> db.users().insertPermissionOnUser(db.getDefaultOrganization(), user, SYSTEM_ADMIN));
+
+ call_updateRootFlagFromPermissions(group1, DATE_1);
+ stream(usersWithAdminInGroup1).forEach(user -> db.rootFlag().verify(user, true, DATE_1));
+ stream(usersWithoutAdminInGroup1).forEach(user -> db.rootFlag().verify(user, false, DATE_1));
+ stream(usersWithAdminInGroup2).forEach(db.rootFlag()::verifyUnchanged);
+ stream(usersWithoutAdminInGroup2).forEach(db.rootFlag()::verifyUnchanged);
+ stream(usersNotInGroup).forEach(db.rootFlag()::verifyUnchanged);
+
+ call_updateRootFlagFromPermissions(group2, DATE_2);
+ stream(usersWithAdminInGroup1).forEach(user -> db.rootFlag().verify(user, true, DATE_1));
+ stream(usersWithoutAdminInGroup1).forEach(user -> db.rootFlag().verify(user, false, DATE_1));
+ stream(usersWithAdminInGroup2).forEach(user -> db.rootFlag().verify(user, true, DATE_2));
+ stream(usersWithoutAdminInGroup2).forEach(user -> db.rootFlag().verify(user, false, DATE_2));
+ stream(usersNotInGroup).forEach(db.rootFlag()::verifyUnchanged);
+ }
+
+ @Test
+ public void updateRootFlagOfUsersInGroupFromPermissions_ignores_permissions_on_anyone_on_default_organization() {
+ UserDto[] usersWithAdminInGroup1 = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser(),
+ };
+ UserDto[] usersWithoutAdminInGroup1 = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser(),
+ };
+ UserDto[] usersWithAdminInGroup2 = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser()
+ };
+ UserDto[] usersWithoutAdminInGroup2 = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser()
+ };
+ UserDto[] usersNotInGroup = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser()
+ };
+ GroupDto group1 = db.users().insertGroup();
+ stream(usersWithAdminInGroup1).forEach(user -> db.users().insertMember(group1, user));
+ stream(usersWithoutAdminInGroup1).forEach(user -> db.users().insertMember(group1, user));
+ GroupDto group2 = db.users().insertGroup();
+ stream(usersWithAdminInGroup2).forEach(user -> db.users().insertMember(group2, user));
+ stream(usersWithoutAdminInGroup2).forEach(user -> db.users().insertMember(group2, user));
+ db.users().insertPermissionOnAnyone(db.getDefaultOrganization(), SYSTEM_ADMIN);
+
+ call_updateRootFlagFromPermissions(group1, DATE_1);
+ stream(usersWithAdminInGroup1).forEach(user -> db.rootFlag().verify(user, false, DATE_1));
+ stream(usersWithoutAdminInGroup1).forEach(user -> db.rootFlag().verify(user, false, DATE_1));
+ stream(usersWithAdminInGroup2).forEach(db.rootFlag()::verifyUnchanged);
+ stream(usersWithoutAdminInGroup2).forEach(db.rootFlag()::verifyUnchanged);
+ stream(usersNotInGroup).forEach(db.rootFlag()::verifyUnchanged);
+
+ call_updateRootFlagFromPermissions(group2, DATE_2);
+ stream(usersWithAdminInGroup1).forEach(user -> db.rootFlag().verify(user, false, DATE_1));
+ stream(usersWithoutAdminInGroup1).forEach(user -> db.rootFlag().verify(user, false, DATE_1));
+ stream(usersWithAdminInGroup2).forEach(user -> db.rootFlag().verify(user, false, DATE_2));
+ stream(usersWithoutAdminInGroup2).forEach(user -> db.rootFlag().verify(user, false, DATE_2));
+ stream(usersNotInGroup).forEach(db.rootFlag()::verifyUnchanged);
+ }
+
+ @Test
+ public void updateRootFlagOfUsersInGroupFromPermissions_ignores_permissions_on_anyone_on_other_organization() {
+ UserDto[] usersInGroup = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser(),
+ };
+ UserDto[] usersInOtherGroup = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser()
+ };
+ UserDto[] usersNotInGroup = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser()
+ };
+ GroupDto group = db.users().insertGroup();
+ stream(usersInGroup).forEach(user -> db.users().insertMember(group, user));
+ OrganizationDto otherOrganization = db.organizations().insert();
+ GroupDto otherGroup = db.users().insertGroup(otherOrganization);
+ stream(usersInOtherGroup).forEach(user -> db.users().insertMember(otherGroup, user));
+ db.users().insertPermissionOnAnyone(otherOrganization, SYSTEM_ADMIN);
+
+ call_updateRootFlagFromPermissions(group, DATE_1);
+ stream(usersInGroup).forEach(user -> db.rootFlag().verify(user, false, DATE_1));
+ stream(usersInOtherGroup).forEach(db.rootFlag()::verifyUnchanged);
+ stream(usersNotInGroup).forEach(db.rootFlag()::verifyUnchanged);
+
+ call_updateRootFlagFromPermissions(otherGroup, DATE_2);
+ stream(usersInGroup).forEach(user -> db.rootFlag().verify(user, false, DATE_1));
+ stream(usersInOtherGroup).forEach(user -> db.rootFlag().verify(user, false, DATE_2));
+ stream(usersNotInGroup).forEach(db.rootFlag()::verifyUnchanged);
+ }
+
+ @Test
+ public void updateRootFlagOfUsersInGroupFromPermissions_set_root_flag_to_false_on_users_of_group_of_non_default_organization() {
+ UserDto[] nonAdminUsers = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser()
+ };
+ UserDto[] adminPerUserPermissionUsers = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser() // incorrectly not root
+ };
+ UserDto[] adminPerGroupPermissionUsers = {
+ db.users().makeRoot(db.users().insertUser()),
+ db.users().insertUser() // incorrectly not root
+ };
+ OrganizationDto otherOrganization = db.organizations().insert();
+ GroupDto nonAdminGroup = db.users().insertGroup(otherOrganization);
+ db.users().insertMembers(nonAdminGroup, nonAdminUsers);
+ db.users().insertMembers(nonAdminGroup, adminPerUserPermissionUsers);
+ stream(adminPerUserPermissionUsers).forEach(user -> db.users().insertPermissionOnUser(otherOrganization, user, SYSTEM_ADMIN));
+ GroupDto adminGroup = db.users().insertAdminGroup(otherOrganization);
+ db.users().insertMembers(adminGroup, adminPerGroupPermissionUsers);
+
+ call_updateRootFlagFromPermissions(nonAdminGroup, DATE_2);
+ stream(nonAdminUsers).forEach(user -> db.rootFlag().verify(user, false, DATE_2));
+ stream(adminPerUserPermissionUsers).forEach(user -> db.rootFlag().verify(user, false, DATE_2));
+ stream(adminPerGroupPermissionUsers).forEach(db.rootFlag()::verifyUnchanged);
+
+ call_updateRootFlagFromPermissions(adminGroup, DATE_1);
+ stream(nonAdminUsers).forEach(user -> db.rootFlag().verify(user, false, DATE_2));
+ stream(adminPerUserPermissionUsers).forEach(user -> db.rootFlag().verify(user, false, DATE_2));
+ stream(adminPerGroupPermissionUsers).forEach(user -> db.rootFlag().verify(user, false, DATE_1));
+ }
+
+ private void call_updateRootFlagFromPermissions(GroupDto groupDto, long now) {
+ when(system2.now()).thenReturn(now);
+ underTest.updateRootFlagOfUsersInGroupFromPermissions(db.getSession(), groupDto.getId(), db.getDefaultOrganization().getUuid());
+ db.commit();
+ }
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.user;
+
+import org.sonar.db.DbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class RootFlagAssertions {
+ private final DbTester db;
+
+ public RootFlagAssertions(DbTester db) {
+ this.db = db;
+ }
+
+ public void verifyUnchanged(UserDto user) {
+ verify(user, user.isRoot(), user.getUpdatedAt());
+ }
+
+ public void verify(UserDto userDto, boolean root, long updatedAt) {
+ UserDto dto = db.getDbClient().userDao().selectByLogin(db.getSession(), userDto.getLogin());
+ assertThat(dto.isRoot())
+ .as("Root flag of user '%s' is same as when created", userDto.getLogin())
+ .isEqualTo(root);
+ assertThat(dto.getUpdatedAt())
+ .as("UpdatedAt of user '%s' has not changed since created")
+ .isEqualTo(updatedAt);
+ }
+
+ public void verify(UserDto userDto, boolean root) {
+ UserDto dto = db.getDbClient().userDao().selectByLogin(db.getSession(), userDto.getLogin());
+ assertThat(dto.isRoot())
+ .as("Root flag of user '%s' is '%s'", userDto.getLogin(), root)
+ .isEqualTo(root);
+ assertThat(dto.getUpdatedAt())
+ .as("UpdatedAt of user '%s' has changed since insertion", userDto.getLogin())
+ .isNotEqualTo(userDto);
+ }
+}
import org.sonar.db.issue.IssueFilterFavouriteDto;
import org.sonar.db.measure.MeasureFilterDto;
import org.sonar.db.measure.MeasureFilterFavouriteDto;
+import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.permission.UserPermissionDto;
import org.sonar.db.property.PropertyDto;
import org.sonar.db.property.PropertyQuery;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
import static org.sonar.db.user.GroupMembershipQuery.IN;
import static org.sonar.db.user.GroupMembershipQuery.builder;
import static org.sonar.db.user.GroupTesting.newGroupDto;
import static org.sonar.db.user.UserTesting.newUserDto;
public class UserDaoTest {
- private static final long NOW = 1500000000000L;
+ private static final long NOW = 1_500_000_000_000L;
+ private static final long DATE_1 = 1_222_001L;
+ private static final long DATE_2 = 4_333_555L;
private System2 system2 = mock(System2.class);
assertThat(underTest.selectByLogin(session, inactiveRootUser.getLogin()).isRoot()).isTrue();
}
+ @Test
+ public void updateRootFlagFromPermissions_sets_root_flag_to_false_if_user_has_no_permission_at_all() {
+ UserDto rootUser = db.users().makeRoot(db.users().insertUser());
+ UserDto notRootUser = db.users().insertUser();
+
+ call_updateRootFlagFromPermissions(rootUser, DATE_1);
+ db.rootFlag().verify(rootUser, false, DATE_1);
+ db.rootFlag().verify(notRootUser, false, notRootUser.getUpdatedAt());
+
+ call_updateRootFlagFromPermissions(notRootUser, DATE_2);
+ db.rootFlag().verify(rootUser, false, DATE_1);
+ db.rootFlag().verify(notRootUser, false, DATE_2);
+ }
+
+ @Test
+ public void updateRootFlagFromPermissions_sets_root_flag_to_true_if_user_has_admin_user_permission_on_default_organization() {
+ UserDto rootUser = db.users().insertRootByUserPermission();
+ UserDto incorrectlyNotRootUser = db.users().insertUser();
+ db.users().insertPermissionOnUser(db.getDefaultOrganization(), incorrectlyNotRootUser, SYSTEM_ADMIN);
+
+ call_updateRootFlagFromPermissions(rootUser, DATE_1);
+ db.rootFlag().verify(rootUser, true, DATE_1);
+ db.rootFlag().verify(incorrectlyNotRootUser, false, incorrectlyNotRootUser.getUpdatedAt());
+
+ call_updateRootFlagFromPermissions(incorrectlyNotRootUser, DATE_2);
+ db.rootFlag().verify(rootUser, true, DATE_1);
+ db.rootFlag().verify(incorrectlyNotRootUser, true, DATE_2);
+ }
+
+ @Test
+ public void updateRootFlagFromPermissions_ignores_permissions_on_anyone_on_default_organization() {
+ UserDto rootUser = db.users().makeRoot(db.users().insertUser());
+ UserDto incorrectlyNotRootUser = db.users().insertUser();
+ db.users().insertPermissionOnAnyone(db.getDefaultOrganization(), SYSTEM_ADMIN);
+
+ call_updateRootFlagFromPermissions(rootUser, DATE_1);
+ db.rootFlag().verify(rootUser, false, DATE_1);
+ db.rootFlag().verify(incorrectlyNotRootUser, false, incorrectlyNotRootUser.getUpdatedAt());
+
+ call_updateRootFlagFromPermissions(incorrectlyNotRootUser, DATE_2);
+ db.rootFlag().verify(rootUser, false, DATE_1);
+ db.rootFlag().verify(incorrectlyNotRootUser, false, DATE_2);
+ }
+
+ @Test
+ public void updateRootFlagFromPermissions_ignores_permissions_on_anyone_on_other_organization() {
+ UserDto falselyRootUser = db.users().makeRoot(db.users().insertUser());
+ UserDto notRootUser = db.users().insertUser();
+ OrganizationDto otherOrganization = db.organizations().insert();
+ db.users().insertPermissionOnAnyone(otherOrganization, SYSTEM_ADMIN);
+
+ call_updateRootFlagFromPermissions(falselyRootUser, DATE_2);
+ db.rootFlag().verify(falselyRootUser, false, DATE_2);
+ db.rootFlag().verify(notRootUser, false, notRootUser.getUpdatedAt());
+
+ call_updateRootFlagFromPermissions(notRootUser, DATE_1);
+ db.rootFlag().verify(falselyRootUser, false, DATE_2);
+ db.rootFlag().verify(notRootUser, false, DATE_1);
+ }
+
+ @Test
+ public void updateRootFlagFromPermissions_sets_root_flag_to_false_if_user_has_admin_user_permission_on_other_organization() {
+ UserDto falselyRootUser = db.users().makeRoot(db.users().insertUser());
+ UserDto notRootUser = db.users().insertUser();
+ OrganizationDto otherOrganization = db.organizations().insert();
+ db.users().insertPermissionOnUser(otherOrganization, falselyRootUser, SYSTEM_ADMIN);
+ db.users().insertPermissionOnUser(otherOrganization, notRootUser, SYSTEM_ADMIN);
+
+ call_updateRootFlagFromPermissions(falselyRootUser, DATE_1);
+ db.rootFlag().verify(falselyRootUser, false, DATE_1);
+ db.rootFlag().verify(notRootUser, false, notRootUser.getUpdatedAt());
+
+ call_updateRootFlagFromPermissions(notRootUser, DATE_2);
+ db.rootFlag().verify(falselyRootUser, false, DATE_1);
+ db.rootFlag().verify(notRootUser, false, DATE_2);
+ }
+
+ @Test
+ public void updateRootFlagFromPermissions_sets_root_flag_to_true_if_user_has_admin_group_permission_on_default_organization() {
+ UserDto rootUser = db.users().makeRoot(db.users().insertUser());
+ UserDto incorrectlyNotRootUser = db.users().insertUser();
+ GroupDto groupDto = db.users().insertAdminGroup(db.getDefaultOrganization());
+ db.users().insertMembers(groupDto, rootUser, incorrectlyNotRootUser);
+
+ call_updateRootFlagFromPermissions(rootUser, DATE_1);
+ db.rootFlag().verify(rootUser, true, DATE_1);
+ db.rootFlag().verify(incorrectlyNotRootUser, false, incorrectlyNotRootUser.getUpdatedAt());
+
+ call_updateRootFlagFromPermissions(incorrectlyNotRootUser, DATE_2);
+ db.rootFlag().verify(rootUser, true, DATE_1);
+ db.rootFlag().verify(incorrectlyNotRootUser, true, DATE_2);
+ }
+
+ @Test
+ public void updateRootFlagFromPermissions_sets_root_flag_to_false_if_user_has_admin_group_permission_on_other_organization() {
+ UserDto falselyRootUser = db.users().makeRoot(db.users().insertUser());
+ UserDto notRootUser = db.users().insertUser();
+ GroupDto otherOrganizationGroupDto = db.users().insertGroup(db.organizations().insert());
+ db.users().insertPermissionOnGroup(otherOrganizationGroupDto, SYSTEM_ADMIN);
+ db.users().insertMembers(otherOrganizationGroupDto, falselyRootUser, notRootUser);
+
+ call_updateRootFlagFromPermissions(falselyRootUser, DATE_2);
+ db.rootFlag().verify(falselyRootUser, false, DATE_2);
+ db.rootFlag().verify(notRootUser, false, notRootUser.getUpdatedAt());
+
+ call_updateRootFlagFromPermissions(notRootUser, DATE_1);
+ db.rootFlag().verify(falselyRootUser, false, DATE_2);
+ db.rootFlag().verify(notRootUser, false, DATE_1);
+ }
+
private void commit(Runnable runnable) {
runnable.run();
session.commit();
dbClient.userGroupDao().insert(session, dto);
return dto;
}
+
+ private void call_updateRootFlagFromPermissions(UserDto userDto, long now) {
+ when(system2.now()).thenReturn(now);
+ underTest.updateRootFlagFromPermissions(db.getSession(), userDto.getId(), db.getDefaultOrganization().getUuid());
+ db.commit();
+ }
+
}
*/
package org.sonar.db.user;
+import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
+import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.permission.GroupPermissionDto;
import org.sonar.db.permission.UserPermissionDto;
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
import static org.sonar.db.user.GroupTesting.newGroupDto;
import static org.sonar.db.user.UserTesting.newUserDto;
return updatedUser;
}
+ public UserDto makeRoot(UserDto userDto) {
+ dbClient.userDao().setRoot(db.getSession(), userDto.getLogin(), true);
+ db.commit();
+ return dbClient.userDao().selectByLogin(db.getSession(), userDto.getLogin());
+ }
+
+ public UserDto makeNotRoot(UserDto userDto) {
+ dbClient.userDao().setRoot(db.getSession(), userDto.getLogin(), false);
+ db.commit();
+ return dbClient.userDao().selectByLogin(db.getSession(), userDto.getLogin());
+ }
+
+ public UserDto insertRootByUserPermission(String login) {
+ return insertRootByUserPermissionImpl(requireNonNull(login));
+ }
+
+ public UserDto insertRootByUserPermission() {
+ return insertRootByUserPermissionImpl(null);
+ }
+
+ private UserDto insertRootByUserPermissionImpl(@Nullable String login) {
+ UserDto rootByUserPermissionUser = makeRoot(login == null ? insertUser() : insertUser(login));
+ insertPermissionOnUser(db.getDefaultOrganization(), rootByUserPermissionUser, SYSTEM_ADMIN);
+ return rootByUserPermissionUser;
+ }
+
+ public UserDto insertRootByGroupPermission(String login) {
+ return insertRootByGroupPermissionImpl(requireNonNull(login), null);
+ }
+
+ /**
+ * @see #insertAdminGroup()
+ */
+ public UserDto insertRootByGroupPermission(String login, GroupDto adminGroupDto) {
+ return insertRootByGroupPermissionImpl(requireNonNull(login), adminGroupDto);
+ }
+
+
+ /**
+ * @see #insertAdminGroup()
+ */
+ public UserDto insertRootByGroupPermission(GroupDto adminGroupDto) {
+ return insertRootByGroupPermissionImpl(null, adminGroupDto);
+ }
+
+ public UserDto insertRootByGroupPermission() {
+ return insertRootByGroupPermissionImpl(null, null);
+ }
+
+ public UserDto insertRootByGroupPermissionImpl(@Nullable String login, @Nullable GroupDto groupDto) {
+ UserDto rootByGroupPermissionUser = db.users().makeRoot(login == null ? insertUser() : insertUser(login));
+ GroupDto adminGroup = createOrCheckAdminGroup(groupDto);
+ insertMember(adminGroup, rootByGroupPermissionUser);
+ return rootByGroupPermissionUser;
+ }
+
+ private GroupDto createOrCheckAdminGroup(@Nullable GroupDto groupDto) {
+ if (groupDto == null) {
+ GroupDto adminGroup = insertGroup(db.getDefaultOrganization());
+ insertPermissionOnGroup(adminGroup, SYSTEM_ADMIN);
+ return adminGroup;
+ }
+ checkArgument(
+ groupDto.getOrganizationUuid().equals(db.getDefaultOrganization().getUuid()),
+ "Group '%s' must belong to the default organization", groupDto.getName());
+ List<String> groupPermissions = db.getDbClient().groupPermissionDao().selectGlobalPermissionsOfGroup(db.getSession(), groupDto.getOrganizationUuid(), groupDto.getId());
+ checkArgument(groupPermissions.contains(SYSTEM_ADMIN), "Group '%s' must have permission '%s'", groupDto.getId(), SYSTEM_ADMIN);
+ return groupDto;
+ }
+
public Optional<UserDto> selectUserByLogin(String login) {
return Optional.ofNullable(dbClient.userDao().selectByLogin(db.getSession(), login));
}
return insertGroup(group);
}
+ /**
+ * Creates a group in the default organization with {@link GlobalPermissions#SYSTEM_ADMIN} permission.
+ */
+ public GroupDto insertAdminGroup() {
+ GroupDto groupDto = insertGroup();
+ insertPermissionOnGroup(groupDto, SYSTEM_ADMIN);
+ return groupDto;
+ }
+
+ /**
+ * Creates a group in the specified organization with {@link GlobalPermissions#SYSTEM_ADMIN} permission.
+ */
+ public GroupDto insertAdminGroup(OrganizationDto organizationDto) {
+ GroupDto groupDto = insertGroup(organizationDto);
+ insertPermissionOnGroup(groupDto, SYSTEM_ADMIN);
+ return groupDto;
+ }
+
+ /**
+ * Create group in specified organization
+ */
+ public GroupDto insertGroup(OrganizationDto organizationDto) {
+ GroupDto group = newGroupDto().setOrganizationUuid(organizationDto.getUuid());
+ return insertGroup(group);
+ }
+
public GroupDto insertGroup(GroupDto dto) {
db.getDbClient().groupDao().insert(db.getSession(), dto);
db.commit();
return dto;
}
+ public void insertMembers(GroupDto group, UserDto... users) {
+ Arrays.stream(users).forEach(user -> {
+ UserGroupDto dto = new UserGroupDto().setGroupId(group.getId()).setUserId(user.getId());
+ db.getDbClient().userGroupDao().insert(db.getSession(), dto);
+ });
+ db.commit();
+ }
+
public List<Long> selectGroupIdsOfUser(UserDto user) {
return db.getDbClient().groupMembershipDao().selectGroupIdsByUserId(db.getSession(), user.getId());
}
return dto;
}
+ public void deletePermissionFromGroup(GroupDto group, String permission) {
+ db.getDbClient().groupPermissionDao().delete(db.getSession(), permission, group.getOrganizationUuid(), group.getId(), null);
+ db.commit();
+ }
+
public GroupPermissionDto insertProjectPermissionOnAnyone(String permission, ComponentDto project) {
return insertProjectPermissionOnAnyone(db.getDefaultOrganization(), permission, project);
}