-
Notifications
You must be signed in to change notification settings - Fork 16
use hostname/path rather than just path to key OIDCCredential map #72
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
Changes from 1 commit
32b961d
266a999
82543b7
634a992
bdcb53f
5a15dbb
e53500e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,8 @@ package handlers | |
| import ( | ||
| "fmt" | ||
| "net/http" | ||
| "net/url" | ||
| "os" | ||
| "strings" | ||
| "sync" | ||
|
|
||
|
|
@@ -46,16 +48,22 @@ func NewNPMRegistryHandler(creds config.Credentials) *NPMRegistryHandler { | |
|
|
||
| oidcCredential, _ := oidc.CreateOIDCCredential(cred) | ||
| if oidcCredential != nil { | ||
| host := cred.Host() | ||
| if host == "" && registry != "" { | ||
| var myUrl string | ||
| maybeUrl := cred.GetString("url") | ||
| if maybeUrl == "" && registry != "" { | ||
| regURL, err := helpers.ParseURLLax(registry) | ||
| if err == nil { | ||
| host = regURL.Hostname() | ||
| myUrl = fmt.Sprintf("%s/%s", regURL.Host, regURL.Path) | ||
| } | ||
| } else { | ||
| parsedUrl, err := helpers.ParseURLLax(maybeUrl) | ||
| if err == nil { | ||
| myUrl = fmt.Sprintf("%s/%s", parsedUrl.Host, parsedUrl.Path) | ||
| } | ||
| } | ||
| if host != "" { | ||
| handler.oidcCredentials[host] = oidcCredential | ||
| logging.RequestLogf(nil, "registered %s OIDC credentials for npm registry: %s", oidcCredential.Provider(), host) | ||
| if myUrl != "" { | ||
| handler.oidcCredentials[myUrl] = oidcCredential | ||
| logging.RequestLogf(nil, "registered %s OIDC credentials for npm registry: %s", oidcCredential.Provider(), myUrl) | ||
| } | ||
| continue | ||
| } | ||
|
|
@@ -73,6 +81,18 @@ func NewNPMRegistryHandler(creds config.Credentials) *NPMRegistryHandler { | |
| return &handler | ||
| } | ||
|
|
||
| // GetOIDCCredential returns oidc credential for url | ||
| func (h *NPMRegistryHandler) GetOIDCCredential(url url.URL) (*oidc.OIDCCredential, bool) { | ||
| targetUrl := fmt.Sprintf("%s/%s", url.Host, url.Path) | ||
|
||
| for registry, cred := range h.oidcCredentials { | ||
| if strings.HasPrefix(targetUrl, registry) { | ||
|
||
| fmt.Fprint(os.Stderr, targetUrl) | ||
microblag marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return cred, true | ||
| } | ||
| } | ||
|
||
| return nil, false | ||
| } | ||
|
|
||
| // HandleRequest adds auth to an npm registry request | ||
| func (h *NPMRegistryHandler) HandleRequest(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) { | ||
| if req.URL.Scheme != "https" || !helpers.MethodPermitted(req, "GET", "HEAD") { | ||
|
|
@@ -87,16 +107,16 @@ func (h *NPMRegistryHandler) HandleRequest(req *http.Request, ctx *goproxy.Proxy | |
|
|
||
| // Try OIDC credentials first | ||
| h.mutex.RLock() | ||
| oidcCred, hasOIDC := h.oidcCredentials[reqHost] | ||
| oidcCred, hasOIDC := h.GetOIDCCredential(*req.URL) | ||
| h.mutex.RUnlock() | ||
|
||
|
|
||
| if hasOIDC { | ||
| token, err := oidc.GetOrRefreshOIDCToken(oidcCred, req.Context()) | ||
| if err != nil { | ||
| logging.RequestLogf(ctx, "* failed to get token via OIDC for %s: %v", reqHost, err) | ||
| logging.RequestLogf(ctx, "* failed to get token via OIDC for %s: %v", req.URL, err) | ||
| // Fall through to try static credentials | ||
| } else { | ||
| logging.RequestLogf(ctx, "* authenticating npm registry request with OIDC token (host: %s)", reqHost) | ||
| logging.RequestLogf(ctx, "* authenticating npm registry request with OIDC token (host: %s)", req.URL) | ||
| req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) | ||
|
||
| return req, nil | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,10 +2,14 @@ package handlers | |||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||
| "fmt" | ||||||||||||||||||||||||||||||||||||||
| "net/http" | ||||||||||||||||||||||||||||||||||||||
| "net/http/httptest" | ||||||||||||||||||||||||||||||||||||||
| "os" | ||||||||||||||||||||||||||||||||||||||
| "testing" | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| "github.com/dependabot/proxy/internal/config" | ||||||||||||||||||||||||||||||||||||||
| "github.com/jarcoal/httpmock" | ||||||||||||||||||||||||||||||||||||||
| "github.com/stretchr/testify/assert" | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| func TestNPMRegistryHandler(t *testing.T) { | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -40,6 +44,24 @@ func TestNPMRegistryHandler(t *testing.T) { | |||||||||||||||||||||||||||||||||||||
| "url": "https://example.org:443/reg-path", | ||||||||||||||||||||||||||||||||||||||
| "token": privateRegToken, | ||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||
| config.Credential{ | ||||||||||||||||||||||||||||||||||||||
| "type": "npm_registry", | ||||||||||||||||||||||||||||||||||||||
| "url": "https://mydomain-123456789123.d.codeartifact.us-east-1.amazonaws.com/npm/my-registry-1/", | ||||||||||||||||||||||||||||||||||||||
| "aws-region": "us-east-1", | ||||||||||||||||||||||||||||||||||||||
| "account-id": "123456789123", | ||||||||||||||||||||||||||||||||||||||
| "role-name": "my-registry-role-1", | ||||||||||||||||||||||||||||||||||||||
| "domain": "mydomain", | ||||||||||||||||||||||||||||||||||||||
| "domain-owner": "123456789123", | ||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||
| config.Credential{ | ||||||||||||||||||||||||||||||||||||||
| "type": "npm_registry", | ||||||||||||||||||||||||||||||||||||||
| "url": "https://mydomain-123456789123.d.codeartifact.us-east-1.amazonaws.com/npm/my-registry-2/", | ||||||||||||||||||||||||||||||||||||||
| "aws-region": "us-east-1", | ||||||||||||||||||||||||||||||||||||||
| "account-id": "123456789123", | ||||||||||||||||||||||||||||||||||||||
| "role-name": "my-registry-role-2", | ||||||||||||||||||||||||||||||||||||||
| "domain": "mydomain", | ||||||||||||||||||||||||||||||||||||||
| "domain-owner": "123456789123", | ||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
| config.Credential{ | |
| "type": "npm_registry", | |
| "url": "https://mydomain-123456789123.d.codeartifact.us-east-1.amazonaws.com/npm/my-registry-1/", | |
| "aws-region": "us-east-1", | |
| "account-id": "123456789123", | |
| "role-name": "my-registry-role-1", | |
| "domain": "mydomain", | |
| "domain-owner": "123456789123", | |
| }, | |
| config.Credential{ | |
| "type": "npm_registry", | |
| "url": "https://mydomain-123456789123.d.codeartifact.us-east-1.amazonaws.com/npm/my-registry-2/", | |
| "aws-region": "us-east-1", | |
| "account-id": "123456789123", | |
| "role-name": "my-registry-role-2", | |
| "domain": "mydomain", | |
| "domain-owner": "123456789123", | |
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these were leftover from an earlier attempt at testing, have now been removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OIDC credential registration no longer considers the credential's
hostfield (orcred.Host()), onlyurl/registry. This is a behavior change from the previous implementation and will break OIDC for npm registries configured viahostonly. Consider falling back tocred.Host()(and/orcred.GetString("host")) whenurlandregistryare empty, while still preferring the full URL+path when available.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now trying host, url, registry (in that order). but not using the .Host() method as it just returns the hostname part if a url is specified