Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

List app installation requests endpoint #2012

Merged
merged 2 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/main/java/org/kohsuke/github/GHApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,22 @@ public Map<String, String> getPermissions() {
return Collections.unmodifiableMap(permissions);
}

/**
* Obtains all the installation requests associated with this app.
* <p>
* You must use a JWT to access this endpoint.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation does not mention that you must use a JWT explicitly for this endpoint, unlike other endpoints in this class, but I am assuming that is just a miss in their documentation.

Copy link
Member

@bitwiseman bitwiseman Jan 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might add a check that throws an exception or at least logs a warning when not using JWT credentials.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already get this: A JSON web token could not be decoded in the response. We can add a pre-check too if you think it would be useful. We'll have to add it to GitHub.getApp() too, as that one is called before listInstallationRequests(). Also, how would such a check look like? a simple authorization.startsWith("Bearer ") check?

*
* @return a list of App installation requests
* @see <a href=
* "https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#list-installation-requests-for-the-authenticated-app">List
* installation requests</a>
*/
public PagedIterable<GHAppInstallationRequest> listInstallationRequests() {
return root().createRequest()
.withUrlPath("/app/installation-requests")
.toIterable(GHAppInstallationRequest[].class, null);
}

/**
* Obtains all the installations associated with this app.
* <p>
Expand Down
42 changes: 42 additions & 0 deletions src/main/java/org/kohsuke/github/GHAppInstallationRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.kohsuke.github;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

/**
* A Github App Installation Request.
*
* @author Anuj Hydrabadi
* @see GHApp#listInstallationRequests() GHApp#listInstallationRequests()
*/
public class GHAppInstallationRequest extends GHObject {
/**
* Create default GHAppInstallationRequest instance
*/
public GHAppInstallationRequest() {
}

private GHOrganization account;

private GHUser requester;

/**
* Gets the organization where the app was requested to be installed.
*
* @return the organization where the app was requested to be installed.
*/
@SuppressFBWarnings(value = { "EI_EXPOSE_REP", "UWF_UNWRITTEN_FIELD" }, justification = "Expected behavior")
public GHOrganization getAccount() {
return account;
}

/**
* Gets the user who requested the installation.
*
* @return the user who requested the installation.
*/
@SuppressFBWarnings(value = { "EI_EXPOSE_REP", "UWF_UNWRITTEN_FIELD" }, justification = "Expected behavior")
public GHUser getRequester() {
return requester;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@
{
"name": "org.kohsuke.github.GHAppInstallationsPage"
},
{
"name": "org.kohsuke.github.GHAppInstallationRequest"
},
{
"name": "org.kohsuke.github.GHAppInstallationToken"
},
Expand Down Expand Up @@ -1340,4 +1343,4 @@
{
"name": "org.kohsuke.github.SkipFromToString"
}
]
]
22 changes: 22 additions & 0 deletions src/test/java/org/kohsuke/github/GHAppTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,28 @@ public void getGitHubApp() throws IOException {
assertThat(app.getInstallationsCount(), is((long) 1));
}

/**
* List installation requests.
*
* @throws IOException
* Signals that an I/O exception has occurred.
*/
@Test
public void listInstallationRequests() throws IOException {
GHApp app = gitHub.getApp();
List<GHAppInstallationRequest> installations = app.listInstallationRequests().toList();
assertThat(installations.size(), is(1));

GHAppInstallationRequest appInstallation = installations.get(0);
assertThat(appInstallation.getId(), is((long) 1037204));
assertThat(appInstallation.getAccount().getId(), is((long) 195438329));
assertThat(appInstallation.getAccount().getLogin(), is("approval-test"));
assertThat(appInstallation.getRequester().getId(), is((long) 195437694));
assertThat(appInstallation.getRequester().getLogin(), is("kaladinstormblessed2"));
assertThat(appInstallation.getCreatedAt(), is(GitHubClient.parseDate("2025-01-17T15:50:51Z")));
assertThat(appInstallation.getNodeId(), is("MDMwOkludGVncmF0aW9uSW5zdGFsbGF0aW9uUmVxdWVzdDEwMzcyMDQ="));
}

