Skip to content

Commit 3f5e291

Browse files
authored
Merge branch 'master' into bugfix/git-data-client-update-ref-force
2 parents 024f85b + d73699d commit 3f5e291

File tree

6 files changed

+239
-3
lines changed

6 files changed

+239
-3
lines changed

pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<name>github-java-client</name>
55
<artifactId>github-client</artifactId>
6-
<version>0.5.3-SNAPSHOT</version>
6+
<version>0.5.6-SNAPSHOT</version>
77

88
<parent>
99
<groupId>com.spotify</groupId>
@@ -67,7 +67,7 @@
6767
<properties>
6868
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
6969
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
70-
<project.build.outputTimestamp>1764581460</project.build.outputTimestamp>
70+
<project.build.outputTimestamp>1765470064</project.build.outputTimestamp>
7171
<spotbugs.excludeFilterFile>spotbugsexclude.xml</spotbugs.excludeFilterFile>
7272
<checkstyle.violationSeverity>error</checkstyle.violationSeverity>
7373
<checkstyle.config.location>checkstyle.xml</checkstyle.config.location>
@@ -85,7 +85,7 @@
8585
<objenesis.version>3.3</objenesis.version>
8686
<opencensus.version>0.31.1</opencensus.version>
8787
<okhttp.version>4.11.0</okhttp.version>
88-
<opentelemetry.version>1.42.1</opentelemetry.version>
88+
<opentelemetry.version>1.51.0</opentelemetry.version>
8989
</properties>
9090

