private void checkOtherAdminsExist(DbSession dbSession, UserPermissionChange change) {
if (SYSTEM_ADMIN.equals(change.getPermission()) && !change.getProjectId().isPresent()) {
- int remaining = dbClient.authorizationDao().countUsersWithGlobalPermissionExcludingUser(dbSession,
+ int remaining = dbClient.authorizationDao().countUsersWithGlobalPermissionExcludingUserPermission(dbSession,
change.getOrganizationUuid(), change.getPermission(), change.getUserId().getId());
if (remaining == 0) {
throw new BadRequestException(String.format("Last user with permission '%s'. Permission cannot be removed.", SYSTEM_ADMIN));
return mapper(dbSession).countUsersWithGlobalPermissionExcludingGroupMember(organizationUuid, permission, groupId, userId);
}
+ /**
+ * The number of users who will still have the permission if the permission {@code permission}
+ * is removed from user {@code userId}. The anyone virtual group is not taken into account.
+ * Contrary to {@link #countUsersWithGlobalPermissionExcludingUser(DbSession, String, String, long)}, user
+ * still exists and may have the permission through groups.
+ */
+ public int countUsersWithGlobalPermissionExcludingUserPermission(DbSession dbSession, String organizationUuid,
+ String permission, long userId) {
+ return mapper(dbSession).countUsersWithGlobalPermissionExcludingUserPermission(organizationUuid, permission, userId);
+ }
+
public Set<Long> keepAuthorizedProjectIds(DbSession dbSession, Collection<Long> componentIds, @Nullable Integer userId, String role) {
return executeLargeInputsIntoSet(
componentIds,
int countUsersWithGlobalPermissionExcludingGroupMember(@Param("organizationUuid") String organizationUuid,
@Param("permission") String permission, @Param("groupId") long groupId, @Param("userId") long userId);
- Set<Long> keepAuthorizedProjectIdsForAnonymous(@Param("role") String role, @Param("componentIds") Collection<Long> componentIds);
+ int countUsersWithGlobalPermissionExcludingUserPermission(@Param("organizationUuid") String organizationUuid,
+ @Param("permission") String permission, @Param("userId") long userId);
+ Set<Long> keepAuthorizedProjectIdsForAnonymous(@Param("role") String role, @Param("componentIds") Collection<Long> componentIds);
+
Set<Long> keepAuthorizedProjectIdsForUser(@Param("userId") long userId, @Param("role") String role, @Param("componentIds") Collection<Long> componentIds);
List<String> keepAuthorizedComponentKeysForAnonymous(@Param("role") String role, @Param("componentKeys") Collection<String> componentKeys);
List<String> keepAuthorizedComponentKeysForUser(@Param("userId") Integer userId, @Param("role") String role, @Param("componentKeys") Collection<String> componentKeys);
List<Long> keepAuthorizedUsersForRoleAndProject(@Param("role") String role, @Param("componentId") long componentId, @Param("userIds") List<Long> userIds);
+
+
}
) remaining
</select>
+ <select id="countUsersWithGlobalPermissionExcludingUserPermission" parameterType="map" resultType="int">
+ select count(1) from
+ (
+ 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} and
+ ur.user_id != #{userId,jdbcType=BIGINT}
+ ) remaining
+ </select>
+
<select id="keepAuthorizedProjectIdsForUser" parameterType="map" resultType="long">
SELECT gr.resource_id
FROM group_roles gr
count = underTest.countUsersWithGlobalPermissionExcludingGroupMember(dbSession, org.getUuid(), DOES_NOT_EXIST, group1.getId(), u2.getId());
assertThat(count).isEqualTo(0);
}
+
+ @Test
+ public void countUsersWithGlobalPermissionExcludingUserPermission() {
+ // u1 and u2 have the direct permission, u3 has the permission through his group
+ UserDto u1 = db.users().insertUser();
+ db.users().insertPermissionOnUser(org, u1, A_PERMISSION);
+ UserDto u2 = db.users().insertUser();
+ db.users().insertPermissionOnUser(org, u2, A_PERMISSION);
+ db.users().insertPermissionOnGroup(group1, A_PERMISSION);
+ UserDto u3 = db.users().insertUser();
+ db.users().insertMember(group1, u3);
+
+ // excluding u2 permission --> remain u1 and u3
+ int count = underTest.countUsersWithGlobalPermissionExcludingUserPermission(dbSession, org.getUuid(), A_PERMISSION, u2.getId());
+ assertThat(count).isEqualTo(2);
+
+ // excluding unknown user
+ count = underTest.countUsersWithGlobalPermissionExcludingUserPermission(dbSession, org.getUuid(), A_PERMISSION, MISSING_ID);
+ assertThat(count).isEqualTo(3);
+
+ // another organization
+ count = underTest.countUsersWithGlobalPermissionExcludingUserPermission(dbSession, DOES_NOT_EXIST, A_PERMISSION, u2.getId());
+ assertThat(count).isEqualTo(0);
+
+ // another permission
+ count = underTest.countUsersWithGlobalPermissionExcludingUserPermission(dbSession, org.getUuid(), DOES_NOT_EXIST, u2.getId());
+ assertThat(count).isEqualTo(0);
+ }
}