/**
* List installations.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"id": 986532,
"client_id": "Iv23liTxF5NAu46u9qto",
"slug": "anuj-github-app",
"node_id": "A_kwDOB7K2ac4ADw2k",
"owner": {
"login": "kaladinstormblessed",
"id": 129152617,
"node_id": "U_kgDOB7K2aQ",
"avatar_url": "https://avatars.githubusercontent.com/u/129152617?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/kaladinstormblessed",
"html_url": "https://github.com/kaladinstormblessed",
"followers_url": "https://api.github.com/users/kaladinstormblessed/followers",
"following_url": "https://api.github.com/users/kaladinstormblessed/following{/other_user}",
"gists_url": "https://api.github.com/users/kaladinstormblessed/gists{/gist_id}",
"starred_url": "https://api.github.com/users/kaladinstormblessed/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/kaladinstormblessed/subscriptions",
"organizations_url": "https://api.github.com/users/kaladinstormblessed/orgs",
"repos_url": "https://api.github.com/users/kaladinstormblessed/repos",
"events_url": "https://api.github.com/users/kaladinstormblessed/events{/privacy}",
"received_events_url": "https://api.github.com/users/kaladinstormblessed/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"name": "anuj-github-app",
"description": "",
"external_url": "https://cloud.cloud",
"html_url": "https://github.com/apps/anuj-github-app",
"created_at": "2024-09-03T07:14:38Z",
"updated_at": "2025-01-17T10:52:47Z",
"permissions": {
"administration": "write",
"contents": "write",
"members": "read",
"metadata": "read",
"pull_requests": "read"
},
"events": [],
"installations_count": 6
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
[
{
"id": 1037204,
"node_id": "MDMwOkludGVncmF0aW9uSW5zdGFsbGF0aW9uUmVxdWVzdDEwMzcyMDQ=",
"account": {
"login": "approval-test",
"id": 195438329,
"node_id": "O_kgDOC6Ym-Q",
"avatar_url": "https://avatars.githubusercontent.com/u/195438329?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/approval-test",
"html_url": "https://github.com/approval-test",
"followers_url": "https://api.github.com/users/approval-test/followers",
"following_url": "https://api.github.com/users/approval-test/following{/other_user}",
"gists_url": "https://api.github.com/users/approval-test/gists{/gist_id}",
"starred_url": "https://api.github.com/users/approval-test/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/approval-test/subscriptions",
"organizations_url": "https://api.github.com/users/approval-test/orgs",
"repos_url": "https://api.github.com/users/approval-test/repos",
"events_url": "https://api.github.com/users/approval-test/events{/privacy}",
"received_events_url": "https://api.github.com/users/approval-test/received_events",
"type": "Organization",
"user_view_type": "public",
"site_admin": false
},
"requester": {
"login": "kaladinstormblessed2",
"id": 195437694,
"node_id": "U_kgDOC6Ykfg",
"avatar_url": "https://avatars.githubusercontent.com/u/195437694?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/kaladinstormblessed2",
"html_url": "https://github.com/kaladinstormblessed2",
"followers_url": "https://api.github.com/users/kaladinstormblessed2/followers",
"following_url": "https://api.github.com/users/kaladinstormblessed2/following{/other_user}",
"gists_url": "https://api.github.com/users/kaladinstormblessed2/gists{/gist_id}",
"starred_url": "https://api.github.com/users/kaladinstormblessed2/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/kaladinstormblessed2/subscriptions",
"organizations_url": "https://api.github.com/users/kaladinstormblessed2/orgs",
"repos_url": "https://api.github.com/users/kaladinstormblessed2/repos",
"events_url": "https://api.github.com/users/kaladinstormblessed2/events{/privacy}",
"received_events_url": "https://api.github.com/users/kaladinstormblessed2/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"created_at": "2025-01-17T15:50:51Z"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"id": "7dd11376-7827-4472-9b35-d129d432687e",
"name": "app",
"request": {
"url": "/app",
"method": "GET",
"headers": {
"Accept": {
"equalTo": "application/vnd.github+json"
}
}
},
"response": {
"status": 200,
"bodyFileName": "1-app.json",
"headers": {
"Date": "Fri, 17 Jan 2025 17:53:40 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/\"2ae03ff428b2f6f2651437f7bbb52bcc5aa4fd43ec20540006591c05a6c4de48\"",
"X-GitHub-Media-Type": "github.v3; format=json",
"x-github-api-version-selected": "2022-11-28",
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset",
"Access-Control-Allow-Origin": "*",
"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'",
"Server": "github.com",
"X-GitHub-Request-Id": "C286:10C02C:61556D:734A43:678A9923"
}
},
"uuid": "7dd11376-7827-4472-9b35-d129d432687e",
"persistent": true,
"insertionIndex": 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"id": "2e6e47a0-0341-45c9-87f6-eda0865764d7",
"name": "app_installation-requests",
"request": {
"url": "/app/installation-requests",
"method": "GET",
"headers": {
"Accept": {
"equalTo": "application/vnd.github+json"
}
}
},
"response": {
"status": 200,
"bodyFileName": "2-app_installation-requests.json",
"headers": {
"Date": "Fri, 17 Jan 2025 17:53:40 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/\"1030c589d5482f2436758d79218af5ab17bd8b28c5b92792fe383357cae28d39\"",
"X-GitHub-Media-Type": "github.v3; format=json",
"x-github-api-version-selected": "2022-11-28",
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset",
"Access-Control-Allow-Origin": "*",
"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'",
"Server": "github.com",
"X-GitHub-Request-Id": "C287:E5098:509DB7:5CBEB7:678A9924"
}
},
"uuid": "2e6e47a0-0341-45c9-87f6-eda0865764d7",
"persistent": true,
"insertionIndex": 2
}
Loading