Search in sources :

Example 1 with AccessToken

use of org.sonar.alm.client.github.security.AccessToken in project sonarqube by SonarSource.

the class GithubApplicationClientImplTest method getRepository_returns_repository.

@Test
public void getRepository_returns_repository() throws IOException {
    String appUrl = "https://github.sonarsource.com";
    AccessToken accessToken = new UserAccessToken(randomAlphanumeric(10));
    String responseJson = "{\n" + "  \"id\": 1296269,\n" + "  \"node_id\": \"MDEwOlJlcG9zaXRvcnkxMjk2MjY5\",\n" + "  \"name\": \"Hello-World\",\n" + "  \"full_name\": \"octocat/Hello-World\",\n" + "  \"owner\": {\n" + "    \"login\": \"octocat\",\n" + "    \"id\": 1,\n" + "    \"node_id\": \"MDQ6VXNlcjE=\",\n" + "    \"avatar_url\": \"https://github.sonarsource.com/images/error/octocat_happy.gif\",\n" + "    \"gravatar_id\": \"\",\n" + "    \"url\": \"https://github.sonarsource.com/api/v3/users/octocat\",\n" + "    \"html_url\": \"https://github.com/octocat\",\n" + "    \"followers_url\": \"https://github.sonarsource.com/api/v3/users/octocat/followers\",\n" + "    \"following_url\": \"https://github.sonarsource.com/api/v3/users/octocat/following{/other_user}\",\n" + "    \"gists_url\": \"https://github.sonarsource.com/api/v3/users/octocat/gists{/gist_id}\",\n" + "    \"starred_url\": \"https://github.sonarsource.com/api/v3/users/octocat/starred{/owner}{/repo}\",\n" + "    \"subscriptions_url\": \"https://github.sonarsource.com/api/v3/users/octocat/subscriptions\",\n" + "    \"organizations_url\": \"https://github.sonarsource.com/api/v3/users/octocat/orgs\",\n" + "    \"repos_url\": \"https://github.sonarsource.com/api/v3/users/octocat/repos\",\n" + "    \"events_url\": \"https://github.sonarsource.com/api/v3/users/octocat/events{/privacy}\",\n" + "    \"received_events_url\": \"https://github.sonarsource.com/api/v3/users/octocat/received_events\",\n" + "    \"type\": \"User\",\n" + "    \"site_admin\": false\n" + "  },\n" + "  \"private\": false,\n" + "  \"html_url\": \"https://github.com/octocat/Hello-World\",\n" + "  \"description\": \"This your first repo!\",\n" + "  \"fork\": false,\n" + "  \"url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World\",\n" + "  \"archive_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/{archive_format}{/ref}\",\n" + "  \"assignees_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/assignees{/user}\",\n" + "  \"blobs_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/git/blobs{/sha}\",\n" + "  \"branches_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/branches{/branch}\",\n" + "  \"collaborators_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/collaborators{/collaborator}\",\n" + "  \"comments_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/comments{/number}\",\n" + "  \"commits_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/commits{/sha}\",\n" + "  \"compare_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/compare/{base}...{head}\",\n" + "  \"contents_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/contents/{+path}\",\n" + "  \"contributors_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/contributors\",\n" + "  \"deployments_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/deployments\",\n" + "  \"downloads_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/downloads\",\n" + "  \"events_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/events\",\n" + "  \"forks_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/forks\",\n" + "  \"git_commits_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/git/commits{/sha}\",\n" + "  \"git_refs_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/git/refs{/sha}\",\n" + "  \"git_tags_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/git/tags{/sha}\",\n" + "  \"git_url\": \"git:github.com/octocat/Hello-World.git\",\n" + "  \"issue_comment_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/issues/comments{/number}\",\n" + "  \"issue_events_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/issues/events{/number}\",\n" + "  \"issues_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/issues{/number}\",\n" + "  \"keys_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/keys{/key_id}\",\n" + "  \"labels_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/labels{/name}\",\n" + "  \"languages_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/languages\",\n" + "  \"merges_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/merges\",\n" + "  \"milestones_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/milestones{/number}\",\n" + "  \"notifications_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/notifications{?since,all,participating}\",\n" + "  \"pulls_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/pulls{/number}\",\n" + "  \"releases_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/releases{/id}\",\n" + "  \"ssh_url\": \"git@github.com:octocat/Hello-World.git\",\n" + "  \"stargazers_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/stargazers\",\n" + "  \"statuses_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/statuses/{sha}\",\n" + "  \"subscribers_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/subscribers\",\n" + "  \"subscription_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/subscription\",\n" + "  \"tags_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/tags\",\n" + "  \"teams_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/teams\",\n" + "  \"trees_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/git/trees{/sha}\",\n" + "  \"clone_url\": \"https://github.com/octocat/Hello-World.git\",\n" + "  \"mirror_url\": \"git:git.example.com/octocat/Hello-World\",\n" + "  \"hooks_url\": \"https://github.sonarsource.com/api/v3/repos/octocat/Hello-World/hooks\",\n" + "  \"svn_url\": \"https://svn.github.com/octocat/Hello-World\",\n" + "  \"homepage\": \"https://github.com\",\n" + "  \"language\": null,\n" + "  \"forks_count\": 9,\n" + "  \"stargazers_count\": 80,\n" + "  \"watchers_count\": 80,\n" + "  \"size\": 108,\n" + "  \"default_branch\": \"master\",\n" + "  \"open_issues_count\": 0,\n" + "  \"is_template\": true,\n" + "  \"topics\": [\n" + "    \"octocat\",\n" + "    \"atom\",\n" + "    \"electron\",\n" + "    \"api\"\n" + "  ],\n" + "  \"has_issues\": true,\n" + "  \"has_projects\": true,\n" + "  \"has_wiki\": true,\n" + "  \"has_pages\": false,\n" + "  \"has_downloads\": true,\n" + "  \"archived\": false,\n" + "  \"disabled\": false,\n" + "  \"visibility\": \"public\",\n" + "  \"pushed_at\": \"2011-01-26T19:06:43Z\",\n" + "  \"created_at\": \"2011-01-26T19:01:12Z\",\n" + "  \"updated_at\": \"2011-01-26T19:14:43Z\",\n" + "  \"permissions\": {\n" + "    \"admin\": false,\n" + "    \"push\": false,\n" + "    \"pull\": true\n" + "  },\n" + "  \"allow_rebase_merge\": true,\n" + "  \"template_repository\": null,\n" + "  \"allow_squash_merge\": true,\n" + "  \"allow_merge_commit\": true,\n" + "  \"subscribers_count\": 42,\n" + "  \"network_count\": 0,\n" + "  \"anonymous_access_enabled\": false,\n" + "  \"license\": {\n" + "    \"key\": \"mit\",\n" + "    \"name\": \"MIT License\",\n" + "    \"spdx_id\": \"MIT\",\n" + "    \"url\": \"https://github.sonarsource.com/api/v3/licenses/mit\",\n" + "    \"node_id\": \"MDc6TGljZW5zZW1pdA==\"\n" + "  },\n" + "  \"organization\": {\n" + "    \"login\": \"octocat\",\n" + "    \"id\": 1,\n" + "    \"node_id\": \"MDQ6VXNlcjE=\",\n" + "    \"avatar_url\": \"https://github.com/images/error/octocat_happy.gif\",\n" + "    \"gravatar_id\": \"\",\n" + "    \"url\": \"https://github.sonarsource.com/api/v3/users/octocat\",\n" + "    \"html_url\": \"https://github.com/octocat\",\n" + "    \"followers_url\": \"https://github.sonarsource.com/api/v3/users/octocat/followers\",\n" + "    \"following_url\": \"https://github.sonarsource.com/api/v3/users/octocat/following{/other_user}\",\n" + "    \"gists_url\": \"https://github.sonarsource.com/api/v3/users/octocat/gists{/gist_id}\",\n" + "    \"starred_url\": \"https://github.sonarsource.com/api/v3/users/octocat/starred{/owner}{/repo}\",\n" + "    \"subscriptions_url\": \"https://github.sonarsource.com/api/v3/users/octocat/subscriptions\",\n" + "    \"organizations_url\": \"https://github.sonarsource.com/api/v3/users/octocat/orgs\",\n" + "    \"repos_url\": \"https://github.sonarsource.com/api/v3/users/octocat/repos\",\n" + "    \"events_url\": \"https://github.sonarsource.com/api/v3/users/octocat/events{/privacy}\",\n" + "    \"received_events_url\": \"https://github.sonarsource.com/api/v3/users/octocat/received_events\",\n" + "    \"type\": \"Organization\",\n" + "    \"site_admin\": false\n" + "  }" + "}";
    when(httpClient.get(appUrl, accessToken, "/repos/octocat/Hello-World")).thenReturn(new GithubApplicationHttpClient.GetResponse() {

        @Override
        public Optional<String> getNextEndPoint() {
            return Optional.empty();
        }

        @Override
        public int getCode() {
            return 200;
        }

        @Override
        public Optional<String> getContent() {
            return Optional.of(responseJson);
        }
    });
    Optional<GithubApplicationClient.Repository> repository = underTest.getRepository(appUrl, accessToken, "octocat", "octocat/Hello-World");
    assertThat(repository).isPresent().get().extracting(GithubApplicationClient.Repository::getId, GithubApplicationClient.Repository::getName, GithubApplicationClient.Repository::getFullName, GithubApplicationClient.Repository::getUrl, GithubApplicationClient.Repository::isPrivate, GithubApplicationClient.Repository::getDefaultBranch).containsOnly(1296269L, "Hello-World", "octocat/Hello-World", "https://github.com/octocat/Hello-World", false, "master");
}
Also used : Optional(java.util.Optional) UserAccessToken(org.sonar.alm.client.github.security.UserAccessToken) AccessToken(org.sonar.alm.client.github.security.AccessToken) UserAccessToken(org.sonar.alm.client.github.security.UserAccessToken) Test(org.junit.Test)

