feat(proxy): resolve push identity from token via SCM provider API#1604
feat(proxy): resolve push identity from token via SCM provider API#1604coopernetes wants to merge 1 commit into
Conversation
✅ Deploy Preview for endearing-brigadeiros-63f9d0 canceled.
|
|
|
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
9c3d053 to
ef788cf
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1604 +/- ##
==========================================
+ Coverage 85.38% 85.76% +0.37%
==========================================
Files 83 85 +2
Lines 7878 8055 +177
Branches 1312 1357 +45
==========================================
+ Hits 6727 6908 +181
+ Misses 1123 1120 -3
+ Partials 28 27 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| const user: GitHubUserResponse = await response.json(); | ||
| return { | ||
| login: user.login, | ||
| email: user.email ?? undefined, |
There was a problem hiding this comment.
As discussed in the related issue, the email field in this API response shouldn't be relied upon as it is almost always null (at least on GitHub) due to default profile privacy settings.
| } | ||
|
|
||
| const [scheme, encoded] = authHeader.split(' '); | ||
| if (!scheme || !encoded || scheme.toLowerCase() !== 'basic') { |
There was a problem hiding this comment.
I'm not sure how much this code path even makes sense given that git by default uses HTTP Basic authorization. A Git Proxy custom credentialHelper could be an interesting angle to explore but that requires a customization on the client side. Maybe worth tracking in the backlog?
|
|
||
| export const findUserByGitAccount = async function (gitAccount: string): Promise<User | null> { | ||
| const collection = await connect(collectionName); | ||
| const doc = await collection.findOne({ gitAccount: { $eq: gitAccount.toLowerCase() } }); |
There was a problem hiding this comment.
Any desire to support an list of accounts here? gitAccount is somewhat of a holdover from v1. It's also singular across the whole user context - there's no shape in the data model today that supports associative git account by upstream provider/hostname.
Ideally, we revisit this shape in support of this PR. Something like this:
# MongoDB doc
{
# existing keys...
"username": "git-proxy-user",
"email": "user@corpo-example.com",
"gitAccounts": {
"github.com": ["foo", "bar"],
"gitlab.com": [ "baz" ]
}
}```
…1400) parsePush incorrectly uses the last commit's committer as the push user. This adds a new chain processor that extracts the token from HTTP Basic auth, calls the SCM provider's user API (GitHub GET /user for now), and maps the SCM login to a git-proxy user via the gitAccount field. - TokenIdentityProvider interface with hostname-based dispatch - GitHubTokenIdentityProvider calling api.github.com/user - resolveUserFromToken chain processor (non-blocking on failure) - findUserByGitAccount DB lookup (file + mongo) - GET/PUT /api/v1/user/:username/git-account endpoints
91a910d to
4b14544
Compare
Description
parsePush uses the last commit's committer as the push user. This adds a new chain processor that extracts the token from HTTP Basic auth, calls the SCM provider's user API (GitHub
GET /userfor now), and maps the SCM login to a git-proxy user via the gitAccount field.This doesn't block a push if the gitAccount isn't mapped in order to allow introduction of the gitAccount via the UI. This acts as a "soft" check for now unless the maintainer team wishes to adopt this model and use it as a requirement for authorising the "pusher" identity link that is missing as per what is described in #1400
How it works
resolveUserFromTokenruns in the push chain afterparsePush, beforecheckUserPushPermissionTokenIdentityProviderbased on the upstream hostname (github.com →GitHubTokenIdentityProvider)GET /userwith the token to get the SCM logingitAccountfield — if found, setsaction.userandaction.userEmailfrom the DB usergitAccountmatch, falls back to using the SCM login directly (non-blocking)Limitations
gitand Bitbucket APIs. A user email can be linked between both "realms" but you cannot use your email to push code to that platform. Supporting Bitbucket proper requires some credential rewriting which is error-prone and brittle. See BitbucketProvider and BitbucketIdentityFilter in RBC/fogwall for details on what is needed in the HTTP flow. I also had only temporary access to a live Bitbucket server (created a single repo, pushed a single commit to it) before Atlassian's trial expired. If there is someone in the community who has a live Bitbucket server or an existing FOSS project which got approved for Bitbucket use to test against, that would needed to rigourously check this type of logic. It's shared here as prior art/learnings only.Related Issue
related to #1400
General
Documentation
Configuration
no configuration changes introduced
Tests
npm test)npm run lintandnpm run format:check)npm run check-types)GET/PUT /api/v1/user/:username/git-account(coverage exists but UI integration testing is deferred)