import org.sonar.db.user.UserPermissionDto;
import static com.google.common.collect.Maps.newHashMap;
+import static java.util.Collections.emptyList;
import static org.sonar.db.DatabaseUtils.executeLargeInputsWithoutOutput;
public class PermissionDao implements Dao {
}
public List<UserPermissionDto> selectUserPermissionsByQuery(DbSession dbSession, PermissionQuery query) {
+ if (query.getLogins() != null && query.getLogins().isEmpty()) {
+ return emptyList();
+ }
+
return mapper(dbSession).selectUserPermissionsByQuery(query);
}
int countUsersByQuery(@Param("query") PermissionQuery query);
- List<UserPermissionDto> selectUserPermissionsByQuery(PermissionQuery query);
+ List<UserPermissionDto> selectUserPermissionsByQuery(@Param("query") PermissionQuery query);
List<GroupWithPermissionDto> selectGroups(Map<String, Object> parameters);
*/
package org.sonar.db.permission;
+import java.util.List;
import java.util.Locale;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
* Query used to get users and groups permissions
*/
public class PermissionQuery {
-
public static final int RESULTS_MAX_SIZE = 100;
public static final int SEARCH_QUERY_MIN_LENGTH = 3;
public static final int DEFAULT_PAGE_SIZE = 20;
private final String searchQuery;
private final String searchQueryToSql;
private final boolean withPermissionOnly;
+ private final List<String> logins;
private final int pageSize;
private final int pageOffset;
this.searchQueryToSql = builder.searchQuery == null ? null : buildLikeValue(builder.searchQuery, WildcardPosition.BEFORE_AND_AFTER).toLowerCase(Locale.ENGLISH);
this.pageSize = builder.pageSize;
this.pageOffset = offset(builder.pageIndex, builder.pageSize);
+ this.logins = builder.logins;
}
@CheckForNull
return pageOffset;
}
+ @CheckForNull
+ public List<String> getLogins() {
+ return logins;
+ }
+
public static Builder builder() {
return new Builder();
}
private String template;
private String searchQuery;
private boolean withPermissionOnly;
+ private List<String> logins;
private Integer pageIndex = DEFAULT_PAGE_INDEX;
private Integer pageSize = DEFAULT_PAGE_SIZE;
return this;
}
+ public Builder setLogins(@Nullable List<String> logins) {
+ this.logins = logins;
+ return this;
+ }
+
public PermissionQuery build() {
this.pageIndex = firstNonNull(pageIndex, DEFAULT_PAGE_INDEX);
this.pageSize = firstNonNull(pageSize, DEFAULT_PAGE_SIZE);
checkArgument(searchQuery == null || searchQuery.length() >= 3);
- checkArgument(!(withPermissionOnly && permission == null));
+ checkArgument(logins == null || !logins.isEmpty());
return new PermissionQuery(this);
}
}
<mapper namespace="org.sonar.db.permission.PermissionMapper">
+ <!-- TODO delete when not used anymore -->
<select id="selectUsers" parameterType="map" resultType="UserWithPermission">
SELECT u.login as login, u.name as name, u.email as email, user_role.role as permission
<include refid="usersSelection"/>
ORDER BY u.name
</select>
+ <!-- TODO delete when not used anymore -->
<select id="countUsers" parameterType="map" resultType="int">
SELECT count(u.login)
<include refid="usersSelection"/>
</select>
+ <!-- TODO delete when not used anymore -->
<sql id="usersSelection">
FROM users u
LEFT JOIN user_roles user_role ON user_role.user_id=u.id
</where>
</sql>
+ <sql id="userColumns">
+ <!-- lower(u.name) and u.id are present to order by with select distinct -->
+ u.login as login, u.name as name, u.email as email, lower(u.name), u.id
+ </sql>
+
<select id="selectUsersByQuery" parameterType="map" resultType="org.sonar.db.permission.UserRef">
select distinct <include refid="userColumns" />
<include refid="usersByQuery"/>
order by lower(u.name), u.name, u.id
</select>
- <sql id="userColumns">
- <!-- lower(u.name) and u.id are present to order by with select distinct -->
- u.login as login, u.name as name, u.email as email, lower(u.name), u.id
- </sql>
-
<select id="countUsersByQuery" parameterType="map" resultType="int">
select count(1)
from (
<include refid="usersByQuery"/>)
</select>
+ <select id="selectUserPermissionsByQuery" parameterType="map" resultType="UserRole">
+ select ur.user_id as userId, ur.resource_id as componentId, ur.role as permission
+ <include refid="usersByQuery" />
+ </select>
+
<sql id="usersByQuery">
from users u
left join user_roles ur ON ur.user_id=u.id
left join projects p on ur.resource_id = p.id
<where>
and u.active = ${_true}
+ <if test="query.logins != null">
+ and u.login in
+ <foreach collection="query.logins" open="(" close=")" item="login" separator=",">
+ #{login}
+ </foreach>
+ </if>
<if test="query.searchQueryToSql != null">
and lower(u.name) like #{query.searchQueryToSql} ESCAPE '/'
</if>
</where>
</sql>
- <select id="selectUserPermissionsByQuery" parameterType="map" resultType="UserRole">
- select ur.user_id as userId, ur.resource_id as componentId, ur.role as permission
- from user_roles ur
- inner join users u on ur.user_id = u.id
- left outer join projects p on ur.resource_id=p.id
- <where>
- <if test="query.logins != null">
- and u.login in
- <foreach collection="query.logins" open="(" close=")" item="login" separator=",">
- #{login}
- </foreach>
- </if>
- <if test="query.searchQueryToSql != null">
- and (lower(u.name) like #{query.searchQueryToSql} ESCAPE '/')
- </if>
- </where>
-
- </select>
-
<select id="usersCountByProjectIdAndPermission" parameterType="map"
resultType="org.sonar.db.permission.CountByProjectAndPermissionDto">
SELECT user_role.resource_id as componentId, user_role.role as permission, count(u.login) as count
import org.sonar.db.user.UserDto;
import org.sonar.db.user.UserRoleDto;
+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.sonar.api.web.UserRole.ADMIN;
import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
import static org.sonar.api.web.UserRole.USER;
permissionDb.addProjectPermissionToUser(UserRole.USER, user4.getId(), project.getId());
PermissionQuery.Builder dbQuery = PermissionQuery.builder();
- List<UserRef> result = selectUsersByQuery(dbQuery);
+ List<UserRef> users = selectUsersByQuery(dbQuery);
int count = countUsersByQuery(dbQuery);
+ List<UserPermissionDto> permissions = selectUserPermissionsByQuery(dbQuery);
- assertThat(result)
+ assertThat(users)
.hasSize(4)
.extracting(UserRef::getName)
.containsExactly("1-name", "2-name", "3-name", "4-name");
- assertThat(result.get(0)).extracting(UserRef::getEmail, UserRef::getLogin)
+ assertThat(users.get(0)).extracting(UserRef::getEmail, UserRef::getLogin)
.containsExactly(user1.getEmail(), user1.getLogin());
assertThat(count).isEqualTo(4);
+
+ assertThat(permissions).hasSize(5).extracting(UserPermissionDto::getUserId, UserPermissionDto::getPermission)
+ .containsOnlyOnce(
+ tuple(user1.getId(), GlobalPermissions.SYSTEM_ADMIN),
+ tuple(user2.getId(), GlobalPermissions.SYSTEM_ADMIN),
+ tuple(user3.getId(), GlobalPermissions.SYSTEM_ADMIN),
+ tuple(user3.getId(), GlobalPermissions.PROVISIONING),
+ tuple(user4.getId(), UserRole.USER));
}
@Test
userDb.insertUser(newUserDto().setName("unknown"));
PermissionQuery.Builder dbQuery = PermissionQuery.builder().setSearchQuery("nam");
- List<UserRef> result = selectUsersByQuery(dbQuery);
+ List<UserRef> users = selectUsersByQuery(dbQuery);
int count = countUsersByQuery(dbQuery);
- assertThat(result).hasSize(1);
- assertThat(result.get(0).getName()).isEqualTo("1-name");
+ assertThat(users).hasSize(1);
+ assertThat(users.get(0).getName()).isEqualTo("1-name");
assertThat(count).isEqualTo(1);
}
+ @Test
+ public void select_user_permissions() {
+ UserDto user = userDb.insertUser(newUserDto().setLogin("user-login"));
+ UserDto anotherUser = userDb.insertUser(newUserDto().setLogin("another-login"));
+ ComponentDto project = componentDb.insertComponent(newProjectDto());
+ permissionDb.addProjectPermissionToUser(UserRole.ADMIN, user.getId(), project.getId());
+ permissionDb.addProjectPermissionToUser(UserRole.ADMIN, anotherUser.getId(), project.getId());
+
+ PermissionQuery.Builder dbQuery = PermissionQuery.builder()
+ .setComponentUuid(project.uuid())
+ .setLogins(singletonList("user-login"))
+ .withPermissionOnly();
+ List<UserPermissionDto> result = selectUserPermissionsByQuery(dbQuery);
+
+ assertThat(result).hasSize(1);
+ UserPermissionDto userPermission = result.get(0);
+ assertThat(userPermission.getComponentId()).isEqualTo(project.getId());
+ assertThat(userPermission.getPermission()).isEqualTo(UserRole.ADMIN);
+ assertThat(userPermission.getUserId()).isEqualTo(user.getId());
+ }
+
@Test
public void select_users_with_global_permissions() {
UserDto user3 = userDb.insertUser(newUserDto().setName("3-name"));
return underTest.countUsersByQuery(session, query.build());
}
+ private List<UserPermissionDto> selectUserPermissionsByQuery(PermissionQuery.Builder query) {
+ return underTest.selectUserPermissionsByQuery(session, query.build());
+ }
+
private void addPermissionToUser(String permission, long userId, long resourceId) {
dbTester.getDbClient().roleDao().insertUserRole(dbTester.getSession(), new UserRoleDto()
.setRole(permission)