Example 2 with AccessToken

use of org.sonar.alm.client.github.security.AccessToken in project sonarqube by SonarSource.

the class GithubApplicationClientImplTest method listRepositories_returns_empty_results.

@Test
public void listRepositories_returns_empty_results() throws IOException {
    String appUrl = "https://github.sonarsource.com";
    AccessToken accessToken = new UserAccessToken(randomAlphanumeric(10));
    String responseJson = "{\n" + "  \"total_count\": 0\n" + "}";
    when(httpClient.get(appUrl, accessToken, String.format("/search/repositories?q=%s&page=%s&per_page=%s", "fork:true+org:github", 1, 100))).thenReturn(new OkGetResponse(responseJson));
    GithubApplicationClient.Repositories repositories = underTest.listRepositories(appUrl, accessToken, "github", null, 1, 100);
    assertThat(repositories.getTotal()).isZero();
    assertThat(repositories.getRepositories()).isNull();
}
Also used : UserAccessToken(org.sonar.alm.client.github.security.UserAccessToken) AccessToken(org.sonar.alm.client.github.security.AccessToken) UserAccessToken(org.sonar.alm.client.github.security.UserAccessToken) Test(org.junit.Test)

Example 3 with AccessToken

use of org.sonar.alm.client.github.security.AccessToken in project sonarqube by SonarSource.

