mirror of
https://github.com/zoriya/octokit.net.git
synced 2025-12-06 07:16:09 +00:00
Adding initial support for GitHub Apps. (#1738)
* Added authentication using bearer token. * Added Installation and AccessToken clients. * Added new clients to Reactive project * added support for DateTime serialized as FileTime * added support for StatusEventPayload * added support for StatusEventPayload * Added test for StatusEventPayload and fixed serializer to return that event payload type. * WIP - added ApplicationClient and related Api Urls. * Continued implementing Installations support. * Fixing build (WIP) * fixed build * added Account property to Installation. prefer nameof(x) over literal "x". * fixed according to code review. * fixed build. * switched Installation ID from int to long. * added Permissions and Events properties to Installation. * added documentation to Application and Installation properties in IGitHubClient. * wip - added tests to new clients * wip - fix build * wip - fixed build. * added InstallationsClient tests. * added integration test for InstallationsClient. * changes requested in code review. * add Get method for App * Create GitHubApp response model instead of re-using existing Application response model * add Get method to observable client * fixed build (both locally and failed test). * Fixed documentation and added some missing XML docs. * added DebuggerDisplay to StatusEventPayload * updated XML docs and added some missing bits. prefer nameof(x) over literal "x". * Add xml comments to AccessToken response model and use DateTimeOffset rather than DateTime * Tidy up XmlComments and make consistent across client and observable client and interfaces * fixup unit tests to independently verify preview header * Implement GetInstallation method * revert commits unrelated to GitHubApps - these can be done on a separate PR if required * this extra authenticator class doesnt appear to be used anywhere * undo project file change as it doesnt appear to be necessary * Revert "Merge remote-tracking branch 'remote/GitHubApps' into GitHubApps" This reverts commit c53cc110b8d807f62fdfeaa7df19e1532d050007, reversing changes made to 0c9e413d420a4725738644ea5b13af6ec102d456. * Revert "Revert "Merge remote-tracking branch 'remote/GitHubApps' into GitHubApps"" This reverts commit 02d52b8adf814b6945c60cb59a907a8cd34b1ce7. * add XmlDoc comments to response models and flesh out installation permissions * name AcceptHeaders member consistently * accidentally lost changes to Credentials.cs * Enhance Intergation test framework to handle GitHubApp settings and discoer tests appropriately Get code ready for GitHubJWT nuget package but for now just hardcode a JWT in ENV VAR Add 1 integration test for each method and ensure they are working! * fixed compiler warnings. * Added support for Installation=>Id field that arrives in a Pull Request Event payload. (See the last field in the sample JSON of https://developer.github.com/v3/activity/events/types/#pullrequestevent) * Change integration test project to netcoreapp2.0 so we can use GitHubJwt nuget package in integration tests * First cut at some GitHubApp doco * update mkdocs config * Moved the Installation property to ActivityPayload, so it's available in all payloads. This feature is not undocumented, unfortunately, but valid: https://platform.github.community/t/determining-which-installation-an-event-came-from/539/11 * Split Installation to Installation and InstallationId, and added a comfort method for gaining its AccessToken. * fixed InstallationId CreateAccessToken to receive IGitHubAppsClient. added (and fixed) docs. * reverted object-oriented style comfort method and it's docs. * update all test projects to netcoreapp2.0 * tweak build configs to use 2.0.3 SDK * also need to update cake frosting build to netcoreapp2.0 * tweak docs some more * fix convention test failures * test projects still had some old runtime parts in them! * travis osx image needs to be at least 10.12 for .NET Core 2.0 * shell script might need the same argument tweak for cake * more doc tweaks * Make sure compiler warning output isnt somehow causing Linux and OSX builds to fail * moar logging for linux/OSX builds * stop sourcelink on linux/OSX builds to see if that is the problem * set verbosity to detailed for the dotnet build step * try new sourcelink and list out remotes * is travis being weird with git clone? * SourceLink may be defaulting to true on CI server so explicitly set it as false rather than omitting it * detailed is a bit too verbose for travis, try normal * turn sourcelink back on for Linux/OSX * fix compiler warning * Try SourceLink.Create.CommandLine instead of SourceLink.Create.GitHub * CliToolReferences did not update to latest versions * remove debug origin info * turn off msbuild output * go back to SourceLink.Create.GitHub! * time diff between dev PC and API causes issues if specifying a full 600 second token * handle extra date format that Installation end point now returns * field needs to be protected in order to be deserialized * provide even more buffer for client vs server clock drift * Update to latest GitHubJwt reference * go back to SDK 1 since SDK 2 is having sporadic travisCI faliures in TestSourceLink build step * get appveyor working * update sourcelink back to latest, and use SDK 1.04 (runtime 1.0.5)
This commit is contained in:
committed by
Ryan Gribble
parent
7aeea34fb2
commit
5ffc96995f
131
docs/github-apps.md
Normal file
131
docs/github-apps.md
Normal file
@@ -0,0 +1,131 @@
|
||||
# Working with GitHub Apps
|
||||
|
||||
## Overview
|
||||
GitHub Apps are a new type of integration offering narrow, specific permissions, compared to OAuth apps or user authentication.
|
||||
|
||||
To learn more, head to the GitHub Apps section under the GitHub Developer [Getting started with Building Apps](https://developer.github.com/apps/getting-started-with-building-apps/#using-github-apps) documentation.
|
||||
|
||||
A GitHub App (known in Octokit as a `GitHubApp`) specifies permissions (read, write, none) it will be granted for various scopes and also registers for various webhook events.
|
||||
|
||||
A GitHub App is installed in an `Organization` or `User` account (known in Octokit as an `Installation`) where it is further limited to nominated (or all) repositories for that account.
|
||||
|
||||
The [GitHub Api Documentation](https://developer.github.com/v3/apps/) on GitHub Apps contains more detailed information.
|
||||
|
||||
## Authentication
|
||||
|
||||
The below walkthrough outlines how to authenticate as a `GitHubApp` and an `Installation` using Octokit.net.
|
||||
|
||||
Be sure to see the [GitHub Api Documentation](https://developer.github.com/apps/building-github-apps/authentication-options-for-github-apps/#authentication-options-for-github-apps) on GitHub Apps authentication, if you require more details.
|
||||
|
||||
## GitHub App Walkthrough
|
||||
|
||||
Each GitHub App has a private certificate (PEM file) generated through the GitHub website and possessed by the owner of the GitHub App. Authentication occurs using a time based JWT token, signed by the GitHub App's private certificate.
|
||||
|
||||
``` csharp
|
||||
// A time based JWT token, signed by the GitHub App's private certificate
|
||||
var jwtToken = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MjA0Mjc3MTQsImV4cCI6MTUyMDQyODMxNCwiaXNzIjo5NzM1fQ.K-d3FKWKddMygFqvPZYWQusqhbF1LYfcIM0VbBq4uJsS9VkjhyXALlHmTJWjdblzx-U55lkZc_KWdJd6GlDxvoRb5w_9nrLcIFRbYVgi9XTYpCc3o5j7Qh3FvKxA1bzEs8XGrxjjE7-WJn_xi85ugFKTy9tlIRPa-PHeIOvNp4fz4ru8SFPoD4epiraeEyLfpU_ke-HYF7Ws7ar19zQkfJKRHSIFm1LxJ5MGKWT8pQBBUSGxGPgEG_tYI83aYw6cVx-DLV290bpr23LRUC684Wv_XabUDzXjPUYynAc01APZF6aN8B0LHdPbG8I6Yd74sQfmN-aHz5moz8ZNWLNm8Q";
|
||||
|
||||
// Use the JWT as a Bearer token
|
||||
var gitHubClient = new GitHubClient(new ProductHeaderValue("MyApp"))
|
||||
{
|
||||
Credentials = new Credentials(jwtToken, AuthenticationType.Bearer)
|
||||
};
|
||||
```
|
||||
|
||||
The authenticated `GitHubApp` can query various top level information about itself:
|
||||
|
||||
``` csharp
|
||||
// Get the current authenticated GitHubApp
|
||||
var app = await appClient.GetCurrent();
|
||||
|
||||
// Get a list of installations for the authenticated GitHubApp
|
||||
var installations = await appClient.GetAllInstallationsForCurrent();
|
||||
|
||||
// Get a specific installation of the authenticated GitHubApp by it's installation Id
|
||||
var installation = await appClient.GetInstallation(123);
|
||||
|
||||
```
|
||||
|
||||
In order to do more than top level calls, a `GitHubApp` needs to authenticate as a specific `Installation` by creating a temporary installation token, and using that for authentication:
|
||||
|
||||
``` csharp
|
||||
// Create an Installation token for Insallation Id 123
|
||||
var response = await appClient.CreateInstallationToken(123);
|
||||
|
||||
// NOTE - the token will expire!
|
||||
response.ExpiresAt;
|
||||
|
||||
// Create a new GitHubClient using the installation token as authentication
|
||||
var installationClient = new GitHubClient(new ProductHeaderValue("MyApp-Installation123"))
|
||||
{
|
||||
Credentials = new Credentials(response.Token)
|
||||
};
|
||||
```
|
||||
|
||||
Once authenticated as an `Installation`, a [subset of regular API endpoints](https://developer.github.com/v3/apps/available-endpoints/) can be queried, using the permissions of the `GitHubApp` and repository settings of the `Installation`:
|
||||
|
||||
``` csharp
|
||||
// Create a Comment on an Issue
|
||||
// - Assuming the GitHub App has read/write permission for issues scope
|
||||
// - Assuming we are operating on a repository that the Installation has access to
|
||||
var response = await installationClient.Issue.Comment.Create("owner", "repo", 1, "Hello from my GitHubApp Installation!");
|
||||
```
|
||||
|
||||
## A Note on identifying Installation Id's
|
||||
GitHub Apps can be registered for webhook events.
|
||||
|
||||
WebHook payloads sent to these registrations now include an extra field to indicate the Id of the GitHub App Installation that is associated with the received webhook.
|
||||
|
||||
Example webhook for an opened Pull Request:
|
||||
``` json
|
||||
{
|
||||
"action": "opened",
|
||||
"number": 1,
|
||||
"pull_request": {
|
||||
...
|
||||
},
|
||||
"repository": {
|
||||
...
|
||||
},
|
||||
"sender": {
|
||||
...
|
||||
},
|
||||
"installation": {
|
||||
"id": 1234
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can retrieve this `installation.id` from your webhook payload, and use it to create the Installation token as above, to further interact with the repository as that Installation of the GitHub App.
|
||||
|
||||
Although Octokit.net doesn't have explicit webhook support, the `ActivityPayload` response classes do generally align with webhook payloads (assuming the octokit.net custom deserializer is used), so we have added the field to these:
|
||||
|
||||
``` csharp
|
||||
// json payload from the received webhook
|
||||
var json = "...";
|
||||
|
||||
// Deserialize the pull_request event
|
||||
var serializer = new Octokit.Internal.SimpleJsonSerializer();
|
||||
var payload = serializer_.Deserialize<PullRequestEventPayload>(json);
|
||||
|
||||
// Create an Installation token for the associated Insallation Id
|
||||
var response = await appClient.CreateInstallationToken(payload.Installation.Id);
|
||||
```
|
||||
|
||||
## A Note on JWT Tokens
|
||||
Octokit.net expects that you will pass in the appropriately signed JWT token required to authenticate the `GitHubApp`.
|
||||
|
||||
Luckily one of our contributors [@adriangodong](https://github.com/adriangodong) has created a library `GitHubJwt` ( [GitHub](https://github.com/adriangodong/githubjwt) | [NuGet](https://www.nuget.org/packages/githubjwt) ) which you can use to help with this (as long as you are targetting `netstandard2.0` or above).
|
||||
|
||||
``` csharp
|
||||
var generator = new GitHubJwt.GitHubJwtFactory(
|
||||
new GitHubJwt.FilePrivateKeySource("/path/to/pem_file"),
|
||||
new GitHubJwt.GitHubJwtFactoryOptions
|
||||
{
|
||||
AppIntegrationId = 123, // The GitHub App Id
|
||||
ExpirationSeconds = 600 // 10 minutes is the maximum time allowed
|
||||
}
|
||||
);
|
||||
|
||||
var jwtToken = generator.CreateEncodedJwtToken();
|
||||
```
|
||||
Reference in New Issue
Block a user