9191
<dependencyManagement>
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*-
2+
* -\-\-
3+
* github-api
4+
* --
5+
* Copyright (C) 2016 - 2020 Spotify AB
6+
* --
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* -/-/-
19+
*/
20+
21+
package com.spotify.github.v3.activity.events;
22+
23+
public enum EventType {
24+
BRANCH_PROTECTION_RULE,
25+
CHECK_RUN,
26+
CHECK_SUITE,
27+
CODE_SCANNING_ALERT,
28+
COMMIT_COMMENT,
29+
CONTENT_REFERENCE,
30+
CREATE,
31+
DELETE,
32+
DEPLOY_KEY,
33+
DEPLOYMENT,
34+
DEPLOYMENT_STATUS,
35+
DISCUSSION,
36+
DISCUSSION_COMMENT,
37+
DOWNLOAD,
38+
FOLLOW,
39+
FORK,
40+
FORK_APPLY,
41+
GITHUB_APP_AUTHORIZATION,
42+
GIST,
43+
GOLLUM,
44+
INSTALLATION,
45+
INSTALLATION_REPOSITORIES,
46+
INTEGRATION_INSTALLATION_REPOSITORIES,
47+
ISSUE_COMMENT,
48+
ISSUES,
49+
LABEL,
50+
MARKETPLACE_PURCHASE,
51+
MEMBER,
52+
MEMBERSHIP,
53+
MERGE_QUEUE_ENTRY,
54+
MERGE_GROUP,
55+
META,
56+
MILESTONE,
57+
ORGANIZATION,
58+
ORG_BLOCK,
59+
PACKAGE,
60+
PAGE_BUILD,
61+
PROJECT_CARD,
62+
PROJECT_COLUMN,
63+
PROJECT,
64+
PING,
65+
PUBLIC,
66+
PULL_REQUEST,
67+
PULL_REQUEST_REVIEW,
68+
PULL_REQUEST_REVIEW_COMMENT,
69+
PULL_REQUEST_REVIEW_THREAD,
70+
PUSH,
71+
REGISTRY_PACKAGE,
72+
RELEASE,
73+
REPOSITORY_DISPATCH,
74+
REPOSITORY,
75+
REPOSITORY_IMPORT,
76+
REPOSITORY_VULNERABILITY_ALERT,
77+
SCHEDULE,
78+
SECURITY_ADVISORY,
79+
STAR,
80+
STATUS,
81+
TEAM,
82+
TEAM_ADD,
83+
WATCH,
84+
WORKFLOW_JOB,
85+
WORKFLOW_DISPATCH,
86+
WORKFLOW_RUN,
87+
UNKNOWN,
88+
ALL;
89+
90+
@Override
91+
public String toString() {
92+
return this.name().toLowerCase();
93+
}
94+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*-
2+
* -\-\-
3+
* github-api
4+
* --
5+
* Copyright (C) 2016 - 2020 Spotify AB
6+
* --
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* -/-/-
19+
*/
20+
package com.spotify.github.v3.apps.requests;
21+
22+
import com.fasterxml.jackson.annotation.JsonInclude;
23+
import com.fasterxml.jackson.annotation.JsonProperty;
24+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
25+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
26+
import com.spotify.github.GithubStyle;
27+
import java.util.List;
28+
import java.util.Optional;
29+
import org.immutables.value.Value;
30+
31+
/** Request to create an installation access token with repository scoping. */
32+
@Value.Immutable
33+
@GithubStyle
34+
@JsonSerialize(as = ImmutableAccessTokenRequest.class)
35+
@JsonDeserialize(as = ImmutableAccessTokenRequest.class)
36+
@JsonInclude(JsonInclude.Include.NON_EMPTY)
37+
public interface AccessTokenRequest {
38+
39+
/**
40+
* List of repository names that the token should be scoped to.
41+
*
42+
* @return list of repository names
43+
*/
44+
Optional<List<String>> repositories();
45+
46+
/**
47+
* List of repository IDs that the token should be scoped to.
48+
*
49+
* @return list of repository IDs
50+
*/
51+
@JsonProperty("repository_ids")
52+
Optional<List<Integer>> repositoryIds();
53+
}

src/main/java/com/spotify/github/v3/clients/GithubAppClient.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.fasterxml.jackson.core.type.TypeReference;
2424
import com.google.common.collect.ImmutableMap;
2525
import com.spotify.github.v3.apps.InstallationRepositoriesResponse;
26+
import com.spotify.github.v3.apps.requests.AccessTokenRequest;
2627
import com.spotify.github.v3.checks.AccessToken;
2728
import com.spotify.github.v3.checks.App;
2829
import com.spotify.github.v3.checks.Installation;
@@ -155,12 +156,28 @@ public CompletableFuture<Installation> getUserInstallation() {
155156
* Authenticates as an installation
156157
*
157158
* @return an Installation Token
159+
* @see #getAccessToken(Integer, AccessTokenRequest) for repository-scoped tokens
158160
*/
159161
public CompletableFuture<AccessToken> getAccessToken(final Integer installationId) {
160162
final String path = String.format(GET_ACCESS_TOKEN_URL, installationId);
161163
return github.post(path, "", AccessToken.class, extraHeaders);
162164
}
163165

166+
/**
167+
* Authenticates as an installation with repository scoping.
168+
*
169+
* @param installationId the installation ID
170+
* @param request the access token request with optional repository scoping
171+
* @return an Installation Token
172+
* @see "https://docs.github.com/en/rest/apps/apps#create-an-installation-access-token-for-an-app"
173+
*/
174+
public CompletableFuture<AccessToken> getAccessToken(
175+
final Integer installationId,
176+
final AccessTokenRequest request) {
177+
final String path = String.format(GET_ACCESS_TOKEN_URL, installationId);
178+
return github.post(path, github.json().toJsonUnchecked(request), AccessToken.class, extraHeaders);
179+
}
180+
164181
/**
165182
* Lists the repositories that an app installation can access.
166183
*

src/test/java/com/spotify/github/v3/clients/GithubAppClientTest.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,16 @@
2424
import static java.nio.charset.Charset.defaultCharset;
2525
import static org.hamcrest.MatcherAssert.assertThat;
2626
import static org.hamcrest.Matchers.containsInAnyOrder;
27+
import static org.hamcrest.Matchers.containsString;
2728
import static org.hamcrest.core.Is.is;
2829

2930
import com.fasterxml.jackson.databind.ObjectMapper;
3031
import com.google.common.io.Resources;
3132
import com.spotify.github.FixtureHelper;
3233
import com.spotify.github.v3.apps.InstallationRepositoriesResponse;
34+
import com.spotify.github.v3.apps.requests.AccessTokenRequest;
35+
import com.spotify.github.v3.apps.requests.ImmutableAccessTokenRequest;
36+
import com.spotify.github.v3.checks.AccessToken;
3337
import com.spotify.github.v3.checks.App;
3438
import com.spotify.github.v3.checks.Installation;
3539
import java.io.File;
@@ -182,4 +186,68 @@ public void getAuthenticatedApp() throws Exception {
182186
recordedRequest.getHeaders().values("Authorization").get(0).startsWith("Bearer "),
183187
is(true));
184188
}
189+
190+
@Test
191+
public void getAccessTokenWithoutScoping() throws Exception {
192+
mockServer.enqueue(
193+
new MockResponse()
194+
.setResponseCode(201)
195+
.setBody(FixtureHelper.loadFixture("githubapp/access-token.json")));
196+
197+
AccessToken token = client.getAccessToken(1234).join();
198+
199+
assertThat(token.token(), is("ghs_16C7e42F292c6912E7710c838347Ae178B4a"));
200+
201+
RecordedRequest recordedRequest = mockServer.takeRequest(1, TimeUnit.MILLISECONDS);
202+
assertThat(recordedRequest.getMethod(), is("POST"));
203+
assertThat(
204+
recordedRequest.getRequestUrl().encodedPath(),
205+
is("/app/installations/1234/access_tokens"));
206+
assertThat(recordedRequest.getBody().readUtf8(), is(""));
207+
}
208+
209+
@Test
210+
public void getAccessTokenWithRepositoryScoping() throws Exception {
211+
mockServer.enqueue(
212+
new MockResponse()
213+
.setResponseCode(201)
214+
.setBody(FixtureHelper.loadFixture("githubapp/access-token.json")));
215+
216+
AccessTokenRequest request = ImmutableAccessTokenRequest.builder()
217+
.repositories(List.of("Hello-World"))
218+
.repositoryIds(List.of(1))
219+
.build();
220+
221+
AccessToken token = client.getAccessToken(1234, request).join();
222+
223+
assertThat(token.token(), is("ghs_16C7e42F292c6912E7710c838347Ae178B4a"));
224+
225+
RecordedRequest recordedRequest = mockServer.takeRequest(1, TimeUnit.MILLISECONDS);
226+
assertThat(recordedRequest.getMethod(), is("POST"));
227+
assertThat(
228+
recordedRequest.getRequestUrl().encodedPath(),
229+
is("/app/installations/1234/access_tokens"));
230+
231+
String requestBody = recordedRequest.getBody().readUtf8();
232+
assertThat(requestBody, containsString("\"repositories\":[\"Hello-World\"]"));
233+
assertThat(requestBody, containsString("\"repository_ids\":[1]"));
234+
}
235+
236+
@Test
237+
public void getAccessTokenWithEmptyRequest() throws Exception {
238+
mockServer.enqueue(
239+
new MockResponse()
240+
.setResponseCode(201)
241+
.setBody(FixtureHelper.loadFixture("githubapp/access-token.json")));
242+
243+
AccessTokenRequest emptyRequest = ImmutableAccessTokenRequest.builder().build();
244+
245+
AccessToken token = client.getAccessToken(1234, emptyRequest).join();
246+
247+
assertThat(token.token(), is("ghs_16C7e42F292c6912E7710c838347Ae178B4a"));
248+
249+
RecordedRequest recordedRequest = mockServer.takeRequest(1, TimeUnit.MILLISECONDS);
250+
String requestBody = recordedRequest.getBody().readUtf8();
251+
assertThat(requestBody, is("{}"));
252+
}
185253
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"token": "ghs_16C7e42F292c6912E7710c838347Ae178B4a",
3+
"expires_at": "2024-08-10T05:54:58Z"
4+
}

0 commit comments

Comments
 (0)