diff --git a/pom.xml b/pom.xml index 25081ba0c6..d446b24180 100644 --- a/pom.xml +++ b/pom.xml @@ -33,8 +33,8 @@ UTF-8 - 4.7.0.0 - 4.6.0 + 4.7.1.1 + 4.7.1 true 2.2 4.9.2 @@ -258,7 +258,7 @@ org.apache.maven.plugins maven-site-plugin - 3.12.0 + 3.12.1 org.apache.maven.plugins @@ -278,7 +278,7 @@ org.apache.maven.plugins maven-project-info-reports-plugin - 3.3.0 + 3.4.0 org.apache.bcel @@ -333,7 +333,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.22.8 + 2.24.0 spotless-check @@ -585,7 +585,7 @@ com.google.code.gson gson - 2.9.0 + 2.9.1 test diff --git a/src/main/java/org/kohsuke/github/GHAppCreateTokenBuilder.java b/src/main/java/org/kohsuke/github/GHAppCreateTokenBuilder.java index 9222ca7fe4..44b49e0129 100644 --- a/src/main/java/org/kohsuke/github/GHAppCreateTokenBuilder.java +++ b/src/main/java/org/kohsuke/github/GHAppCreateTokenBuilder.java @@ -46,6 +46,20 @@ public GHAppCreateTokenBuilder repositoryIds(List repositoryIds) { return this; } + /** + * By default the installation token has access to all repositories that the installation can access. To restrict + * the access to specific repositories, you can provide repository names when creating the token. + * + * @param repositories + * Array containing the repository names + * @return a GHAppCreateTokenBuilder + */ + @BetaApi + public GHAppCreateTokenBuilder repositories(List repositories) { + this.builder.with("repositories", repositories); + return this; + } + /** * Set the permissions granted to the access token. The permissions object includes the permission names and their * access type. diff --git a/src/test/java/org/kohsuke/github/GHAppTest.java b/src/test/java/org/kohsuke/github/GHAppTest.java index c3ebb3c6bb..29e0da23c6 100644 --- a/src/test/java/org/kohsuke/github/GHAppTest.java +++ b/src/test/java/org/kohsuke/github/GHAppTest.java @@ -146,6 +146,27 @@ public void createToken() throws IOException { assertThat(installationToken2.getRepositories(), nullValue());; } + @Test + public void createTokenWithRepositories() throws IOException { + GHApp app = gitHub.getApp(); + GHAppInstallation installation = app.getInstallationByUser("bogus"); + + // Create token specifying repositories (not repository_ids!) + GHAppInstallationToken installationToken = installation.createToken() + .repositories(Collections.singletonList("bogus")) + .create(); + + assertThat(installationToken.getToken(), is("bogus")); + assertThat(installationToken.getPermissions().entrySet(), hasSize(4)); + assertThat(installationToken.getRepositorySelection(), is(GHRepositorySelection.SELECTED)); + assertThat(installationToken.getExpiresAt(), is(GitHubClient.parseDate("2022-07-27T21:38:33Z"))); + + GHRepository repository = installationToken.getRepositories().get(0); + assertThat(installationToken.getRepositories().size(), is(1)); + assertThat(repository.getId(), is((long) 11111111)); + assertThat(repository.getName(), is("bogus")); + } + private void testAppInstallation(GHAppInstallation appInstallation) throws IOException { Map appPermissions = appInstallation.getPermissions(); GHUser appAccount = appInstallation.getAccount(); diff --git a/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/__files/app-1.json b/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/__files/app-1.json new file mode 100644 index 0000000000..98f64483b4 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/__files/app-1.json @@ -0,0 +1,41 @@ +{ + "id": 11111111, + "slug": "bogus-testing", + "node_id": "asdfasdfasdf", + "owner": { + "login": "bogus", + "id": 11111111, + "node_id": "asdfasfasdf", + "avatar_url": "https://avatars.githubusercontent.com/u/11111111?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/bogus", + "html_url": "https://github.com/bogus", + "followers_url": "https://api.github.com/users/bogus/followers", + "following_url": "https://api.github.com/users/bogus/following{/other_user}", + "gists_url": "https://api.github.com/users/bogus/gists{/gist_id}", + "starred_url": "https://api.github.com/users/bogus/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bogus/subscriptions", + "organizations_url": "https://api.github.com/users/bogus/orgs", + "repos_url": "https://api.github.com/users/bogus/repos", + "events_url": "https://api.github.com/users/bogus/events{/privacy}", + "received_events_url": "https://api.github.com/users/bogus/received_events", + "type": "User", + "site_admin": false + }, + "name": "bogus-testing", + "description": "description here", + "external_url": "https://github.com/bogus", + "html_url": "https://github.com/apps/bogus-testing", + "created_at": "2022-07-15T17:51:32Z", + "updated_at": "2022-07-15T17:51:32Z", + "permissions": { + "contents": "write", + "metadata": "read", + "organization_plan": "read", + "plan": "read", + "pull_requests": "read", + "statuses": "write" + }, + "events": [], + "installations_count": 1 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/__files/app_installations_27419505_access_tokens-3.json b/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/__files/app_installations_27419505_access_tokens-3.json new file mode 100644 index 0000000000..e2ed7454d9 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/__files/app_installations_27419505_access_tokens-3.json @@ -0,0 +1,112 @@ +{ + "token": "bogus", + "expires_at": "2022-07-27T21:38:33Z", + "permissions": { + "contents": "write", + "metadata": "read", + "pull_requests": "read", + "statuses": "write" + }, + "repository_selection": "selected", + "repositories": [ + { + "id": 11111111, + "node_id": "asdfasdf", + "name": "bogus", + "full_name": "bogus/bogus", + "private": true, + "owner": { + "login": "bogus", + "id": 11111111, + "node_id": "asdfasdf", + "avatar_url": "https://avatars.githubusercontent.com/u/11111111?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/bogus", + "html_url": "https://github.com/bogus", + "followers_url": "https://api.github.com/users/bogus/followers", + "following_url": "https://api.github.com/users/bogus/following{/other_user}", + "gists_url": "https://api.github.com/users/bogus/gists{/gist_id}", + "starred_url": "https://api.github.com/users/bogus/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bogus/subscriptions", + "organizations_url": "https://api.github.com/users/bogus/orgs", + "repos_url": "https://api.github.com/users/bogus/repos", + "events_url": "https://api.github.com/users/bogus/events{/privacy}", + "received_events_url": "https://api.github.com/users/bogus/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/bogus/bogus", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/bogus/bogus", + "forks_url": "https://api.github.com/repos/bogus/bogus/forks", + "keys_url": "https://api.github.com/repos/bogus/bogus/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/bogus/bogus/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/bogus/bogus/teams", + "hooks_url": "https://api.github.com/repos/bogus/bogus/hooks", + "issue_events_url": "https://api.github.com/repos/bogus/bogus/issues/events{/number}", + "events_url": "https://api.github.com/repos/bogus/bogus/events", + "assignees_url": "https://api.github.com/repos/bogus/bogus/assignees{/user}", + "branches_url": "https://api.github.com/repos/bogus/bogus/branches{/branch}", + "tags_url": "https://api.github.com/repos/bogus/bogus/tags", + "blobs_url": "https://api.github.com/repos/bogus/bogus/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/bogus/bogus/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/bogus/bogus/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/bogus/bogus/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/bogus/bogus/statuses/{sha}", + "languages_url": "https://api.github.com/repos/bogus/bogus/languages", + "stargazers_url": "https://api.github.com/repos/bogus/bogus/stargazers", + "contributors_url": "https://api.github.com/repos/bogus/bogus/contributors", + "subscribers_url": "https://api.github.com/repos/bogus/bogus/subscribers", + "subscription_url": "https://api.github.com/repos/bogus/bogus/subscription", + "commits_url": "https://api.github.com/repos/bogus/bogus/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/bogus/bogus/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/bogus/bogus/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/bogus/bogus/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/bogus/bogus/contents/{+path}", + "compare_url": "https://api.github.com/repos/bogus/bogus/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/bogus/bogus/merges", + "archive_url": "https://api.github.com/repos/bogus/bogus/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/bogus/bogus/downloads", + "issues_url": "https://api.github.com/repos/bogus/bogus/issues{/number}", + "pulls_url": "https://api.github.com/repos/bogus/bogus/pulls{/number}", + "milestones_url": "https://api.github.com/repos/bogus/bogus/milestones{/number}", + "notifications_url": "https://api.github.com/repos/bogus/bogus/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/bogus/bogus/labels{/name}", + "releases_url": "https://api.github.com/repos/bogus/bogus/releases{/id}", + "deployments_url": "https://api.github.com/repos/bogus/bogus/deployments", + "created_at": "2018-08-30T17:18:24Z", + "updated_at": "2022-06-14T22:15:20Z", + "pushed_at": "2022-07-15T20:04:26Z", + "git_url": "git://github.com/bogus/bogus.git", + "ssh_url": "git@github.com:bogus/bogus.git", + "clone_url": "https://github.com/bogus/bogus.git", + "svn_url": "https://github.com/bogus/bogus", + "homepage": null, + "size": 36, + "stargazers_count": 0, + "watchers_count": 0, + "language": "Groovy", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "private", + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/__files/users_bogus_installation-2.json b/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/__files/users_bogus_installation-2.json new file mode 100644 index 0000000000..07b4061b60 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/__files/users_bogus_installation-2.json @@ -0,0 +1,45 @@ +{ + "id": 11111111, + "account": { + "login": "bogus", + "id": 11111111, + "node_id": "asdfasdfasdf=", + "avatar_url": "https://avatars2.githubusercontent.com/u/111111111?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/bogus", + "html_url": "https://github.com/bogus", + "followers_url": "https://api.github.com/users/bogus/followers", + "following_url": "https://api.github.com/users/bogus/following{/other_user}", + "gists_url": "https://api.github.com/users/bogus/gists{/gist_id}", + "starred_url": "https://api.github.com/users/bogus/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bogus/subscriptions", + "organizations_url": "https://api.github.com/users/bogus/orgs", + "repos_url": "https://api.github.com/users/bogus/repos", + "events_url": "https://api.github.com/users/bogus/events{/privacy}", + "received_events_url": "https://api.github.com/users/bogus/received_events", + "type": "Organization", + "site_admin": false + }, + "repository_selection": "all", + "access_tokens_url": "https://api.github.com/app/installations/11111111/access_tokens", + "repositories_url": "https://api.github.com/installation/repositories", + "html_url": "https://github.com/settings/installations/11111111", + "app_id": 111111, + "app_slug": "bogus-testing", + "target_id": 11111111, + "target_type": "Organization", + "permissions": { + "checks": "write", + "pull_requests": "write", + "contents": "read", + "metadata": "read" + }, + "events": [], + "created_at": "2022-07-15T17:55:36.000Z", + "updated_at": "2022-07-15T19:15:12.000Z", + "single_file_name": null, + "has_multiple_single_files": false, + "single_file_paths": [], + "suspended_by": null, + "suspended_at": null +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/mappings/app-1.json b/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/mappings/app-1.json new file mode 100644 index 0000000000..06417be608 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/mappings/app-1.json @@ -0,0 +1,39 @@ +{ + "id": "32a6d293-46e2-48e0-a7f5-cf9ec061cd02", + "name": "app", + "request": { + "url": "/app", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "application/vnd.github.machine-man-preview+json" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "app-1.json", + "headers": { + "Server": "GitHub.com", + "Date": "Wed, 27 Jul 2022 20:38:33 GMT", + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "public, max-age=60, s-maxage=60", + "Vary": [ + "Accept", + "Accept-Encoding, Accept, X-Requested-With" + ], + "ETag": "W/\"139628cbc6b3b04a0aa89130c8d2d7eb6935386aeaa396cbef97166394e38723\"", + "X-GitHub-Media-Type": "github.v3; param=machine-man-preview; format=json", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "0", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "X-GitHub-Request-Id": "F861:6983:622AD5:115FE5B:62E1A249" + } + }, + "uuid": "32a6d293-46e2-48e0-a7f5-cf9ec061cd02", + "persistent": true, + "insertionIndex": 1 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/mappings/app_installations_27419505_access_tokens-3.json b/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/mappings/app_installations_27419505_access_tokens-3.json new file mode 100644 index 0000000000..cc68198f80 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/mappings/app_installations_27419505_access_tokens-3.json @@ -0,0 +1,46 @@ +{ + "id": "9e9f33d9-1b63-4f67-81a3-82ec45bd0afa", + "name": "app_installations_27419505_access_tokens", + "request": { + "url": "/app/installations/11111111/access_tokens", + "method": "POST", + "headers": { + "Accept": { + "equalTo": "application/vnd.github.machine-man-preview+json" + } + }, + "bodyPatterns": [ + { + "equalToJson": "{\"repositories\":[\"bogus\"]}", + "ignoreArrayOrder": true, + "ignoreExtraElements": false + } + ] + }, + "response": { + "status": 201, + "bodyFileName": "app_installations_27419505_access_tokens-3.json", + "headers": { + "Server": "GitHub.com", + "Date": "Wed, 27 Jul 2022 20:38:33 GMT", + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "public, max-age=60, s-maxage=60", + "Vary": [ + "Accept", + "Accept-Encoding, Accept, X-Requested-With" + ], + "ETag": "\"6cfb04630611056af08d2652a018429d37ca8e0df7d861b918a985d5e646e2de\"", + "X-GitHub-Media-Type": "github.v3; param=machine-man-preview; format=json", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "0", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "X-GitHub-Request-Id": "F863:32FC:5F7C97:10FD23D:62E1A249" + } + }, + "uuid": "9e9f33d9-1b63-4f67-81a3-82ec45bd0afa", + "persistent": true, + "insertionIndex": 3 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/mappings/users_bogus_installation-2.json b/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/mappings/users_bogus_installation-2.json new file mode 100644 index 0000000000..2f2f27a708 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHAppTest/wiremock/createTokenWithRepositories/mappings/users_bogus_installation-2.json @@ -0,0 +1,39 @@ +{ + "id": "b3d0192b-f564-437c-b705-d1662ba3f8c5", + "name": "users_bogus_installation", + "request": { + "url": "/users/bogus/installation", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "application/vnd.github.machine-man-preview+json" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "users_bogus_installation-2.json", + "headers": { + "Server": "GitHub.com", + "Date": "Wed, 27 Jul 2022 20:38:33 GMT", + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "public, max-age=60, s-maxage=60", + "Vary": [ + "Accept", + "Accept-Encoding, Accept, X-Requested-With" + ], + "ETag": "W/\"c95438f7909eebbaa54f451239b617b063a83ab1193afa1e180c144dd6295033\"", + "X-GitHub-Media-Type": "github.v3; param=machine-man-preview; format=json", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "0", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "X-GitHub-Request-Id": "F862:0322:510DC3:B06CF0:62E1A249" + } + }, + "uuid": "b3d0192b-f564-437c-b705-d1662ba3f8c5", + "persistent": true, + "insertionIndex": 2 +} \ No newline at end of file