the class GithubApplicationClientImplTest method listOrganizations_fail_on_failure.

@Test
public void listOrganizations_fail_on_failure() throws IOException {
    String appUrl = "https://github.sonarsource.com";
    AccessToken accessToken = new UserAccessToken(randomAlphanumeric(10));
    when(httpClient.get(appUrl, accessToken, String.format("/user/installations?page=%s&per_page=%s", 1, 100))).thenThrow(new IOException("OOPS"));
    assertThatThrownBy(() -> underTest.listOrganizations(appUrl, accessToken, 1, 100)).isInstanceOf(IllegalStateException.class).hasMessage("Failed to list all organizations accessible by user access token on %s", appUrl);
}
Also used : UserAccessToken(org.sonar.alm.client.github.security.UserAccessToken) AccessToken(org.sonar.alm.client.github.security.AccessToken) UserAccessToken(org.sonar.alm.client.github.security.UserAccessToken) IOException(java.io.IOException) Test(org.junit.Test)

Example 4 with AccessToken

use of org.sonar.alm.client.github.security.AccessToken in project sonarqube by SonarSource.

the class ListGithubOrganizationsAction method doHandle.

private ListGithubOrganizationsWsResponse doHandle(Request request) {
    try (DbSession dbSession = dbClient.openSession(false)) {
        userSession.checkLoggedIn().checkPermission(PROVISION_PROJECTS);
        String almSettingKey = request.mandatoryParam(PARAM_ALM_SETTING);
        AlmSettingDto almSettingDto = dbClient.almSettingDao().selectByKey(dbSession, almSettingKey).orElseThrow(() -> new NotFoundException(String.format("GitHub ALM Setting '%s' not found", almSettingKey)));
        String userUuid = requireNonNull(userSession.getUuid(), "User UUID is not null");
        String url = requireNonNull(almSettingDto.getUrl(), String.format("No URL set for GitHub ALM '%s'", almSettingKey));
        AccessToken accessToken;
        if (request.hasParam(PARAM_TOKEN)) {
            String code = request.mandatoryParam(PARAM_TOKEN);
            String clientId = requireNonNull(almSettingDto.getClientId(), String.format("No clientId set for GitHub ALM '%s'", almSettingKey));
            String clientSecret = requireNonNull(almSettingDto.getDecryptedClientSecret(encryption), String.format("No clientSecret set for GitHub ALM '%s'", almSettingKey));
            try {
                accessToken = githubApplicationClient.createUserAccessToken(url, clientId, clientSecret, code);
            } catch (IllegalArgumentException e) {
                // it could also be that the code has expired!
                throw BadRequestException.create("Unable to authenticate with GitHub. " + "Check the GitHub App client ID and client secret configured in the Global Settings and try again.");
            }
            Optional<AlmPatDto> almPatDto = dbClient.almPatDao().selectByUserAndAlmSetting(dbSession, userUuid, almSettingDto);
            if (almPatDto.isPresent()) {
                AlmPatDto almPat = almPatDto.get();
                almPat.setPersonalAccessToken(accessToken.getValue());
                dbClient.almPatDao().update(dbSession, almPat, userSession.getLogin(), almSettingDto.getKey());
            } else {
                AlmPatDto almPat = new AlmPatDto().setPersonalAccessToken(accessToken.getValue()).setAlmSettingUuid(almSettingDto.getUuid()).setUserUuid(userUuid);
                dbClient.almPatDao().insert(dbSession, almPat, userSession.getLogin(), almSettingDto.getKey());
            }
            dbSession.commit();
        } else {
            accessToken = dbClient.almPatDao().selectByUserAndAlmSetting(dbSession, userUuid, almSettingDto).map(AlmPatDto::getPersonalAccessToken).map(UserAccessToken::new).orElseThrow(() -> new IllegalArgumentException("No personal access token found"));
        }
        int page = request.hasParam(PAGE) ? request.mandatoryParamAsInt(PAGE) : 1;
        int pageSize = request.hasParam(PAGE_SIZE) ? request.mandatoryParamAsInt(PAGE_SIZE) : 100;
        GithubApplicationClient.Organizations githubOrganizations = githubApplicationClient.listOrganizations(url, accessToken, page, pageSize);
        ListGithubOrganizationsWsResponse.Builder response = ListGithubOrganizationsWsResponse.newBuilder().setPaging(Common.Paging.newBuilder().setPageIndex(page).setPageSize(pageSize).setTotal(githubOrganizations.getTotal()).build());
        List<Organization> organizations = githubOrganizations.getOrganizations();
        if (organizations != null) {
            organizations.forEach(githubOrganization -> response.addOrganizations(AlmIntegrations.GithubOrganization.newBuilder().setKey(githubOrganization.getLogin()).setName(githubOrganization.getLogin()).build()));
        }
        return response.build();
    }
}
Also used : GithubApplicationClient(org.sonar.alm.client.github.GithubApplicationClient) Organization(org.sonar.alm.client.github.GithubApplicationClient.Organization) UserAccessToken(org.sonar.alm.client.github.security.UserAccessToken) AlmPatDto(org.sonar.db.alm.pat.AlmPatDto) NotFoundException(org.sonar.server.exceptions.NotFoundException) DbSession(org.sonar.db.DbSession) UserAccessToken(org.sonar.alm.client.github.security.UserAccessToken) AccessToken(org.sonar.alm.client.github.security.AccessToken) AlmSettingDto(org.sonar.db.alm.setting.AlmSettingDto) ListGithubOrganizationsWsResponse(org.sonarqube.ws.AlmIntegrations.ListGithubOrganizationsWsResponse)

