aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorGuillaume Jambet <guillaume.jambet@sonarsource.com>2018-02-22 11:00:45 +0100
committerStas Vilchik <stas.vilchik@sonarsource.com>2018-03-02 13:17:32 +0100
commitf1a7b51a442031acc42867f0d1b9c5dcfc07b1fc (patch)
tree2721d450bec12b364e34a5672d546596b7ffb55c /server
parent58e9f8b9ad49d518712ad14fa33fd51e232a7cd6 (diff)
downloadsonarqube-f1a7b51a442031acc42867f0d1b9c5dcfc07b1fc.tar.gz
sonarqube-f1a7b51a442031acc42867f0d1b9c5dcfc07b1fc.zip
SONAR-10426 Add homepage default when db is inconsistent
Diffstat (limited to 'server')
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDao.java8
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/user/UserMapper.java4
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/user/UserMapper.xml428
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/user/UserDaoTest.java16
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java109
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypes.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypesImpl.java17
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java100
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java45
9 files changed, 437 insertions, 294 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDao.java
index c063482fc98..e58945b21aa 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDao.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDao.java
@@ -124,11 +124,15 @@ public class UserDao implements Dao {
}
public void cleanHomepage(DbSession dbSession, OrganizationDto organization) {
- mapper(dbSession).clearHomepage("ORGANIZATION", organization.getUuid(), system2.now());
+ mapper(dbSession).clearHomepages("ORGANIZATION", organization.getUuid(), system2.now());
}
public void cleanHomepage(DbSession dbSession, ComponentDto project) {
- mapper(dbSession).clearHomepage("PROJECT", project.uuid(), system2.now());
+ mapper(dbSession).clearHomepages("PROJECT", project.uuid(), system2.now());
+ }
+
+ public void cleanHomepage(DbSession dbSession, UserDto user) {
+ mapper(dbSession).clearHomepage(user.getLogin(), system2.now());
}
@CheckForNull
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserMapper.java
index 5d816dab951..fa80aba9ac8 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserMapper.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserMapper.java
@@ -70,5 +70,7 @@ public interface UserMapper {
void deactivateUser(@Param("login") String login, @Param("now") long now);
- void clearHomepage(@Param("homepageType") String type, @Param("homepageParameter") String value, @Param("now") long now);
+ void clearHomepages(@Param("homepageType") String type, @Param("homepageParameter") String value, @Param("now") long now);
+
+ void clearHomepage(@Param("login") String login, @Param("now") long now);
}
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/user/UserMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/user/UserMapper.xml
index d7c568696e5..9b6f5c9f5ee 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/user/UserMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/user/UserMapper.xml
@@ -3,216 +3,226 @@
<mapper namespace="org.sonar.db.user.UserMapper">
- <sql id="userColumns">
- u.id as id,
- u.login as login,
- u.name as name,
- u.email as email,
- u.active as "active",
- u.scm_accounts as "scmAccounts",
- u.salt as "salt",
- u.crypted_password as "cryptedPassword",
- u.external_identity as "externalIdentity",
- u.external_identity_provider as "externalIdentityProvider",
- u.user_local as "local",
- u.is_root as "root",
- u.onboarded as "onboarded",
- u.created_at as "createdAt",
- u.updated_at as "updatedAt",
- u.homepage_type as "homepageType",
- u.homepage_parameter as "homepageParameter"
- </sql>
-
- <select id="selectByLogin" parameterType="String" resultType="User">
- SELECT
- <include refid="userColumns"/>
- FROM users u
- WHERE u.login=#{login}
- </select>
-
- <select id="selectNullableByScmAccountOrLoginOrEmail" parameterType="map" resultType="User">
- SELECT
- <include refid="userColumns"/>
- FROM users u
- WHERE
- u.login=#{scmAccount}
- OR u.email=#{scmAccount}
- OR u.scm_accounts like #{likeScmAccount}
- </select>
-
- <select id="selectUser" parameterType="int" resultType="User">
- SELECT
- <include refid="userColumns"/>
- FROM users u
- WHERE u.id=#{id}
- </select>
-
- <select id="selectUserByLogin" parameterType="string" resultType="User">
- SELECT
- <include refid="userColumns"/>
- FROM users u
- WHERE u.login=#{id} AND u.active=${_true}
- </select>
-
- <select id="selectByLogins" parameterType="string" resultType="User">
- SELECT
- <include refid="userColumns"/>
- FROM users u
- WHERE u.login in
- <foreach collection="list" open="(" close=")" item="login" separator=",">
- #{login}
- </foreach>
- </select>
-
- <select id="scrollAll" resultType="User" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
- select <include refid="userColumns"/>
- from users u
- </select>
-
- <select id="selectByIds" parameterType="string" resultType="User">
- SELECT
- <include refid="userColumns"/>
- FROM users u
- WHERE u.id in
- <foreach collection="ids" open="(" close=")" item="id" separator=",">
- #{id}
- </foreach>
- </select>
-
- <select id="selectUsers" parameterType="map" resultType="User">
- SELECT
- <include refid="userColumns"/>
- FROM users u
- <where>
- <if test="logins != null and logins.size() > 0">
- u.login IN
- <foreach item="login" index="index" collection="logins" open="(" separator="," close=")">
- #{login}
+ <sql id="userColumns">
+ u.id as id,
+ u.login as login,
+ u.name as name,
+ u.email as email,
+ u.active as "active",
+ u.scm_accounts as "scmAccounts",
+ u.salt as "salt",
+ u.crypted_password as "cryptedPassword",
+ u.external_identity as "externalIdentity",
+ u.external_identity_provider as "externalIdentityProvider",
+ u.user_local as "local",
+ u.is_root as "root",
+ u.onboarded as "onboarded",
+ u.created_at as "createdAt",
+ u.updated_at as "updatedAt",
+ u.homepage_type as "homepageType",
+ u.homepage_parameter as "homepageParameter"
+ </sql>
+
+ <select id="selectByLogin" parameterType="String" resultType="User">
+ SELECT
+ <include refid="userColumns"/>
+ FROM users u
+ WHERE u.login=#{login}
+ </select>
+
+ <select id="selectNullableByScmAccountOrLoginOrEmail" parameterType="map" resultType="User">
+ SELECT
+ <include refid="userColumns"/>
+ FROM users u
+ WHERE
+ u.login=#{scmAccount}
+ OR u.email=#{scmAccount}
+ OR u.scm_accounts like #{likeScmAccount}
+ </select>
+
+ <select id="selectUser" parameterType="int" resultType="User">
+ SELECT
+ <include refid="userColumns"/>
+ FROM users u
+ WHERE u.id=#{id}
+ </select>
+
+ <select id="selectUserByLogin" parameterType="string" resultType="User">
+ SELECT
+ <include refid="userColumns"/>
+ FROM users u
+ WHERE u.login=#{id} AND u.active=${_true}
+ </select>
+
+ <select id="selectByLogins" parameterType="string" resultType="User">
+ SELECT
+ <include refid="userColumns"/>
+ FROM users u
+ WHERE u.login in
+ <foreach collection="list" open="(" close=")" item="login" separator=",">
+ #{login}
</foreach>
- </if>
- <if test="includeDeactivated==false">
+ </select>
+
+ <select id="scrollAll" resultType="User" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
+ select
+ <include refid="userColumns"/>
+ from users u
+ </select>
+
+ <select id="selectByIds" parameterType="string" resultType="User">
+ SELECT
+ <include refid="userColumns"/>
+ FROM users u
+ WHERE u.id in
+ <foreach collection="ids" open="(" close=")" item="id" separator=",">
+ #{id}
+ </foreach>
+ </select>
+
+ <select id="selectUsers" parameterType="map" resultType="User">
+ SELECT
+ <include refid="userColumns"/>
+ FROM users u
+ <where>
+ <if test="logins != null and logins.size() > 0">
+ u.login IN
+ <foreach item="login" index="index" collection="logins" open="(" separator="," close=")">
+ #{login}
+ </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 '/')
+ </if>
+ <if test="mustBeRoot != null and mustBeRoot==true">
+ AND u.is_root = ${_true}
+ </if>
+ <if test="mustBeRoot != null and mustBeRoot==false">
+ AND u.is_root = ${_false}
+ </if>
+ </where>
+ ORDER BY u.name
+ </select>
+
+ <select id="selectByEmail" parameterType="String" resultType="User">
+ SELECT
+ <include refid="userColumns"/>
+ FROM users u
+ WHERE lower(u.email)=#{email, jdbcType=VARCHAR}
AND u.active=${_true}
- </if>
- <if test="searchText != null">
- AND (u.login LIKE #{searchTextSql} ESCAPE '/' OR u.name LIKE #{searchTextSql} ESCAPE '/')
- </if>
- <if test="mustBeRoot != null and mustBeRoot==true">
- AND u.is_root = ${_true}
- </if>
- <if test="mustBeRoot != null and mustBeRoot==false">
- AND u.is_root = ${_false}
- </if>
- </where>
- ORDER BY u.name
- </select>
-
- <select id="selectByEmail" parameterType="String" resultType="User">
- SELECT
- <include refid="userColumns"/>
- FROM users u
- WHERE lower(u.email)=#{email, jdbcType=VARCHAR}
- AND u.active=${_true}
- </select>
-
- <select id="countRootUsersButLogin" parameterType="String" resultType="long">
- select
- count(1)
- from
- users u
- where
- u.active = ${_true}
- and u.is_root = ${_true}
- and u.login &lt;&gt; #{login}
- </select>
-
- <update id="deactivateUser" parameterType="map">
- update users set
- active = ${_false},
- email = null,
- scm_accounts = null,
- external_identity = null,
- external_identity_provider = null,
- salt = null,
- crypted_password = null,
- updated_at = #{now, jdbcType=BIGINT}
- where
- login = #{login, jdbcType=VARCHAR}
- </update>
-
- <update id="clearHomepage" parameterType="map">
- update users set
- homepage_type = null,
- homepage_parameter = null,
- updated_at = #{now, jdbcType=BIGINT}
- where
- homepage_type = #{homepageType, jdbcType=VARCHAR}
- and homepage_parameter = #{homepageParameter, jdbcType=VARCHAR}
- </update>
-
- <update id="setRoot">
- update users set
- is_root = #{root, jdbcType=BOOLEAN},
- updated_at = #{now, jdbcType=BIGINT}
- where
- login = #{login, jdbcType=VARCHAR}
- and active = ${_true}
- </update>
-
- <insert id="insert" parameterType="map" keyColumn="id" useGeneratedKeys="true" keyProperty="user.id">
- insert into users (
- login,
- name,
- email,
- active,
- scm_accounts,
- external_identity,
- external_identity_provider,
- user_local,
- salt,
- crypted_password,
- is_root,
- onboarded,
- created_at,
- updated_at,
- homepage_type,
- homepage_parameter
- ) values (
- #{user.login,jdbcType=VARCHAR},
- #{user.name,jdbcType=VARCHAR},
- #{user.email,jdbcType=VARCHAR},
- #{user.active,jdbcType=BOOLEAN},
- #{user.scmAccounts,jdbcType=VARCHAR},
- #{user.externalIdentity,jdbcType=VARCHAR},
- #{user.externalIdentityProvider,jdbcType=VARCHAR},
- #{user.local,jdbcType=BOOLEAN},
- #{user.salt,jdbcType=VARCHAR},
- #{user.cryptedPassword,jdbcType=VARCHAR},
- #{user.root,jdbcType=BOOLEAN},
- #{user.onboarded,jdbcType=BOOLEAN},
- #{now,jdbcType=BIGINT},
- #{now,jdbcType=BIGINT},
- #{user.homepageType,jdbcType=VARCHAR},
- #{user.homepageParameter,jdbcType=VARCHAR}
- )
- </insert>
-
- <update id="update" parameterType="map">
- update users set
- name = #{user.name, jdbcType=VARCHAR},
- email = #{user.email, jdbcType=VARCHAR},
- active = #{user.active, jdbcType=BOOLEAN},
- scm_accounts = #{user.scmAccounts, jdbcType=VARCHAR},
- external_identity = #{user.externalIdentity, jdbcType=VARCHAR},
- external_identity_provider = #{user.externalIdentityProvider, jdbcType=VARCHAR},
- user_local = #{user.local, jdbcType=BOOLEAN},
- onboarded = #{user.onboarded, jdbcType=BOOLEAN},
- salt = #{user.salt, jdbcType=VARCHAR},
- crypted_password = #{user.cryptedPassword, jdbcType=BIGINT},
- updated_at = #{now, jdbcType=BIGINT},
- homepage_type = #{user.homepageType, jdbcType=VARCHAR},
- homepage_parameter = #{user.homepageParameter, jdbcType=VARCHAR}
- where
- login = #{user.login, jdbcType=VARCHAR}
- </update>
+ </select>
+
+ <select id="countRootUsersButLogin" parameterType="String" resultType="long">
+ select
+ count(1)
+ from
+ users u
+ where
+ u.active = ${_true}
+ and u.is_root = ${_true}
+ and u.login &lt;&gt; #{login}
+ </select>
+
+ <update id="deactivateUser" parameterType="map">
+ update users set
+ active = ${_false},
+ email = null,
+ scm_accounts = null,
+ external_identity = null,
+ external_identity_provider = null,
+ salt = null,
+ crypted_password = null,
+ updated_at = #{now, jdbcType=BIGINT}
+ where
+ login = #{login, jdbcType=VARCHAR}
+ </update>
+
+ <update id="clearHomepages" parameterType="map">
+ update users set
+ homepage_type = null,
+ homepage_parameter = null,
+ updated_at = #{now, jdbcType=BIGINT}
+ where
+ homepage_type = #{homepageType, jdbcType=VARCHAR}
+ and homepage_parameter = #{homepageParameter, jdbcType=VARCHAR}
+ </update>
+
+ <update id="clearHomepage" parameterType="map">
+ update users set
+ homepage_type = null,
+ homepage_parameter = null,
+ updated_at = #{now, jdbcType=BIGINT}
+ where
+ login = #{login, jdbcType=VARCHAR}
+ </update>
+
+ <update id="setRoot">
+ update users set
+ is_root = #{root, jdbcType=BOOLEAN},
+ updated_at = #{now, jdbcType=BIGINT}
+ where
+ login = #{login, jdbcType=VARCHAR}
+ and active = ${_true}
+ </update>
+
+ <insert id="insert" parameterType="map" keyColumn="id" useGeneratedKeys="true" keyProperty="user.id">
+ insert into users (
+ login,
+ name,
+ email,
+ active,
+ scm_accounts,
+ external_identity,
+ external_identity_provider,
+ user_local,
+ salt,
+ crypted_password,
+ is_root,
+ onboarded,
+ created_at,
+ updated_at,
+ homepage_type,
+ homepage_parameter
+ ) values (
+ #{user.login,jdbcType=VARCHAR},
+ #{user.name,jdbcType=VARCHAR},
+ #{user.email,jdbcType=VARCHAR},
+ #{user.active,jdbcType=BOOLEAN},
+ #{user.scmAccounts,jdbcType=VARCHAR},
+ #{user.externalIdentity,jdbcType=VARCHAR},
+ #{user.externalIdentityProvider,jdbcType=VARCHAR},
+ #{user.local,jdbcType=BOOLEAN},
+ #{user.salt,jdbcType=VARCHAR},
+ #{user.cryptedPassword,jdbcType=VARCHAR},
+ #{user.root,jdbcType=BOOLEAN},
+ #{user.onboarded,jdbcType=BOOLEAN},
+ #{now,jdbcType=BIGINT},
+ #{now,jdbcType=BIGINT},
+ #{user.homepageType,jdbcType=VARCHAR},
+ #{user.homepageParameter,jdbcType=VARCHAR}
+ )
+ </insert>
+
+ <update id="update" parameterType="map">
+ update users set
+ name = #{user.name, jdbcType=VARCHAR},
+ email = #{user.email, jdbcType=VARCHAR},
+ active = #{user.active, jdbcType=BOOLEAN},
+ scm_accounts = #{user.scmAccounts, jdbcType=VARCHAR},
+ external_identity = #{user.externalIdentity, jdbcType=VARCHAR},
+ external_identity_provider = #{user.externalIdentityProvider, jdbcType=VARCHAR},
+ user_local = #{user.local, jdbcType=BOOLEAN},
+ onboarded = #{user.onboarded, jdbcType=BOOLEAN},
+ salt = #{user.salt, jdbcType=VARCHAR},
+ crypted_password = #{user.cryptedPassword, jdbcType=BIGINT},
+ updated_at = #{now, jdbcType=BIGINT},
+ homepage_type = #{user.homepageType, jdbcType=VARCHAR},
+ homepage_parameter = #{user.homepageParameter, jdbcType=VARCHAR}
+ where
+ login = #{user.login, jdbcType=VARCHAR}
+ </update>
</mapper>
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/user/UserDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/user/UserDaoTest.java
index e4e219ec665..1286768f703 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/user/UserDaoTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/user/UserDaoTest.java
@@ -467,6 +467,22 @@ public class UserDaoTest {
}
@Test
+ public void clean_user_homepage() {
+
+ UserDto user = newUserDto().setHomepageType("RANDOM").setHomepageParameter("any-string");
+ underTest.insert(session, user);
+ session.commit();
+
+ underTest.cleanHomepage(session,user);
+
+ UserDto reloaded = underTest.selectUserById(session, user.getId());
+ assertThat(reloaded.getUpdatedAt()).isEqualTo(NOW);
+ assertThat(reloaded.getHomepageType()).isNull();
+ assertThat(reloaded.getHomepageParameter()).isNull();
+
+ }
+
+ @Test
public void does_not_fail_to_deactivate_missing_user() {
underTest.deactivateUser(session, UserTesting.newUserDto());
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java
index 3b7ad430f56..2df9909bcee 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java
@@ -21,11 +21,12 @@ package org.sonar.server.user.ws;
import java.util.Collection;
import java.util.List;
-import javax.annotation.Nullable;
+import java.util.Optional;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService.NewController;
+import org.sonar.core.platform.PluginRepository;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
@@ -39,9 +40,12 @@ import org.sonarqube.ws.Users.CurrentWsResponse;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Strings.emptyToNull;
-import static java.lang.String.format;
import static java.util.Collections.singletonList;
+import static java.util.Optional.empty;
+import static java.util.Optional.of;
+import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toList;
+import static org.apache.commons.lang.StringUtils.EMPTY;
import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.Users.CurrentWsResponse.Permissions;
@@ -54,20 +58,23 @@ import static org.sonarqube.ws.client.user.UsersWsParameters.ACTION_CURRENT;
public class CurrentAction implements UsersWsAction {
+ private static final String GOVERNANCE_PLUGIN_KEY = "governance";
+
private final UserSession userSession;
private final DbClient dbClient;
private final DefaultOrganizationProvider defaultOrganizationProvider;
private final AvatarResolver avatarResolver;
private final HomepageTypes homepageTypes;
- private static final String HOMEPAGE_PARAMETER_SHOULD_NOT_BE_NULL = "Homepage parameter should not be null";
+ private final PluginRepository pluginRepository;
public CurrentAction(UserSession userSession, DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider,
- AvatarResolver avatarResolver, HomepageTypes homepageTypes) {
+ AvatarResolver avatarResolver, HomepageTypes homepageTypes, PluginRepository pluginRepository) {
this.userSession = userSession;
this.dbClient = dbClient;
this.defaultOrganizationProvider = defaultOrganizationProvider;
this.avatarResolver = avatarResolver;
this.homepageTypes = homepageTypes;
+ this.pluginRepository = pluginRepository;
}
@Override
@@ -129,42 +136,74 @@ public class CurrentAction implements UsersWsAction {
}
private CurrentWsResponse.Homepage buildHomepage(DbSession dbSession, UserDto user) {
- String homepageType = user.getHomepageType();
- if (homepageType == null) {
+ if (noHomepageSet(user)) {
return defaultHomepage();
}
- CurrentWsResponse.Homepage.Builder homepage = CurrentWsResponse.Homepage.newBuilder()
- .setType(CurrentWsResponse.HomepageType.valueOf(homepageType));
- setHomepageParameter(dbSession, homepageType, user.getHomepageParameter(), homepage);
- return homepage.build();
+
+ return doBuildHomepage(dbSession, user).orElse(defaultHomepage());
+ }
+
+ private Optional<CurrentWsResponse.Homepage> doBuildHomepage(DbSession dbSession, UserDto user) {
+
+ if (PROJECT.toString().equals(user.getHomepageType())) {
+ return projectHomepage(dbSession, user);
+ }
+
+ if (APPLICATION.toString().equals(user.getHomepageType()) || PORTFOLIO.toString().equals(user.getHomepageType())) {
+ return applicationAndPortfolioHomepage(dbSession, user);
+ }
+
+ if (ORGANIZATION.toString().equals(user.getHomepageType())) {
+ return organizationHomepage(dbSession, user);
+ }
+
+ return of(CurrentWsResponse.Homepage.newBuilder()
+ .setType(CurrentWsResponse.HomepageType.valueOf(user.getHomepageType()))
+ .build());
}
- private void setHomepageParameter(DbSession dbSession, String homepageType, @Nullable String homepageParameter, CurrentWsResponse.Homepage.Builder homepage) {
- if (PROJECT.toString().equals(homepageType)) {
- checkState(homepageParameter != null, HOMEPAGE_PARAMETER_SHOULD_NOT_BE_NULL);
- ComponentDto component = dbClient.componentDao().selectByUuid(dbSession, homepageParameter)
- .or(() -> {
- throw new IllegalStateException(format("Unknown component '%s' for homepageParameter", homepageParameter));
- });
- homepage.setComponent(component.getKey());
- setNullable(component.getBranch(), homepage::setBranch);
- return;
+ private Optional<CurrentWsResponse.Homepage> projectHomepage(DbSession dbSession, UserDto user) {
+ Optional<ComponentDto> projectOptional = ofNullable(dbClient.componentDao().selectByUuid(dbSession, of(user.getHomepageParameter()).orElse(EMPTY)).orNull());
+ if (!projectOptional.isPresent()) {
+ cleanUserHomepageInDb(dbSession, user);
+ return empty();
}
- if (APPLICATION.toString().equals(homepageType) || PORTFOLIO.toString().equals(homepageType)) {
- checkState(homepageParameter != null, HOMEPAGE_PARAMETER_SHOULD_NOT_BE_NULL);
- ComponentDto component = dbClient.componentDao().selectByUuid(dbSession, homepageParameter)
- .or(() -> {
- throw new IllegalStateException(format("Unknown component '%s' for homepageParameter", homepageParameter));
- });
- homepage.setComponent(component.getKey());
- return;
+
+ CurrentWsResponse.Homepage.Builder homepage = CurrentWsResponse.Homepage.newBuilder()
+ .setType(CurrentWsResponse.HomepageType.valueOf(user.getHomepageType()))
+ .setComponent(projectOptional.get().getKey());
+ setNullable(projectOptional.get().getBranch(), homepage::setBranch);
+ return of(homepage.build());
+ }
+
+ private Optional<CurrentWsResponse.Homepage> applicationAndPortfolioHomepage(DbSession dbSession, UserDto user) {
+ Optional<ComponentDto> componentOptional = ofNullable(dbClient.componentDao().selectByUuid(dbSession, of(user.getHomepageParameter()).orElse(EMPTY)).orNull());
+ if (!componentOptional.isPresent() || !pluginRepository.hasPlugin(GOVERNANCE_PLUGIN_KEY)) {
+ cleanUserHomepageInDb(dbSession, user);
+ return empty();
}
- if (ORGANIZATION.toString().equals(homepageType)) {
- checkState(homepageParameter != null, HOMEPAGE_PARAMETER_SHOULD_NOT_BE_NULL);
- OrganizationDto organization = dbClient.organizationDao().selectByUuid(dbSession, homepageParameter)
- .orElseThrow(() -> new IllegalStateException(format("Unknown organization '%s' for homepageParameter", homepageParameter)));
- homepage.setOrganization(organization.getKey());
+
+ return of(CurrentWsResponse.Homepage.newBuilder()
+ .setType(CurrentWsResponse.HomepageType.valueOf(user.getHomepageType()))
+ .setComponent(componentOptional.get().getKey())
+ .build());
+ }
+
+ private Optional<CurrentWsResponse.Homepage> organizationHomepage(DbSession dbSession, UserDto user) {
+ Optional<OrganizationDto> organizationOptional = dbClient.organizationDao().selectByUuid(dbSession, of(user.getHomepageParameter()).orElse(EMPTY));
+ if (!organizationOptional.isPresent()) {
+ cleanUserHomepageInDb(dbSession, user);
+ return empty();
}
+
+ return of(CurrentWsResponse.Homepage.newBuilder()
+ .setType(CurrentWsResponse.HomepageType.valueOf(user.getHomepageType()))
+ .setOrganization(organizationOptional.get().getKey())
+ .build());
+ }
+
+ private void cleanUserHomepageInDb(DbSession dbSession, UserDto user) {
+ dbClient.userDao().cleanHomepage(dbSession, user);
}
private CurrentWsResponse.Homepage defaultHomepage() {
@@ -173,4 +212,8 @@ public class CurrentAction implements UsersWsAction {
.build();
}
+ private static boolean noHomepageSet(UserDto user) {
+ return user.getHomepageType() == null;
+ }
+
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypes.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypes.java
index be7f40ebc60..816555047f7 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypes.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypes.java
@@ -26,7 +26,7 @@ public interface HomepageTypes {
enum Type {
PROJECT,
/**
- * These types in only available on SonarQube
+ * These types are only available on SonarQube
*/
PROJECTS, ISSUES, PORTFOLIOS, PORTFOLIO, APPLICATION,
/**
@@ -34,7 +34,7 @@ public interface HomepageTypes {
*/
MY_PROJECTS, MY_ISSUES,
/**
- * This type in only available when organizations are enabled
+ * This type is only available when organizations are enabled
*/
ORGANIZATION
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypesImpl.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypesImpl.java
index 7dfc2527d59..d4ddeaa8318 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypesImpl.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypesImpl.java
@@ -50,7 +50,6 @@ public class HomepageTypesImpl implements HomepageTypes, Startable {
private final DbClient dbClient;
private List<Type> types;
- private Type defaultType;
public HomepageTypesImpl(Configuration configuration, OrganizationFlags organizationFlags, DbClient dbClient) {
this.configuration = configuration;
@@ -66,23 +65,29 @@ public class HomepageTypesImpl implements HomepageTypes, Startable {
@Override
public Type getDefaultType() {
- checkState(types != null, "Homepage types have not been initialized yet");
- return defaultType;
+ return isOnSonarCloud() ? MY_PROJECTS : PROJECTS;
}
@Override
public void start() {
try (DbSession dbSession = dbClient.openSession(false)) {
- boolean isOnSonarCloud = configuration.getBoolean(ProcessProperties.Property.SONARCLOUD_ENABLED.getKey()).orElse(false);
- boolean isOrganizationEnabled = organizationFlags.isEnabled(dbSession);
+ boolean isOnSonarCloud = isOnSonarCloud();
+ boolean isOrganizationEnabled = isOrganizationEnabled(dbSession);
this.types = stream(values())
.filter(type -> (isOnSonarCloud && ON_SONARCLOUD.contains(type)) || (!isOnSonarCloud && ON_SONARQUBE.contains(type)))
.filter(type -> isOrganizationEnabled || !(type.equals(ORGANIZATION)))
.collect(toList());
- this.defaultType = isOnSonarCloud ? Type.MY_PROJECTS : PROJECTS;
}
}
+ private boolean isOrganizationEnabled(DbSession dbSession) {
+ return organizationFlags.isEnabled(dbSession);
+ }
+
+ private Boolean isOnSonarCloud() {
+ return configuration.getBoolean(ProcessProperties.Property.SONARCLOUD_ENABLED.getKey()).orElse(false);
+ }
+
@Override
public void stop() {
// Nothing to do
diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java
index 7748ff91811..f148c030860 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java
@@ -19,12 +19,13 @@
*/
package org.sonar.server.user.ws;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.System2;
+import org.sonar.core.platform.PluginRepository;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
@@ -32,6 +33,7 @@ import org.sonar.db.user.UserDto;
import org.sonar.server.issue.ws.AvatarResolverImpl;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
+import org.sonar.server.organization.TestOrganizationFlags;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsActionTester;
import org.sonarqube.ws.Users.CurrentWsResponse;
@@ -57,15 +59,14 @@ public class CurrentActionTest {
private DbClient dbClient = db.getDbClient();
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
- private HomepageTypes homepageTypes = mock(HomepageTypes.class);
- private WsActionTester ws = new WsActionTester(new CurrentAction(userSessionRule, dbClient, defaultOrganizationProvider, new AvatarResolverImpl(), homepageTypes));
+ private PluginRepository pluginRepository = mock(PluginRepository.class);
+ private MapSettings settings = new MapSettings();
+ private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone();
+ private HomepageTypesImpl homepageTypes = new HomepageTypesImpl(settings.asConfig(), organizationFlags, db.getDbClient());
- @Before
- public void setUp() {
- when(homepageTypes.getDefaultType()).thenReturn(HomepageTypes.Type.MY_PROJECTS);
- ws = new WsActionTester(new CurrentAction(userSessionRule, dbClient, defaultOrganizationProvider, new AvatarResolverImpl(), homepageTypes));
- }
+ private WsActionTester ws = new WsActionTester(
+ new CurrentAction(userSessionRule, dbClient, defaultOrganizationProvider, new AvatarResolverImpl(), homepageTypes, pluginRepository));
@Test
public void return_user_info() {
@@ -180,6 +181,7 @@ public class CurrentActionTest {
@Test
public void return_homepage_when_set_to_a_portfolio() {
+ withGovernancePlugin();
ComponentDto portfolio = db.components().insertPrivatePortfolio(db.getDefaultOrganization());
UserDto user = db.users().insertUser(u -> u.setHomepageType("PORTFOLIO").setHomepageParameter(portfolio.uuid()));
userSessionRule.logIn(user);
@@ -193,6 +195,7 @@ public class CurrentActionTest {
@Test
public void return_homepage_when_set_to_an_application() {
+ withGovernancePlugin();
ComponentDto application = db.components().insertPrivateApplication(db.getDefaultOrganization());
UserDto user = db.users().insertUser(u -> u.setHomepageType("APPLICATION").setHomepageParameter(application.uuid()));
userSessionRule.logIn(user);
@@ -306,25 +309,90 @@ public class CurrentActionTest {
}
@Test
- public void fail_with_ISE_when_user_homepage_project_does_not_exist_in_db() {
+ public void fallback_when_user_homepage_project_does_not_exist_in_db() {
UserDto user = db.users().insertUser(u -> u.setHomepageType("PROJECT").setHomepageParameter("not-existing-project-uuid"));
userSessionRule.logIn(user.getLogin());
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("Unknown component 'not-existing-project-uuid' for homepageParameter");
+ CurrentWsResponse response = ws.newRequest().executeProtobuf(CurrentWsResponse.class);
- call();
+ assertThat(response.getHomepage()).isNotNull();
}
@Test
- public void fail_with_ISE_when_user_homepage_organization_does_not_exist_in_db() {
+ public void fallback_when_user_homepage_organization_does_not_exist_in_db() {
UserDto user = db.users().insertUser(u -> u.setHomepageType("ORGANIZATION").setHomepageParameter("not-existing-organization-uuid"));
userSessionRule.logIn(user.getLogin());
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("Unknown organization 'not-existing-organization-uuid' for homepageParameter");
+ CurrentWsResponse response = ws.newRequest().executeProtobuf(CurrentWsResponse.class);
- call();
+ assertThat(response.getHomepage()).isNotNull();
+ }
+
+ @Test
+ public void fallback_when_user_homepage_portfolio_does_not_exist_in_db() {
+ withGovernancePlugin();
+ UserDto user = db.users().insertUser(u -> u.setHomepageType("PORTFOLIO").setHomepageParameter("not-existing-portfolio-uuid"));
+ userSessionRule.logIn(user.getLogin());
+
+ CurrentWsResponse response = ws.newRequest().executeProtobuf(CurrentWsResponse.class);
+
+ assertThat(response.getHomepage()).isNotNull();
+ }
+
+ @Test
+ public void fallback_when_user_homepage_application_does_not_exist_in_db() {
+ withGovernancePlugin();
+ UserDto user = db.users().insertUser(u -> u.setHomepageType("APPLICATION").setHomepageParameter("not-existing-application-uuid"));
+ userSessionRule.logIn(user.getLogin());
+
+ CurrentWsResponse response = ws.newRequest().executeProtobuf(CurrentWsResponse.class);
+
+ assertThat(response.getHomepage()).isNotNull();
+ }
+
+ @Test
+ public void fallback_when_user_homepage_application_and_governance_plugin_is_not_installed() {
+ withoutGovernancePlugin();
+ ComponentDto application = db.components().insertPrivateApplication(db.getDefaultOrganization());
+ UserDto user = db.users().insertUser(u -> u.setHomepageType("APPLICATION").setHomepageParameter(application.uuid()));
+ userSessionRule.logIn(user.getLogin());
+
+ CurrentWsResponse response = ws.newRequest().executeProtobuf(CurrentWsResponse.class);
+
+ assertThat(response.getHomepage().getType().toString()).isEqualTo("PROJECTS");
+ }
+
+ @Test
+ public void fallback_to_PROJECTS_when_on_SonarQube() {
+ UserDto user = db.users().insertUser(u -> u.setHomepageType("PROJECT").setHomepageParameter("not-existing-project-uuid"));
+ userSessionRule.logIn(user.getLogin());
+
+ CurrentWsResponse response = ws.newRequest().executeProtobuf(CurrentWsResponse.class);
+
+ assertThat(response.getHomepage().getType().toString()).isEqualTo("PROJECTS");
+ }
+
+ @Test
+ public void fallback_to_MY_PROJECTS_when_on_SonarCloud() {
+ onSonarCloud();
+ UserDto user = db.users().insertUser(u -> u.setHomepageType("PROJECT").setHomepageParameter("not-existing-project-uuid"));
+ userSessionRule.logIn(user.getLogin());
+
+ CurrentWsResponse response = ws.newRequest().executeProtobuf(CurrentWsResponse.class);
+
+ assertThat(response.getHomepage().getType().toString()).isEqualTo("MY_PROJECTS");
+ }
+
+ private void onSonarCloud() {
+ settings.setProperty("sonar.sonarcloud.enabled", true);
+ }
+
+ private void withGovernancePlugin(){
+ when(pluginRepository.hasPlugin("governance")).thenReturn(true);
+ }
+
+ private void withoutGovernancePlugin(){
+ when(pluginRepository.hasPlugin("governance")).thenReturn(false);
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java
index 4d221650f45..92e8444c54b 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java
@@ -19,7 +19,6 @@
*/
package org.sonar.server.user.ws;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -35,17 +34,8 @@ import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
-import static java.util.Arrays.asList;
import static org.apache.http.HttpStatus.SC_NO_CONTENT;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.sonar.server.user.ws.HomepageTypes.Type.ISSUES;
-import static org.sonar.server.user.ws.HomepageTypes.Type.MY_ISSUES;
-import static org.sonar.server.user.ws.HomepageTypes.Type.MY_PROJECTS;
-import static org.sonar.server.user.ws.HomepageTypes.Type.ORGANIZATION;
-import static org.sonar.server.user.ws.HomepageTypes.Type.PROJECT;
-import static org.sonar.server.user.ws.HomepageTypes.Type.PROJECTS;
import static org.sonar.server.user.ws.SetHomepageAction.PARAM_COMPONENT;
import static org.sonar.server.user.ws.SetHomepageAction.PARAM_TYPE;
@@ -61,15 +51,8 @@ public class SetHomepageActionTest {
public ExpectedException expectedException = ExpectedException.none();
private DbClient dbClient = db.getDbClient();
- private HomepageTypes homepageTypes = mock(HomepageTypes.class);
- private WsActionTester ws;
-
- @Before
- public void setUp() {
- when(homepageTypes.getTypes()).thenReturn(asList(PROJECT, ORGANIZATION, MY_ISSUES, MY_PROJECTS));
- ws = new WsActionTester(new SetHomepageAction(userSession, dbClient, TestComponentFinder.from(db)));
- }
+ private WsActionTester ws = new WsActionTester(new SetHomepageAction(userSession, dbClient, TestComponentFinder.from(db)));
@Test
public void verify_definition() {
@@ -163,7 +146,7 @@ public class SetHomepageActionTest {
}
@Test
- public void set_sonarcloud_my_issues_homepage() {
+ public void set_SonarCloud_my_issues_homepage() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
@@ -179,10 +162,7 @@ public class SetHomepageActionTest {
}
@Test
- public void set_sonarqube_issues_homepage() {
-
- when(homepageTypes.getTypes()).thenReturn(asList(PROJECT, ORGANIZATION, ISSUES, PROJECTS));
- ws = new WsActionTester(new SetHomepageAction(userSession, dbClient, TestComponentFinder.from(db)));
+ public void set_SonarQube_issues_homepage() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
@@ -199,7 +179,7 @@ public class SetHomepageActionTest {
}
@Test
- public void set_sonarcloud_my_projects_homepage() {
+ public void set_SonarCloud_my_projects_homepage() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
@@ -215,7 +195,7 @@ public class SetHomepageActionTest {
}
@Test
- public void set_sonarqube_projects_homepage() {
+ public void set_SonarQube_projects_homepage() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
@@ -328,6 +308,21 @@ public class SetHomepageActionTest {
}
@Test
+ public void fail_when_invalid_homepage_type() {
+ UserDto user = db.users().insertUser();
+ userSession.logIn(user);
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException
+ .expectMessage("Value of parameter 'type' (PIPO) must be one of: [PROJECT, PROJECTS, ISSUES, PORTFOLIOS, PORTFOLIO, APPLICATION, MY_PROJECTS, MY_ISSUES, ORGANIZATION]");
+
+ ws.newRequest()
+ .setMethod("POST")
+ .setParam(PARAM_TYPE, "PIPO")
+ .execute();
+ }
+
+ @Test
public void fail_for_anonymous() {
userSession.anonymous();