diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2019-10-08 17:51:53 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2019-11-06 10:04:19 +0100 |
commit | 58d04f69bb33f17cfe6db3d9885fe4c9adabd2d1 (patch) | |
tree | bc48a5c0b0e2884ffa6ec2b61c99326844f030ba /server | |
parent | f8c9b9c8b3e7040907e0ded89511f86b827449ad (diff) | |
download | sonarqube-58d04f69bb33f17cfe6db3d9885fe4c9adabd2d1.tar.gz sonarqube-58d04f69bb33f17cfe6db3d9885fe4c9adabd2d1.zip |
SONAR-12512 Allow configuration of multiple GitHub instances
Diffstat (limited to 'server')
40 files changed, 1947 insertions, 6 deletions
diff --git a/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java b/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java index 1e9ae9a5156..c44ad41287f 100644 --- a/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java +++ b/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java @@ -123,12 +123,12 @@ public class ComputeEngineContainerImplTest { assertThat(picoContainer.getParent().getParent().getComponentAdapters()).hasSize( CONTAINER_ITSELF + 6 // MigrationConfigurationModule - + 15 // level 2 + + 16 // level 2 ); assertThat(picoContainer.getParent().getParent().getParent().getComponentAdapters()).hasSize( COMPONENTS_IN_LEVEL_1_AT_CONSTRUCTION + 27 // level 1 - + 63 // content of DaoModule + + 64 // content of DaoModule + 3 // content of EsModule + 51 // content of CorePropertyDefinitions + 1 // StopFlagContainer diff --git a/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java b/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java index 160fa40e821..a2b67326dd3 100644 --- a/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java +++ b/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java @@ -53,6 +53,7 @@ public final class SqTables { "active_rules", "active_rule_parameters", "alm_app_installs", + "alm_settings", "analysis_properties", "ce_activity", "ce_queue", diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java b/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java index f5cca91191f..add145bf020 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java @@ -24,6 +24,7 @@ import java.util.Collections; import java.util.List; import org.sonar.core.platform.Module; import org.sonar.db.alm.AlmAppInstallDao; +import org.sonar.db.alm.setting.AlmSettingDao; import org.sonar.db.alm.OrganizationAlmBindingDao; import org.sonar.db.alm.ProjectAlmBindingDao; import org.sonar.db.ce.CeActivityDao; @@ -115,6 +116,7 @@ public class DaoModule extends Module { GroupMembershipDao.class, GroupPermissionDao.class, AlmAppInstallDao.class, + AlmSettingDao.class, ProjectAlmBindingDao.class, InternalComponentPropertiesDao.class, InternalPropertiesDao.class, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java b/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java index 33fbf8d2662..fea23b1b590 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java @@ -24,6 +24,7 @@ import java.util.Map; import org.sonar.db.alm.AlmAppInstallDao; import org.sonar.db.alm.OrganizationAlmBindingDao; import org.sonar.db.alm.ProjectAlmBindingDao; +import org.sonar.db.alm.setting.AlmSettingDao; import org.sonar.db.ce.CeActivityDao; import org.sonar.db.ce.CeQueueDao; import org.sonar.db.ce.CeScannerContextDao; @@ -99,6 +100,7 @@ public class DbClient { private final QualityProfileExportDao qualityProfileExportDao; private final PropertiesDao propertiesDao; private final AlmAppInstallDao almAppInstallDao; + private final AlmSettingDao almSettingDao; private final ProjectAlmBindingDao projectAlmBindingDao; private final InternalComponentPropertiesDao internalComponentPropertiesDao; private final InternalPropertiesDao internalPropertiesDao; @@ -165,6 +167,7 @@ public class DbClient { map.put(dao.getClass(), dao); } almAppInstallDao = getDao(map, AlmAppInstallDao.class); + almSettingDao = getDao(map, AlmSettingDao.class); projectAlmBindingDao = getDao(map, ProjectAlmBindingDao.class); schemaMigrationDao = getDao(map, SchemaMigrationDao.class); authorizationDao = getDao(map, AuthorizationDao.class); @@ -241,6 +244,10 @@ public class DbClient { return almAppInstallDao; } + public AlmSettingDao almSettingDao() { + return almSettingDao; + } + public ProjectAlmBindingDao projectAlmBindingsDao() { return projectAlmBindingDao; } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java index e9bf8807ba5..09cce2fab5a 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java @@ -38,6 +38,7 @@ import org.sonar.db.alm.AlmAppInstallMapper; import org.sonar.db.alm.OrganizationAlmBindingMapper; import org.sonar.db.alm.ProjectAlmBindingDto; import org.sonar.db.alm.ProjectAlmBindingMapper; +import org.sonar.db.alm.setting.AlmSettingMapper; import org.sonar.db.ce.CeActivityMapper; import org.sonar.db.ce.CeQueueMapper; import org.sonar.db.ce.CeScannerContextMapper; @@ -224,6 +225,7 @@ public class MyBatis implements Startable { Class<?>[] mappers = { ActiveRuleMapper.class, AlmAppInstallMapper.class, + AlmSettingMapper.class, AnalysisPropertiesMapper.class, AuthorizationMapper.class, BranchMapper.class, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/ALM.java b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/ALM.java new file mode 100644 index 00000000000..e99482e3ed8 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/ALM.java @@ -0,0 +1,36 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.alm.setting; + +import java.util.Locale; + +public enum ALM { + GITHUB, + BITBUCKET, + AZURE_DEVOPS; + + public static ALM fromId(String almId) { + return ALM.valueOf(almId.toUpperCase(Locale.ENGLISH)); + } + + public String getId() { + return this.name().toLowerCase(Locale.ENGLISH); + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/AlmSettingDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/AlmSettingDao.java new file mode 100644 index 00000000000..d416dcb72f7 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/AlmSettingDao.java @@ -0,0 +1,73 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.alm.setting; + +import java.util.List; +import java.util.Optional; +import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactory; +import org.sonar.db.Dao; +import org.sonar.db.DbSession; + +public class AlmSettingDao implements Dao { + + private final System2 system2; + private final UuidFactory uuidFactory; + + public AlmSettingDao(System2 system2, UuidFactory uuidFactory) { + this.system2 = system2; + this.uuidFactory = uuidFactory; + } + + private static AlmSettingMapper getMapper(DbSession dbSession) { + return dbSession.getMapper(AlmSettingMapper.class); + } + + public void insert(DbSession dbSession, AlmSettingDto almSettingDto) { + String uuid = uuidFactory.create(); + long now = system2.now(); + getMapper(dbSession).insert(almSettingDto, uuid, now); + almSettingDto.setUuid(uuid); + almSettingDto.setCreatedAt(now); + almSettingDto.setUpdatedAt(now); + } + + public Optional<AlmSettingDto> selectByUuid(DbSession dbSession, String uuid) { + return Optional.ofNullable(getMapper(dbSession).selectByUuid(uuid)); + } + + public Optional<AlmSettingDto> selectByKey(DbSession dbSession, String key) { + return Optional.ofNullable(getMapper(dbSession).selectByKey(key)); + } + + public List<AlmSettingDto> selectAll(DbSession dbSession) { + return getMapper(dbSession).selectAll(); + } + + public void delete(DbSession dbSession, AlmSettingDto almSettingDto){ + getMapper(dbSession).deleteByKey(almSettingDto.getKey()); + } + + public void update(DbSession dbSession, AlmSettingDto almSettingDto) { + long now = system2.now(); + getMapper(dbSession).update(almSettingDto, now); + almSettingDto.setUpdatedAt(now); + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/AlmSettingDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/AlmSettingDto.java new file mode 100644 index 00000000000..82f5db0b6d2 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/AlmSettingDto.java @@ -0,0 +1,127 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.alm.setting; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +public class AlmSettingDto { + + private String uuid; + private String key; + private String rawAlm; + private String url; + private String appId; + private String privateKey; + private String personalAccessToken; + private long updatedAt; + private long createdAt; + + String getUuid() { + return uuid; + } + + void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getKey() { + return key; + } + + public AlmSettingDto setKey(String key) { + this.key = key; + return this; + } + + public ALM getAlm() { + return ALM.fromId(rawAlm); + } + + public AlmSettingDto setAlm(ALM alm) { + rawAlm = alm.getId(); + return this; + } + + public String getRawAlm() { + return rawAlm; + } + + public AlmSettingDto setRawAlm(String rawAlm) { + this.rawAlm = rawAlm; + return this; + } + + @CheckForNull + public String getUrl() { + return url; + } + + public AlmSettingDto setUrl(@Nullable String url) { + this.url = url; + return this; + } + + @CheckForNull + public String getAppId() { + return appId; + } + + public AlmSettingDto setAppId(@Nullable String appId) { + this.appId = appId; + return this; + } + + @CheckForNull + public String getPrivateKey() { + return privateKey; + } + + public AlmSettingDto setPrivateKey(@Nullable String privateKey) { + this.privateKey = privateKey; + return this; + } + + @CheckForNull + public String getPersonalAccessToken() { + return personalAccessToken; + } + + public AlmSettingDto setPersonalAccessToken(@Nullable String personalAccessToken) { + this.personalAccessToken = personalAccessToken; + return this; + } + + long getUpdatedAt() { + return updatedAt; + } + + void setUpdatedAt(long updatedAt) { + this.updatedAt = updatedAt; + } + + long getCreatedAt() { + return createdAt; + } + + void setCreatedAt(long createdAt) { + this.createdAt = createdAt; + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/AlmSettingMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/AlmSettingMapper.java new file mode 100644 index 00000000000..584cd4a648c --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/AlmSettingMapper.java @@ -0,0 +1,41 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.alm.setting; + +import java.util.List; +import javax.annotation.CheckForNull; +import org.apache.ibatis.annotations.Param; + +public interface AlmSettingMapper { + + @CheckForNull + AlmSettingDto selectByUuid(@Param("uuid") String uuid); + + @CheckForNull + AlmSettingDto selectByKey(@Param("key") String key); + + List<AlmSettingDto> selectAll(); + + void insert(@Param("dto") AlmSettingDto almSettingDto, @Param("uuid") String uuid, @Param("now") long now); + + void update(@Param("dto") AlmSettingDto almSettingDto, @Param("now") long now); + + void deleteByKey(@Param("key") String key); +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/package-info.java b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/package-info.java new file mode 100644 index 00000000000..1e3bea4ce3a --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/package-info.java @@ -0,0 +1,24 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +@ParametersAreNonnullByDefault +package org.sonar.db.alm.setting; + +import javax.annotation.ParametersAreNonnullByDefault; + diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/alm/setting/AlmSettingMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/alm/setting/AlmSettingMapper.xml new file mode 100644 index 00000000000..bf66e2983fe --- /dev/null +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/alm/setting/AlmSettingMapper.xml @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> + +<mapper namespace="org.sonar.db.alm.setting.AlmSettingMapper"> + + <sql id="sqlColumns"> + a.kee as key, + a.uuid as uuid, + a.alm_id as rawAlm, + a.url as url, + a.app_id as appId, + a.private_key as privateKey, + a.pat as personalAccessToken, + a.created_at as createdAt, + a.updated_at as updatedAt + </sql> + + <select id="selectByUuid" parameterType="string" resultType="org.sonar.db.alm.setting.AlmSettingDto"> + select <include refid="sqlColumns"/> + from + alm_settings a + where + a.uuid = #{uuid, jdbcType=VARCHAR} + </select> + + <select id="selectByKey" parameterType="string" resultType="org.sonar.db.alm.setting.AlmSettingDto"> + select <include refid="sqlColumns"/> + from + alm_settings a + where + a.kee = #{key, jdbcType=VARCHAR} + </select> + + <select id="selectAll" resultType="org.sonar.db.alm.setting.AlmSettingDto"> + select <include refid="sqlColumns"/> + from alm_settings a + </select> + + + <insert id="insert" parameterType="Map" useGeneratedKeys="false"> + INSERT INTO alm_settings + ( + uuid, + kee, + alm_id, + url, + app_id, + private_key, + pat, + created_at, + updated_at + ) + VALUES ( + #{uuid, jdbcType=VARCHAR}, + #{dto.key, jdbcType=VARCHAR}, + #{dto.rawAlm, jdbcType=VARCHAR}, + #{dto.url, jdbcType=VARCHAR}, + #{dto.appId, jdbcType=VARCHAR}, + #{dto.privateKey, jdbcType=VARCHAR}, + #{dto.personalAccessToken, jdbcType=VARCHAR}, + #{now, jdbcType=BIGINT}, + #{now, jdbcType=BIGINT} + ) + </insert> + + <update id="update" parameterType="Map"> + UPDATE alm_settings + <set> + kee = #{dto.key, jdbcType=VARCHAR}, + url = #{dto.url, jdbcType=VARCHAR}, + app_id = #{dto.appId, jdbcType=VARCHAR}, + private_key = #{dto.privateKey, jdbcType=VARCHAR}, + pat = #{dto.personalAccessToken, jdbcType=VARCHAR}, + updated_at = #{now, jdbcType=BIGINT} + </set> + <where> + uuid = #{dto.uuid, jdbcType=VARCHAR} + </where> + </update> + + <delete id="deleteByKey" parameterType="String"> + DELETE FROM alm_settings WHERE kee = #{key, jdbcType=VARCHAR} + </delete> + + +</mapper> diff --git a/server/sonar-db-dao/src/schema/schema-sq.ddl b/server/sonar-db-dao/src/schema/schema-sq.ddl index 9f5c9f136b8..b286019ea08 100644 --- a/server/sonar-db-dao/src/schema/schema-sq.ddl +++ b/server/sonar-db-dao/src/schema/schema-sq.ddl @@ -50,6 +50,20 @@ CREATE UNIQUE INDEX ALM_APP_INSTALLS_OWNER ON ALM_APP_INSTALLS(ALM_ID, OWNER_ID) CREATE UNIQUE INDEX ALM_APP_INSTALLS_INSTALL ON ALM_APP_INSTALLS(ALM_ID, INSTALL_ID); CREATE INDEX ALM_APP_INSTALLS_EXTERNAL_ID ON ALM_APP_INSTALLS(USER_EXTERNAL_ID); +CREATE TABLE ALM_SETTINGS( + UUID VARCHAR(40) NOT NULL, + ALM_ID VARCHAR(40) NOT NULL, + KEE VARCHAR(40) NOT NULL, + URL VARCHAR(2000), + APP_ID VARCHAR(80), + PRIVATE_KEY VARCHAR(2000), + PAT VARCHAR(2000), + UPDATED_AT BIGINT NOT NULL, + CREATED_AT BIGINT NOT NULL +); +ALTER TABLE ALM_SETTINGS ADD CONSTRAINT PK_ALM_SETTINGS PRIMARY KEY(UUID); +CREATE UNIQUE INDEX UNIQ_ALM_SETTINGS ON ALM_SETTINGS(KEE); + CREATE TABLE ANALYSIS_PROPERTIES( UUID VARCHAR(40) NOT NULL, ANALYSIS_UUID VARCHAR(40) NOT NULL, diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java index 5063ba33bd1..d805141a0f2 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java @@ -30,6 +30,6 @@ public class DaoModuleTest { public void verify_count_of_added_components() { ComponentContainer container = new ComponentContainer(); new DaoModule().configure(container); - assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 63); + assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 64); } } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/alm/setting/AlmSettingDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/alm/setting/AlmSettingDaoTest.java new file mode 100644 index 00000000000..14dd5311aa4 --- /dev/null +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/alm/setting/AlmSettingDaoTest.java @@ -0,0 +1,140 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.alm.setting; + +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactory; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.almsettings.AlmSettingsTesting; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.db.almsettings.AlmSettingsTesting.newGithubAlmSettingDto; + +public class AlmSettingDaoTest { + + public static final long NOW = 1000000L; + private static final String A_UUID = "SOME_UUID"; + @Rule + public ExpectedException expectedException = ExpectedException.none(); + private System2 system2 = mock(System2.class); + @Rule + public DbTester db = DbTester.create(system2); + + private DbSession dbSession = db.getSession(); + private UuidFactory uuidFactory = mock(UuidFactory.class); + private AlmSettingDao underTest = new AlmSettingDao(system2, uuidFactory); + + @Test + public void selectByUuid() { + when(uuidFactory.create()).thenReturn(A_UUID); + when(system2.now()).thenReturn(NOW); + + AlmSettingDto almSettingDto = newGithubAlmSettingDto(); + underTest.insert(dbSession, almSettingDto); + + assertThat(underTest.selectByUuid(dbSession, A_UUID).get()) + .extracting(AlmSettingDto::getUuid, AlmSettingDto::getKey, AlmSettingDto::getRawAlm, AlmSettingDto::getUrl, + AlmSettingDto::getAppId, AlmSettingDto::getPrivateKey, AlmSettingDto::getPersonalAccessToken, + AlmSettingDto::getCreatedAt, AlmSettingDto::getUpdatedAt) + .containsExactly(A_UUID, almSettingDto.getKey(), ALM.GITHUB.getId(), almSettingDto.getUrl(), + almSettingDto.getAppId(), almSettingDto.getPrivateKey(), + almSettingDto.getPersonalAccessToken(), NOW, NOW); + + assertThat(underTest.selectByUuid(dbSession, "foo")).isNotPresent(); + } + + @Test + public void selectByKey() { + when(uuidFactory.create()).thenReturn(A_UUID); + when(system2.now()).thenReturn(NOW); + + AlmSettingDto almSettingDto = AlmSettingsTesting.newGithubAlmSettingDto(); + underTest.insert(dbSession, almSettingDto); + + assertThat(underTest.selectByKey(dbSession, almSettingDto.getKey()).get()) + .extracting(AlmSettingDto::getUuid, AlmSettingDto::getKey, AlmSettingDto::getRawAlm, AlmSettingDto::getUrl, + AlmSettingDto::getAppId, AlmSettingDto::getPrivateKey, AlmSettingDto::getPersonalAccessToken, + AlmSettingDto::getCreatedAt, AlmSettingDto::getUpdatedAt) + .containsExactly(A_UUID, almSettingDto.getKey(), ALM.GITHUB.getId(), almSettingDto.getUrl(), + almSettingDto.getAppId(), almSettingDto.getPrivateKey(), + almSettingDto.getPersonalAccessToken(), NOW, NOW); + + assertThat(underTest.selectByKey(dbSession, "foo")).isNotPresent(); + } + + @Test + public void selectAll() { + when(uuidFactory.create()).thenReturn(A_UUID); + when(system2.now()).thenReturn(NOW); + underTest.insert(dbSession, newGithubAlmSettingDto()); + when(uuidFactory.create()).thenReturn(A_UUID + "bis"); + underTest.insert(dbSession, newGithubAlmSettingDto()); + + List<AlmSettingDto> almSettings = underTest.selectAll(dbSession); + assertThat(almSettings).isNotNull(); + assertThat(almSettings).size().isEqualTo(2); + } + + @Test + public void update() { + when(uuidFactory.create()).thenReturn(A_UUID); + when(system2.now()).thenReturn(NOW); + AlmSettingDto almSettingDto = newGithubAlmSettingDto(); + underTest.insert(dbSession, almSettingDto); + + almSettingDto.setPrivateKey("updated private key"); + almSettingDto.setAppId("updated app id"); + almSettingDto.setUrl("updated url"); + almSettingDto.setPersonalAccessToken("updated pat"); + almSettingDto.setKey("updated key"); + + when(system2.now()).thenReturn(NOW + 1); + underTest.update(dbSession, almSettingDto); + + AlmSettingDto result = underTest.selectByUuid(dbSession, A_UUID).get(); + assertThat(result) + .extracting(AlmSettingDto::getUuid, AlmSettingDto::getKey, AlmSettingDto::getRawAlm, AlmSettingDto::getUrl, + AlmSettingDto::getAppId, AlmSettingDto::getPrivateKey, AlmSettingDto::getPersonalAccessToken, + AlmSettingDto::getCreatedAt, AlmSettingDto::getUpdatedAt) + .containsExactly(A_UUID, almSettingDto.getKey(), ALM.GITHUB.getId(), almSettingDto.getUrl(), + almSettingDto.getAppId(), almSettingDto.getPrivateKey(), + almSettingDto.getPersonalAccessToken(), NOW, NOW + 1); + } + + @Test + public void delete() { + when(uuidFactory.create()).thenReturn(A_UUID); + when(system2.now()).thenReturn(NOW); + AlmSettingDto almSettingDto = newGithubAlmSettingDto(); + underTest.insert(dbSession, almSettingDto); + + underTest.delete(dbSession, almSettingDto); + + assertThat(underTest.selectByKey(dbSession, almSettingDto.getKey()).isPresent()).isFalse(); + } + +} diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java index 1fc19513ada..a39cd1dea64 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java @@ -33,6 +33,7 @@ import org.picocontainer.containers.TransientPicoContainer; import org.sonar.api.utils.System2; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.db.alm.AlmDbTester; +import org.sonar.db.almsettings.AlmSettingsDbTester; import org.sonar.db.component.ComponentDbTester; import org.sonar.db.component.ProjectLinkDbTester; import org.sonar.db.event.EventDbTester; @@ -96,6 +97,7 @@ public class DbTester extends AbstractDbTester<TestDbImpl> { private final WebhookDeliveryDbTester webhookDeliveryDbTester; private final AlmDbTester almDbTester; private final InternalComponentPropertyDbTester internalComponentPropertyTester; + private final AlmSettingsDbTester almSettingsDbTester; private DbTester(System2 system2, @Nullable String schemaPath, MyBatisConfExtension... confExtensions) { super(TestDbImpl.create(schemaPath, confExtensions)); @@ -124,6 +126,7 @@ public class DbTester extends AbstractDbTester<TestDbImpl> { this.almDbTester = new AlmDbTester(this); this.internalComponentPropertyTester = new InternalComponentPropertyDbTester(this); this.newCodePeriodTester = new NewCodePeriodDbTester(this); + this.almSettingsDbTester = new AlmSettingsDbTester(this); } public static DbTester create() { @@ -294,6 +297,10 @@ public class DbTester extends AbstractDbTester<TestDbImpl> { return internalComponentPropertyTester; } + public AlmSettingsDbTester almSettings() { + return almSettingsDbTester; + } + @Override protected void after() { if (session != null) { diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/almsettings/AlmSettingsDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/almsettings/AlmSettingsDbTester.java new file mode 100644 index 00000000000..0a74acc40cf --- /dev/null +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/almsettings/AlmSettingsDbTester.java @@ -0,0 +1,47 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.almsettings; + +import java.util.function.Consumer; +import org.sonar.db.DbTester; +import org.sonar.db.alm.setting.AlmSettingDto; + +import static java.util.Arrays.stream; +import static org.sonar.db.almsettings.AlmSettingsTesting.newGithubAlmSettingDto; + +public class AlmSettingsDbTester { + + private final DbTester db; + + public AlmSettingsDbTester(DbTester db) { + this.db = db; + } + + @SafeVarargs + public final AlmSettingDto insertGitHubAlmSetting(Consumer<AlmSettingDto>... populators) { + AlmSettingDto dto = newGithubAlmSettingDto(); + stream(populators).forEach(p -> p.accept(dto)); + + db.getDbClient().almSettingDao().insert(db.getSession(), dto); + db.commit(); + return dto; + } + +} diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/almsettings/AlmSettingsTesting.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/almsettings/AlmSettingsTesting.java new file mode 100644 index 00000000000..e799a859f8f --- /dev/null +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/almsettings/AlmSettingsTesting.java @@ -0,0 +1,37 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.almsettings; + +import org.sonar.db.alm.setting.ALM; +import org.sonar.db.alm.setting.AlmSettingDto; + +import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; + +public class AlmSettingsTesting { + + public static AlmSettingDto newGithubAlmSettingDto() { + return new AlmSettingDto() + .setKey(randomAlphanumeric(40)) + .setUrl(randomAlphanumeric(2000)) + .setAppId(randomAlphanumeric(80)) + .setAlm(ALM.GITHUB) + .setPrivateKey(randomAlphanumeric(2000)); + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java index b199571a48c..1fc8fe3222f 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java @@ -26,6 +26,7 @@ import org.sonar.server.platform.db.migration.step.MigrationStepRegistryImpl; import org.sonar.server.platform.db.migration.step.MigrationStepsProvider; import org.sonar.server.platform.db.migration.version.v00.DbVersion00; import org.sonar.server.platform.db.migration.version.v80.DbVersion80; +import org.sonar.server.platform.db.migration.version.v81.DbVersion81; public class MigrationConfigurationModule extends Module { @Override @@ -34,6 +35,7 @@ public class MigrationConfigurationModule extends Module { // DbVersion implementations DbVersion00.class, DbVersion80.class, + DbVersion81.class, // migration steps MigrationStepRegistryImpl.class, diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v00/PopulateInitialSchema.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v00/PopulateInitialSchema.java index 0af992cc500..271b94f43f5 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v00/PopulateInitialSchema.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v00/PopulateInitialSchema.java @@ -74,8 +74,8 @@ public class PopulateInitialSchema extends DataChange { long now = system2.now(); context.prepareUpsert("insert into users " + - "(uuid, login, name, email, external_id, external_login, external_identity_provider, user_local, crypted_password, salt, hash_method, is_root, onboarded, created_at, updated_at)" - + + "(uuid, login, name, email, external_id, external_login, external_identity_provider, user_local, crypted_password, salt, hash_method, is_root, onboarded, " + + "created_at, updated_at)" + " values " + "(?, ?, 'Administrator', null, 'admin', 'admin', 'sonarqube', ?, '$2a$12$uCkkXmhW5ThVK8mpBvnXOOJRLd64LJeHTeCkSuB3lfaR2N0AYBaSi', null, 'BCRYPT', ?, ?, ?, ?)") .setString(1, uuidFactory.create()) diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v81/CreateAlmSettingsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v81/CreateAlmSettingsTable.java new file mode 100644 index 00000000000..abdfd3188eb --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v81/CreateAlmSettingsTable.java @@ -0,0 +1,109 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.platform.db.migration.version.v81; + +import java.sql.Connection; +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.DatabaseUtils; +import org.sonar.server.platform.db.migration.def.VarcharColumnDef; +import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; +import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; +import org.sonar.server.platform.db.migration.step.DdlChange; + +import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder; +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; + +public class CreateAlmSettingsTable extends DdlChange { + + private static final String TABLE_NAME = "alm_settings"; + + private static final VarcharColumnDef KEY = newVarcharColumnDefBuilder() + .setColumnName("kee") + .setIsNullable(false) + .setLimit(40) + .build(); + + public CreateAlmSettingsTable(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + if (tableExists()) { + return; + } + context.execute(new CreateTableBuilder(getDialect(), TABLE_NAME) + .addPkColumn(newVarcharColumnDefBuilder() + .setColumnName("uuid") + .setIsNullable(false) + .setLimit(UUID_SIZE) + .build()) + .addColumn(newVarcharColumnDefBuilder() + .setColumnName("alm_id") + .setIsNullable(false) + .setLimit(40) + .build()) + .addColumn(KEY) + .addColumn(newVarcharColumnDefBuilder() + .setColumnName("url") + .setIsNullable(true) + .setLimit(2000) + .build()) + .addColumn(newVarcharColumnDefBuilder() + .setColumnName("app_id") + .setIsNullable(true) + .setLimit(80) + .build()) + .addColumn(newVarcharColumnDefBuilder() + .setColumnName("private_key") + .setIsNullable(true) + .setLimit(2000) + .build()) + .addColumn(newVarcharColumnDefBuilder() + .setColumnName("pat") + .setIsNullable(true) + .setLimit(2000) + .build()) + .addColumn(newBigIntegerColumnDefBuilder() + .setColumnName("updated_at") + .setIsNullable(false) + .build()) + .addColumn(newBigIntegerColumnDefBuilder() + .setColumnName("created_at") + .setIsNullable(false) + .build()) + .build()); + + context.execute(new CreateIndexBuilder() + .setTable(TABLE_NAME) + .addColumn(KEY) + .setName("uniq_alm_settings") + .setUnique(true) + .build()); + } + + private boolean tableExists() throws SQLException { + try (Connection connection = getDatabase().getDataSource().getConnection()) { + return DatabaseUtils.tableExists(TABLE_NAME, connection); + } + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v81/DbVersion81.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v81/DbVersion81.java new file mode 100644 index 00000000000..b5b2897a92b --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v81/DbVersion81.java @@ -0,0 +1,31 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.platform.db.migration.version.v81; + +import org.sonar.server.platform.db.migration.step.MigrationStepRegistry; +import org.sonar.server.platform.db.migration.version.DbVersion; + +public class DbVersion81 implements DbVersion { + @Override + public void addSteps(MigrationStepRegistry registry) { + registry + .add(3100, "Create ALM_SETTINGS table", CreateAlmSettingsTable.class); + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v81/package-info.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v81/package-info.java new file mode 100644 index 00000000000..835eb4a8909 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v81/package-info.java @@ -0,0 +1,23 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +@ParametersAreNonnullByDefault +package org.sonar.server.platform.db.migration.version.v81; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/MigrationConfigurationModuleTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/MigrationConfigurationModuleTest.java index 4244868b614..aa4755278b6 100644 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/MigrationConfigurationModuleTest.java +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/MigrationConfigurationModuleTest.java @@ -37,7 +37,7 @@ public class MigrationConfigurationModuleTest { assertThat(container.getPicoContainer().getComponentAdapters()) .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER // DbVersion classes - + 2 + + 3 // Others + 4); } diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v81/CreateAlmSettingsTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v81/CreateAlmSettingsTableTest.java new file mode 100644 index 00000000000..cd9114c28bf --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v81/CreateAlmSettingsTableTest.java @@ -0,0 +1,65 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.server.platform.db.migration.version.v81; + +import java.sql.SQLException; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.db.CoreDbTester; + +import static java.sql.Types.BIGINT; +import static java.sql.Types.VARCHAR; + +public class CreateAlmSettingsTableTest { + + private static final String TABLE_NAME = "alm_settings"; + + @Rule + public CoreDbTester dbTester = CoreDbTester.createEmpty(); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private CreateAlmSettingsTable underTest = new CreateAlmSettingsTable(dbTester.database()); + + @Test + public void table_has_been_created() throws SQLException { + underTest.execute(); + + dbTester.assertTableExists(TABLE_NAME); + dbTester.assertPrimaryKey(TABLE_NAME, "pk_alm_settings", "uuid"); + dbTester.assertUniqueIndex(TABLE_NAME, "uniq_alm_settings", "kee"); + + dbTester.assertColumnDefinition(TABLE_NAME, "uuid", VARCHAR, 40, false); + dbTester.assertColumnDefinition(TABLE_NAME, "alm_id", VARCHAR, 40, false); + dbTester.assertColumnDefinition(TABLE_NAME, "url", VARCHAR, 2000, true); + dbTester.assertColumnDefinition(TABLE_NAME, "app_id", VARCHAR, 80, true); + dbTester.assertColumnDefinition(TABLE_NAME, "private_key", VARCHAR, 2000, true); + dbTester.assertColumnDefinition(TABLE_NAME, "pat", VARCHAR, 2000, true); + dbTester.assertColumnDefinition(TABLE_NAME, "updated_at", BIGINT, 20, false); + dbTester.assertColumnDefinition(TABLE_NAME, "created_at", BIGINT, 20, false); + + // script should not fail if executed twice + underTest.execute(); + } + +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v81/DbVersion81Test.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v81/DbVersion81Test.java new file mode 100644 index 00000000000..a8dcfb748ca --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v81/DbVersion81Test.java @@ -0,0 +1,43 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.server.platform.db.migration.version.v81; + +import org.junit.Test; +import org.sonar.server.platform.db.migration.version.DbVersion; + +import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMigrationCount; +import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMinimumMigrationNumber; + +public class DbVersion81Test { + + private DbVersion underTest = new DbVersion81(); + + @Test + public void migrationNumber_starts_at_3000() { + verifyMinimumMigrationNumber(underTest, 3100); + } + + @Test + public void verify_migration_count() { + verifyMigrationCount(underTest, 1); + } + +} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/AlmSettingsWs.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/AlmSettingsWs.java new file mode 100644 index 00000000000..19cf36a7547 --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/AlmSettingsWs.java @@ -0,0 +1,42 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.almsettings; + +import java.util.List; +import org.sonar.api.server.ws.WebService; + +public class AlmSettingsWs implements WebService { + private final List<AlmSettingsWsAction> actions; + + public AlmSettingsWs(List<AlmSettingsWsAction> actions) { + this.actions = actions; + } + + @Override + public void define(Context context) { + NewController controller = context.createController("api/alm_settings") + .setDescription("Manage ALM Settings") + .setSince("8.1"); + + actions.forEach(a -> a.define(controller)); + + controller.done(); + } +} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/AlmSettingsWsAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/AlmSettingsWsAction.java new file mode 100644 index 00000000000..c9508e79f88 --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/AlmSettingsWsAction.java @@ -0,0 +1,26 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.almsettings; + +import org.sonar.server.ws.WsAction; + +public interface AlmSettingsWsAction extends WsAction { + // marker interface +} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/AlmSettingsWsModule.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/AlmSettingsWsModule.java new file mode 100644 index 00000000000..2b568c07bef --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/AlmSettingsWsModule.java @@ -0,0 +1,34 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.almsettings; + +import org.sonar.core.platform.Module; + +public class AlmSettingsWsModule extends Module { + @Override + protected void configureModule() { + add( + AlmSettingsWs.class, + ListDefinitionsAction.class, + CreateGithubAction.class, + UpdateGitHubAction.class, + DeleteAction.class); + } +} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/CreateGithubAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/CreateGithubAction.java new file mode 100644 index 00000000000..6412a90293c --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/CreateGithubAction.java @@ -0,0 +1,102 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.almsettings; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.server.user.UserSession; + +import static java.lang.String.format; +import static org.sonar.db.alm.setting.ALM.GITHUB; + +public class CreateGithubAction implements AlmSettingsWsAction { + + private static final String PARAM_KEY = "key"; + private static final String PARAM_URL = "url"; + private static final String PARAM_APP_ID = "appId"; + private static final String PARAM_PRIVATE_KEY = "privateKey"; + + private final DbClient dbClient; + private UserSession userSession; + + public CreateGithubAction(DbClient dbClient, UserSession userSession) { + this.dbClient = dbClient; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context.createAction("create_github") + .setDescription("Create GitHub ALM instance Setting. <br/>" + + "Requires the 'Administer System' permission") + .setPost(true) + .setSince("8.1") + .setHandler(this); + + action.createParam(PARAM_KEY) + .setRequired(true) + .setMaximumLength(40) + .setDescription("Unique key of the GitHub instance setting"); + action.createParam(PARAM_URL) + .setRequired(true) + .setMaximumLength(2000) + .setDescription("GitHub API URL"); + action.createParam(PARAM_APP_ID) + .setRequired(true) + .setMaximumLength(80) + .setDescription("GitHub API ID"); + action.createParam(PARAM_PRIVATE_KEY) + .setRequired(true) + .setMaximumLength(2000) + .setDescription("GitHub App private key"); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkIsSystemAdministrator(); + doHandle(request); + response.noContent(); + } + + private void doHandle(Request request) { + String key = request.mandatoryParam(PARAM_KEY); + String url = request.mandatoryParam(PARAM_URL); + String appId = request.mandatoryParam(PARAM_APP_ID); + String privateKey = request.mandatoryParam(PARAM_PRIVATE_KEY); + try (DbSession dbSession = dbClient.openSession(false)) { + dbClient.almSettingDao().selectByKey(dbSession, key) + .ifPresent(almSetting -> { + throw new IllegalArgumentException(format("An ALM setting with key '%s' already exist", almSetting.getKey())); + }); + dbClient.almSettingDao().insert(dbSession, new AlmSettingDto() + .setAlm(GITHUB) + .setKey(key) + .setUrl(url) + .setAppId(appId) + .setPrivateKey(privateKey)); + dbSession.commit(); + } + } + +} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/DeleteAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/DeleteAction.java new file mode 100644 index 00000000000..915430c839f --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/DeleteAction.java @@ -0,0 +1,77 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.almsettings; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.user.UserSession; + +import static java.lang.String.format; + +public class DeleteAction implements AlmSettingsWsAction { + + private static final String PARAM_KEY = "key"; + + private final DbClient dbClient; + private UserSession userSession; + + public DeleteAction(DbClient dbClient, UserSession userSession) { + this.dbClient = dbClient; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context + .createAction("delete") + .setDescription("Delete ALM Settings.<br/>" + + "Requires the 'Administer System' permission") + .setSince("8.1") + .setPost(true) + .setHandler(this); + + action + .createParam(PARAM_KEY) + .setDescription("ALM Setting key") + .setRequired(true); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkIsSystemAdministrator(); + doHandle(request); + response.noContent(); + } + + private void doHandle(Request request) { + String key = request.mandatoryParam(PARAM_KEY); + try (DbSession dbSession = dbClient.openSession(false)) { + AlmSettingDto almSettingDto = dbClient.almSettingDao().selectByKey(dbSession, key) + .orElseThrow(() -> new NotFoundException(format("No ALM setting with key '%s' has been found", key))); + dbClient.almSettingDao().delete(dbSession, almSettingDto); + dbSession.commit(); + } + } +} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ListDefinitionsAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ListDefinitionsAction.java new file mode 100644 index 00000000000..a79ef988ee1 --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ListDefinitionsAction.java @@ -0,0 +1,86 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.almsettings; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.alm.setting.ALM; +import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.server.user.UserSession; +import org.sonarqube.ws.AlmSettings.AlmSettingGithub; + +import static java.util.Collections.emptyList; +import static java.util.Objects.requireNonNull; +import static org.sonar.server.ws.WsUtils.writeProtobuf; +import static org.sonarqube.ws.AlmSettings.ListDefinitionsWsResponse; + +public class ListDefinitionsAction implements AlmSettingsWsAction { + + private final DbClient dbClient; + private UserSession userSession; + + public ListDefinitionsAction(DbClient dbClient, UserSession userSession) { + this.dbClient = dbClient; + this.userSession = userSession; + } + + private static AlmSettingGithub convert(AlmSettingDto settingDto) { + return AlmSettingGithub + .newBuilder() + .setKey(settingDto.getKey()) + .setUrl(requireNonNull(settingDto.getUrl(), "URL cannot be null for GitHub ALM setting")) + .setAppId(requireNonNull(settingDto.getAppId(), "App ID cannot be null for GitHub ALM setting")) + .setPrivateKey(requireNonNull(settingDto.getPrivateKey(), "Private Key cannot be null for GitHub ALM setting")) + .build(); + } + + @Override + public void define(WebService.NewController context) { + context.createAction("list_definitions") + .setDescription("List ALM Settings. <br/>" + + "Requires the 'Administer System' permission") + .setSince("8.1") + .setResponseExample(getClass().getResource("list_definitions-example.json")) + .setHandler(this); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkIsSystemAdministrator(); + ListDefinitionsWsResponse wsResponse = doHandle(); + writeProtobuf(wsResponse, request, response); + } + + private ListDefinitionsWsResponse doHandle() { + try (DbSession dbSession = dbClient.openSession(false)) { + List<AlmSettingDto> settings = dbClient.almSettingDao().selectAll(dbSession); + Map<ALM, List<AlmSettingDto>> settingsByAlm = settings.stream().collect(Collectors.groupingBy(AlmSettingDto::getAlm)); + List<AlmSettingGithub> githubSettings = settingsByAlm.getOrDefault(ALM.GITHUB, emptyList()).stream() + .map(ListDefinitionsAction::convert).collect(Collectors.toList()); + return ListDefinitionsWsResponse.newBuilder().addAllGithub(githubSettings).build(); + } + } +} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/UpdateGitHubAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/UpdateGitHubAction.java new file mode 100644 index 00000000000..d2e05875764 --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/UpdateGitHubAction.java @@ -0,0 +1,114 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.almsettings; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.user.UserSession; + +import static java.lang.String.format; +import static org.apache.commons.lang.StringUtils.isNotBlank; + +public class UpdateGitHubAction implements AlmSettingsWsAction { + + private static final String PARAM_KEY = "key"; + private static final String PARAM_NEW_KEY = "newKey"; + private static final String PARAM_URL = "url"; + private static final String PARAM_APP_ID = "appId"; + private static final String PARAM_PRIVATE_KEY = "privateKey"; + + private final DbClient dbClient; + private UserSession userSession; + + public UpdateGitHubAction(DbClient dbClient, UserSession userSession) { + this.dbClient = dbClient; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context.createAction("update_github") + .setDescription("Update GitHub ALM instance Setting. <br/>" + + "Requires the 'Administer System' permission") + .setPost(true) + .setSince("8.1") + .setHandler(this); + + action.createParam(PARAM_KEY) + .setRequired(true) + .setMaximumLength(40) + .setDescription("Unique key of the GitHub instance setting"); + action.createParam(PARAM_NEW_KEY) + .setRequired(false) + .setMaximumLength(40) + .setDescription("Optional new value for an unique key of the GitHub instance setting"); + action.createParam(PARAM_URL) + .setRequired(true) + .setMaximumLength(2000) + .setDescription("GitHub API URL"); + action.createParam(PARAM_APP_ID) + .setRequired(true) + .setMaximumLength(80) + .setDescription("GitHub API ID"); + action.createParam(PARAM_PRIVATE_KEY) + .setRequired(true) + .setMaximumLength(2000) + .setDescription("GitHub App private key"); + } + + @Override + public void handle(Request request, Response response) throws Exception { + userSession.checkIsSystemAdministrator(); + doHandle(request); + response.noContent(); + } + + private void doHandle(Request request) { + String key = request.mandatoryParam(PARAM_KEY); + String newKey = request.param(PARAM_NEW_KEY); + String url = request.mandatoryParam(PARAM_URL); + String appId = request.mandatoryParam(PARAM_APP_ID); + String privateKey = request.mandatoryParam(PARAM_PRIVATE_KEY); + + try (DbSession dbSession = dbClient.openSession(false)) { + + AlmSettingDto almSettingDto = dbClient.almSettingDao().selectByKey(dbSession, key) + .orElseThrow(() -> new NotFoundException(format("No ALM setting with key '%s' has been found", key))); + if (isNotBlank(newKey) && !newKey.equals(key)) { + dbClient.almSettingDao().selectByKey(dbSession, newKey) + .ifPresent(almSetting -> { + throw new IllegalArgumentException(format("ALM setting with key '%s' already exists", almSetting.getKey())); + }); + } + dbClient.almSettingDao().update(dbSession, almSettingDto + .setKey(isNotBlank(newKey) ? newKey : key) + .setUrl(url) + .setAppId(appId) + .setPrivateKey(privateKey)); + dbSession.commit(); + } + } + +} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/package-info.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/package-info.java new file mode 100644 index 00000000000..a01307de8b1 --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/package-info.java @@ -0,0 +1,24 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +@ParametersAreNonnullByDefault +package org.sonar.server.almsettings; + +import javax.annotation.ParametersAreNonnullByDefault; + diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/almsettings/list_definitions-example.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/almsettings/list_definitions-example.json new file mode 100644 index 00000000000..a4d22e5844c --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/almsettings/list_definitions-example.json @@ -0,0 +1,10 @@ +{ + "github": [ + { + "key": "GitHub Server - Dev Team", + "url": "https://github.enterprise.com", + "appId": "12345", + "privateKey": "54684654" + } + ] +} diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/AlmSettingsWsModuleTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/AlmSettingsWsModuleTest.java new file mode 100644 index 00000000000..2ebabef0854 --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/AlmSettingsWsModuleTest.java @@ -0,0 +1,38 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.server.almsettings; + +import org.junit.Test; +import org.sonar.core.platform.ComponentContainer; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.core.platform.ComponentContainer.COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER; + +public class AlmSettingsWsModuleTest { + + @Test + public void verify_count_of_added_components() { + ComponentContainer container = new ComponentContainer(); + new AlmSettingsWsModule().configure(container); + assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 5); + } + +} diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/CreateGithubActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/CreateGithubActionTest.java new file mode 100644 index 00000000000..3e48df770b5 --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/CreateGithubActionTest.java @@ -0,0 +1,107 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.server.almsettings; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbTester; +import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsActionTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.groups.Tuple.tuple; + +public class CreateGithubActionTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public DbTester db = DbTester.create(); + + private WsActionTester ws = new WsActionTester(new CreateGithubAction(db.getDbClient(), userSession)); + + @Test + public void create() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + + ws.newRequest() + .setParam("key", "GitHub Server - Dev Team") + .setParam("url", "https://github.enterprise.com") + .setParam("appId", "12345") + .setParam("privateKey", "678910") + .execute(); + + assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession())) + .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getAppId, AlmSettingDto::getPrivateKey) + .containsOnly(tuple("GitHub Server - Dev Team", "https://github.enterprise.com", "12345", "678910")); + } + + @Test + public void fail_when_key_is_already_used() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + AlmSettingDto gitHubAlmSetting = db.almSettings().insertGitHubAlmSetting(); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage(String.format("An ALM setting with key '%s' already exist", gitHubAlmSetting.getKey())); + + ws.newRequest() + .setParam("key", gitHubAlmSetting.getKey()) + .setParam("url", "https://github.enterprise.com") + .setParam("appId", "12345") + .setParam("privateKey", "678910") + .execute(); + } + + @Test + public void fail_when_missing_administer_system_permission() { + UserDto user = db.users().insertUser(); + userSession.logIn(user); + + expectedException.expect(ForbiddenException.class); + + ws.newRequest() + .setParam("key", "GitHub Server - Dev Team") + .setParam("url", "https://github.enterprise.com") + .setParam("appId", "12345") + .setParam("privateKey", "678910") + .execute(); + } + + @Test + public void definition() { + WebService.Action def = ws.getDef(); + + assertThat(def.since()).isEqualTo("8.1"); + assertThat(def.isPost()).isTrue(); + assertThat(def.params()) + .extracting(WebService.Param::key, WebService.Param::isRequired) + .containsExactlyInAnyOrder(tuple("key", true), tuple("url", true), tuple("appId", true), tuple("privateKey", true)); + } +} diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/DeleteActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/DeleteActionTest.java new file mode 100644 index 00000000000..aec45c06f25 --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/DeleteActionTest.java @@ -0,0 +1,97 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.almsettings; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbTester; +import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsActionTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.groups.Tuple.tuple; + +public class DeleteActionTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public DbTester db = DbTester.create(); + + private WsActionTester ws = new WsActionTester(new DeleteAction(db.getDbClient(), userSession)); + + @Test + public void delete() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + AlmSettingDto almSettingDto = db.almSettings().insertGitHubAlmSetting(); + + ws.newRequest() + .setParam("key", almSettingDto.getKey()) + .execute(); + + assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession())).isEmpty(); + } + + @Test + public void fail_when_key_does_not_match_existing_alm_setting() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("No ALM setting with key 'unknown' has been found"); + + ws.newRequest() + .setParam("key", "unknown") + .execute(); + } + + @Test + public void fail_when_missing_administer_system_permission() { + UserDto user = db.users().insertUser(); + userSession.logIn(user); + AlmSettingDto almSettingDto = db.almSettings().insertGitHubAlmSetting(); + + expectedException.expect(ForbiddenException.class); + + ws.newRequest() + .setParam("key", almSettingDto.getKey()) + .execute(); + } + + @Test + public void definition() { + WebService.Action def = ws.getDef(); + + assertThat(def.since()).isEqualTo("8.1"); + assertThat(def.isPost()).isTrue(); + assertThat(def.params()) + .extracting(WebService.Param::key, WebService.Param::isRequired) + .containsExactlyInAnyOrder(tuple("key", true)); + } +} diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ListDefinitionsActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ListDefinitionsActionTest.java new file mode 100644 index 00000000000..63a9dac0d4d --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ListDefinitionsActionTest.java @@ -0,0 +1,114 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.almsettings; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbTester; +import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsActionTester; +import org.sonarqube.ws.AlmSettings; +import org.sonarqube.ws.AlmSettings.AlmSettingGithub; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; +import static org.junit.rules.ExpectedException.none; +import static org.sonar.server.tester.UserSessionRule.standalone; +import static org.sonar.test.JsonAssert.assertJson; +import static org.sonarqube.ws.AlmSettings.*; + +public class ListDefinitionsActionTest { + + @Rule + public ExpectedException expectedException = none(); + @Rule + public UserSessionRule userSession = standalone(); + @Rule + public DbTester db = DbTester.create(); + + private WsActionTester ws = new WsActionTester(new ListDefinitionsAction(db.getDbClient(), userSession)); + + @Test + public void list_github_settings() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + AlmSettingDto almSetting1 = db.almSettings().insertGitHubAlmSetting(); + AlmSettingDto almSetting2 = db.almSettings().insertGitHubAlmSetting(); + + ListDefinitionsWsResponse wsResponse = ws.newRequest().executeProtobuf(ListDefinitionsWsResponse.class); + + assertThat(wsResponse.getGithubList()) + .extracting(AlmSettingGithub::getKey, AlmSettingGithub::getUrl, AlmSettingGithub::getAppId, AlmSettingGithub::getPrivateKey) + .containsExactlyInAnyOrder( + tuple(almSetting1.getKey(), almSetting1.getUrl(), almSetting1.getAppId(), almSetting1.getPrivateKey()), + tuple(almSetting2.getKey(), almSetting2.getUrl(), almSetting2.getAppId(), almSetting2.getPrivateKey())); + } + + @Test + public void return_empty_list_when_no_settings() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + + ListDefinitionsWsResponse wsResponse = ws.newRequest().executeProtobuf(ListDefinitionsWsResponse.class); + + assertThat(wsResponse.getGithubList()).isEmpty(); + } + + @Test + public void fail_when_user_is_not_system_administrator() { + UserDto user = db.users().insertUser(); + userSession.logIn(user); + db.almSettings().insertGitHubAlmSetting(); + + expectedException.expect(ForbiddenException.class); + + ws.newRequest().executeProtobuf(ListDefinitionsWsResponse.class); + } + + @Test + public void json_example() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + db.almSettings().insertGitHubAlmSetting( + almSettingDto -> almSettingDto + .setKey("GitHub Server - Dev Team") + .setUrl("https://github.enterprise.com") + .setAppId("12345") + .setPrivateKey("54684654")); + + String response = ws.newRequest().execute().getInput(); + + assertJson(response).isSimilarTo(getClass().getResource("list_definitions-example.json")); + } + + @Test + public void definition() { + WebService.Action def = ws.getDef(); + + assertThat(def.since()).isEqualTo("8.1"); + assertThat(def.params()).isEmpty(); + assertThat(def.isPost()).isFalse(); + } +} diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/UpdateGithubActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/UpdateGithubActionTest.java new file mode 100644 index 00000000000..c0deea9aa10 --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/UpdateGithubActionTest.java @@ -0,0 +1,151 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.server.almsettings; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbTester; +import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsActionTester; + +import static java.lang.String.format; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.groups.Tuple.tuple; + +public class UpdateGithubActionTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public DbTester db = DbTester.create(); + + private WsActionTester ws = new WsActionTester(new UpdateGitHubAction(db.getDbClient(), userSession)); + + @Test + public void update() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + AlmSettingDto almSettingDto = db.almSettings().insertGitHubAlmSetting(); + + ws.newRequest() + .setParam("key", almSettingDto.getKey()) + .setParam("url", "https://github.enterprise-unicorn.com") + .setParam("appId", "54321") + .setParam("privateKey", "10987654321") + .execute(); + + assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession())) + .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getAppId, AlmSettingDto::getPrivateKey) + .containsOnly(tuple(almSettingDto.getKey(), "https://github.enterprise-unicorn.com", "54321", "10987654321")); + } + + @Test + public void update_with_new_key() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + AlmSettingDto almSettingDto = db.almSettings().insertGitHubAlmSetting(); + + ws.newRequest() + .setParam("key", almSettingDto.getKey()) + .setParam("newKey", "GitHub Server - Infra Team") + .setParam("url", "https://github.enterprise-unicorn.com") + .setParam("appId", "54321") + .setParam("privateKey", "10987654321") + .execute(); + + assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession())) + .extracting(AlmSettingDto::getKey, AlmSettingDto::getUrl, AlmSettingDto::getAppId, AlmSettingDto::getPrivateKey) + .containsOnly(tuple("GitHub Server - Infra Team", "https://github.enterprise-unicorn.com", "54321", "10987654321")); + } + + @Test + public void fail_when_key_does_not_match_existing_alm_setting() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("No ALM setting with key 'unknown' has been found"); + + ws.newRequest() + .setParam("key", "unknown") + .setParam("newKey", "GitHub Server - Infra Team") + .setParam("url", "https://github.enterprise-unicorn.com") + .setParam("appId", "54321") + .setParam("privateKey", "10987654321") + .execute(); + } + + @Test + public void fail_when_new_key_matches_existing_alm_setting() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + AlmSettingDto almSetting1 = db.almSettings().insertGitHubAlmSetting(); + AlmSettingDto almSetting2 = db.almSettings().insertGitHubAlmSetting(); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage(format("ALM setting with key '%s' already exists", almSetting2.getKey())); + + ws.newRequest() + .setParam("key", almSetting1.getKey()) + .setParam("newKey", almSetting2.getKey()) + .setParam("url", "https://github.enterprise-unicorn.com") + .setParam("appId", "54321") + .setParam("privateKey", "10987654321") + .execute(); + } + + @Test + public void fail_when_missing_administer_system_permission() { + UserDto user = db.users().insertUser(); + userSession.logIn(user); + AlmSettingDto almSettingDto = db.almSettings().insertGitHubAlmSetting(); + + expectedException.expect(ForbiddenException.class); + + ws.newRequest() + .setParam("key", almSettingDto.getKey()) + .setParam("newKey", "GitHub Server - Infra Team") + .setParam("url", "https://github.enterprise-unicorn.com") + .setParam("appId", "54321") + .setParam("privateKey", "10987654321") + .execute(); + } + + @Test + public void definition() { + WebService.Action def = ws.getDef(); + + assertThat(def.since()).isEqualTo("8.1"); + assertThat(def.isPost()).isTrue(); + assertThat(def.params()) + .extracting(WebService.Param::key, WebService.Param::isRequired) + .containsExactlyInAnyOrder(tuple("key", true), tuple("newKey", false), tuple("url", true), tuple("appId", true), tuple("privateKey", true)); + } + +} diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java index 23601bc33b6..3e4cef7bb38 100644 --- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java @@ -38,6 +38,7 @@ import org.sonar.core.component.DefaultResourceTypes; import org.sonar.core.extension.CoreExtensionsInstaller; import org.sonar.core.platform.ComponentContainer; import org.sonar.core.platform.PlatformEditionProvider; +import org.sonar.server.almsettings.AlmSettingsWsModule; import org.sonar.server.authentication.AuthenticationModule; import org.sonar.server.authentication.LogOAuthWarning; import org.sonar.server.authentication.ws.AuthenticationWsModule; @@ -469,6 +470,7 @@ public class PlatformLevel4 extends PlatformLevel { PropertiesWs.class, org.sonar.server.property.ws.IndexAction.class, SettingsWsModule.class, + AlmSettingsWsModule.class, TypeValidationModule.class, |