public class AuthorizationDao implements Dao {
/**
- * Loads all the permissions granted to logged-in user for the specified organization
+ * Loads all the permissions granted to user for the specified organization
*/
public Set<String> selectOrganizationPermissions(DbSession dbSession, String organizationUuid, int userId) {
return mapper(dbSession).selectOrganizationPermissions(organizationUuid, userId);
return mapper(dbSession).countUsersWithGlobalPermissionExcludingUser(organizationUuid, permission, excludedUserId);
}
+ /**
+ * The list of users who have the global permission.
+ * The anyone virtual group is not taken into account.
+ */
+ public List<Integer> selectUserIdsWithGlobalPermission(DbSession dbSession, String organizationUuid, String permission) {
+ return mapper(dbSession).selectUserIdsWithGlobalPermission(organizationUuid, permission);
+ }
+
/**
* The number of users who will still have the permission if the user {@code userId}
* is removed from group {@code groupId}. The anyone virtual group is not taken into account.
int countUsersWithGlobalPermissionExcludingUser(@Param("organizationUuid") String organizationUuid, @Param("permission") String permission,
@Param("excludedUserId") int excludedUserId);
+ List<Integer> selectUserIdsWithGlobalPermission(@Param("organizationUuid") String organizationUuid, @Param("permission") String permission);
+
int countUsersWithGlobalPermissionExcludingGroupMember(@Param("organizationUuid") String organizationUuid,
@Param("permission") String permission, @Param("groupId") int groupId, @Param("userId") int userId);
return mapper(dbSession).selectByExternalIdAndIdentityProvider(externalId, externalIdentityProvider);
}
+ public List<UserDto> selectByExternalIdsAndIdentityProvider(DbSession dbSession, Collection<String> externalIds, String externalIdentityProvider) {
+ return executeLargeInputs(externalIds, e -> mapper(dbSession).selectByExternalIdsAndIdentityProvider(e, externalIdentityProvider));
+ }
+
@CheckForNull
public UserDto selectByExternalLoginAndIdentityProvider(DbSession dbSession, String externalLogin, String externalIdentityProvider) {
return mapper(dbSession).selectByExternalLoginAndIdentityProvider(externalLogin, externalIdentityProvider);
@CheckForNull
UserDto selectByExternalIdAndIdentityProvider(@Param("externalId") String externalId, @Param("externalIdentityProvider") String externalExternalIdentityProvider);
+ List<UserDto> selectByExternalIdsAndIdentityProvider(@Param("externalIds") List<String> externalIds, @Param("externalIdentityProvider") String externalExternalIdentityProvider);
+
+ @CheckForNull
UserDto selectByExternalLoginAndIdentityProvider(@Param("externalLogin") String externalLogin, @Param("externalIdentityProvider") String externalExternalIdentityProvider);
void scrollAll(ResultHandler<UserDto> handler);
from group_roles gr
inner join groups_users gu on gr.group_id=gu.group_id
where
- gr.organization_uuid=#{organizationUuid,jdbcType=VARCHAR} and
+ gr.organization_uuid=#{organizationUuid, jdbcType=VARCHAR} and
gr.resource_id is null and
- gu.user_id=#{userId,jdbcType=INTEGER}
+ gu.user_id=#{userId, jdbcType=INTEGER}
union
select gr.role
from group_roles gr
where
- gr.organization_uuid=#{organizationUuid,jdbcType=VARCHAR} and
+ gr.organization_uuid=#{organizationUuid, jdbcType=VARCHAR} and
gr.group_id is null and
gr.resource_id is null
select ur.role
from user_roles ur
where
- ur.organization_uuid=#{organizationUuid,jdbcType=VARCHAR} and
- ur.user_id=#{userId,jdbcType=INTEGER}
+ ur.organization_uuid=#{organizationUuid, jdbcType=VARCHAR} and
+ ur.user_id=#{userId, jdbcType=INTEGER}
and ur.resource_id is null
</select>
select gr.role
from group_roles gr
where
- gr.organization_uuid=#{organizationUuid,jdbcType=VARCHAR} and
+ gr.organization_uuid=#{organizationUuid, jdbcType=VARCHAR} and
gr.resource_id is null and
gr.group_id is null
</select>
from groups_users gu
inner join group_roles gr on gr.group_id = gu.group_id
where
- gr.organization_uuid = #{organizationUuid,jdbcType=VARCHAR} and
- gr.role = #{permission,jdbcType=VARCHAR} and
+ gr.organization_uuid = #{organizationUuid, jdbcType=VARCHAR} and
+ gr.role = #{permission, jdbcType=VARCHAR} and
gr.resource_id is null and
gr.group_id is not null and
- gr.group_id != #{excludedGroupId,jdbcType=INTEGER}
+ gr.group_id != #{excludedGroupId, jdbcType=INTEGER}
union
select ur.user_id
from user_roles ur
where
- ur.organization_uuid = #{organizationUuid,jdbcType=VARCHAR} and
+ ur.organization_uuid = #{organizationUuid, jdbcType=VARCHAR} and
ur.resource_id is null and
- ur.role = #{permission,jdbcType=VARCHAR}
+ ur.role = #{permission, jdbcType=VARCHAR}
) remaining
</select>
from groups_users gu
inner join group_roles gr on gr.group_id = gu.group_id
where
- gr.organization_uuid = #{organizationUuid,jdbcType=VARCHAR} and
- gr.role = #{permission,jdbcType=VARCHAR} and
+ gr.organization_uuid = #{organizationUuid, jdbcType=VARCHAR} and
+ gr.role = #{permission, jdbcType=VARCHAR} and
gr.resource_id is null and
gr.group_id is not null and
- gu.user_id != #{excludedUserId,jdbcType=INTEGER}
+ gu.user_id != #{excludedUserId, jdbcType=INTEGER}
union
select ur.user_id
from user_roles ur
where
- ur.organization_uuid = #{organizationUuid,jdbcType=VARCHAR} and
+ ur.organization_uuid = #{organizationUuid, jdbcType=VARCHAR} and
ur.resource_id is null and
- ur.role = #{permission,jdbcType=VARCHAR} and
- ur.user_id != #{excludedUserId,jdbcType=INTEGER}
+ ur.role = #{permission, jdbcType=VARCHAR} and
+ ur.user_id != #{excludedUserId, jdbcType=INTEGER}
) remaining
</select>
+ <select id="selectUserIdsWithGlobalPermission" parameterType="map" resultType="int">
+ select gu.user_id
+ from groups_users gu
+ inner join group_roles gr on gr.group_id = gu.group_id
+ where
+ gr.organization_uuid = #{organizationUuid, jdbcType=VARCHAR} and
+ gr.role = #{permission, jdbcType=VARCHAR} and
+ gr.resource_id is null and
+ gr.group_id is not null
+
+ union
+
+ select ur.user_id
+ from user_roles ur
+ where
+ ur.organization_uuid = #{organizationUuid, jdbcType=VARCHAR} and
+ ur.resource_id is null and
+ ur.role = #{permission, jdbcType=VARCHAR}
+ </select>
+
<select id="countUsersWithGlobalPermissionExcludingGroupMember" parameterType="map" resultType="int">
select count(1) from
(
from groups_users gu
inner join group_roles gr on gr.group_id = gu.group_id
where
- gr.organization_uuid = #{organizationUuid,jdbcType=VARCHAR} and
- gr.role = #{permission,jdbcType=VARCHAR} and
+ gr.organization_uuid = #{organizationUuid, jdbcType=VARCHAR} and
+ gr.role = #{permission, jdbcType=VARCHAR} and
gr.resource_id is null and
gr.group_id is not null and
- (gu.group_id != #{groupId,jdbcType=INTEGER} or gu.user_id != #{userId,jdbcType=INTEGER})
+ (gu.group_id != #{groupId, jdbcType=INTEGER} or gu.user_id != #{userId, jdbcType=INTEGER})
union
select ur.user_id
from user_roles ur
where
- ur.organization_uuid = #{organizationUuid,jdbcType=VARCHAR} and
+ ur.organization_uuid = #{organizationUuid, jdbcType=VARCHAR} and
ur.resource_id is null and
- ur.role = #{permission,jdbcType=VARCHAR}
+ ur.role = #{permission, jdbcType=VARCHAR}
) remaining
</select>
from groups_users gu
inner join group_roles gr on gr.group_id = gu.group_id
where
- gr.organization_uuid = #{organizationUuid,jdbcType=VARCHAR} and
- gr.role = #{permission,jdbcType=VARCHAR} and
+ gr.organization_uuid = #{organizationUuid, jdbcType=VARCHAR} and
+ gr.role = #{permission, jdbcType=VARCHAR} and
gr.resource_id is null and
gr.group_id is not null
select ur.user_id
from user_roles ur
where
- ur.organization_uuid = #{organizationUuid,jdbcType=VARCHAR} and
+ ur.organization_uuid = #{organizationUuid, jdbcType=VARCHAR} and
ur.resource_id is null and
- ur.role = #{permission,jdbcType=VARCHAR} and
- ur.user_id != #{userId,jdbcType=INTEGER}
+ ur.role = #{permission, jdbcType=VARCHAR} and
+ ur.user_id != #{userId, jdbcType=INTEGER}
) remaining
</select>
from group_roles gr
inner join groups_users gu on gr.group_id = gu.group_id
where
- gr.role = #{permission,jdbcType=VARCHAR} and
+ gr.role = #{permission, jdbcType=VARCHAR} and
gr.resource_id is null and
gr.group_id is not null and
- gu.user_id = #{userId,jdbcType=INTEGER}
+ gu.user_id = #{userId, jdbcType=INTEGER}
union
from user_roles ur
where
ur.resource_id is null and
- ur.role = #{permission,jdbcType=VARCHAR} and
- ur.user_id = #{userId,jdbcType=INTEGER}
+ ur.role = #{permission, jdbcType=VARCHAR} and
+ ur.user_id = #{userId, jdbcType=INTEGER}
</select>
<select id="keepAuthorizedProjectIdsForUser" parameterType="map" resultType="long">
from
group_roles gr
where
- gr.role=#{role,jdbcType=VARCHAR}
+ gr.role=#{role, jdbcType=VARCHAR}
and (
gr.group_id is null
or exists (
)
)
and <foreach collection="componentIds" open="(" close=")" item="element" index="index" separator=" or ">
- gr.resource_id=#{element,jdbcType=BIGINT}
+ gr.resource_id=#{element, jdbcType=BIGINT}
</foreach>
union
inner join projects p on
p.id = ur.resource_id
where
- ur.role=#{role,jdbcType=VARCHAR}
- and ur.user_id=#{userId,jdbcType=INTEGER}
+ ur.role=#{role, jdbcType=VARCHAR}
+ and ur.user_id=#{userId, jdbcType=INTEGER}
and <foreach collection="componentIds" open="(" close=")" item="element" index="index" separator=" or ">
- p.id=#{element,jdbcType=BIGINT}
+ p.id=#{element, jdbcType=BIGINT}
</foreach>
union
from
group_roles gr
where
- gr.role=#{role,jdbcType=VARCHAR}
+ gr.role=#{role, jdbcType=VARCHAR}
and gr.group_id is null
and <foreach collection="componentIds" open="(" close=")" item="element" index="index" separator=" or ">
- gr.resource_id=#{element,jdbcType=BIGINT}
+ gr.resource_id=#{element, jdbcType=BIGINT}
</foreach>
union
projects p
where
<foreach collection="componentIds" open="(" close=")" item="element" index="index" separator=" or ">
- p.id=#{element,jdbcType=BIGINT}
+ p.id=#{element ,jdbcType=BIGINT}
</foreach>
and p.private = ${_false}
- and #{role,jdbcType=VARCHAR} in ('user','codeviewer')
+ and #{role, jdbcType=VARCHAR} in ('user','codeviewer')
</sql>
<select id="keepAuthorizedProjectUuidsForUser" parameterType="map" resultType="String">
from projects p
inner join group_roles gr on p.id = gr.resource_id
where
- gr.role = #{permission,jdbcType=VARCHAR}
+ gr.role = #{permission, jdbcType=VARCHAR}
and (gr.group_id is null or exists (
select 1 from groups_users gu
where
gu.user_id = #{userId, jdbcType=INTEGER}
and gr.group_id = gu.group_id)
)
- and p.uuid in <foreach collection="projectUuids" open="(" close=")" item="projectUuid" index="index" separator=",">#{projectUuid,jdbcType=VARCHAR}</foreach>
+ and p.uuid in <foreach collection="projectUuids" open="(" close=")" item="projectUuid" index="index" separator=",">#{projectUuid, jdbcType=VARCHAR}</foreach>
union
from projects p
inner join user_roles ur on p.id = ur.resource_id
where
- ur.role=#{permission,jdbcType=VARCHAR}
- and ur.user_id=#{userId,jdbcType=INTEGER}
- and p.uuid in <foreach collection="projectUuids" open="(" close=")" item="projectUuid" index="index" separator=",">#{projectUuid,jdbcType=VARCHAR}</foreach>
+ ur.role=#{permission, jdbcType=VARCHAR}
+ and ur.user_id=#{userId, jdbcType=INTEGER}
+ and p.uuid in <foreach collection="projectUuids" open="(" close=")" item="projectUuid" index="index" separator=",">#{projectUuid, jdbcType=VARCHAR}</foreach>
<if test="permission == 'user' or permission == 'codeviewer'">
union
select p.uuid
from projects p
where
- p.uuid in <foreach collection="projectUuids" open="(" close=")" item="projectUuid" index="index" separator=",">#{projectUuid,jdbcType=VARCHAR}</foreach>
+ p.uuid in <foreach collection="projectUuids" open="(" close=")" item="projectUuid" index="index" separator=",">#{projectUuid, jdbcType=VARCHAR}</foreach>
and p.private = ${_false}
</if>
</select>
from projects p
inner join group_roles gr on p.id = gr.resource_id
where
- gr.role=#{permission,jdbcType=VARCHAR}
+ gr.role=#{permission, jdbcType=VARCHAR}
and gr.group_id is null
- and p.uuid in <foreach collection="projectUuids" open="(" close=")" item="projectUuid" index="index" separator=",">#{projectUuid,jdbcType=VARCHAR}</foreach>
+ and p.uuid in <foreach collection="projectUuids" open="(" close=")" item="projectUuid" index="index" separator=",">#{projectUuid, jdbcType=VARCHAR}</foreach>
<if test="permission == 'user' or permission == 'codeviewer'">
union
select p.uuid
from projects p
where
- p.uuid in <foreach collection="projectUuids" open="(" close=")" item="projectUuid" index="index" separator=",">#{projectUuid,jdbcType=VARCHAR}</foreach>
+ p.uuid in <foreach collection="projectUuids" open="(" close=")" item="projectUuid" index="index" separator=",">#{projectUuid, jdbcType=VARCHAR}</foreach>
and p.private = ${_false}
</if>
</select>
inner join group_roles gr on
gr.group_id=gu.group_id
where
- gr.resource_id=#{componentId,jdbcType=BIGINT}
- and gr.role=#{role,jdbcType=VARCHAR}
+ gr.resource_id=#{componentId, jdbcType=BIGINT}
+ and gr.role=#{role, jdbcType=VARCHAR}
and gu.user_id in
<foreach collection="userIds" open="(" close=")" item="id" separator=",">
- #{id,jdbcType=BIGINT}
+ #{id, jdbcType=BIGINT}
</foreach>
union
from
user_roles ur
where
- ur.resource_id=#{componentId,jdbcType=BIGINT}
- and ur.role=#{role,jdbcType=VARCHAR}
+ ur.resource_id=#{componentId, jdbcType=BIGINT}
+ and ur.role=#{role, jdbcType=VARCHAR}
and ur.user_id IN
<foreach collection="userIds" open="(" close=")" item="id" separator=",">
- #{id,jdbcType=BIGINT}
+ #{id, jdbcType=BIGINT}
</foreach>
union
where
u.id in
<foreach collection="userIds" open="(" close=")" item="id" separator=",">
- #{id,jdbcType=BIGINT}
+ #{id, jdbcType=BIGINT}
</foreach>
and exists (
select
from
projects p
where
- p.id =#{componentId,jdbcType=BIGINT}
+ p.id =#{componentId, jdbcType=BIGINT}
and p.private = ${_false}
- and #{role,jdbcType=VARCHAR} in ('user','codeviewer')
+ and #{role, jdbcType=VARCHAR} in ('user','codeviewer')
)
</select>
from user_roles ur
inner join projects p on p.id = ur.resource_id
where
- p.uuid = #{projectUuid,jdbcType=VARCHAR} and
+ p.uuid = #{projectUuid, jdbcType=VARCHAR} and
p.organization_uuid = ur.organization_uuid and
- ur.user_id = #{userId,jdbcType=BIGINT}
+ ur.user_id = #{userId, jdbcType=BIGINT}
union
inner join groups_users gu on gr.group_id = gu.group_id
inner join projects p on p.id = gr.resource_id
where
- p.uuid = #{projectUuid,jdbcType=VARCHAR} and
+ p.uuid = #{projectUuid, jdbcType=VARCHAR} and
p.organization_uuid = gr.organization_uuid and
- gu.user_id = #{userId,jdbcType=BIGINT}
+ gu.user_id = #{userId, jdbcType=BIGINT}
union
inner join projects p on
p.id = gr.resource_id
where
- p.uuid = #{projectUuid,jdbcType=VARCHAR}
+ p.uuid = #{projectUuid, jdbcType=VARCHAR}
and p.organization_uuid = gr.organization_uuid
and gr.group_id is null
</sql>
from user_roles ur
inner join users u on u.id=ur.user_id
where
- ur.role=#{permission,jdbcType=VARCHAR}
+ ur.role=#{permission, jdbcType=VARCHAR}
and ur.resource_id is null
union
inner join groups_users gu on gr.group_id = gu.group_id
inner join users u on u.id=gu.user_id
where
- gr.role = #{permission,jdbcType=VARCHAR} and
+ gr.role = #{permission, jdbcType=VARCHAR} and
gr.resource_id is null and
gr.group_id is not null
</select>
select u.login
from users u
where
- u.login in <foreach collection="logins" open="(" close=")" item="login" separator=",">#{login,jdbcType=VARCHAR}</foreach>
+ u.login in <foreach collection="logins" open="(" close=")" item="login" separator=",">#{login, jdbcType=VARCHAR}</foreach>
and (
exists (
select 1
from user_roles ur
inner join projects p on p.id = ur.resource_id and p.organization_uuid = ur.organization_uuid
where
- p.kee = #{projectKey,jdbcType=VARCHAR}
- and ur.role = #{permission,jdbcType=VARCHAR}
+ p.kee = #{projectKey, jdbcType=VARCHAR}
+ and ur.role = #{permission, jdbcType=VARCHAR}
and ur.user_id = u.id
) or exists (
select 1
inner join group_roles gr on gr.resource_id = p.id and gr.organization_uuid = p.organization_uuid
inner join groups_users gu on gu.group_id = gr.group_id
where
- p.kee = #{projectKey,jdbcType=VARCHAR}
+ p.kee = #{projectKey, jdbcType=VARCHAR}
and gu.user_id = u.id
- and gr.role = #{permission,jdbcType=VARCHAR}
+ and gr.role = #{permission, jdbcType=VARCHAR}
)
<if test="permission == 'user' or permission == 'codeviewer'">
or exists (
select 1
from projects p
where
- p.kee = #{projectKey,jdbcType=VARCHAR}
+ p.kee = #{projectKey, jdbcType=VARCHAR}
and p.private = ${_false}
)
</if>
SELECT
<include refid="userColumns"/>
FROM users u
- WHERE u.uuid=#{uuid}
+ WHERE u.uuid=#{uuid, jdbcType=VARCHAR}
</select>
<select id="selectByLogin" parameterType="String" resultType="User">
SELECT
<include refid="userColumns"/>
FROM users u
- WHERE u.login=#{login}
+ WHERE u.login=#{login, jdbcType=VARCHAR}
</select>
<select id="selectNullableByScmAccountOrLoginOrEmail" parameterType="map" resultType="User">
<include refid="userColumns"/>
FROM users u
WHERE
- u.login=#{scmAccount}
- OR u.email=#{scmAccount}
- OR u.scm_accounts like #{likeScmAccount}
+ u.login=#{scmAccount, jdbcType=VARCHAR}
+ OR u.email=#{scmAccount, jdbcType=VARCHAR}
+ OR u.scm_accounts like #{likeScmAccount, jdbcType=VARCHAR}
</select>
<select id="selectUser" parameterType="int" resultType="User">
SELECT
<include refid="userColumns"/>
FROM users u
- WHERE u.id=#{id}
+ WHERE u.id=#{id, jdbcType=INTEGER}
</select>
<select id="selectUserByLogin" parameterType="string" resultType="User">
SELECT
<include refid="userColumns"/>
FROM users u
- WHERE u.login=#{id} AND u.active=${_true}
+ WHERE u.login=#{id, jdbcType=INTEGER} AND u.active=${_true}
</select>
<select id="selectByLogins" parameterType="string" resultType="User">
FROM users u
WHERE u.login in
<foreach collection="list" open="(" close=")" item="login" separator=",">
- #{login}
+ #{login, jdbcType=VARCHAR}
</foreach>
</select>
FROM users u
WHERE u.uuid in
<foreach collection="list" open="(" close=")" item="uuid" separator=",">
- #{uuid}
+ #{uuid, jdbcType=VARCHAR}
</foreach>
</select>
FROM users u
WHERE u.id in
<foreach collection="ids" open="(" close=")" item="id" separator=",">
- #{id}
+ #{id, jdbcType=INTEGER}
</foreach>
</select>
<if test="logins != null and logins.size() > 0">
u.login IN
<foreach item="login" index="index" collection="logins" open="(" separator="," close=")">
- #{login}
+ #{login, jdbcType=VARCHAR}
</foreach>
</if>
<if test="includeDeactivated==false">
AND u.active=${_true}
</if>
<if test="searchText != null">
- AND (u.login LIKE #{searchTextSql} ESCAPE '/' OR u.name LIKE #{searchTextSql} ESCAPE '/')
+ AND (u.login LIKE #{searchTextSql, jdbcType=VARCHAR} ESCAPE '/' OR u.name LIKE #{searchTextSql, jdbcType=VARCHAR} ESCAPE '/')
</if>
<if test="mustBeRoot != null and mustBeRoot==true">
AND u.is_root = ${_true}
SELECT
<include refid="userColumns"/>
FROM users u
- WHERE u.external_id=#{externalId} AND u.external_identity_provider=#{externalIdentityProvider, jdbcType=VARCHAR}
+ WHERE u.external_id=#{externalId, jdbcType=VARCHAR} AND u.external_identity_provider=#{externalIdentityProvider, jdbcType=VARCHAR}
+ </select>
+
+ <select id="selectByExternalIdsAndIdentityProvider" parameterType="map" resultType="User">
+ SELECT
+ <include refid="userColumns"/>
+ FROM users u
+ WHERE u.external_identity_provider=#{externalIdentityProvider, jdbcType=VARCHAR}
+ AND u.external_id in
+ <foreach collection="externalIds" open="(" close=")" item="externalId" separator=",">
+ #{externalId, jdbcType=VARCHAR}
+ </foreach>
</select>
<select id="selectByExternalLoginAndIdentityProvider" parameterType="map" resultType="User">
SELECT
<include refid="userColumns"/>
FROM users u
- WHERE u.external_login=#{externalLogin} AND u.external_identity_provider=#{externalIdentityProvider, jdbcType=VARCHAR}
+ WHERE u.external_login=#{externalLogin, jdbcType=VARCHAR} AND u.external_identity_provider=#{externalIdentityProvider, jdbcType=VARCHAR}
</select>
<select id="countRootUsersButLogin" parameterType="String" resultType="long">
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
+import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS;
import static org.sonar.db.permission.OrganizationPermission.SCAN;
public class AuthorizationDaoTest {
organization.getUuid(), "missingPermission", group1.getId())).isEqualTo(0);
}
+ @Test
+ public void selectUserIdsWithGlobalPermission() {
+ // group g1 has the permission p1 and has members user1 and user2
+ // user3 has the permission
+ UserDto user1 = db.users().insertUser();
+ UserDto user2 = db.users().insertUser();
+ UserDto user3 = db.users().insertUser();
+
+ OrganizationDto organization = db.organizations().insert();
+ GroupDto group1 = db.users().insertGroup(organization);
+ db.users().insertPermissionOnGroup(group1, ADMINISTER);
+ db.users().insertPermissionOnGroup(group1, PROVISION_PROJECTS);
+ db.users().insertMember(group1, user1);
+ db.users().insertMember(group1, user2);
+ db.users().insertPermissionOnUser(organization, user3, ADMINISTER);
+ db.users().insertPermissionOnAnyone(organization, ADMINISTER);
+
+ // other organizations are ignored
+ OrganizationDto org2 = db.organizations().insert();
+ db.users().insertPermissionOnUser(org2, user1, ADMINISTER);
+
+ assertThat(underTest.selectUserIdsWithGlobalPermission(db.getSession(), organization.getUuid(), ADMINISTER.getKey()))
+ .containsExactlyInAnyOrder(user1.getId(), user2.getId(), user3.getId());
+ assertThat(underTest.selectUserIdsWithGlobalPermission(db.getSession(), organization.getUuid(), PROVISION_PROJECTS.getKey()))
+ .containsExactlyInAnyOrder(user1.getId(), user2.getId());
+ assertThat(underTest.selectUserIdsWithGlobalPermission(db.getSession(), org2.getUuid(), ADMINISTER.getKey()))
+ .containsExactlyInAnyOrder(user1.getId());
+ }
+
@Test
public void keepAuthorizedProjectIds_returns_empty_for_group_AnyOne_if_project_set_is_empty_on_public_project() {
assertThat(underTest.keepAuthorizedProjectIds(dbSession, Collections.emptySet(), null, UserRole.USER))
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.groups.Tuple.tuple;
assertThat(underTest.selectByExternalIdAndIdentityProvider(session, "unknown", "unknown")).isNull();
}
+ @Test
+ public void select_by_external_ids_and_identity_provider() {
+ UserDto user1 = db.users().insertUser(u -> u.setExternalIdentityProvider("github"));
+ UserDto user2 = db.users().insertUser(u -> u.setExternalIdentityProvider("github"));
+ UserDto user3 = db.users().insertUser(u -> u.setExternalIdentityProvider("bitbucket"));
+ UserDto disableUser = db.users().insertDisabledUser(u -> u.setExternalIdentityProvider("github"));
+
+ assertThat(underTest.selectByExternalIdsAndIdentityProvider(session, singletonList(user1.getExternalId()), "github"))
+ .extracting(UserDto::getUuid).containsExactlyInAnyOrder(user1.getUuid());
+ assertThat(underTest.selectByExternalIdsAndIdentityProvider(session,
+ asList(user1.getExternalId(), user2.getExternalId(), user3.getExternalId(), disableUser.getExternalId()), "github"))
+ .extracting(UserDto::getUuid).containsExactlyInAnyOrder(user1.getUuid(), user2.getUuid(), disableUser.getUuid());
+ assertThat(underTest.selectByExternalIdsAndIdentityProvider(session, singletonList("unknown"), "github")).isEmpty();
+ assertThat(underTest.selectByExternalIdsAndIdentityProvider(session, singletonList(user1.getExternalId()), "unknown")).isEmpty();
+ }
+
@Test
public void select_by_external_login_and_identity_provider() {
UserDto activeUser = db.users().insertUser();
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info 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.server.organization;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.organization.OrganizationMemberDto;
+import org.sonar.db.user.UserDto;
+import org.sonar.db.user.UserGroupDto;
+import org.sonar.server.user.index.UserIndexer;
+import org.sonar.server.usergroups.DefaultGroupFinder;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.Sets.difference;
+import static java.util.Collections.singletonList;
+import static java.util.stream.Collectors.toSet;
+import static org.sonar.api.CoreProperties.DEFAULT_ISSUE_ASSIGNEE;
+import static org.sonar.core.util.stream.MoreCollectors.toList;
+import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
+
+public class MemberUpdater {
+
+ private final DbClient dbClient;
+ private final DefaultGroupFinder defaultGroupFinder;
+ private final UserIndexer userIndexer;
+
+ public MemberUpdater(DbClient dbClient, DefaultGroupFinder defaultGroupFinder, UserIndexer userIndexer) {
+ this.dbClient = dbClient;
+ this.defaultGroupFinder = defaultGroupFinder;
+ this.userIndexer = userIndexer;
+ }
+
+ public void addMember(DbSession dbSession, OrganizationDto organization, UserDto user) {
+ addMembers(dbSession, organization, singletonList(user));
+ }
+
+ public void addMembers(DbSession dbSession, OrganizationDto organization, List<UserDto> users) {
+ Set<Integer> currentMemberIds = new HashSet<>(dbClient.organizationMemberDao().selectUserIdsByOrganizationUuid(dbSession, organization.getUuid()));
+ List<UserDto> usersToAdd = users.stream()
+ .filter(UserDto::isActive)
+ .filter(u -> !currentMemberIds.contains(u.getId()))
+ .collect(toList());
+ if (usersToAdd.isEmpty()){
+ return;
+ }
+ usersToAdd.forEach(u -> addMemberInDb(dbSession, organization, u));
+ userIndexer.commitAndIndex(dbSession, usersToAdd);
+ }
+
+ private void addMemberInDb(DbSession dbSession, OrganizationDto organization, UserDto user) {
+ dbClient.organizationMemberDao().insert(dbSession, new OrganizationMemberDto()
+ .setOrganizationUuid(organization.getUuid())
+ .setUserId(user.getId()));
+ dbClient.userGroupDao().insert(dbSession,
+ new UserGroupDto().setGroupId(defaultGroupFinder.findDefaultGroup(dbSession, organization.getUuid()).getId()).setUserId(user.getId()));
+ }
+
+ public void removeMember(DbSession dbSession, OrganizationDto organization, UserDto user) {
+ removeMembers(dbSession, organization, singletonList(user));
+ }
+
+ public void removeMembers(DbSession dbSession, OrganizationDto organization, List<UserDto> users) {
+ Set<Integer> currentMemberIds = new HashSet<>(dbClient.organizationMemberDao().selectUserIdsByOrganizationUuid(dbSession, organization.getUuid()));
+ List<UserDto> usersToRemove = users.stream()
+ .filter(UserDto::isActive)
+ .filter(u -> currentMemberIds.contains(u.getId()))
+ .collect(toList());
+ if (usersToRemove.isEmpty()){
+ return;
+ }
+
+ Set<Integer> userIdsToRemove = usersToRemove.stream().map(UserDto::getId).collect(toSet());
+ Set<Integer> adminIds = new HashSet<>(dbClient.authorizationDao().selectUserIdsWithGlobalPermission(dbSession, organization.getUuid(), ADMINISTER.getKey()));
+ checkArgument(!difference(adminIds, userIdsToRemove).isEmpty(), "The last administrator member cannot be removed");
+
+ usersToRemove.forEach(u -> removeMemberInDb(dbSession, organization, u));
+ userIndexer.commitAndIndex(dbSession, usersToRemove);
+ }
+
+ private void removeMemberInDb(DbSession dbSession, OrganizationDto organization, UserDto user) {
+ int userId = user.getId();
+ String organizationUuid = organization.getUuid();
+ dbClient.userPermissionDao().deleteOrganizationMemberPermissions(dbSession, organizationUuid, userId);
+ dbClient.permissionTemplateDao().deleteUserPermissionsByOrganization(dbSession, organizationUuid, userId);
+ dbClient.qProfileEditUsersDao().deleteByOrganizationAndUser(dbSession, organization, user);
+ dbClient.userGroupDao().deleteByOrganizationAndUser(dbSession, organizationUuid, userId);
+ dbClient.propertiesDao().deleteByOrganizationAndUser(dbSession, organizationUuid, userId);
+ dbClient.propertiesDao().deleteByOrganizationAndMatchingLogin(dbSession, organizationUuid, user.getLogin(), singletonList(DEFAULT_ISSUE_ASSIGNEE));
+
+ dbClient.organizationMemberDao().delete(dbSession, organizationUuid, userId);
+ }
+
+}
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
-import org.sonar.db.organization.OrganizationMemberDto;
import org.sonar.db.permission.OrganizationPermission;
import org.sonar.db.user.GroupMembershipQuery;
import org.sonar.db.user.UserDto;
-import org.sonar.db.user.UserGroupDto;
import org.sonar.server.issue.ws.AvatarResolver;
+import org.sonar.server.organization.MemberUpdater;
import org.sonar.server.user.UserSession;
-import org.sonar.server.user.index.UserIndexer;
-import org.sonar.server.usergroups.DefaultGroupFinder;
import org.sonarqube.ws.Organizations.AddMemberWsResponse;
import org.sonarqube.ws.Organizations.User;
public class AddMemberAction implements OrganizationsWsAction {
private final DbClient dbClient;
private final UserSession userSession;
- private final UserIndexer userIndexer;
- private final DefaultGroupFinder defaultGroupFinder;
private final AvatarResolver avatarResolver;
private final OrganizationsWsSupport wsSupport;
+ private final MemberUpdater memberUpdater;
- public AddMemberAction(DbClient dbClient, UserSession userSession, UserIndexer userIndexer, DefaultGroupFinder defaultGroupFinder,
- AvatarResolver avatarResolver, OrganizationsWsSupport wsSupport) {
+ public AddMemberAction(DbClient dbClient, UserSession userSession, AvatarResolver avatarResolver, OrganizationsWsSupport wsSupport,
+ MemberUpdater memberUpdater) {
this.dbClient = dbClient;
this.userSession = userSession;
- this.userIndexer = userIndexer;
- this.defaultGroupFinder = defaultGroupFinder;
this.avatarResolver = avatarResolver;
this.wsSupport = wsSupport;
+ this.memberUpdater = memberUpdater;
}
@Override
try (DbSession dbSession = dbClient.openSession(false)) {
OrganizationDto organization = checkFoundWithOptional(dbClient.organizationDao().selectByKey(dbSession, organizationKey), "Organization '%s' is not found",
organizationKey);
- UserDto user = checkFound(dbClient.userDao().selectByLogin(dbSession, login), "User '%s' is not found", login);
+ userSession.checkPermission(OrganizationPermission.ADMINISTER, organization);
wsSupport.checkMemberSyncIsDisabled(dbSession, organization);
-
- addMember(dbSession, organization, user);
+ UserDto user = checkFound(dbClient.userDao().selectByLogin(dbSession, login), "User '%s' is not found", login);
+ memberUpdater.addMember(dbSession, organization, user);
int groups = dbClient.groupMembershipDao().countGroups(dbSession, GroupMembershipQuery.builder()
.organizationUuid(organization.getUuid())
}
}
- private void addMember(DbSession dbSession, OrganizationDto organization, UserDto user) {
- userSession.checkPermission(OrganizationPermission.ADMINISTER, organization);
- if (isMemberOf(dbSession, organization, user)) {
- return;
- }
-
- dbClient.organizationMemberDao().insert(dbSession, new OrganizationMemberDto()
- .setOrganizationUuid(organization.getUuid())
- .setUserId(user.getId()));
- dbClient.userGroupDao().insert(dbSession,
- new UserGroupDto().setGroupId(defaultGroupFinder.findDefaultGroup(dbSession, organization.getUuid()).getId()).setUserId(user.getId()));
- userIndexer.commitAndIndex(dbSession, user);
- }
-
private AddMemberWsResponse buildResponse(UserDto user, int groups) {
AddMemberWsResponse.Builder response = AddMemberWsResponse.newBuilder();
User.Builder wsUser = User.newBuilder()
return response.build();
}
- private boolean isMemberOf(DbSession dbSession, OrganizationDto organizationDto, UserDto userDto) {
- return dbClient.organizationMemberDao().select(dbSession, organizationDto.getUuid(), userDto.getId()).isPresent();
- }
-
}
import org.sonar.api.config.Configuration;
import org.sonar.core.platform.Module;
+import org.sonar.server.organization.MemberUpdater;
import org.sonar.server.organization.OrganisationSupport;
import static org.sonar.process.ProcessProperties.Property.SONARCLOUD_ENABLED;
AddMemberAction.class,
CreateAction.class,
DeleteAction.class,
+ MemberUpdater.class,
RemoveMemberAction.class,
UpdateAction.class,
SetMembersSyncAction.class);
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.user.UserDto;
+import org.sonar.server.organization.MemberUpdater;
import org.sonar.server.user.UserSession;
-import org.sonar.server.user.index.UserIndexer;
-import static java.util.Collections.singletonList;
-import static org.sonar.api.CoreProperties.DEFAULT_ISSUE_ASSIGNEE;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
import static org.sonar.server.organization.ws.OrganizationsWsSupport.PARAM_LOGIN;
import static org.sonar.server.organization.ws.OrganizationsWsSupport.PARAM_ORGANIZATION;
import static org.sonar.server.ws.KeyExamples.KEY_ORG_EXAMPLE_001;
import static org.sonar.server.ws.WsUtils.checkFound;
import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
-import static org.sonar.server.ws.WsUtils.checkRequest;
public class RemoveMemberAction implements OrganizationsWsAction {
private final DbClient dbClient;
private final UserSession userSession;
- private final UserIndexer userIndexer;
private final OrganizationsWsSupport wsSupport;
+ private final MemberUpdater memberUpdater;
- public RemoveMemberAction(DbClient dbClient, UserSession userSession, UserIndexer userIndexer, OrganizationsWsSupport wsSupport) {
+ public RemoveMemberAction(DbClient dbClient, UserSession userSession, OrganizationsWsSupport wsSupport,
+ MemberUpdater memberUpdater) {
this.dbClient = dbClient;
this.userSession = userSession;
- this.userIndexer = userIndexer;
this.wsSupport = wsSupport;
+ this.memberUpdater = memberUpdater;
}
@Override
try (DbSession dbSession = dbClient.openSession(false)) {
OrganizationDto organization = checkFoundWithOptional(dbClient.organizationDao().selectByKey(dbSession, organizationKey),
"Organization '%s' is not found", organizationKey);
- UserDto user = checkFound(dbClient.userDao().selectActiveUserByLogin(dbSession, login), "User '%s' is not found", login);
userSession.checkPermission(ADMINISTER, organization);
wsSupport.checkMemberSyncIsDisabled(dbSession, organization);
- dbClient.organizationMemberDao().select(dbSession, organization.getUuid(), user.getId())
- .ifPresent(om -> removeMember(dbSession, organization, user));
+
+ UserDto user = checkFound(dbClient.userDao().selectActiveUserByLogin(dbSession, login), "User '%s' is not found", login);
+ memberUpdater.removeMember(dbSession, organization, user);
}
response.noContent();
}
- private void removeMember(DbSession dbSession, OrganizationDto organization, UserDto user) {
- ensureLastAdminIsNotRemoved(dbSession, organization, user);
- int userId = user.getId();
- String organizationUuid = organization.getUuid();
- dbClient.userPermissionDao().deleteOrganizationMemberPermissions(dbSession, organizationUuid, userId);
- dbClient.permissionTemplateDao().deleteUserPermissionsByOrganization(dbSession, organizationUuid, userId);
- dbClient.qProfileEditUsersDao().deleteByOrganizationAndUser(dbSession, organization, user);
- dbClient.userGroupDao().deleteByOrganizationAndUser(dbSession, organizationUuid, userId);
- dbClient.propertiesDao().deleteByOrganizationAndUser(dbSession, organizationUuid, userId);
- dbClient.propertiesDao().deleteByOrganizationAndMatchingLogin(dbSession, organizationUuid, user.getLogin(), singletonList(DEFAULT_ISSUE_ASSIGNEE));
-
- dbClient.organizationMemberDao().delete(dbSession, organizationUuid, userId);
- userIndexer.commitAndIndex(dbSession, user);
- }
-
- private void ensureLastAdminIsNotRemoved(DbSession dbSession, OrganizationDto organizationDto, UserDto user) {
- int remainingAdmins = dbClient.authorizationDao().countUsersWithGlobalPermissionExcludingUser(dbSession,
- organizationDto.getUuid(), ADMINISTER.getKey(), user.getId());
- checkRequest(remainingAdmins > 0, "The last administrator member cannot be removed");
- }
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info 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.server.organization;
+
+import java.util.HashSet;
+import javax.annotation.Nullable;
+import org.assertj.core.groups.Tuple;
+import org.elasticsearch.action.search.SearchRequestBuilder;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.permission.OrganizationPermission;
+import org.sonar.db.permission.template.PermissionTemplateDto;
+import org.sonar.db.permission.template.PermissionTemplateUserDto;
+import org.sonar.db.property.PropertyDto;
+import org.sonar.db.property.PropertyQuery;
+import org.sonar.db.qualityprofile.QProfileDto;
+import org.sonar.db.user.GroupDto;
+import org.sonar.db.user.GroupMembershipDto;
+import org.sonar.db.user.GroupMembershipQuery;
+import org.sonar.db.user.UserDto;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.es.SearchOptions;
+import org.sonar.server.user.index.UserDoc;
+import org.sonar.server.user.index.UserIndex;
+import org.sonar.server.user.index.UserIndexDefinition;
+import org.sonar.server.user.index.UserIndexer;
+import org.sonar.server.user.index.UserQuery;
+import org.sonar.server.usergroups.DefaultGroupFinder;
+
+import static java.lang.String.format;
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
+import static org.elasticsearch.index.query.QueryBuilders.termQuery;
+import static org.sonar.api.CoreProperties.DEFAULT_ISSUE_ASSIGNEE;
+import static org.sonar.api.web.UserRole.CODEVIEWER;
+import static org.sonar.api.web.UserRole.USER;
+import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
+import static org.sonar.db.permission.OrganizationPermission.SCAN;
+import static org.sonar.db.user.GroupMembershipQuery.IN;
+import static org.sonar.server.user.index.UserIndexDefinition.FIELD_ORGANIZATION_UUIDS;
+import static org.sonar.server.user.index.UserIndexDefinition.FIELD_UUID;
+
+public class MemberUpdaterTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+ @Rule
+ public EsTester es = EsTester.create();
+ @Rule
+ public DbTester db = DbTester.create();
+
+ private DbClient dbClient = db.getDbClient();
+ private UserIndex userIndex = new UserIndex(es.client(), System2.INSTANCE);
+ private UserIndexer userIndexer = new UserIndexer(dbClient, es.client());
+
+ private MemberUpdater underTest = new MemberUpdater(dbClient, new DefaultGroupFinder(dbClient), userIndexer);
+
+ @Test
+ public void add_member_in_db_and_user_index() {
+ OrganizationDto organization = db.organizations().insert();
+ db.users().insertDefaultGroup(organization, "Members");
+ UserDto user = db.users().insertUser();
+
+ underTest.addMember(db.getSession(), organization, user);
+
+ assertUserIsMember(organization, user);
+ assertThat(userIndex.search(UserQuery.builder().build(), new SearchOptions()).getDocs())
+ .extracting(UserDoc::login, UserDoc::organizationUuids)
+ .containsExactlyInAnyOrder(tuple(user.getLogin(), singletonList(organization.getUuid())));
+ }
+
+ @Test
+ public void does_not_fail_to_add_member_if_user_already_added_in_organization() {
+ OrganizationDto organization = db.organizations().insert();
+ GroupDto defaultGroup = db.users().insertDefaultGroup(organization, "Members");
+ UserDto user = db.users().insertUser();
+ db.organizations().addMember(organization, user);
+ db.users().insertMember(defaultGroup, user);
+ assertUserIsMember(organization, user);
+
+ underTest.addMember(db.getSession(), organization, user);
+
+ assertUserIsMember(organization, user);
+ }
+
+ @Test
+ public void add_member_fails_when_organization_has_no_default_group() {
+ OrganizationDto organization = db.organizations().insert();
+ UserDto user = db.users().insertUser();
+
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage(format("Default group cannot be found on organization '%s'", organization.getUuid()));
+
+ underTest.addMember(db.getSession(), organization, user);
+ }
+
+ @Test
+ public void add_members_in_db_and_user_index() {
+ OrganizationDto organization = db.organizations().insert();
+ db.users().insertDefaultGroup(organization, "Members");
+ UserDto user1 = db.users().insertUser();
+ UserDto user2 = db.users().insertUser();
+ UserDto disableUser = db.users().insertDisabledUser();
+
+ underTest.addMembers(db.getSession(), organization, asList(user1, user2, disableUser));
+
+ assertUserIsMember(organization, user1);
+ assertUserIsMember(organization, user2);
+ assertUserIsNotMember(organization, disableUser);
+ assertThat(userIndex.search(UserQuery.builder().build(), new SearchOptions()).getDocs())
+ .extracting(UserDoc::login, UserDoc::organizationUuids)
+ .containsExactlyInAnyOrder(
+ tuple(user1.getLogin(), singletonList(organization.getUuid())),
+ tuple(user2.getLogin(), singletonList(organization.getUuid())));
+ }
+
+ @Test
+ public void add_members_does_not_fail_when_one_user_is_already_member_of_organization() {
+ OrganizationDto organization = db.organizations().insert();
+ GroupDto defaultGroup = db.users().insertDefaultGroup(organization, "Members");
+ UserDto userAlreadyMember = db.users().insertUser();
+ db.organizations().addMember(organization, userAlreadyMember);
+ db.users().insertMember(defaultGroup, userAlreadyMember);
+ UserDto userNotMember = db.users().insertUser();
+ userIndexer.indexOnStartup(new HashSet<>());
+
+ underTest.addMembers(db.getSession(), organization, asList(userAlreadyMember, userNotMember));
+
+ assertUserIsMember(organization, userAlreadyMember);
+ assertUserIsMember(organization, userNotMember);
+ assertThat(userIndex.search(UserQuery.builder().build(), new SearchOptions()).getDocs())
+ .extracting(UserDoc::login, UserDoc::organizationUuids)
+ .containsExactlyInAnyOrder(
+ tuple(userAlreadyMember.getLogin(), singletonList(organization.getUuid())),
+ tuple(userNotMember.getLogin(), singletonList(organization.getUuid())));
+ }
+
+ @Test
+ public void remove_member_from_db_and_user_index() {
+ OrganizationDto organization = db.organizations().insert();
+ GroupDto defaultGroup = db.users().insertDefaultGroup(organization, "Members");
+ UserDto user = db.users().insertUser();
+ UserDto adminUser = db.users().insertAdminByUserPermission(organization);
+ db.organizations().addMember(organization, user, adminUser);
+ db.users().insertMember(defaultGroup, user);
+ userIndexer.indexOnStartup(new HashSet<>());
+
+ underTest.removeMember(db.getSession(), organization, user);
+
+ assertUserIsNotMember(organization, user);
+ }
+
+ @Test
+ public void remove_members_from_db_and_user_index() {
+ OrganizationDto organization = db.organizations().insert();
+ GroupDto defaultGroup = db.users().insertDefaultGroup(organization, "Members");
+ UserDto user1 = db.users().insertUser();
+ UserDto user2 = db.users().insertUser();
+ UserDto adminUser = db.users().insertAdminByUserPermission(organization);
+ db.organizations().addMember(organization, user1, user2, adminUser);
+ db.users().insertMember(defaultGroup, user1);
+ db.users().insertMember(defaultGroup, user2);
+ db.users().insertMember(defaultGroup, adminUser);
+ userIndexer.indexOnStartup(new HashSet<>());
+
+ underTest.removeMembers(db.getSession(), organization, asList(user1, user2));
+
+ assertUserIsNotMember(organization, user1);
+ assertUserIsNotMember(organization, user2);
+ assertUserIsMember(organization, adminUser);
+ }
+
+ @Test
+ public void remove_member_removes_permissions() {
+ OrganizationDto organization = db.organizations().insert();
+ ComponentDto project = db.components().insertPrivateProject(organization);
+ GroupDto defaultGroup = db.users().insertDefaultGroup(organization, "Members");
+ UserDto user = db.users().insertUser();
+ UserDto adminUser = db.users().insertAdminByUserPermission(organization);
+ db.organizations().addMember(organization, user, adminUser);
+ db.users().insertMember(defaultGroup, user);
+ UserDto anotherUser = db.users().insertUser();
+ OrganizationDto anotherOrganization = db.organizations().insert();
+ ComponentDto anotherProject = db.components().insertPrivateProject(anotherOrganization);
+ userIndexer.indexOnStartup(new HashSet<>());
+
+ db.users().insertPermissionOnUser(organization, user, ADMINISTER);
+ db.users().insertPermissionOnUser(organization, user, SCAN);
+ db.users().insertPermissionOnUser(anotherOrganization, user, ADMINISTER);
+ db.users().insertPermissionOnUser(anotherOrganization, user, SCAN);
+ db.users().insertPermissionOnUser(organization, anotherUser, ADMINISTER);
+ db.users().insertPermissionOnUser(organization, anotherUser, SCAN);
+ db.users().insertProjectPermissionOnUser(user, CODEVIEWER, project);
+ db.users().insertProjectPermissionOnUser(user, USER, project);
+ db.users().insertProjectPermissionOnUser(user, CODEVIEWER, anotherProject);
+ db.users().insertProjectPermissionOnUser(user, USER, anotherProject);
+ db.users().insertProjectPermissionOnUser(anotherUser, CODEVIEWER, project);
+ db.users().insertProjectPermissionOnUser(anotherUser, USER, project);
+
+ underTest.removeMember(db.getSession(), organization, user);
+
+ assertUserIsNotMember(organization, user);
+ assertOrgPermissionsOfUser(user, organization);
+ assertOrgPermissionsOfUser(user, anotherOrganization, ADMINISTER, SCAN);
+ assertOrgPermissionsOfUser(anotherUser, organization, ADMINISTER, SCAN);
+ assertProjectPermissionsOfUser(user, project);
+ assertProjectPermissionsOfUser(user, anotherProject, CODEVIEWER, USER);
+ assertProjectPermissionsOfUser(anotherUser, project, CODEVIEWER, USER);
+ }
+
+ @Test
+ public void remove_member_removes_template_permissions() {
+ OrganizationDto organization = db.organizations().insert();
+ GroupDto defaultGroup = db.users().insertDefaultGroup(organization, "Members");
+ UserDto user = db.users().insertUser();
+ UserDto adminUser = db.users().insertAdminByUserPermission(organization);
+ db.organizations().addMember(organization, user, adminUser);
+ db.users().insertMember(defaultGroup, user);
+ userIndexer.indexOnStartup(new HashSet<>());
+
+ OrganizationDto anotherOrganization = db.organizations().insert();
+ UserDto anotherUser = db.users().insertUser();
+ PermissionTemplateDto template = db.permissionTemplates().insertTemplate(organization);
+ PermissionTemplateDto anotherTemplate = db.permissionTemplates().insertTemplate(anotherOrganization);
+ String permission = "browse";
+ db.permissionTemplates().addUserToTemplate(template.getId(), user.getId(), permission);
+ db.permissionTemplates().addUserToTemplate(template.getId(), anotherUser.getId(), permission);
+ db.permissionTemplates().addUserToTemplate(anotherTemplate.getId(), user.getId(), permission);
+
+ underTest.removeMember(db.getSession(), organization, user);
+
+ assertThat(dbClient.permissionTemplateDao().selectUserPermissionsByTemplateId(db.getSession(), template.getId())).extracting(PermissionTemplateUserDto::getUserId)
+ .containsOnly(anotherUser.getId());
+ assertThat(dbClient.permissionTemplateDao().selectUserPermissionsByTemplateId(db.getSession(), anotherTemplate.getId())).extracting(PermissionTemplateUserDto::getUserId)
+ .containsOnly(user.getId());
+ }
+
+ @Test
+ public void remove_member_removes_qprofiles_user_permission() {
+ OrganizationDto organization = db.organizations().insert();
+ GroupDto defaultGroup = db.users().insertDefaultGroup(organization, "Members");
+ UserDto user = db.users().insertUser();
+ UserDto adminUser = db.users().insertAdminByUserPermission(organization);
+ db.organizations().addMember(organization, user, adminUser);
+ db.users().insertMember(defaultGroup, user);
+ userIndexer.indexOnStartup(new HashSet<>());
+
+ OrganizationDto anotherOrganization = db.organizations().insert();
+ db.organizations().addMember(anotherOrganization, user);
+ QProfileDto profile = db.qualityProfiles().insert(organization);
+ QProfileDto anotherProfile = db.qualityProfiles().insert(anotherOrganization);
+ db.qualityProfiles().addUserPermission(profile, user);
+ db.qualityProfiles().addUserPermission(anotherProfile, user);
+
+ underTest.removeMember(db.getSession(), organization, user);
+
+ assertThat(db.getDbClient().qProfileEditUsersDao().exists(db.getSession(), profile, user)).isFalse();
+ assertThat(db.getDbClient().qProfileEditUsersDao().exists(db.getSession(), anotherProfile, user)).isTrue();
+ }
+
+ @Test
+ public void remove_member_removes_user_from_organization_groups() {
+ OrganizationDto organization = db.organizations().insert();
+ GroupDto defaultGroup = db.users().insertDefaultGroup(organization, "Members");
+ UserDto user = db.users().insertUser();
+ UserDto adminUser = db.users().insertAdminByUserPermission(organization);
+ db.organizations().addMember(organization, user, adminUser);
+ db.users().insertMember(defaultGroup, user);
+ userIndexer.indexOnStartup(new HashSet<>());
+
+ OrganizationDto anotherOrganization = db.organizations().insert();
+ UserDto anotherUser = db.users().insertUser();
+ GroupDto group = db.users().insertGroup(organization);
+ GroupDto anotherGroup = db.users().insertGroup(anotherOrganization);
+ db.users().insertMembers(group, user, anotherUser);
+ db.users().insertMembers(anotherGroup, user, anotherUser);
+
+ underTest.removeMember(db.getSession(), organization, user);
+
+ assertThat(dbClient.groupMembershipDao().selectGroupIdsByUserId(db.getSession(), user.getId()))
+ .containsOnly(anotherGroup.getId());
+ assertThat(dbClient.groupMembershipDao().selectGroupIdsByUserId(db.getSession(), anotherUser.getId()))
+ .containsOnly(group.getId(), anotherGroup.getId());
+ }
+
+ @Test
+ public void remove_member_removes_user_from_default_organization_group() {
+ OrganizationDto organization = db.organizations().insert();
+ GroupDto defaultGroup = db.users().insertDefaultGroup(organization, "Members");
+ UserDto user = db.users().insertUser();
+ UserDto adminUser = db.users().insertAdminByUserPermission(organization);
+ db.organizations().addMember(organization, user, adminUser);
+ db.users().insertMember(defaultGroup, user);
+ userIndexer.indexOnStartup(new HashSet<>());
+
+ underTest.removeMember(db.getSession(), organization, user);
+
+ assertThat(dbClient.groupMembershipDao().selectGroupIdsByUserId(db.getSession(), user.getId())).isEmpty();
+ }
+
+ @Test
+ public void remove_member_removes_user_from_org_properties() {
+ OrganizationDto organization = db.organizations().insert();
+ ComponentDto project = db.components().insertPrivateProject(organization);
+ GroupDto defaultGroup = db.users().insertDefaultGroup(organization, "Members");
+ UserDto user = db.users().insertUser();
+ UserDto adminUser = db.users().insertAdminByUserPermission(organization);
+ db.organizations().addMember(organization, user, adminUser);
+ db.users().insertMember(defaultGroup, user);
+ userIndexer.indexOnStartup(new HashSet<>());
+
+ OrganizationDto anotherOrganization = db.organizations().insert();
+ ComponentDto anotherProject = db.components().insertPrivateProject(anotherOrganization);
+ UserDto anotherUser = db.users().insertUser();
+ insertProperty("KEY_11", "VALUE", project.getId(), user.getId());
+ insertProperty("KEY_12", "VALUE", project.getId(), user.getId());
+ insertProperty("KEY_11", "VALUE", project.getId(), anotherUser.getId());
+ insertProperty("KEY_11", "VALUE", anotherProject.getId(), user.getId());
+
+ underTest.removeMember(db.getSession(), organization, user);
+
+ assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setComponentId(project.getId()).build(), db.getSession()))
+ .hasSize(1).extracting(PropertyDto::getUserId).containsOnly(anotherUser.getId());
+ assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setComponentId(anotherProject.getId()).build(), db.getSession())).extracting(PropertyDto::getUserId)
+ .hasSize(1).containsOnly(user.getId());
+ }
+
+ @Test
+ public void remove_member_removes_user_from_default_assignee_properties() {
+ OrganizationDto organization = db.organizations().insert();
+ ComponentDto project = db.components().insertPrivateProject(organization);
+ GroupDto defaultGroup = db.users().insertDefaultGroup(organization, "Members");
+ UserDto user = db.users().insertUser();
+ UserDto adminUser = db.users().insertAdminByUserPermission(organization);
+ db.organizations().addMember(organization, user, adminUser);
+ db.users().insertMember(defaultGroup, user);
+ userIndexer.indexOnStartup(new HashSet<>());
+
+ OrganizationDto anotherOrganization = db.organizations().insert();
+ ComponentDto anotherProject = db.components().insertPrivateProject(anotherOrganization);
+ UserDto anotherUser = db.users().insertUser();
+ insertProperty(DEFAULT_ISSUE_ASSIGNEE, user.getLogin(), project.getId(), null);
+ insertProperty("ANOTHER_KEY", user.getLogin(), project.getId(), null);
+ insertProperty(DEFAULT_ISSUE_ASSIGNEE, anotherUser.getLogin(), project.getId(), null);
+ insertProperty(DEFAULT_ISSUE_ASSIGNEE, user.getLogin(), anotherProject.getId(), null);
+
+ underTest.removeMember(db.getSession(), organization, user);
+
+ assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setComponentId(project.getId()).build(), db.getSession()))
+ .hasSize(2).extracting(PropertyDto::getKey, PropertyDto::getValue)
+ .containsOnly(Tuple.tuple("ANOTHER_KEY", user.getLogin()), Tuple.tuple(DEFAULT_ISSUE_ASSIGNEE, anotherUser.getLogin()));
+ assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setComponentId(anotherProject.getId()).build(), db.getSession())).extracting(PropertyDto::getValue)
+ .hasSize(1).containsOnly(user.getLogin());
+ }
+
+ @Test
+ public void fail_to_remove_members_when_no_more_admin() {
+ OrganizationDto organization = db.organizations().insert();
+ GroupDto defaultGroup = db.users().insertDefaultGroup(organization, "Members");
+ GroupDto adminGroup = db.users().insertGroup(organization);
+ db.users().insertPermissionOnGroup(adminGroup, ADMINISTER);
+ UserDto user1 = db.users().insertUser();
+ UserDto admin1 = db.users().insertAdminByUserPermission(organization);
+ UserDto admin2 = db.users().insertUser();
+ db.organizations().addMember(organization, user1, admin1, admin2);
+ db.users().insertMember(defaultGroup, user1);
+ db.users().insertMember(defaultGroup, admin1);
+ db.users().insertMember(defaultGroup, admin2);
+ db.users().insertMember(adminGroup, admin2);
+ userIndexer.indexOnStartup(new HashSet<>());
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("The last administrator member cannot be removed");
+
+ underTest.removeMembers(db.getSession(), organization, asList(admin1, admin2));
+ }
+
+ private void assertUserIsMember(OrganizationDto organization, UserDto user) {
+ assertThat(dbClient.organizationMemberDao().select(db.getSession(), organization.getUuid(), user.getId())).isPresent();
+ Integer defaultGroupId = dbClient.organizationDao().getDefaultGroupId(db.getSession(), organization.getUuid()).get();
+ assertThat(db.getDbClient().groupMembershipDao().selectGroups(
+ db.getSession(),
+ GroupMembershipQuery.builder().membership(IN).organizationUuid(organization.getUuid()).build(),
+ user.getId(), 0, 10))
+ .extracting(GroupMembershipDto::getId)
+ .containsOnly(defaultGroupId.longValue());
+ }
+
+ private void assertUserIsNotMember(OrganizationDto organization, UserDto user) {
+ assertThat(dbClient.organizationMemberDao().select(db.getSession(), organization.getUuid(), user.getId())).isNotPresent();
+ SearchRequestBuilder request = es.client().prepareSearch(UserIndexDefinition.INDEX_TYPE_USER)
+ .setQuery(boolQuery()
+ .must(termQuery(FIELD_ORGANIZATION_UUIDS, organization.getUuid()))
+ .must(termQuery(FIELD_UUID, user.getUuid())));
+ assertThat(request.get().getHits().getHits()).isEmpty();
+ }
+
+ private void assertOrgPermissionsOfUser(UserDto user, OrganizationDto organization, OrganizationPermission... permissions) {
+ assertThat(dbClient.userPermissionDao().selectGlobalPermissionsOfUser(db.getSession(), user.getId(), organization.getUuid()).stream()
+ .map(OrganizationPermission::fromKey))
+ .containsOnly(permissions);
+ }
+
+ private void assertProjectPermissionsOfUser(UserDto user, ComponentDto project, String... permissions) {
+ assertThat(dbClient.userPermissionDao().selectProjectPermissionsOfUser(db.getSession(), user.getId(), project.getId())).containsOnly(permissions);
+ }
+
+ private void insertProperty(String key, @Nullable String value, @Nullable Long resourceId, @Nullable Integer userId) {
+ PropertyDto dto = new PropertyDto().setKey(key)
+ .setResourceId(resourceId)
+ .setUserId(userId)
+ .setValue(value);
+ db.properties().insertProperty(dto);
+ }
+
+}
*/
package org.sonar.server.organization.ws;
-import java.util.List;
import java.util.stream.IntStream;
import javax.annotation.Nullable;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.server.ws.WebService;
-import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.user.GroupMembershipQuery;
import org.sonar.db.user.UserDto;
import org.sonar.server.es.EsTester;
-import org.sonar.server.es.SearchOptions;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.issue.ws.AvatarResolverImpl;
+import org.sonar.server.organization.MemberUpdater;
import org.sonar.server.organization.OrganizationValidationImpl;
import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.user.index.UserDoc;
-import org.sonar.server.user.index.UserIndex;
import org.sonar.server.user.index.UserIndexer;
-import org.sonar.server.user.index.UserQuery;
import org.sonar.server.usergroups.DefaultGroupFinder;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
public UserSessionRule userSession = UserSessionRule.standalone().logIn().setRoot();
@Rule
public EsTester es = EsTester.create();
- private UserIndex userIndex = new UserIndex(es.client(), System2.INSTANCE);
@Rule
public DbTester db = DbTester.create();
+
private DbClient dbClient = db.getDbClient();
private DbSession dbSession = db.getSession();
private OrganizationsWsSupport wsSupport = new OrganizationsWsSupport(new OrganizationValidationImpl(), dbClient);
private WsActionTester ws = new WsActionTester(
- new AddMemberAction(dbClient, userSession, new UserIndexer(dbClient, es.client()), new DefaultGroupFinder(dbClient), new AvatarResolverImpl(), wsSupport));
+ new AddMemberAction(dbClient, userSession, new AvatarResolverImpl(), wsSupport,
+ new MemberUpdater(dbClient, new DefaultGroupFinder(dbClient), new UserIndexer(dbClient, es.client()))));
@Test
- public void add_member_in_db_and_user_index() {
+ public void add_member() {
OrganizationDto organization = db.organizations().insert();
db.users().insertDefaultGroup(organization, "default");
UserDto user = db.users().insertUser();
call(organization.getKey(), user.getLogin());
assertMember(organization.getUuid(), user.getId());
- List<UserDoc> userDocs = userIndex.search(UserQuery.builder().build(), new SearchOptions()).getDocs();
- assertThat(userDocs).hasSize(1);
- assertThat(userDocs.get(0).organizationUuids()).containsOnly(organization.getUuid());
}
@Test
underTest.configure(container);
assertThat(container.getPicoContainer().getComponentAdapters())
- .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 12);
+ .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 13);
}
}
import java.util.HashSet;
import javax.annotation.Nullable;
-import org.elasticsearch.action.search.SearchRequestBuilder;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
-import org.sonar.db.permission.OrganizationPermission;
-import org.sonar.db.permission.template.PermissionTemplateDto;
-import org.sonar.db.permission.template.PermissionTemplateUserDto;
-import org.sonar.db.property.PropertyDto;
-import org.sonar.db.property.PropertyQuery;
-import org.sonar.db.qualityprofile.QProfileDto;
-import org.sonar.db.user.GroupDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.es.EsTester;
import org.sonar.server.es.SearchOptions;
-import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.organization.MemberUpdater;
import org.sonar.server.organization.OrganizationValidationImpl;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.user.index.UserIndex;
-import org.sonar.server.user.index.UserIndexDefinition;
import org.sonar.server.user.index.UserIndexer;
import org.sonar.server.user.index.UserQuery;
+import org.sonar.server.usergroups.DefaultGroupFinder;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
import static java.util.Arrays.asList;
import static java.util.Optional.ofNullable;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.groups.Tuple.tuple;
-import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
-import static org.elasticsearch.index.query.QueryBuilders.termQuery;
-import static org.sonar.api.CoreProperties.DEFAULT_ISSUE_ASSIGNEE;
-import static org.sonar.api.web.UserRole.CODEVIEWER;
-import static org.sonar.api.web.UserRole.USER;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES;
-import static org.sonar.db.permission.OrganizationPermission.SCAN;
import static org.sonar.server.organization.ws.OrganizationsWsSupport.PARAM_ORGANIZATION;
-import static org.sonar.server.user.index.UserIndexDefinition.FIELD_ORGANIZATION_UUIDS;
-import static org.sonar.server.user.index.UserIndexDefinition.FIELD_UUID;
public class RemoveMemberActionTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
- public UserSessionRule userSession = UserSessionRule.standalone().logIn().setRoot();
+ public UserSessionRule userSession = UserSessionRule.standalone();
@Rule
public EsTester es = EsTester.create();
@Rule
private UserIndexer userIndexer = new UserIndexer(dbClient, es.client());
private OrganizationsWsSupport wsSupport = new OrganizationsWsSupport(new OrganizationValidationImpl(), dbClient);
- private WsActionTester ws = new WsActionTester(new RemoveMemberAction(dbClient, userSession, userIndexer, wsSupport));
+ private WsActionTester ws = new WsActionTester(new RemoveMemberAction(dbClient, userSession, wsSupport,
+ new MemberUpdater(dbClient, new DefaultGroupFinder(dbClient), new UserIndexer(dbClient, es.client()))));
- private OrganizationDto organization;
- private ComponentDto project;
- private UserDto user;
-
- @Before
- public void setUp() {
- organization = db.organizations().insert();
- project = db.components().insertPrivateProject(organization);
-
- user = db.users().insertUser();
+ @Test
+ public void remove_member() {
+ OrganizationDto organization = db.organizations().insert();
+ UserDto user = db.users().insertUser();
db.organizations().addMember(organization, user);
-
UserDto adminUser = db.users().insertAdminByUserPermission(organization);
db.organizations().addMember(organization, adminUser);
-
userIndexer.indexOnStartup(new HashSet<>());
- }
-
- @Test
- public void definition() {
- WebService.Action definition = ws.getDef();
-
- assertThat(definition.key()).isEqualTo("remove_member");
- assertThat(definition.since()).isEqualTo("6.4");
- assertThat(definition.isPost()).isTrue();
- assertThat(definition.isInternal()).isTrue();
- assertThat(definition.params()).extracting(WebService.Param::key).containsOnly("organization", "login");
-
- WebService.Param organization = definition.param("organization");
- assertThat(organization.isRequired()).isTrue();
-
- WebService.Param login = definition.param("login");
- assertThat(login.isRequired()).isTrue();
- }
-
- @Test
- public void no_content_http_204_returned() {
- TestResponse result = call(organization.getKey(), user.getLogin());
-
- assertThat(result.getStatus()).isEqualTo(HTTP_NO_CONTENT);
- assertThat(result.getInput()).isEmpty();
- }
-
- @Test
- public void remove_member_from_db_and_user_index() {
assertMember(organization.getUuid(), user);
+ userSession.logIn().addPermission(ADMINISTER, organization);
call(organization.getKey(), user.getLogin());
}
@Test
- public void remove_organization_permissions() {
- UserDto anotherUser = db.users().insertUser();
- OrganizationDto anotherOrganization = db.organizations().insert();
- ComponentDto anotherProject = db.components().insertPrivateProject(anotherOrganization);
+ public void no_content_http_204_returned() {
+ OrganizationDto organization = db.organizations().insert();
+ UserDto user = db.users().insertUser();
+ db.organizations().addMember(organization, user);
+ UserDto adminUser = db.users().insertAdminByUserPermission(organization);
+ db.organizations().addMember(organization, adminUser);
+ userIndexer.indexOnStartup(new HashSet<>());
assertMember(organization.getUuid(), user);
- db.users().insertPermissionOnUser(organization, user, ADMINISTER);
- db.users().insertPermissionOnUser(organization, user, SCAN);
- db.users().insertPermissionOnUser(anotherOrganization, user, ADMINISTER);
- db.users().insertPermissionOnUser(anotherOrganization, user, SCAN);
- db.users().insertPermissionOnUser(organization, anotherUser, ADMINISTER);
- db.users().insertPermissionOnUser(organization, anotherUser, SCAN);
- db.users().insertProjectPermissionOnUser(user, CODEVIEWER, project);
- db.users().insertProjectPermissionOnUser(user, USER, project);
- db.users().insertProjectPermissionOnUser(user, CODEVIEWER, anotherProject);
- db.users().insertProjectPermissionOnUser(user, USER, anotherProject);
- db.users().insertProjectPermissionOnUser(anotherUser, CODEVIEWER, project);
- db.users().insertProjectPermissionOnUser(anotherUser, USER, project);
-
- call(organization.getKey(), user.getLogin());
-
- assertNotAMember(organization.getUuid(), user);
- assertOrgPermissionsOfUser(user, organization);
- assertOrgPermissionsOfUser(user, anotherOrganization, ADMINISTER, SCAN);
- assertOrgPermissionsOfUser(anotherUser, organization, ADMINISTER, SCAN);
- assertProjectPermissionsOfUser(user, project);
- assertProjectPermissionsOfUser(user, anotherProject, CODEVIEWER, USER);
- assertProjectPermissionsOfUser(anotherUser, project, CODEVIEWER, USER);
- }
-
- @Test
- public void remove_template_permissions() {
- OrganizationDto anotherOrganization = db.organizations().insert();
- UserDto anotherUser = db.users().insertUser();
- PermissionTemplateDto template = db.permissionTemplates().insertTemplate(organization);
- PermissionTemplateDto anotherTemplate = db.permissionTemplates().insertTemplate(anotherOrganization);
- String permission = "PERMISSION";
- db.permissionTemplates().addUserToTemplate(template.getId(), user.getId(), permission);
- db.permissionTemplates().addUserToTemplate(template.getId(), anotherUser.getId(), permission);
- db.permissionTemplates().addUserToTemplate(anotherTemplate.getId(), user.getId(), permission);
-
- call(organization.getKey(), user.getLogin());
-
- assertThat(dbClient.permissionTemplateDao().selectUserPermissionsByTemplateId(dbSession, template.getId())).extracting(PermissionTemplateUserDto::getUserId)
- .containsOnly(anotherUser.getId());
- assertThat(dbClient.permissionTemplateDao().selectUserPermissionsByTemplateId(dbSession, anotherTemplate.getId())).extracting(PermissionTemplateUserDto::getUserId)
- .containsOnly(user.getId());
- }
-
- @Test
- public void remove_qprofiles_user_permission() {
- OrganizationDto anotherOrganization = db.organizations().insert();
- db.organizations().addMember(anotherOrganization, user);
- QProfileDto profile = db.qualityProfiles().insert(organization);
- QProfileDto anotherProfile = db.qualityProfiles().insert(anotherOrganization);
- db.qualityProfiles().addUserPermission(profile, user);
- db.qualityProfiles().addUserPermission(anotherProfile, user);
-
- call(organization.getKey(), user.getLogin());
-
- assertThat(db.getDbClient().qProfileEditUsersDao().exists(dbSession, profile, user)).isFalse();
- assertThat(db.getDbClient().qProfileEditUsersDao().exists(dbSession, anotherProfile, user)).isTrue();
- }
-
- @Test
- public void remove_from_organization_groups() {
- OrganizationDto anotherOrganization = db.organizations().insert();
- UserDto anotherUser = db.users().insertUser();
- GroupDto group = db.users().insertGroup(organization);
- GroupDto anotherGroup = db.users().insertGroup(anotherOrganization);
- db.users().insertMembers(group, user, anotherUser);
- db.users().insertMembers(anotherGroup, user, anotherUser);
-
- call(organization.getKey(), user.getLogin());
-
- assertThat(dbClient.groupMembershipDao().selectGroupIdsByUserId(dbSession, user.getId()))
- .containsOnly(anotherGroup.getId());
- assertThat(dbClient.groupMembershipDao().selectGroupIdsByUserId(dbSession, anotherUser.getId()))
- .containsOnly(group.getId(), anotherGroup.getId());
- }
-
- @Test
- public void remove_from_default_organization_group() {
- GroupDto defaultGroup = db.users().insertDefaultGroup(organization, "default");
- db.users().insertMember(defaultGroup, user);
-
- call(organization.getKey(), user.getLogin());
-
- assertThat(dbClient.groupMembershipDao().selectGroupIdsByUserId(dbSession, user.getId())).isEmpty();
- }
-
- @Test
- public void remove_from_org_properties() {
- OrganizationDto anotherOrganization = db.organizations().insert();
- ComponentDto anotherProject = db.components().insertPrivateProject(anotherOrganization);
- UserDto anotherUser = db.users().insertUser();
- insertProperty("KEY_11", "VALUE", project.getId(), user.getId());
- insertProperty("KEY_12", "VALUE", project.getId(), user.getId());
- insertProperty("KEY_11", "VALUE", project.getId(), anotherUser.getId());
- insertProperty("KEY_11", "VALUE", anotherProject.getId(), user.getId());
-
- call(organization.getKey(), user.getLogin());
-
- assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setComponentId(project.getId()).build(), dbSession))
- .hasSize(1).extracting(PropertyDto::getUserId).containsOnly(anotherUser.getId());
- assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setComponentId(anotherProject.getId()).build(), dbSession)).extracting(PropertyDto::getUserId)
- .hasSize(1).containsOnly(user.getId());
- }
-
- @Test
- public void remove_from_default_assignee_properties() {
- OrganizationDto anotherOrganization = db.organizations().insert();
- ComponentDto anotherProject = db.components().insertPrivateProject(anotherOrganization);
- UserDto anotherUser = db.users().insertUser();
- insertProperty(DEFAULT_ISSUE_ASSIGNEE, user.getLogin(), project.getId(), null);
- insertProperty("ANOTHER_KEY", user.getLogin(), project.getId(), null);
- insertProperty(DEFAULT_ISSUE_ASSIGNEE, anotherUser.getLogin(), project.getId(), null);
- insertProperty(DEFAULT_ISSUE_ASSIGNEE, user.getLogin(), anotherProject.getId(), null);
+ userSession.logIn().addPermission(ADMINISTER, organization);
- call(organization.getKey(), user.getLogin());
+ TestResponse result = call(organization.getKey(), user.getLogin());
- assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setComponentId(project.getId()).build(), dbSession))
- .hasSize(2).extracting(PropertyDto::getKey, PropertyDto::getValue)
- .containsOnly(tuple("ANOTHER_KEY", user.getLogin()), tuple(DEFAULT_ISSUE_ASSIGNEE, anotherUser.getLogin()));
- assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setComponentId(anotherProject.getId()).build(), dbSession)).extracting(PropertyDto::getValue)
- .hasSize(1).containsOnly(user.getLogin());
+ assertThat(result.getStatus()).isEqualTo(HTTP_NO_CONTENT);
+ assertThat(result.getInput()).isEmpty();
}
@Test
public void user_is_removed_only_from_designated_organization() {
+ OrganizationDto organization = db.organizations().insert();
+ UserDto user = db.users().insertUser();
+ db.organizations().addMember(organization, user);
+ UserDto adminUser = db.users().insertAdminByUserPermission(organization);
+ db.organizations().addMember(organization, adminUser);
+ userIndexer.indexOnStartup(new HashSet<>());
+ assertMember(organization.getUuid(), user);
OrganizationDto anotherOrg = db.organizations().insert();
db.organizations().addMember(anotherOrg, user);
-
- call(organization.getKey(), user.getLogin());
-
- assertMember(anotherOrg.getUuid(), user);
- }
-
- @Test
- public void remove_member_as_organization_admin() {
userSession.logIn().addPermission(ADMINISTER, organization);
call(organization.getKey(), user.getLogin());
- assertNotAMember(organization.getUuid(), user);
+ assertMember(anotherOrg.getUuid(), user);
}
@Test
public void do_not_fail_if_user_already_removed_from_organization() {
+ OrganizationDto organization = db.organizations().insert();
+ UserDto user = db.users().insertUser();
+ db.organizations().addMember(organization, user);
+ UserDto adminUser = db.users().insertAdminByUserPermission(organization);
+ db.organizations().addMember(organization, adminUser);
+ userIndexer.indexOnStartup(new HashSet<>());
+ assertMember(organization.getUuid(), user);
+ userSession.logIn().addPermission(ADMINISTER, organization);
call(organization.getKey(), user.getLogin());
call(organization.getKey(), user.getLogin());
@Test
public void fail_if_login_does_not_exist() {
+ OrganizationDto organization = db.organizations().insert();
+ userSession.logIn().addPermission(ADMINISTER, organization);
+
expectedException.expect(NotFoundException.class);
expectedException.expectMessage("User 'login-42' is not found");
@Test
public void fail_if_organization_does_not_exist() {
+ UserDto user = db.users().insertUser();
+
expectedException.expect(NotFoundException.class);
expectedException.expectMessage("Organization 'org-42' is not found");
@Test
public void fail_if_no_login_provided() {
+ OrganizationDto organization = db.organizations().insert();
+ userSession.logIn().addPermission(ADMINISTER, organization);
+
expectedException.expect(IllegalArgumentException.class);
call(organization.getKey(), null);
@Test
public void fail_if_no_organization_provided() {
+ UserDto user = db.users().insertUser();
+
expectedException.expect(IllegalArgumentException.class);
call(null, user.getLogin());
@Test
public void fail_if_insufficient_permissions() {
+ OrganizationDto organization = db.organizations().insert();
+ UserDto user = db.users().insertUser();
+ db.organizations().addMember(organization, user);
+ UserDto adminUser = db.users().insertAdminByUserPermission(organization);
+ db.organizations().addMember(organization, adminUser);
+ userIndexer.indexOnStartup(new HashSet<>());
userSession.logIn().addPermission(ADMINISTER_QUALITY_GATES, organization);
expectedException.expect(ForbiddenException.class);
OrganizationDto organization = db.organizations().insert();
db.alm().insertOrganizationAlmBinding(organization, db.alm().insertAlmAppInstall());
UserDto user = db.users().insertUser();
+ userSession.logIn().addPermission(ADMINISTER, organization);
expectedException.expect(IllegalArgumentException.class);
UserDto admin2 = db.users().insertAdminByUserPermission(anotherOrganization);
db.organizations().addMember(anotherOrganization, admin2);
userIndexer.commitAndIndex(db.getSession(), asList(admin1, admin2));
+ userSession.logIn().addPermission(ADMINISTER, anotherOrganization);
call(anotherOrganization.getKey(), admin1.getLogin());
db.organizations().addMember(anotherOrganization, admin);
UserDto user = db.users().insertUser();
db.organizations().addMember(anotherOrganization, user);
+ userSession.logIn().addPermission(ADMINISTER, anotherOrganization);
- expectedException.expect(BadRequestException.class);
+ expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("The last administrator member cannot be removed");
call(anotherOrganization.getKey(), admin.getLogin());
}
+ @Test
+ public void definition() {
+ WebService.Action definition = ws.getDef();
+
+ assertThat(definition.key()).isEqualTo("remove_member");
+ assertThat(definition.since()).isEqualTo("6.4");
+ assertThat(definition.isPost()).isTrue();
+ assertThat(definition.isInternal()).isTrue();
+ assertThat(definition.params()).extracting(WebService.Param::key).containsOnly("organization", "login");
+
+ WebService.Param organization = definition.param("organization");
+ assertThat(organization.isRequired()).isTrue();
+
+ WebService.Param login = definition.param("login");
+ assertThat(login.isRequired()).isTrue();
+ }
+
private TestResponse call(@Nullable String organizationKey, @Nullable String login) {
TestRequest request = ws.newRequest();
ofNullable(organizationKey).ifPresent(o -> request.setParam(PARAM_ORGANIZATION, o));
private void assertNotAMember(String organizationUuid, UserDto user) {
assertThat(dbClient.organizationMemberDao().select(dbSession, organizationUuid, user.getId())).isNotPresent();
- assertMemberInIndex(organizationUuid, user, false);
}
private void assertMember(String organizationUuid, UserDto user) {
.build(),
new SearchOptions()).getDocs())
.hasSize(1);
- assertMemberInIndex(organizationUuid, user, true);
}
- private void assertMemberInIndex(String organizationUuid, UserDto user, boolean isMember) {
- SearchRequestBuilder request = es.client().prepareSearch(UserIndexDefinition.INDEX_TYPE_USER)
- .setQuery(boolQuery()
- .must(termQuery(FIELD_ORGANIZATION_UUIDS, organizationUuid))
- .must(termQuery(FIELD_UUID, user.getUuid())));
- if (isMember) {
- assertThat(request.get().getHits().getHits()).hasSize(1);
- } else {
- assertThat(request.get().getHits().getHits()).isEmpty();
- }
- }
-
- private void assertOrgPermissionsOfUser(UserDto user, OrganizationDto organization, OrganizationPermission... permissions) {
- assertThat(dbClient.userPermissionDao().selectGlobalPermissionsOfUser(dbSession, user.getId(), organization.getUuid()).stream()
- .map(OrganizationPermission::fromKey))
- .containsOnly(permissions);
- }
-
- private void assertProjectPermissionsOfUser(UserDto user, ComponentDto project, String... permissions) {
- assertThat(dbClient.userPermissionDao().selectProjectPermissionsOfUser(dbSession, user.getId(), project.getId())).containsOnly(permissions);
- }
-
- private void insertProperty(String key, @Nullable String value, @Nullable Long resourceId, @Nullable Integer userId) {
- PropertyDto dto = new PropertyDto().setKey(key)
- .setResourceId(resourceId)
- .setUserId(userId)
- .setValue(value);
- db.properties().insertProperty(dto);
- }
}