Skip to content

Commit a428ca6

Browse files
authored
feat: support per-host scope hints (#604)
The purpose of this PR is to fix the bug, but new APIs are needed to avoid breaking changes. 1. Introduce `auth.WithScopesForHost` 2. Introduce `auth.AppendScopesForHost` 3. Introduce `auth.GetScopesForHost` and `auth.GetAllScopesForHost` 4. Introduce `auth.AppendRepositoryScope` Resolves: #581 Signed-off-by: Lixia (Sylvia) Lei <lixlei@microsoft.com>
1 parent 2d371a0 commit a428ca6

File tree

8 files changed

+2207
-195
lines changed

8 files changed

+2207
-195
lines changed

content.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import (
2929
"oras.land/oras-go/v2/internal/docker"
3030
"oras.land/oras-go/v2/internal/interfaces"
3131
"oras.land/oras-go/v2/internal/platform"
32-
"oras.land/oras-go/v2/internal/registryutil"
3332
"oras.land/oras-go/v2/internal/syncutil"
3433
"oras.land/oras-go/v2/registry"
3534
"oras.land/oras-go/v2/registry/remote/auth"
@@ -91,7 +90,7 @@ func TagN(ctx context.Context, target Target, srcReference string, dstReferences
9190
if err != nil {
9291
return ocispec.Descriptor{}, err
9392
}
94-
ctx = registryutil.WithScopeHint(ctx, ref, auth.ActionPull, auth.ActionPush)
93+
ctx = auth.AppendRepositoryScope(ctx, ref, auth.ActionPull, auth.ActionPush)
9594
}
9695

9796
desc, contentBytes, err := FetchBytes(ctx, target, srcReference, FetchBytesOptions{
@@ -149,7 +148,7 @@ func Tag(ctx context.Context, target Target, src, dst string) (ocispec.Descripto
149148
if err != nil {
150149
return ocispec.Descriptor{}, err
151150
}
152-
ctx = registryutil.WithScopeHint(ctx, ref, auth.ActionPull, auth.ActionPush)
151+
ctx = auth.AppendRepositoryScope(ctx, ref, auth.ActionPull, auth.ActionPush)
153152
}
154153
desc, rc, err := refFetcher.FetchReference(ctx, src)
155154
if err != nil {

internal/registryutil/auth.go

-29
This file was deleted.

registry/remote/auth/client.go

+14-14
Original file line numberDiff line numberDiff line change
@@ -177,19 +177,19 @@ func (c *Client) Do(originalReq *http.Request) (*http.Response, error) {
177177
// attempt cached auth token
178178
var attemptedKey string
179179
cache := c.cache()
180-
registry := originalReq.Host
181-
scheme, err := cache.GetScheme(ctx, registry)
180+
host := originalReq.Host
181+
scheme, err := cache.GetScheme(ctx, host)
182182
if err == nil {
183183
switch scheme {
184184
case SchemeBasic:
185-
token, err := cache.GetToken(ctx, registry, SchemeBasic, "")
185+
token, err := cache.GetToken(ctx, host, SchemeBasic, "")
186186
if err == nil {
187187
req.Header.Set("Authorization", "Basic "+token)
188188
}
189189
case SchemeBearer:
190-
scopes := GetScopes(ctx)
190+
scopes := GetAllScopesForHost(ctx, host)
191191
attemptedKey = strings.Join(scopes, " ")
192-
token, err := cache.GetToken(ctx, registry, SchemeBearer, attemptedKey)
192+
token, err := cache.GetToken(ctx, host, SchemeBearer, attemptedKey)
193193
if err == nil {
194194
req.Header.Set("Authorization", "Bearer "+token)
195195
}
@@ -211,8 +211,8 @@ func (c *Client) Do(originalReq *http.Request) (*http.Response, error) {
211211
case SchemeBasic:
212212
resp.Body.Close()
213213

214-
token, err := cache.Set(ctx, registry, SchemeBasic, "", func(ctx context.Context) (string, error) {
215-
return c.fetchBasicAuth(ctx, registry)
214+
token, err := cache.Set(ctx, host, SchemeBasic, "", func(ctx context.Context) (string, error) {
215+
return c.fetchBasicAuth(ctx, host)
216216
})
217217
if err != nil {
218218
return nil, fmt.Errorf("%s %q: %w", resp.Request.Method, resp.Request.URL, err)
@@ -223,17 +223,17 @@ func (c *Client) Do(originalReq *http.Request) (*http.Response, error) {
223223
case SchemeBearer:
224224
resp.Body.Close()
225225

226-
// merge hinted scopes with challenged scopes
227-
scopes := GetScopes(ctx)
228-
if scope := params["scope"]; scope != "" {
229-
scopes = append(scopes, strings.Split(scope, " ")...)
226+
scopes := GetAllScopesForHost(ctx, host)
227+
if paramScope := params["scope"]; paramScope != "" {
228+
// merge hinted scopes with challenged scopes
229+
scopes = append(scopes, strings.Split(paramScope, " ")...)
230230
scopes = CleanScopes(scopes)
231231
}
232232
key := strings.Join(scopes, " ")
233233

234234
// attempt the cache again if there is a scope change
235235
if key != attemptedKey {
236-
if token, err := cache.GetToken(ctx, registry, SchemeBearer, key); err == nil {
236+
if token, err := cache.GetToken(ctx, host, SchemeBearer, key); err == nil {
237237
req = originalReq.Clone(ctx)
238238
req.Header.Set("Authorization", "Bearer "+token)
239239
if err := rewindRequestBody(req); err != nil {
@@ -254,8 +254,8 @@ func (c *Client) Do(originalReq *http.Request) (*http.Response, error) {
254254
// attempt with credentials
255255
realm := params["realm"]
256256
service := params["service"]
257-
token, err := cache.Set(ctx, registry, SchemeBearer, key, func(ctx context.Context) (string, error) {
258-
return c.fetchBearerToken(ctx, registry, realm, service, scopes)
257+
token, err := cache.Set(ctx, host, SchemeBearer, key, func(ctx context.Context) (string, error) {
258+
return c.fetchBearerToken(ctx, host, realm, service, scopes)
259259
})
260260
if err != nil {
261261
return nil, fmt.Errorf("%s %q: %w", resp.Request.Method, resp.Request.URL, err)

0 commit comments

Comments
 (0)