Example 5 with AccessToken

use of org.sonar.alm.client.github.security.AccessToken in project sonarqube by SonarSource.

the class GithubApplicationClientImplTest method listOrganizations_returns_no_installations.

@Test
public void listOrganizations_returns_no_installations() throws IOException {
    String appUrl = "https://github.sonarsource.com";
    AccessToken accessToken = new UserAccessToken(randomAlphanumeric(10));
    String responseJson = "{\n" + "  \"total_count\": 0\n" + "} ";
    when(httpClient.get(appUrl, accessToken, String.format("/user/installations?page=%s&per_page=%s", 1, 100))).thenReturn(new OkGetResponse(responseJson));
    GithubApplicationClient.Organizations organizations = underTest.listOrganizations(appUrl, accessToken, 1, 100);
    assertThat(organizations.getTotal()).isZero();
    assertThat(organizations.getOrganizations()).isNull();
}
Also used : UserAccessToken(org.sonar.alm.client.github.security.UserAccessToken) AccessToken(org.sonar.alm.client.github.security.AccessToken) UserAccessToken(org.sonar.alm.client.github.security.UserAccessToken) Test(org.junit.Test)

Aggregations

AccessToken (org.sonar.alm.client.github.security.AccessToken)11 UserAccessToken (org.sonar.alm.client.github.security.UserAccessToken)11 Test (org.junit.Test)8 DbSession (org.sonar.db.DbSession)3 AlmPatDto (org.sonar.db.alm.pat.AlmPatDto)3 AlmSettingDto (org.sonar.db.alm.setting.AlmSettingDto)3 NotFoundException (org.sonar.server.exceptions.NotFoundException)3 IOException (java.io.IOException)2 Optional (java.util.Optional)2 GithubApplicationClient (org.sonar.alm.client.github.GithubApplicationClient)2 Repository (org.sonar.alm.client.github.GithubApplicationClient.Repository)2 ProjectAlmSettingDto (org.sonar.db.alm.setting.ProjectAlmSettingDto)2 Organization (org.sonar.alm.client.github.GithubApplicationClient.Organization)1 ComponentDto (org.sonar.db.component.ComponentDto)1 ProjectDto (org.sonar.db.project.ProjectDto)1 ListGithubOrganizationsWsResponse (org.sonarqube.ws.AlmIntegrations.ListGithubOrganizationsWsResponse)1