Repository navigation
feat: report the scope GitHub granted and accept owner/repo in --repos - #90
Merged
Merged
Conversation
An installation token now carries GitHub's answer in its oauth2 Extra fields: ExtraPermissions, a map of the permissions granted, and ExtraRepositories, the repository names when the token is limited to some. That can differ from what was asked: metadata:read comes with every token. githubauth token --json prints both, so a caller can check the scope it got rather than assume it. InstallationPermissions now decodes a permission with no field into Other. Which names have a field is read from the struct's JSON tags, ignoring case as encoding/json does, so an empty level or a name in another case stays on its field, and a second decode replaces a level in Other as it does for a field. --repos acme/api finds the installation as --owner acme does, the form actions/create-github-app-token takes. Names of two owners, or an owner prefix beside --installation or a different --owner, exit 2. Comparing two installation tokens with == now panics when GitHub sent a scope, as it does for any oauth2 token whose Extra holds a map.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #90 +/- ##
==========================================
+ Coverage 97.71% 97.86% +0.15%
==========================================
Files 8 8
Lines 787 845 +58
==========================================
+ Hits 769 827 +58
Misses 18 18 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When githubauth mints an installation token, GitHub's reply says what the token can actually do: its permissions and, for a scoped token, its repositories. The library threw that away, so a script or agent could not check it got the scope it asked for. It can differ from the request: GitHub adds
metadata:readto every token. The token now carries that answer, andgithubauth token --jsonprints it. Separately,--repos acme/apinow finds the installation the way--owner acmedoes.What this does
token --jsontoken,expires_atpermissionsand, for a scoped token,repositoriestoken --repos acme/apiacme's installation, scopes toapitoken --repos acme/api,other/webtoken --repos acme/api --installation 9Changes
Extra(githubauth.ExtraPermissions)is amap[string]string, andExtra(githubauth.ExtraRepositories)a[]string.InstallationPermissionsdecodes a permission with no field intoOther. Field names come from the struct's JSON tags, matched ignoring case asencoding/jsondoes.--repostakesowner/repo, stripped before the names reach GitHub.Rationale
The scope travels in
oauth2.Token's Extra, the standard place for provider data, rather than a new type or method. One consequence: comparing two installation tokens with==panics when GitHub sent a scope, as it already does for any oauth2 token whose Extra holds a map.An adversarial Codex review found that decoding decided which names had a field from their values, so
{"contents":""},{"Contents":"read"}and a second decode all misbehaved. Matching on the struct's tags fixed all three, and each has a regression test.Migration Notes
None. Tested against a real App:
--repos gopherguru/test --permissions pull_requests:read --jsonreported{"metadata":"read","pull_requests":"read"}and["test"].