import org.sonar.db.Pagination;
import org.sonar.db.user.GroupDto;
import org.sonar.db.user.SearchGroupMembershipDto;
-import org.sonar.db.user.SearchGroupsQuery;
+import org.sonar.db.user.SearchPermissionQuery;
import static org.sonar.core.util.stream.MoreCollectors.toList;
import static org.sonar.db.DatabaseUtils.executeLargeInputs;
return dbSession.getMapper(QualityGateGroupPermissionsMapper.class);
}
- public List<SearchGroupMembershipDto> selectByQuery(DbSession dbSession, SearchGroupsQuery query, Pagination pagination) {
+ public List<SearchGroupMembershipDto> selectByQuery(DbSession dbSession, SearchPermissionQuery query, Pagination pagination) {
return mapper(dbSession).selectByQuery(query, pagination);
}
- public int countByQuery(DbSession dbSession, SearchGroupsQuery query) {
+ public int countByQuery(DbSession dbSession, SearchPermissionQuery query) {
return mapper(dbSession).countByQuery(query);
}
}
import org.apache.ibatis.annotations.Param;
import org.sonar.db.Pagination;
import org.sonar.db.user.SearchGroupMembershipDto;
-import org.sonar.db.user.SearchGroupsQuery;
+import org.sonar.db.user.SearchPermissionQuery;
public interface QualityGateGroupPermissionsMapper {
void insert(@Param("dto") QualityGateGroupPermissionsDto dto, @Param("now") long now);
- List<SearchGroupMembershipDto> selectByQuery(@Param("query") SearchGroupsQuery query, @Param("pagination") Pagination pagination);
+ List<SearchGroupMembershipDto> selectByQuery(@Param("query") SearchPermissionQuery query, @Param("pagination") Pagination pagination);
- int countByQuery(@Param("query") SearchGroupsQuery query);
+ int countByQuery(@Param("query") SearchPermissionQuery query);
}
*/
package org.sonar.db.qualitygate;
+import java.util.List;
import javax.annotation.Nullable;
import org.sonar.api.utils.System2;
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
+import org.sonar.db.Pagination;
+import org.sonar.db.user.SearchPermissionQuery;
+import org.sonar.db.user.SearchUserMembershipDto;
import org.sonar.db.user.UserDto;
public class QualityGateUserPermissionsDao implements Dao {
mapper(dbSession).insert(dto, system2.now());
}
+ public List<SearchUserMembershipDto> selectByQuery(DbSession dbSession, SearchPermissionQuery query, Pagination pagination) {
+ return mapper(dbSession).selectByQuery(query, pagination);
+ }
+
+ public int countByQuery(DbSession dbSession, SearchPermissionQuery query) {
+ return mapper(dbSession).countByQuery(query);
+ }
+
private static QualityGateUserPermissionsMapper mapper(DbSession dbSession) {
return dbSession.getMapper(QualityGateUserPermissionsMapper.class);
}
*/
package org.sonar.db.qualitygate;
+import java.util.List;
import org.apache.ibatis.annotations.Param;
+import org.sonar.db.Pagination;
+import org.sonar.db.user.SearchPermissionQuery;
+import org.sonar.db.user.SearchUserMembershipDto;
public interface QualityGateUserPermissionsMapper {
void insert(@Param("dto") QualityGateUserPermissionsDto dto, @Param("now") long now);
+ List<SearchUserMembershipDto> selectByQuery(@Param("query") SearchPermissionQuery query, @Param("pagination") Pagination pagination);
+
+ int countByQuery(@Param("query") SearchPermissionQuery query);
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.db.qualitygate;
-
-import java.util.Locale;
-import org.sonar.db.user.SearchGroupsQuery;
-
-import static org.sonar.db.DaoUtils.buildLikeValue;
-import static org.sonar.db.WildcardPosition.BEFORE_AND_AFTER;
-
-public class SearchQualityGateGroupsQuery extends SearchGroupsQuery {
-
- private final String qualityGateUuid;
-
- public SearchQualityGateGroupsQuery(Builder builder) {
- this.qualityGateUuid = builder.qualityGate.getUuid();
- this.query = builder.getQuery();
- this.membership = builder.getMembership();
- this.querySqlLowercase = query == null ? null : buildLikeValue(query, BEFORE_AND_AFTER).toLowerCase(Locale.ENGLISH);
- }
-
- public String getQualityGateUuid() {
- return qualityGateUuid;
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder extends SearchGroupsQuery.Builder<Builder> {
- private QualityGateDto qualityGate;
-
- public Builder setQualityGate(QualityGateDto qualityGate) {
- this.qualityGate = qualityGate;
- return this;
- }
-
- public SearchQualityGateGroupsQuery build() {
- initMembership();
- return new SearchQualityGateGroupsQuery(this);
- }
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.db.qualitygate;
+
+import java.util.Locale;
+import org.sonar.db.user.SearchPermissionQuery;
+
+import static java.util.Objects.requireNonNull;
+import static org.sonar.db.DaoUtils.buildLikeValue;
+import static org.sonar.db.WildcardPosition.BEFORE_AND_AFTER;
+
+public class SearchQualityGatePermissionQuery extends SearchPermissionQuery {
+
+ private final String qualityGateUuid;
+
+ public SearchQualityGatePermissionQuery(Builder builder) {
+ this.qualityGateUuid = builder.qualityGate.getUuid();
+ this.query = builder.getQuery();
+ this.membership = builder.getMembership();
+ this.querySql = query == null ? null : buildLikeValue(query, BEFORE_AND_AFTER);
+ this.querySqlLowercase = querySql == null ? null : querySql.toLowerCase(Locale.ENGLISH);
+ }
+
+ public String getQualityGateUuid() {
+ return qualityGateUuid;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder extends SearchPermissionQuery.Builder<Builder> {
+ private QualityGateDto qualityGate;
+
+ public Builder setQualityGate(QualityGateDto qualityGate) {
+ this.qualityGate = qualityGate;
+ return this;
+ }
+
+ public SearchQualityGatePermissionQuery build() {
+ requireNonNull(qualityGate, "Quality gate cant be null.");
+ initMembership();
+ return new SearchQualityGatePermissionQuery(this);
+ }
+ }
+}
.isEmpty();
}
- public int countByQuery(DbSession dbSession, SearchQualityProfileGroupsQuery query) {
+ public int countByQuery(DbSession dbSession, SearchQualityProfilePermissionQuery query) {
return mapper(dbSession).countByQuery(query);
}
- public List<SearchGroupMembershipDto> selectByQuery(DbSession dbSession, SearchQualityProfileGroupsQuery query, Pagination pagination) {
+ public List<SearchGroupMembershipDto> selectByQuery(DbSession dbSession, SearchQualityProfilePermissionQuery query, Pagination pagination) {
return mapper(dbSession).selectByQuery(query, pagination);
}
List<QProfileEditGroupsDto> selectByQProfileAndGroups(@Param("qProfileUuid") String qProfileUuid, @Param("groupUuids") List<String> groupUuids);
- int countByQuery(@Param("query") SearchQualityProfileGroupsQuery query);
+ int countByQuery(@Param("query") SearchQualityProfilePermissionQuery query);
- List<SearchGroupMembershipDto> selectByQuery(@Param("query") SearchQualityProfileGroupsQuery query, @Param("pagination") Pagination pagination);
+ List<SearchGroupMembershipDto> selectByQuery(@Param("query") SearchQualityProfilePermissionQuery query, @Param("pagination") Pagination pagination);
List<String> selectQProfileUuidsByGroups(@Param("groupUuids") List<String> groupUuids);
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
import org.sonar.db.Pagination;
+import org.sonar.db.user.SearchUserMembershipDto;
import org.sonar.db.user.UserDto;
import static org.sonar.core.util.stream.MoreCollectors.toList;
return mapper(dbSession).selectByQProfileAndUser(profile.getKee(), user.getUuid()) != null;
}
- public int countByQuery(DbSession dbSession, SearchUsersQuery query) {
+ public int countByQuery(DbSession dbSession, SearchQualityProfilePermissionQuery query) {
return mapper(dbSession).countByQuery(query);
}
- public List<UserMembershipDto> selectByQuery(DbSession dbSession, SearchUsersQuery query, Pagination pagination) {
+ public List<SearchUserMembershipDto> selectByQuery(DbSession dbSession, SearchQualityProfilePermissionQuery query, Pagination pagination) {
return mapper(dbSession).selectByQuery(query, pagination);
}
- public List<String> selectQProfileUuidsByUser(DbSession dbSession,UserDto userDto) {
+ public List<String> selectQProfileUuidsByUser(DbSession dbSession, UserDto userDto) {
return mapper(dbSession).selectQProfileUuidsByUser(userDto.getUuid());
}
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.sonar.db.Pagination;
+import org.sonar.db.user.SearchUserMembershipDto;
public interface QProfileEditUsersMapper {
QProfileEditUsersDto selectByQProfileAndUser(@Param("qProfileUuid") String qProfileUuid, @Param("userUuid") String userUuid);
- int countByQuery(@Param("query") SearchUsersQuery query);
+ int countByQuery(@Param("query") SearchQualityProfilePermissionQuery query);
- List<UserMembershipDto> selectByQuery(@Param("query") SearchUsersQuery query, @Param("pagination") Pagination pagination);
+ List<SearchUserMembershipDto> selectByQuery(@Param("query") SearchQualityProfilePermissionQuery query, @Param("pagination") Pagination pagination);
List<String> selectQProfileUuidsByUser(@Param("userUuid") String userUuid);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.db.qualityprofile;
-
-import java.util.Locale;
-import org.sonar.db.user.SearchGroupsQuery;
-
-import static org.sonar.db.DaoUtils.buildLikeValue;
-import static org.sonar.db.WildcardPosition.BEFORE_AND_AFTER;
-
-public class SearchQualityProfileGroupsQuery extends SearchGroupsQuery {
-
- private final String qProfileUuid;
-
- public SearchQualityProfileGroupsQuery(Builder builder) {
- this.qProfileUuid = builder.profile.getKee();
- this.query = builder.getQuery();
- this.membership = builder.getMembership();
- this.querySqlLowercase = query == null ? null : buildLikeValue(query, BEFORE_AND_AFTER).toLowerCase(Locale.ENGLISH);
- }
-
- public String getQProfileUuid() {
- return qProfileUuid;
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder extends SearchGroupsQuery.Builder<Builder> {
- private QProfileDto profile;
-
- public Builder setProfile(QProfileDto profile) {
- this.profile = profile;
- return this;
- }
-
- public SearchQualityProfileGroupsQuery build() {
- initMembership();
- return new SearchQualityProfileGroupsQuery(this);
- }
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.db.qualityprofile;
+
+import java.util.Locale;
+import org.sonar.db.user.SearchPermissionQuery;
+
+import static java.util.Objects.requireNonNull;
+import static org.sonar.db.DaoUtils.buildLikeValue;
+import static org.sonar.db.WildcardPosition.BEFORE_AND_AFTER;
+
+public class SearchQualityProfilePermissionQuery extends SearchPermissionQuery {
+
+ private final String qProfileUuid;
+
+ public SearchQualityProfilePermissionQuery(Builder builder) {
+ this.qProfileUuid = builder.profile.getKee();
+ this.query = builder.getQuery();
+ this.membership = builder.getMembership();
+ this.querySql = query == null ? null : buildLikeValue(query, BEFORE_AND_AFTER);
+ this.querySqlLowercase = querySql == null ? null : querySql.toLowerCase(Locale.ENGLISH);
+ }
+
+ public String getQProfileUuid() {
+ return qProfileUuid;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder extends SearchPermissionQuery.Builder<Builder> {
+ private QProfileDto profile;
+
+ public Builder setProfile(QProfileDto profile) {
+ this.profile = profile;
+ return this;
+ }
+
+ public SearchQualityProfilePermissionQuery build() {
+ requireNonNull(profile, "Quality profile cant be null.");
+ initMembership();
+ return new SearchQualityProfilePermissionQuery(this);
+ }
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.db.qualityprofile;
-
-import com.google.common.collect.ImmutableSet;
-import java.util.Locale;
-import java.util.Set;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.apache.commons.lang.StringUtils;
-
-import static com.google.common.base.MoreObjects.firstNonNull;
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNull;
-import static org.sonar.db.DaoUtils.buildLikeValue;
-import static org.sonar.db.WildcardPosition.BEFORE_AND_AFTER;
-
-public class SearchUsersQuery {
-
- public static final String ANY = "ANY";
- public static final String IN = "IN";
- public static final String OUT = "OUT";
- public static final Set<String> AVAILABLE_MEMBERSHIPS = ImmutableSet.of(ANY, IN, OUT);
-
- private final String qProfileUuid;
- private final String query;
- private final String membership;
-
- // for internal use in MyBatis
- final String querySql;
- final String querySqlLowercase;
-
- private SearchUsersQuery(Builder builder) {
- this.qProfileUuid = builder.profile.getKee();
- this.query = builder.query;
- this.membership = builder.membership;
- this.querySql = query == null ? null : buildLikeValue(query, BEFORE_AND_AFTER);
- this.querySqlLowercase = querySql == null ? null : querySql.toLowerCase(Locale.ENGLISH);
- }
-
- public String getQProfileUuid() {
- return qProfileUuid;
- }
-
- public String getMembership() {
- return membership;
- }
-
- @CheckForNull
- public String getQuery() {
- return query;
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
- private QProfileDto profile;
- private String query;
- private String membership;
-
- private Builder() {
- }
-
- public Builder setProfile(QProfileDto profile) {
- this.profile = profile;
- return this;
- }
-
- public Builder setMembership(@Nullable String membership) {
- this.membership = membership;
- return this;
- }
-
- public Builder setQuery(@Nullable String s) {
- this.query = StringUtils.defaultIfBlank(s, null);
- return this;
- }
-
- private void initMembership() {
- membership = firstNonNull(membership, ANY);
- checkArgument(AVAILABLE_MEMBERSHIPS.contains(membership),
- "Membership is not valid (got " + membership + "). Availables values are " + AVAILABLE_MEMBERSHIPS);
- }
-
- public SearchUsersQuery build() {
- requireNonNull(profile, "Quality profile cant be null.");
- initMembership();
- return new SearchUsersQuery(this);
- }
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.db.qualityprofile;
-
-public class UserMembershipDto {
-
- private String userUuid;
- // Set by MyBatis
- private String uuid;
-
- public String getUserUuid() {
- return userUuid;
- }
-
- public UserMembershipDto setUserUuid(String userUuid) {
- this.userUuid = userUuid;
- return this;
- }
-
- public boolean isSelected() {
- return uuid != null;
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 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.db.user;
-
-import java.util.Set;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.apache.commons.lang.StringUtils;
-
-import static com.google.common.base.MoreObjects.firstNonNull;
-import static com.google.common.base.Preconditions.checkArgument;
-
-public abstract class SearchGroupsQuery {
-
- public static final String ANY = "ANY";
- public static final String IN = "IN";
- public static final String OUT = "OUT";
- public static final Set<String> AVAILABLE_MEMBERSHIPS = Set.of(ANY, IN, OUT);
-
- protected String query;
- protected String membership;
-
- // for internal use in MyBatis
- protected String querySqlLowercase;
-
- public String getMembership() {
- return membership;
- }
-
- @CheckForNull
- public String getQuery() {
- return query;
- }
-
- public abstract static class Builder<T extends Builder<T>> {
- private String query;
- private String membership;
-
- public String getQuery(){
- return query;
- }
-
- public T setQuery(@Nullable String s) {
- this.query = StringUtils.defaultIfBlank(s, null);
- return self();
- }
-
- public String getMembership(){
- return membership;
- }
-
- public T setMembership(@Nullable String membership) {
- this.membership = membership;
- return self();
- }
-
- public void initMembership() {
- membership = firstNonNull(membership, ANY);
- checkArgument(AVAILABLE_MEMBERSHIPS.contains(membership),
- "Membership is not valid (got " + membership + "). Availables values are " + AVAILABLE_MEMBERSHIPS);
- }
-
- @SuppressWarnings("unchecked")
- final T self() {
- return (T) this;
- }
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.db.user;
+
+import java.util.Set;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.apache.commons.lang.StringUtils;
+
+import static com.google.common.base.MoreObjects.firstNonNull;
+import static com.google.common.base.Preconditions.checkArgument;
+
+public abstract class SearchPermissionQuery {
+
+ public static final String ANY = "ANY";
+ public static final String IN = "IN";
+ public static final String OUT = "OUT";
+ public static final Set<String> AVAILABLE_MEMBERSHIPS = Set.of(ANY, IN, OUT);
+
+ protected String query;
+ protected String membership;
+
+ // for internal use in MyBatis
+ protected String querySql;
+ protected String querySqlLowercase;
+
+ public String getMembership() {
+ return membership;
+ }
+
+ @CheckForNull
+ public String getQuery() {
+ return query;
+ }
+
+ public abstract static class Builder<T extends Builder<T>> {
+ private String query;
+ private String membership;
+
+ public String getQuery(){
+ return query;
+ }
+
+ public T setQuery(@Nullable String s) {
+ this.query = StringUtils.defaultIfBlank(s, null);
+ return self();
+ }
+
+ public String getMembership(){
+ return membership;
+ }
+
+ public T setMembership(@Nullable String membership) {
+ this.membership = membership;
+ return self();
+ }
+
+ public void initMembership() {
+ membership = firstNonNull(membership, ANY);
+ checkArgument(AVAILABLE_MEMBERSHIPS.contains(membership),
+ "Membership is not valid (got " + membership + "). Availables values are " + AVAILABLE_MEMBERSHIPS);
+ }
+
+ @SuppressWarnings("unchecked")
+ final T self() {
+ return (T) this;
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.db.user;
+
+public class SearchUserMembershipDto {
+
+ private String userUuid;
+ // Set by MyBatis
+ private String uuid;
+
+ public SearchUserMembershipDto() {
+ // Do nothing
+ }
+
+ public String getUserUuid() {
+ return userUuid;
+ }
+
+ public SearchUserMembershipDto setUserUuid(String userUuid) {
+ this.userUuid = userUuid;
+ return this;
+ }
+
+ public boolean isSelected() {
+ return uuid != null;
+ }
+
+}
)
</insert>
+ <select id="countByQuery" resultType="int">
+ select count(u.uuid)
+ <include refid="sqlSelectByQuery"/>
+ </select>
+
+ <select id="selectByQuery" parameterType="map" resultType="org.sonar.db.user.SearchUserMembershipDto">
+ SELECT u.uuid as userUuid, u.name as name, qup.uuid as uuid
+ <include refid="sqlSelectByQuery"/>
+ ORDER BY u.name ASC
+ LIMIT #{pagination.pageSize,jdbcType=INTEGER}
+ OFFSET #{pagination.offset,jdbcType=INTEGER}
+ </select>
+
+ <select id="selectByQuery" parameterType="map" resultType="org.sonar.db.user.SearchUserMembershipDto"
+ databaseId="mssql">
+ select * from (
+ select row_number() over(order by u.name asc) as number,
+ u.uuid as userUuid, u.name as name, qup.uuid as uuid
+ <include refid="sqlSelectByQuery"/>
+ ) as query
+ where
+ query.number between #{pagination.startRowNumber,jdbcType=INTEGER} and #{pagination.endRowNumber,jdbcType=INTEGER}
+ order by query.name asc
+ </select>
+
+ <select id="selectByQuery" parameterType="map" resultType="org.sonar.db.user.SearchUserMembershipDto"
+ databaseId="oracle">
+ select * from (
+ select rownum as rn, t.* from (
+ select u.uuid as userUuid, u.name as name, qup.uuid as uuid
+ <include refid="sqlSelectByQuery"/>
+ order by u.name ASC
+ ) t
+ ) t
+ where
+ t.rn between #{pagination.startRowNumber,jdbcType=INTEGER} and #{pagination.endRowNumber,jdbcType=INTEGER}
+ </select>
+
+ <sql id="sqlSelectByQuery">
+ FROM users u
+ LEFT JOIN qgate_user_permissions qup ON qup.user_uuid=u.uuid AND
+ qup.quality_gate_uuid=#{query.qualityGateUuid, jdbcType=VARCHAR}
+ <where>
+ <choose>
+ <when test="query.getMembership() == 'IN'">
+ AND qup.uuid IS NOT NULL
+ </when>
+ <when test="query.getMembership() == 'OUT'">
+ AND qup.uuid IS NULL
+ </when>
+ </choose>
+ <if test="query.getQuery() != null">
+ AND (
+ lower(u.name) like #{query.querySqlLowercase} ESCAPE '/'
+ or u.login like #{query.querySql} ESCAPE '/')
+ </if>
+ AND u.active=${_true}
+ </where>
+ </sql>
</mapper>
<include refid="sqlSelectByQuery" />
</select>
- <select id="selectByQuery" parameterType="map" resultType="org.sonar.db.qualityprofile.UserMembershipDto">
+ <select id="selectByQuery" parameterType="map" resultType="org.sonar.db.user.SearchUserMembershipDto">
SELECT u.uuid as userUuid, u.name as name, qeu.uuid as uuid
<include refid="sqlSelectByQuery"/>
ORDER BY u.name ASC
OFFSET #{pagination.offset,jdbcType=INTEGER}
</select>
- <select id="selectByQuery" parameterType="map" resultType="org.sonar.db.qualityprofile.UserMembershipDto" databaseId="mssql">
+ <select id="selectByQuery" parameterType="map" resultType="org.sonar.db.user.SearchUserMembershipDto"
+ databaseId="mssql">
select * from (
select row_number() over(order by u.name asc) as number,
- u.uuid as userUuid, u.name as name, qeu.uuid as uuid
- <include refid="sqlSelectByQuery" />
+ u.uuid as userUuid, u.name as name, qeu.uuid as uuid
+ <include refid="sqlSelectByQuery"/>
) as query
where
query.number between #{pagination.startRowNumber,jdbcType=INTEGER} and #{pagination.endRowNumber,jdbcType=INTEGER}
order by query.name asc
</select>
- <select id="selectByQuery" parameterType="map" resultType="org.sonar.db.qualityprofile.UserMembershipDto" databaseId="oracle">
+ <select id="selectByQuery" parameterType="map" resultType="org.sonar.db.user.SearchUserMembershipDto"
+ databaseId="oracle">
select * from (
- select rownum as rn, t.* from (
- select u.uuid as userUuid, u.name as name, qeu.uuid as uuid
- <include refid="sqlSelectByQuery"/>
- order by u.name ASC
- ) t
+ select rownum as rn, t.* from (
+ select u.uuid as userUuid, u.name as name, qeu.uuid as uuid
+ <include refid="sqlSelectByQuery"/>
+ order by u.name ASC
+ ) t
) t
where
t.rn between #{pagination.startRowNumber,jdbcType=INTEGER} and #{pagination.endRowNumber,jdbcType=INTEGER}
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
-import static org.sonar.db.qualitygate.SearchQualityGateGroupsQuery.builder;
-import static org.sonar.db.user.SearchGroupsQuery.ANY;
-import static org.sonar.db.user.SearchGroupsQuery.IN;
-import static org.sonar.db.user.SearchGroupsQuery.OUT;
+import static org.sonar.db.qualitygate.SearchQualityGatePermissionQuery.builder;
+import static org.sonar.db.user.SearchPermissionQuery.ANY;
+import static org.sonar.db.user.SearchPermissionQuery.IN;
+import static org.sonar.db.user.SearchPermissionQuery.OUT;
public class QualityGateGroupPermissionsDaoTest {
import org.sonar.api.utils.System2;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
+import org.sonar.db.Pagination;
+import org.sonar.db.user.SearchUserMembershipDto;
import org.sonar.db.user.UserDbTester;
import org.sonar.db.user.UserDto;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+import static org.sonar.db.qualitygate.SearchQualityGatePermissionQuery.builder;
+import static org.sonar.db.user.SearchPermissionQuery.ANY;
+import static org.sonar.db.user.SearchPermissionQuery.IN;
+import static org.sonar.db.user.SearchPermissionQuery.OUT;
public class QualityGateUserPermissionsDaoTest {
@Rule
@Test
public void exist() {
- UserDto user = userDbTester.insertUser();
+ UserDto user1 = userDbTester.insertUser();
+ UserDto user2 = userDbTester.insertUser();
QualityGateDto qualityGate = qualityGateDbTester.insertQualityGate();
- QualityGateUserPermissionsDto qualityGateUserPermissions = new QualityGateUserPermissionsDto("uuid", user.getUuid(), qualityGate.getUuid());
+ QualityGateUserPermissionsDto qualityGateUserPermissions = new QualityGateUserPermissionsDto("uuid", user1.getUuid(), qualityGate.getUuid());
underTest.insert(dbSession, qualityGateUserPermissions);
dbSession.commit();
- assertThat(underTest.exists(dbSession, qualityGate.getUuid(), user.getUuid())).isTrue();
- assertThat(underTest.exists(dbSession, qualityGate, user)).isTrue();
+ assertThat(underTest.exists(dbSession, qualityGate.getUuid(), user1.getUuid())).isTrue();
+ assertThat(underTest.exists(dbSession, qualityGate, user1)).isTrue();
+ assertThat(underTest.exists(dbSession, qualityGate.getUuid(), user2.getUuid())).isFalse();
+ assertThat(underTest.exists(dbSession, qualityGate, user2)).isFalse();
+ }
+
+ @Test
+ public void exist_can_handle_null_param_and_return_false() {
+ assertThat(underTest.exists(dbSession, "uuid", null)).isFalse();
+ assertThat(underTest.exists(dbSession, null, "uuid")).isFalse();
+ }
+
+ @Test
+ public void countByQuery() {
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
+ UserDto user1 = db.users().insertUser();
+ UserDto user2 = db.users().insertUser();
+ UserDto user3 = db.users().insertUser();
+ db.qualityGates().addUserPermission(qualityGate, user1);
+ db.qualityGates().addUserPermission(qualityGate, user2);
+
+ assertThat(underTest.countByQuery(db.getSession(), builder()
+ .setQualityGate(qualityGate)
+ .setMembership(ANY).build()))
+ .isEqualTo(3);
+
+ assertThat(underTest.countByQuery(db.getSession(), builder()
+ .setQualityGate(qualityGate)
+ .setMembership(IN).build()))
+ .isEqualTo(2);
+
+ assertThat(underTest.countByQuery(db.getSession(), builder()
+ .setQualityGate(qualityGate)
+ .setMembership(OUT).build()))
+ .isEqualTo(1);
+ }
+
+ @Test
+ public void selectByQuery() {
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
+ UserDto user1 = db.users().insertUser();
+ UserDto user2 = db.users().insertUser();
+ UserDto user3 = db.users().insertUser();
+ db.qualityGates().addUserPermission(qualityGate, user1);
+ db.qualityGates().addUserPermission(qualityGate, user2);
+
+ assertThat(underTest.selectByQuery(db.getSession(), builder()
+ .setQualityGate(qualityGate)
+ .setMembership(ANY).build(), Pagination.all()))
+ .extracting(SearchUserMembershipDto::getUserUuid, SearchUserMembershipDto::isSelected)
+ .containsExactlyInAnyOrder(
+ tuple(user1.getUuid(), true),
+ tuple(user2.getUuid(), true),
+ tuple(user3.getUuid(), false));
+
+ assertThat(underTest.selectByQuery(db.getSession(), builder()
+ .setQualityGate(qualityGate)
+ .setMembership(IN).build(),
+ Pagination.all()))
+ .extracting(SearchUserMembershipDto::getUserUuid, SearchUserMembershipDto::isSelected)
+ .containsExactlyInAnyOrder(tuple(user1.getUuid(), true), tuple(user2.getUuid(), true));
+
+ assertThat(underTest.selectByQuery(db.getSession(), builder()
+ .setQualityGate(qualityGate)
+ .setMembership(OUT).build(),
+ Pagination.all()))
+ .extracting(SearchUserMembershipDto::getUserUuid, SearchUserMembershipDto::isSelected)
+ .containsExactlyInAnyOrder(tuple(user3.getUuid(), false));
+ }
+
+ @Test
+ public void selectByQuery_search_by_name_or_login() {
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
+ UserDto user1 = db.users().insertUser(u -> u.setLogin("user1").setName("John Doe"));
+ UserDto user2 = db.users().insertUser(u -> u.setLogin("user2").setName("John Smith"));
+ UserDto user3 = db.users().insertUser(u -> u.setLogin("user3").setName("Jane Doe"));
+ db.qualityGates().addUserPermission(qualityGate, user1);
+ db.qualityGates().addUserPermission(qualityGate, user2);
+ db.qualityGates().addUserPermission(qualityGate, user3);
+
+ assertThat(underTest.selectByQuery(db.getSession(), builder()
+ .setQualityGate(qualityGate)
+ .setMembership(IN)
+ .setQuery("user2").build(),
+ Pagination.all()))
+ .extracting(SearchUserMembershipDto::getUserUuid)
+ .containsExactlyInAnyOrder(user2.getUuid());
+
+ assertThat(underTest.selectByQuery(db.getSession(), builder()
+ .setQualityGate(qualityGate)
+ .setMembership(IN)
+ .setQuery("joh").build(),
+ Pagination.all()))
+ .extracting(SearchUserMembershipDto::getUserUuid)
+ .containsExactlyInAnyOrder(user1.getUuid(), user2.getUuid());
+
+ assertThat(underTest.selectByQuery(db.getSession(), builder()
+ .setQualityGate(qualityGate)
+ .setMembership(IN)
+ .setQuery("Doe").build(),
+ Pagination.all()))
+ .extracting(SearchUserMembershipDto::getUserUuid)
+ .containsExactlyInAnyOrder(user1.getUuid(), user3.getUuid());
+ }
+
+ @Test
+ public void selectByQuery_with_paging() {
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
+ UserDto user1 = db.users().insertUser(u -> u.setName("user1"));
+ UserDto user2 = db.users().insertUser(u -> u.setName("user2"));
+ UserDto user3 = db.users().insertUser(u -> u.setName("user3"));
+ db.qualityGates().addUserPermission(qualityGate, user1);
+ db.qualityGates().addUserPermission(qualityGate, user2);
+
+ assertThat(underTest.selectByQuery(db.getSession(), builder()
+ .setQualityGate(qualityGate)
+ .setMembership(ANY)
+ .build(),
+ Pagination.forPage(1).andSize(1)))
+ .extracting(SearchUserMembershipDto::getUserUuid)
+ .containsExactly(user1.getUuid());
+
+ assertThat(underTest.selectByQuery(db.getSession(), builder()
+ .setQualityGate(qualityGate)
+ .setMembership(ANY)
+ .build(),
+ Pagination.forPage(3).andSize(1)))
+ .extracting(SearchUserMembershipDto::getUserUuid)
+ .containsExactly(user3.getUuid());
+
+ assertThat(underTest.selectByQuery(db.getSession(), builder()
+ .setQualityGate(qualityGate)
+ .setMembership(ANY)
+ .build(),
+ Pagination.forPage(1).andSize(10)))
+ .extracting(SearchUserMembershipDto::getUserUuid)
+ .containsExactly(user1.getUuid(), user2.getUuid(), user3.getUuid());
}
}
\ No newline at end of file
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.assertj.core.api.Assertions.tuple;
-import static org.sonar.db.qualityprofile.SearchQualityProfileGroupsQuery.ANY;
-import static org.sonar.db.qualityprofile.SearchQualityProfileGroupsQuery.IN;
-import static org.sonar.db.qualityprofile.SearchQualityProfileGroupsQuery.OUT;
-import static org.sonar.db.qualityprofile.SearchQualityProfileGroupsQuery.builder;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.ANY;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.IN;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.OUT;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.builder;
public class QProfileEditGroupsDaoTest {
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
import org.sonar.db.Pagination;
+import org.sonar.db.user.SearchUserMembershipDto;
import org.sonar.db.user.UserDto;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.assertj.core.api.Assertions.tuple;
-import static org.sonar.db.qualityprofile.SearchUsersQuery.ANY;
-import static org.sonar.db.qualityprofile.SearchUsersQuery.IN;
-import static org.sonar.db.qualityprofile.SearchUsersQuery.OUT;
-import static org.sonar.db.qualityprofile.SearchUsersQuery.builder;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.ANY;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.IN;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.OUT;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.builder;
import static org.sonar.test.ExceptionCauseMatcher.hasType;
public class QProfileEditUsersDaoTest {
assertThat(underTest.selectByQuery(db.getSession(), builder()
.setProfile(profile)
.setMembership(ANY).build(), Pagination.all()))
- .extracting(UserMembershipDto::getUserUuid, UserMembershipDto::isSelected)
+ .extracting(SearchUserMembershipDto::getUserUuid, SearchUserMembershipDto::isSelected)
.containsExactlyInAnyOrder(
tuple(user1.getUuid(), true),
tuple(user2.getUuid(), true),
tuple(user3.getUuid(), false));
assertThat(underTest.selectByQuery(db.getSession(), builder()
- .setProfile(profile)
- .setMembership(IN).build(),
+ .setProfile(profile)
+ .setMembership(IN).build(),
Pagination.all()))
- .extracting(UserMembershipDto::getUserUuid, UserMembershipDto::isSelected)
+ .extracting(SearchUserMembershipDto::getUserUuid, SearchUserMembershipDto::isSelected)
.containsExactlyInAnyOrder(tuple(user1.getUuid(), true), tuple(user2.getUuid(), true));
assertThat(underTest.selectByQuery(db.getSession(), builder()
- .setProfile(profile)
- .setMembership(OUT).build(),
+ .setProfile(profile)
+ .setMembership(OUT).build(),
Pagination.all()))
- .extracting(UserMembershipDto::getUserUuid, UserMembershipDto::isSelected)
+ .extracting(SearchUserMembershipDto::getUserUuid, SearchUserMembershipDto::isSelected)
.containsExactlyInAnyOrder(tuple(user3.getUuid(), false));
}
db.qualityProfiles().addUserPermission(profile, user3);
assertThat(underTest.selectByQuery(db.getSession(), builder()
- .setProfile(profile)
- .setMembership(IN)
- .setQuery("user2").build(),
+ .setProfile(profile)
+ .setMembership(IN)
+ .setQuery("user2").build(),
Pagination.all()))
- .extracting(UserMembershipDto::getUserUuid)
+ .extracting(SearchUserMembershipDto::getUserUuid)
.containsExactlyInAnyOrder(user2.getUuid());
assertThat(underTest.selectByQuery(db.getSession(), builder()
- .setProfile(profile)
- .setMembership(IN)
- .setQuery("joh").build(),
+ .setProfile(profile)
+ .setMembership(IN)
+ .setQuery("joh").build(),
Pagination.all()))
- .extracting(UserMembershipDto::getUserUuid)
+ .extracting(SearchUserMembershipDto::getUserUuid)
.containsExactlyInAnyOrder(user1.getUuid(), user2.getUuid());
assertThat(underTest.selectByQuery(db.getSession(), builder()
- .setProfile(profile)
- .setMembership(IN)
- .setQuery("Doe").build(),
+ .setProfile(profile)
+ .setMembership(IN)
+ .setQuery("Doe").build(),
Pagination.all()))
- .extracting(UserMembershipDto::getUserUuid)
+ .extracting(SearchUserMembershipDto::getUserUuid)
.containsExactlyInAnyOrder(user1.getUuid(), user3.getUuid());
}
db.qualityProfiles().addUserPermission(profile, user2);
assertThat(underTest.selectByQuery(db.getSession(), builder()
- .setProfile(profile)
- .setMembership(ANY)
- .build(),
+ .setProfile(profile)
+ .setMembership(ANY)
+ .build(),
Pagination.forPage(1).andSize(1)))
- .extracting(UserMembershipDto::getUserUuid)
+ .extracting(SearchUserMembershipDto::getUserUuid)
.containsExactly(user1.getUuid());
assertThat(underTest.selectByQuery(db.getSession(), builder()
- .setProfile(profile)
- .setMembership(ANY)
- .build(),
+ .setProfile(profile)
+ .setMembership(ANY)
+ .build(),
Pagination.forPage(3).andSize(1)))
- .extracting(UserMembershipDto::getUserUuid)
+ .extracting(SearchUserMembershipDto::getUserUuid)
.containsExactly(user3.getUuid());
assertThat(underTest.selectByQuery(db.getSession(), builder()
- .setProfile(profile)
- .setMembership(ANY)
- .build(),
+ .setProfile(profile)
+ .setMembership(ANY)
+ .build(),
Pagination.forPage(1).andSize(10)))
- .extracting(UserMembershipDto::getUserUuid)
+ .extracting(SearchUserMembershipDto::getUserUuid)
.containsExactly(user1.getUuid(), user2.getUuid(), user3.getUuid());
}
ProjectStatusAction.class,
GetByProjectAction.class,
AddGroupAction.class,
- SearchGroupsAction.class
+ SearchGroupsAction.class,
+ SearchUsersAction.class
);
}
}
public static final String ACTION_ADD_GROUP = "add_group";
public static final String ACTION_ADD_USER = "add_user";
public static final String ACTION_SEARCH_GROUPS = "search_groups";
+ public static final String ACTION_SEARCH_USERS = "search_users";
public static final String PARAM_ANALYSIS_ID = "analysisId";
public static final String PARAM_BRANCH = "branch";
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.qualitygate.QualityGateDto;
-import org.sonar.db.user.SearchGroupMembershipDto;
-import org.sonar.db.user.SearchGroupsQuery;
import org.sonar.db.user.GroupDto;
+import org.sonar.db.user.SearchGroupMembershipDto;
+import org.sonar.db.user.SearchPermissionQuery;
import org.sonarqube.ws.Common;
import org.sonarqube.ws.Qualitygates;
import static org.sonar.api.server.ws.WebService.SelectionMode.fromParam;
import static org.sonar.core.util.stream.MoreCollectors.toList;
import static org.sonar.db.Pagination.forPage;
-import static org.sonar.db.qualitygate.SearchQualityGateGroupsQuery.builder;
-import static org.sonar.db.user.SearchGroupsQuery.ANY;
-import static org.sonar.db.user.SearchGroupsQuery.IN;
-import static org.sonar.db.user.SearchGroupsQuery.OUT;
+import static org.sonar.db.qualitygate.SearchQualityGatePermissionQuery.builder;
+import static org.sonar.db.user.SearchPermissionQuery.ANY;
+import static org.sonar.db.user.SearchPermissionQuery.IN;
+import static org.sonar.db.user.SearchPermissionQuery.OUT;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.ACTION_SEARCH_GROUPS;
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_GATE_NAME;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
QualityGateDto gate = wsSupport.getByName(dbSession, wsRequest.getQualityGate());
wsSupport.checkCanLimitedEdit(dbSession, gate);
- SearchGroupsQuery query = builder()
+ SearchPermissionQuery query = builder()
.setQualityGate(gate)
.setQuery(wsRequest.getQuery())
.setMembership(MEMBERSHIP.get(fromParam(wsRequest.getSelected())))
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.qualitygate.ws;
+
+import java.util.List;
+import java.util.Map;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.server.ws.WebService.SelectionMode;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.qualitygate.QualityGateDto;
+import org.sonar.db.user.SearchPermissionQuery;
+import org.sonar.db.user.SearchUserMembershipDto;
+import org.sonar.db.user.UserDto;
+import org.sonar.server.issue.AvatarResolver;
+import org.sonarqube.ws.Common;
+import org.sonarqube.ws.Qualitygates.SearchUsersResponse;
+
+import static com.google.common.base.Strings.emptyToNull;
+import static java.util.Optional.ofNullable;
+import static org.sonar.api.server.ws.WebService.Param.PAGE;
+import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
+import static org.sonar.api.server.ws.WebService.Param.SELECTED;
+import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
+import static org.sonar.api.server.ws.WebService.SelectionMode.ALL;
+import static org.sonar.api.server.ws.WebService.SelectionMode.DESELECTED;
+import static org.sonar.api.server.ws.WebService.SelectionMode.fromParam;
+import static org.sonar.core.util.stream.MoreCollectors.toList;
+import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;
+import static org.sonar.db.Pagination.forPage;
+import static org.sonar.db.qualitygate.SearchQualityGatePermissionQuery.builder;
+import static org.sonar.db.user.SearchPermissionQuery.ANY;
+import static org.sonar.db.user.SearchPermissionQuery.IN;
+import static org.sonar.db.user.SearchPermissionQuery.OUT;
+import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.ACTION_SEARCH_USERS;
+import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_GATE_NAME;
+import static org.sonar.server.ws.WsUtils.writeProtobuf;
+
+public class SearchUsersAction implements QualityGatesWsAction {
+
+ private static final Map<SelectionMode, String> MEMBERSHIP = Map.of(SelectionMode.SELECTED, IN, DESELECTED, OUT, ALL, ANY);
+
+ private final DbClient dbClient;
+ private final QualityGatesWsSupport wsSupport;
+ private final AvatarResolver avatarResolver;
+
+ public SearchUsersAction(DbClient dbClient, QualityGatesWsSupport wsSupport, AvatarResolver avatarResolver) {
+ this.dbClient = dbClient;
+ this.wsSupport = wsSupport;
+ this.avatarResolver = avatarResolver;
+ }
+
+ @Override
+ public void define(WebService.NewController context) {
+ WebService.NewAction action = context
+ .createAction(ACTION_SEARCH_USERS)
+ .setDescription("List the users that are allowed to edit a Quality Gate.<br>" +
+ "Requires one of the following permissions:" +
+ "<ul>" +
+ " <li>'Administer Quality Gates'</li>" +
+ " <li>Edit right on the specified quality gate</li>" +
+ "</ul>")
+ .setHandler(this)
+ .setInternal(true)
+ .addSearchQuery("freddy", "names", "logins")
+ .addSelectionModeParam()
+ .addPagingParams(25)
+ .setResponseExample(getClass().getResource("search_users-example.json"))
+ .setSince("9.2");
+
+ action.createParam(PARAM_GATE_NAME)
+ .setDescription("Quality Gate name")
+ .setRequired(true)
+ .setExampleValue("Recommended quality gate");
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ SearchQualityGateUsersRequest wsRequest = buildRequest(request);
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ QualityGateDto gate = wsSupport.getByName(dbSession, wsRequest.getQualityGate());
+ wsSupport.checkCanLimitedEdit(dbSession, gate);
+
+ SearchPermissionQuery query = builder()
+ .setQualityGate(gate)
+ .setQuery(wsRequest.getQuery())
+ .setMembership(MEMBERSHIP.get(fromParam(wsRequest.getSelected())))
+ .build();
+ int total = dbClient.qualityGateUserPermissionDao().countByQuery(dbSession, query);
+ List<SearchUserMembershipDto> usersMembership = dbClient.qualityGateUserPermissionDao().selectByQuery(dbSession, query,
+ forPage(wsRequest.getPage()).andSize(wsRequest.getPageSize()));
+ Map<String, UserDto> usersById = dbClient.userDao().selectByUuids(dbSession, usersMembership.stream().map(SearchUserMembershipDto::getUserUuid).collect(toList()))
+ .stream().collect(uniqueIndex(UserDto::getUuid));
+ writeProtobuf(
+ SearchUsersResponse.newBuilder()
+ .addAllUsers(usersMembership.stream()
+ .map(userMembershipDto -> toUser(usersById.get(userMembershipDto.getUserUuid()), userMembershipDto.isSelected()))
+ .collect(toList()))
+ .setPaging(buildPaging(wsRequest, total)).build(),
+ request, response);
+ }
+ }
+
+ private static SearchQualityGateUsersRequest buildRequest(Request request) {
+ return SearchQualityGateUsersRequest.builder()
+ .setQualityGate(request.mandatoryParam(PARAM_GATE_NAME))
+ .setQuery(request.param(TEXT_QUERY))
+ .setSelected(request.mandatoryParam(SELECTED))
+ .setPage(request.mandatoryParamAsInt(PAGE))
+ .setPageSize(request.mandatoryParamAsInt(PAGE_SIZE))
+ .build();
+ }
+
+ private SearchUsersResponse.User toUser(UserDto user, boolean isSelected) {
+ SearchUsersResponse.User.Builder builder = SearchUsersResponse.User.newBuilder()
+ .setLogin(user.getLogin())
+ .setSelected(isSelected);
+ ofNullable(user.getName()).ifPresent(builder::setName);
+ ofNullable(emptyToNull(user.getEmail())).ifPresent(e -> builder.setAvatar(avatarResolver.create(user)));
+ return builder
+ .build();
+ }
+
+ private static Common.Paging buildPaging(SearchQualityGateUsersRequest wsRequest, int total) {
+ return Common.Paging.newBuilder()
+ .setPageIndex(wsRequest.getPage())
+ .setPageSize(wsRequest.getPageSize())
+ .setTotal(total)
+ .build();
+ }
+
+
+}
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.qualityprofile.QProfileDto;
-import org.sonar.db.qualityprofile.SearchQualityProfileGroupsQuery;
+import org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery;
import org.sonar.db.user.GroupDto;
import org.sonar.db.user.SearchGroupMembershipDto;
import org.sonarqube.ws.Common;
import static org.sonar.core.util.stream.MoreCollectors.toList;
import static org.sonar.core.util.stream.MoreCollectors.toSet;
import static org.sonar.db.Pagination.forPage;
-import static org.sonar.db.qualityprofile.SearchQualityProfileGroupsQuery.ANY;
-import static org.sonar.db.qualityprofile.SearchQualityProfileGroupsQuery.IN;
-import static org.sonar.db.qualityprofile.SearchQualityProfileGroupsQuery.OUT;
-import static org.sonar.db.qualityprofile.SearchQualityProfileGroupsQuery.builder;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.ANY;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.IN;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.OUT;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.builder;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_SEARCH_GROUPS;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE;
QProfileDto profile = wsSupport.getProfile(dbSession, wsRequest.getQualityProfile(), wsRequest.getLanguage());
wsSupport.checkCanEdit(dbSession, profile);
- SearchQualityProfileGroupsQuery query = builder()
+ SearchQualityProfilePermissionQuery query = builder()
.setProfile(profile)
.setQuery(wsRequest.getQuery())
.setMembership(MEMBERSHIP.get(fromParam(wsRequest.getSelected())))
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.qualityprofile.QProfileDto;
-import org.sonar.db.qualityprofile.SearchUsersQuery;
-import org.sonar.db.qualityprofile.UserMembershipDto;
+import org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery;
+import org.sonar.db.user.SearchUserMembershipDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.issue.AvatarResolver;
import org.sonarqube.ws.Common;
import static org.sonar.core.util.stream.MoreCollectors.toSet;
import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;
import static org.sonar.db.Pagination.forPage;
-import static org.sonar.db.qualityprofile.SearchUsersQuery.ANY;
-import static org.sonar.db.qualityprofile.SearchUsersQuery.IN;
-import static org.sonar.db.qualityprofile.SearchUsersQuery.OUT;
-import static org.sonar.db.qualityprofile.SearchUsersQuery.builder;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.ANY;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.IN;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.OUT;
+import static org.sonar.db.qualityprofile.SearchQualityProfilePermissionQuery.builder;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_SEARCH_USERS;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE;
QProfileDto profile = wsSupport.getProfile(dbSession, wsRequest.getQualityProfile(), wsRequest.getLanguage());
wsSupport.checkCanEdit(dbSession, profile);
- SearchUsersQuery query = builder()
+ SearchQualityProfilePermissionQuery query = builder()
.setProfile(profile)
.setQuery(wsRequest.getQuery())
.setMembership(MEMBERSHIP.get(fromParam(wsRequest.getSelected())))
.build();
int total = dbClient.qProfileEditUsersDao().countByQuery(dbSession, query);
- List<UserMembershipDto> usersMembership = dbClient.qProfileEditUsersDao().selectByQuery(dbSession, query,
+ List<SearchUserMembershipDto> usersMembership = dbClient.qProfileEditUsersDao().selectByQuery(dbSession, query,
forPage(wsRequest.getPage()).andSize(wsRequest.getPageSize()));
- Map<String, UserDto> usersById = dbClient.userDao().selectByUuids(dbSession, usersMembership.stream().map(UserMembershipDto::getUserUuid).collect(toList()))
+ Map<String, UserDto> usersById = dbClient.userDao().selectByUuids(dbSession, usersMembership.stream().map(SearchUserMembershipDto::getUserUuid).collect(toList()))
.stream().collect(uniqueIndex(UserDto::getUuid));
writeProtobuf(
SearchUsersResponse.newBuilder()
--- /dev/null
+{
+ "paging": {
+ "pageSize": 25,
+ "total": 2,
+ "pageIndex": 1
+ },
+ "users": [
+ {
+ "login": "admin",
+ "name": "Administrator",
+ "avatar": "59235f35e4763abb0b547bd093562f6e",
+ "selected": true
+ },
+ {
+ "login": "george.orwell",
+ "name": "George Orwell",
+ "avatar": "61a6fd6cba04e9394b35f349c9ca3380",
+ "selected": false
+ }
+ ]
+}
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new QualityGateWsModule().configure(container);
- assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 20);
+ assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 21);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.qualitygate.ws;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbTester;
+import org.sonar.db.qualitygate.QualityGateDto;
+import org.sonar.db.user.UserDto;
+import org.sonar.server.component.TestComponentFinder;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.issue.AvatarResolver;
+import org.sonar.server.issue.AvatarResolverImpl;
+import org.sonar.server.issue.FakeAvatarResolver;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.TestRequest;
+import org.sonar.server.ws.WsActionTester;
+import org.sonarqube.ws.Qualitygates.SearchUsersResponse;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.Assertions.tuple;
+import static org.sonar.api.server.ws.WebService.Param.PAGE;
+import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
+import static org.sonar.api.server.ws.WebService.Param.SELECTED;
+import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
+import static org.sonar.db.permission.GlobalPermission.ADMINISTER_QUALITY_GATES;
+import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_GATE_NAME;
+import static org.sonar.test.JsonAssert.assertJson;
+import static org.sonarqube.ws.MediaTypes.JSON;
+
+public class SearchUsersActionTest {
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+ @Rule
+ public DbTester db = DbTester.create();
+
+ private final QualityGatesWsSupport wsSupport = new QualityGatesWsSupport(db.getDbClient(), userSession, TestComponentFinder.from(db));
+ private AvatarResolver avatarResolver = new FakeAvatarResolver();
+
+ private WsActionTester ws = new WsActionTester(new SearchUsersAction(db.getDbClient(), wsSupport, avatarResolver));
+
+ @Test
+ public void test_definition() {
+ WebService.Action def = ws.getDef();
+ assertThat(def.key()).isEqualTo("search_users");
+ assertThat(def.isPost()).isFalse();
+ assertThat(def.isInternal()).isTrue();
+ assertThat(def.params()).extracting(WebService.Param::key)
+ .containsExactlyInAnyOrder("gateName", "selected", "q", "p", "ps");
+ }
+
+ @Test
+ public void test_example() {
+ avatarResolver = new AvatarResolverImpl();
+ ws = new WsActionTester(new SearchUsersAction(db.getDbClient(), wsSupport, avatarResolver));
+ QualityGateDto gate = db.qualityGates().insertQualityGate();
+ UserDto user1 = db.users().insertUser(u -> u.setLogin("admin").setName("Administrator").setEmail("admin@email.com"));
+ UserDto user2 = db.users().insertUser(u -> u.setLogin("george.orwell").setName("George Orwell").setEmail("george@orwell.com"));
+ db.qualityGates().addUserPermission(gate, user1);
+ userSession.logIn().addPermission(ADMINISTER_QUALITY_GATES);
+
+ String result = ws.newRequest()
+ .setParam(PARAM_GATE_NAME, gate.getName())
+ .setParam(SELECTED, "all")
+ .setMediaType(JSON)
+ .execute()
+ .getInput();
+
+ assertJson(result).isSimilarTo(ws.getDef().responseExampleAsString());
+ }
+
+ @Test
+ public void search_all_users() {
+ QualityGateDto gate = db.qualityGates().insertQualityGate();
+ UserDto user1 = db.users().insertUser(u -> u.setEmail("user1@email.com"));
+ UserDto user2 = db.users().insertUser(u -> u.setEmail("user2@email.com"));
+ db.qualityGates().addUserPermission(gate, user1);
+ userSession.logIn().addPermission(ADMINISTER_QUALITY_GATES);
+
+ SearchUsersResponse response = ws.newRequest()
+ .setParam(PARAM_GATE_NAME, gate.getName())
+ .setParam(SELECTED, "all")
+ .executeProtobuf(SearchUsersResponse.class);
+
+ assertThat(response.getUsersList())
+ .extracting(SearchUsersResponse.User::getLogin, SearchUsersResponse.User::getName, SearchUsersResponse.User::getAvatar, SearchUsersResponse.User::getSelected)
+ .containsExactlyInAnyOrder(
+ tuple(user1.getLogin(), user1.getName(), "user1@email.com_avatar", true),
+ tuple(user2.getLogin(), user2.getName(), "user2@email.com_avatar", false));
+ }
+
+ @Test
+ public void search_selected_users() {
+ QualityGateDto gate = db.qualityGates().insertQualityGate();
+ UserDto user1 = db.users().insertUser();
+ UserDto user2 = db.users().insertUser();
+ db.qualityGates().addUserPermission(gate, user1);
+ userSession.logIn().addPermission(ADMINISTER_QUALITY_GATES);
+
+ SearchUsersResponse response = ws.newRequest()
+ .setParam(PARAM_GATE_NAME, gate.getName())
+ .setParam(SELECTED, "selected")
+ .executeProtobuf(SearchUsersResponse.class);
+
+ assertThat(response.getUsersList()).extracting(SearchUsersResponse.User::getLogin, SearchUsersResponse.User::getName, SearchUsersResponse.User::getSelected)
+ .containsExactlyInAnyOrder(
+ tuple(user1.getLogin(), user1.getName(), true));
+ }
+
+ @Test
+ public void search_deselected_users() {
+ QualityGateDto gate = db.qualityGates().insertQualityGate();
+ UserDto user1 = db.users().insertUser();
+ UserDto user2 = db.users().insertUser();
+ db.qualityGates().addUserPermission(gate, user1);
+ userSession.logIn().addPermission(ADMINISTER_QUALITY_GATES);
+
+ SearchUsersResponse response = ws.newRequest()
+ .setParam(PARAM_GATE_NAME, gate.getName())
+ .setParam(SELECTED, "deselected")
+ .executeProtobuf(SearchUsersResponse.class);
+
+ assertThat(response.getUsersList()).extracting(SearchUsersResponse.User::getLogin, SearchUsersResponse.User::getName, SearchUsersResponse.User::getSelected)
+ .containsExactlyInAnyOrder(
+ tuple(user2.getLogin(), user2.getName(), false));
+ }
+
+ @Test
+ public void search_by_login() {
+ QualityGateDto gate = db.qualityGates().insertQualityGate();
+ UserDto user1 = db.users().insertUser();
+ UserDto user2 = db.users().insertUser();
+ db.qualityGates().addUserPermission(gate, user1);
+ userSession.logIn().addPermission(ADMINISTER_QUALITY_GATES);
+
+ SearchUsersResponse response = ws.newRequest()
+ .setParam(PARAM_GATE_NAME, gate.getName())
+ .setParam(TEXT_QUERY, user1.getLogin())
+ .setParam(SELECTED, "all")
+ .executeProtobuf(SearchUsersResponse.class);
+
+ assertThat(response.getUsersList()).extracting(SearchUsersResponse.User::getLogin)
+ .containsExactlyInAnyOrder(user1.getLogin());
+ }
+
+ @Test
+ public void search_by_name() {
+ QualityGateDto gate = db.qualityGates().insertQualityGate();
+ UserDto user1 = db.users().insertUser(u -> u.setName("John Doe"));
+ UserDto user2 = db.users().insertUser(u -> u.setName("Jane Doe"));
+ UserDto user3 = db.users().insertUser(u -> u.setName("John Smith"));
+ db.qualityGates().addUserPermission(gate, user1);
+ userSession.logIn().addPermission(ADMINISTER_QUALITY_GATES);
+
+ SearchUsersResponse response = ws.newRequest()
+ .setParam(PARAM_GATE_NAME, gate.getName())
+ .setParam(TEXT_QUERY, "ohn")
+ .setParam(SELECTED, "all")
+ .executeProtobuf(SearchUsersResponse.class);
+
+ assertThat(response.getUsersList()).extracting(SearchUsersResponse.User::getLogin)
+ .containsExactlyInAnyOrder(user1.getLogin(), user3.getLogin());
+ }
+
+ @Test
+ public void user_without_email() {
+ QualityGateDto gate = db.qualityGates().insertQualityGate();
+ UserDto user = db.users().insertUser(u -> u.setEmail(null));
+ db.qualityGates().addUserPermission(gate, user);
+ userSession.logIn().addPermission(ADMINISTER_QUALITY_GATES);
+
+ SearchUsersResponse response = ws.newRequest()
+ .setParam(PARAM_GATE_NAME, gate.getName())
+ .setParam(SELECTED, "all")
+ .executeProtobuf(SearchUsersResponse.class);
+
+ assertThat(response.getUsersList()).extracting(SearchUsersResponse.User::getLogin, SearchUsersResponse.User::hasAvatar)
+ .containsExactlyInAnyOrder(tuple(user.getLogin(), false));
+ }
+
+ @Test
+ public void paging_search() {
+ QualityGateDto gate = db.qualityGates().insertQualityGate();
+ UserDto user2 = db.users().insertUser(u -> u.setName("user2"));
+ UserDto user3 = db.users().insertUser(u -> u.setName("user3"));
+ UserDto user1 = db.users().insertUser(u -> u.setName("user1"));
+ db.qualityGates().addUserPermission(gate, user1);
+ db.qualityGates().addUserPermission(gate, user2);
+ userSession.logIn().addPermission(ADMINISTER_QUALITY_GATES);
+
+ assertThat(ws.newRequest()
+ .setParam(PARAM_GATE_NAME, gate.getName())
+ .setParam(SELECTED, "all")
+ .setParam(PAGE, "1")
+ .setParam(PAGE_SIZE, "1")
+ .executeProtobuf(SearchUsersResponse.class).getUsersList())
+ .extracting(SearchUsersResponse.User::getLogin)
+ .containsExactly(user1.getLogin());
+
+ assertThat(ws.newRequest()
+ .setParam(PARAM_GATE_NAME, gate.getName())
+ .setParam(SELECTED, "all")
+ .setParam(PAGE, "3")
+ .setParam(PAGE_SIZE, "1")
+ .executeProtobuf(SearchUsersResponse.class).getUsersList())
+ .extracting(SearchUsersResponse.User::getLogin)
+ .containsExactly(user3.getLogin());
+
+ assertThat(ws.newRequest()
+ .setParam(PARAM_GATE_NAME, gate.getName())
+ .setParam(SELECTED, "all")
+ .setParam(PAGE, "1")
+ .setParam(PAGE_SIZE, "10")
+ .executeProtobuf(SearchUsersResponse.class).getUsersList())
+ .extracting(SearchUsersResponse.User::getLogin)
+ .containsExactly(user1.getLogin(), user2.getLogin(), user3.getLogin());
+ }
+
+ @Test
+ public void uses_global_permission() {
+ QualityGateDto gate = db.qualityGates().insertQualityGate();
+ UserDto user1 = db.users().insertUser();
+ db.qualityGates().addUserPermission(gate, user1);
+ userSession.logIn().addPermission(ADMINISTER_QUALITY_GATES);
+
+ SearchUsersResponse response = ws.newRequest()
+ .setParam(PARAM_GATE_NAME, gate.getName())
+ .setParam(SELECTED, "all")
+ .executeProtobuf(SearchUsersResponse.class);
+
+ assertThat(response.getUsersList()).extracting(SearchUsersResponse.User::getLogin).containsExactlyInAnyOrder(user1.getLogin());
+ }
+
+ @Test
+ public void qp_administers_can_search_users() {
+ QualityGateDto gate = db.qualityGates().insertQualityGate();
+ UserDto user = db.users().insertUser();
+ userSession.logIn().addPermission(ADMINISTER_QUALITY_GATES);
+
+ SearchUsersResponse response = ws.newRequest()
+ .setParam(PARAM_GATE_NAME, gate.getName())
+ .setParam(SELECTED, "all")
+ .executeProtobuf(SearchUsersResponse.class);
+
+ assertThat(response.getUsersList()).extracting(SearchUsersResponse.User::getLogin).containsExactlyInAnyOrder(user.getLogin());
+ }
+
+ @Test
+ public void qp_editors_can_search_users() {
+ QualityGateDto gate = db.qualityGates().insertQualityGate();
+ UserDto user = db.users().insertUser();
+ UserDto userAllowedToEditProfile = db.users().insertUser();
+ db.qualityGates().addUserPermission(gate, userAllowedToEditProfile);
+ userSession.logIn(userAllowedToEditProfile);
+
+ SearchUsersResponse response = ws.newRequest()
+ .setParam(PARAM_GATE_NAME, gate.getName())
+ .setParam(SELECTED, "all")
+ .executeProtobuf(SearchUsersResponse.class);
+
+ assertThat(response.getUsersList()).extracting(SearchUsersResponse.User::getLogin).containsExactlyInAnyOrder(user.getLogin(), userAllowedToEditProfile.getLogin());
+ }
+
+ @Test
+ public void fail_when_quality_gate_does_not_exist() {
+ UserDto user = db.users().insertUser();
+ userSession.logIn().addPermission(ADMINISTER_QUALITY_GATES);
+
+ TestRequest request = ws.newRequest().setParam(PARAM_GATE_NAME, "unknown");
+
+ assertThatThrownBy(() -> request.execute())
+ .isInstanceOf(NotFoundException.class)
+ .hasMessage("No quality gate has been found for name unknown");
+ }
+
+
+ @Test
+ public void fail_when_not_enough_permission() {
+ QualityGateDto gate = db.qualityGates().insertQualityGate();
+ UserDto user = db.users().insertUser();
+ userSession.logIn(db.users().insertUser());
+
+ TestRequest request = ws.newRequest().setParam(PARAM_GATE_NAME, gate.getName());
+
+ assertThatThrownBy(() -> request.execute())
+ .isInstanceOf(ForbiddenException.class);
+ }
+}
optional bool manageConditions = 6;
}
+// WS api/qualitygates/search_users
+message SearchUsersResponse {
+ optional sonarqube.ws.commons.Paging paging = 1;
+ repeated User users = 2;
+
+ message User {
+ optional string login = 1;
+ optional string name = 2;
+ optional string avatar = 3;
+ optional bool selected = 4;
+ }
+}
+
// WS api/qualitygates/search_groups
message SearchGroupsResponse {
optional sonarqube.ws.commons.Paging paging = 1;