--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.common.github.permissions;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.audit.AuditPersister;
+import org.sonar.db.provisioning.GithubPermissionsMappingDao;
+import org.sonar.db.provisioning.GithubPermissionsMappingDto;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.sonar.server.common.github.permissions.GithubPermissionsMappingService.ADMIN_GITHUB_ROLE;
+import static org.sonar.server.common.github.permissions.GithubPermissionsMappingService.MAINTAIN_GITHUB_ROLE;
+import static org.sonar.server.common.github.permissions.GithubPermissionsMappingService.READ_GITHUB_ROLE;
+import static org.sonar.server.common.github.permissions.GithubPermissionsMappingService.TRIAGE_GITHUB_ROLE;
+import static org.sonar.server.common.github.permissions.GithubPermissionsMappingService.WRITE_GITHUB_ROLE;
+
+public class GithubPermissionsMappingServiceIT {
+
+ @Rule
+ public DbTester db = DbTester.create();
+ private final DbSession dbSession = db.getSession();
+
+ private final AuditPersister auditPersister = mock();
+ private final GithubPermissionsMappingDao githubPermissionsMappingDao = new GithubPermissionsMappingDao(auditPersister);
+
+ private final GithubPermissionsMappingService underTest = new GithubPermissionsMappingService(db.getDbClient(), githubPermissionsMappingDao);
+
+ @Test
+ public void getPermissionsMapping_whenMappingNotDefined_returnMappingEntirelyFalse() {
+ List<GithubPermissionsMapping> actualPermissionsMapping = underTest.getPermissionsMapping();
+
+ List<GithubPermissionsMapping> expectedPermissionsMapping = List.of(
+ new GithubPermissionsMapping(READ_GITHUB_ROLE, new SonarqubePermissions(false, false, false, false, false, false)),
+ new GithubPermissionsMapping(TRIAGE_GITHUB_ROLE, new SonarqubePermissions(false, false, false, false, false, false)),
+ new GithubPermissionsMapping(WRITE_GITHUB_ROLE, new SonarqubePermissions(false, false, false, false, false, false)),
+ new GithubPermissionsMapping(MAINTAIN_GITHUB_ROLE, new SonarqubePermissions(false, false, false, false, false, false)),
+ new GithubPermissionsMapping(ADMIN_GITHUB_ROLE, new SonarqubePermissions(false, false, false, false, false, false))
+ );
+
+ assertThat(actualPermissionsMapping).containsAll(expectedPermissionsMapping);
+ }
+
+ @Test
+ public void getPermissionsMapping_whenMappingDefined_returnMapping() {
+ Map<String, Set<String>> githubRolesToSqPermissions = Map.of(
+ READ_GITHUB_ROLE, Set.of("user", "codeviewer"),
+ WRITE_GITHUB_ROLE, Set.of("user", "codeviewer", "issueadmin", "securityhotspotadmin", "admin", "scan")
+ );
+ persistGithubPermissionsMapping(githubRolesToSqPermissions);
+
+ List<GithubPermissionsMapping> actualPermissionsMapping = underTest.getPermissionsMapping();
+
+ List<GithubPermissionsMapping> expectedPermissionsMapping = List.of(
+ new GithubPermissionsMapping(READ_GITHUB_ROLE, new SonarqubePermissions(true, true, false, false, false, false)),
+ new GithubPermissionsMapping(TRIAGE_GITHUB_ROLE, new SonarqubePermissions(false, false, false, false, false, false)),
+ new GithubPermissionsMapping(WRITE_GITHUB_ROLE, new SonarqubePermissions(true, true, true, true, true, true)),
+ new GithubPermissionsMapping(MAINTAIN_GITHUB_ROLE, new SonarqubePermissions(false, false, false, false, false, false)),
+ new GithubPermissionsMapping(ADMIN_GITHUB_ROLE, new SonarqubePermissions(false, false, false, false, false, false))
+ );
+
+ assertThat(actualPermissionsMapping).containsAll(expectedPermissionsMapping);
+ }
+
+ private void persistGithubPermissionsMapping(Map<String, Set<String>> githubRolesToSonarqubePermissions) {
+ for (Map.Entry<String, Set<String>> githubRoleToSonarqubePermissions : githubRolesToSonarqubePermissions.entrySet()) {
+ String githubRole = githubRoleToSonarqubePermissions.getKey();
+ githubRoleToSonarqubePermissions.getValue()
+ .forEach(permission -> githubPermissionsMappingDao.insert(
+ dbSession,
+ new GithubPermissionsMappingDto("uuid_" + githubRole + "_" + permission, githubRole, permission)));
+ }
+ dbSession.commit();
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.common.github.permissions;
+
+public record GithubPermissionsMapping(String roleName, SonarqubePermissions permissions) {
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.common.github.permissions;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Consumer;
+import org.sonar.api.web.UserRole;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.provisioning.GithubPermissionsMappingDao;
+import org.sonar.db.provisioning.GithubPermissionsMappingDto;
+
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.toSet;
+
+public class GithubPermissionsMappingService {
+ public static final String READ_GITHUB_ROLE = "read";
+ public static final String TRIAGE_GITHUB_ROLE = "triage";
+ public static final String WRITE_GITHUB_ROLE = "write";
+ public static final String MAINTAIN_GITHUB_ROLE = "maintain";
+ public static final String ADMIN_GITHUB_ROLE = "admin";
+
+ private static final Set<String> GITHUB_BASE_ROLE = Set.of(
+ READ_GITHUB_ROLE,
+ TRIAGE_GITHUB_ROLE,
+ WRITE_GITHUB_ROLE,
+ MAINTAIN_GITHUB_ROLE,
+ ADMIN_GITHUB_ROLE
+ );
+
+ private static final Map<String, Consumer<SonarqubePermissions.Builder>> permissionAsStringToSonarqubePermission = Map.of(
+ UserRole.USER, builder -> builder.user(true),
+ UserRole.CODEVIEWER, builder -> builder.codeViewer(true),
+ UserRole.ISSUE_ADMIN, builder -> builder.issueAdmin(true),
+ UserRole.SECURITYHOTSPOT_ADMIN, builder -> builder.securityHotspotAdmin(true),
+ UserRole.ADMIN, builder -> builder.admin(true),
+ UserRole.SCAN, builder -> builder.scan(true)
+ );
+
+ private final DbClient dbClient;
+ private final GithubPermissionsMappingDao githubPermissionsMappingDao;
+
+ public GithubPermissionsMappingService(DbClient dbClient, GithubPermissionsMappingDao githubPermissionsMappingDao) {
+ this.dbClient = dbClient;
+ this.githubPermissionsMappingDao = githubPermissionsMappingDao;
+ }
+
+ public List<GithubPermissionsMapping> getPermissionsMapping() {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ return toGithubPermissionsMappings(githubPermissionsMappingDao.findAll(dbSession));
+ }
+ }
+
+ private static List<GithubPermissionsMapping> toGithubPermissionsMappings(Set<GithubPermissionsMappingDto> githubPermissionsMappingDtos) {
+ Map<String, Set<GithubPermissionsMappingDto>> githubRoleToGithubPermissionsMappingDto = githubPermissionsMappingDtos.stream()
+ .collect(groupingBy(GithubPermissionsMappingDto::githubRole, toSet()));
+ return GITHUB_BASE_ROLE.stream()
+ .map(githubRole -> toGithubPermissionsMapping(githubRoleToGithubPermissionsMappingDto.get(githubRole), githubRole))
+ .toList();
+ }
+
+ private static GithubPermissionsMapping toGithubPermissionsMapping(Set<GithubPermissionsMappingDto> githubPermissionsMappingDtos, String githubRole) {
+ return new GithubPermissionsMapping(githubRole, getSonarqubePermissions(githubPermissionsMappingDtos));
+ }
+
+ private static SonarqubePermissions getSonarqubePermissions(Set<GithubPermissionsMappingDto> githubPermissionsMappingDtos) {
+ SonarqubePermissions.Builder builder = SonarqubePermissions.Builder.builder();
+ if (githubPermissionsMappingDtos != null) {
+ githubPermissionsMappingDtos.stream()
+ .map(GithubPermissionsMappingDto::sonarqubePermission)
+ .map(permissionAsStringToSonarqubePermission::get)
+ .forEach(builderConsumer -> builderConsumer.accept(builder));
+ }
+ return builder.build();
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.common.github.permissions;
+
+public record SonarqubePermissions(
+ boolean user,
+ boolean codeViewer,
+ boolean issueadmin,
+ boolean securityHotspotAdmin,
+ boolean admin,
+ boolean scan) {
+
+
+ public static final class Builder {
+ private boolean user = false;
+ private boolean codeViewer = false;
+ private boolean issueAdmin = false;
+ private boolean securityHotspotAdmin = false;
+ private boolean admin = false;
+ private boolean scan = false;
+
+ private Builder() {
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public Builder user(boolean user) {
+ this.user = user;
+ return this;
+ }
+
+ public Builder codeViewer(boolean codeViewer) {
+ this.codeViewer = codeViewer;
+ return this;
+ }
+
+ public Builder issueAdmin(boolean issueAdmin) {
+ this.issueAdmin = issueAdmin;
+ return this;
+ }
+
+ public Builder securityHotspotAdmin(boolean securityHotspotAdmin) {
+ this.securityHotspotAdmin = securityHotspotAdmin;
+ return this;
+ }
+
+ public Builder admin(boolean admin) {
+ this.admin = admin;
+ return this;
+ }
+
+ public Builder scan(boolean scan) {
+ this.scan = scan;
+ return this;
+ }
+
+ public SonarqubePermissions build() {
+ return new SonarqubePermissions(user, codeViewer, issueAdmin, securityHotspotAdmin, admin, scan);
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.common.github.permissions;
+
+import javax.annotation.ParametersAreNonnullByDefault;
public static final String LIVENESS_ENDPOINT = SYSTEM_ENDPOINTS + "/liveness";
public static final String HEALTH_ENDPOINT = SYSTEM_ENDPOINTS + "/health";
public static final String USER_ENDPOINT = "/users";
+ public static final String GITHUB_PERMISSIONS_ENDPOINT = "/github-permission-mappings";
public static final String JSON_MERGE_PATCH_CONTENT_TYPE = "application/json-merge-patch+json";
private WebApiEndpoints() {
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.v2.api.github.permissions.controller;
+
+import java.util.List;
+import org.sonar.server.common.github.permissions.GithubPermissionsMapping;
+import org.sonar.server.common.github.permissions.GithubPermissionsMappingService;
+import org.sonar.server.user.UserSession;
+import org.sonar.server.v2.api.github.permissions.model.RestGithubPermissionsMapping;
+import org.sonar.server.v2.api.github.permissions.response.GithubPermissionsMappingRestResponse;
+
+public class DefaultGithubPermissionsController implements GithubPermissionsController{
+
+ private UserSession userSession;
+ private GithubPermissionsMappingService githubPermissionsMappingService;
+
+ public DefaultGithubPermissionsController(UserSession userSession, GithubPermissionsMappingService githubPermissionsMappingService) {
+ this.userSession = userSession;
+ this.githubPermissionsMappingService = githubPermissionsMappingService;
+ }
+
+ @Override
+ public GithubPermissionsMappingRestResponse fetchAll() {
+ userSession.checkLoggedIn().checkIsSystemAdministrator();
+ List<GithubPermissionsMapping> permissionsMapping = githubPermissionsMappingService.getPermissionsMapping();
+ return new GithubPermissionsMappingRestResponse(toRestResources(permissionsMapping));
+ }
+
+ private static List<RestGithubPermissionsMapping> toRestResources(List<GithubPermissionsMapping> permissionsMapping) {
+ return permissionsMapping.stream()
+ .map(e -> new RestGithubPermissionsMapping(e.roleName(), e.roleName(), e.permissions()))
+ .toList();
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.v2.api.github.permissions.controller;
+
+import io.swagger.v3.oas.annotations.Operation;
+import org.sonar.server.v2.WebApiEndpoints;
+import org.sonar.server.v2.api.github.permissions.response.GithubPermissionsMappingRestResponse;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+@RequestMapping(WebApiEndpoints.GITHUB_PERMISSIONS_ENDPOINT)
+@RestController
+public interface GithubPermissionsController {
+
+ @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
+ @ResponseStatus(HttpStatus.OK)
+ @Operation(summary = "Fetch the GitHub permissions mapping", description = "Requires Administer System permission.")
+ GithubPermissionsMappingRestResponse fetchAll();
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.v2.api.github.permissions.controller;
+
+import javax.annotation.ParametersAreNonnullByDefault;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.v2.api.github.permissions.model;
+
+import org.sonar.server.common.github.permissions.SonarqubePermissions;
+
+public record RestGithubPermissionsMapping(String id, String roleName, SonarqubePermissions permissions) {
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.v2.api.github.permissions.model;
+
+import javax.annotation.ParametersAreNonnullByDefault;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.v2.api.github.permissions.response;
+
+import java.util.List;
+import org.sonar.server.v2.api.github.permissions.model.RestGithubPermissionsMapping;
+
+public record GithubPermissionsMappingRestResponse(List<RestGithubPermissionsMapping> githubPermissionsMappings) {
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.v2.api.github.permissions.response;
+
+import javax.annotation.ParametersAreNonnullByDefault;
package org.sonar.server.v2.config;
import javax.annotation.Nullable;
+import org.sonar.db.DbClient;
+import org.sonar.db.provisioning.GithubPermissionsMappingDao;
+import org.sonar.server.common.github.permissions.GithubPermissionsMappingService;
import org.sonar.server.common.health.CeStatusNodeCheck;
import org.sonar.server.common.health.DbConnectionNodeCheck;
import org.sonar.server.common.health.EsStatusNodeCheck;
import org.sonar.server.platform.NodeInformation;
import org.sonar.server.user.SystemPasscode;
import org.sonar.server.user.UserSession;
+import org.sonar.server.v2.api.github.permissions.controller.DefaultGithubPermissionsController;
import org.sonar.server.v2.api.system.controller.DefaultLivenessController;
import org.sonar.server.v2.api.system.controller.HealthController;
import org.sonar.server.v2.api.system.controller.LivenessController;
return new DefaultUserController(userSession, userService, usersSearchResponseGenerator);
}
+ @Bean
+ public GithubPermissionsMappingService githubPermissionsMappingService(DbClient dbClient, GithubPermissionsMappingDao githubPermissionsMappingDao) {
+ return new GithubPermissionsMappingService(dbClient, githubPermissionsMappingDao);
+ }
+
+ @Bean
+ public DefaultGithubPermissionsController githubPermissionsController(UserSession userSession, GithubPermissionsMappingService githubPermissionsMappingService) {
+ return new DefaultGithubPermissionsController(userSession, githubPermissionsMappingService);
+ }
+
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.v2.api.github.permissions.controller;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.util.List;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.server.common.github.permissions.GithubPermissionsMapping;
+import org.sonar.server.common.github.permissions.GithubPermissionsMappingService;
+import org.sonar.server.common.github.permissions.SonarqubePermissions;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.v2.api.ControllerTester;
+import org.sonar.server.v2.api.github.permissions.model.RestGithubPermissionsMapping;
+import org.sonar.server.v2.api.github.permissions.response.GithubPermissionsMappingRestResponse;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+
+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.v2.WebApiEndpoints.GITHUB_PERMISSIONS_ENDPOINT;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+public class DefaultGithubPermissionsControllerTest {
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+ private final GithubPermissionsMappingService githubPermissionsMappingService = mock();
+
+ private final MockMvc mockMvc = ControllerTester.getMockMvc(new DefaultGithubPermissionsController(userSession, githubPermissionsMappingService));
+
+ private static final Gson gson = new GsonBuilder().create();
+
+
+ @Test
+ public void fetchMapping_whenUserIsNotAdministrator_shouldReturnForbidden() throws Exception {
+ userSession.logIn().setNonSystemAdministrator();
+
+ mockMvc.perform(get(GITHUB_PERMISSIONS_ENDPOINT))
+ .andExpectAll(
+ status().isForbidden(),
+ content().json("{\"message\":\"Insufficient privileges\"}"));
+ }
+
+ @Test
+ public void fetchMapping_whenMappingSet_shouldReturnMapping() throws Exception {
+ userSession.logIn().setSystemAdministrator();
+
+ List<GithubPermissionsMapping> mapping = List.of(
+ new GithubPermissionsMapping("role1", new SonarqubePermissions(true, false, true, false, true, false)),
+ new GithubPermissionsMapping("role2", new SonarqubePermissions(false, true, false, true, false, true))
+ );
+ when(githubPermissionsMappingService.getPermissionsMapping()).thenReturn(mapping);
+
+ MvcResult mvcResult = mockMvc.perform(get(GITHUB_PERMISSIONS_ENDPOINT))
+ .andExpect(status().isOk())
+ .andReturn();
+
+ GithubPermissionsMappingRestResponse response = gson.fromJson(mvcResult.getResponse().getContentAsString(), GithubPermissionsMappingRestResponse.class);
+ assertThat(response.githubPermissionsMappings()).isEqualTo(toRestResources(mapping));
+ }
+
+ private static List<RestGithubPermissionsMapping> toRestResources(List<GithubPermissionsMapping> permissionsMapping) {
+ return permissionsMapping.stream()
+ .map(e -> new RestGithubPermissionsMapping(e.roleName(), e.roleName(), e.permissions()))
+ .toList();
+ }
+
+}