Skip to content

Commit e84a84a

Browse files
committed
Add function to set custom auth scope in context
Currently auth.docker.io uses a custom auth scope for (docker) plugins `repository(plugin):<repo>:<perms>`. This makes it impossible to use containerd distribution tooling to fetch plugins without also supplying a totally custom authorizer. This changes allows clients to set the correct scope on the context. It's a little bit nasty but "works". I'm also a bit suspect of some a couple of these unexported context functrions. Before the primary one used `contextWithRepositoryScope` overwrites any scope value and there is another one that appends the scope value. With this change they both append... Signed-off-by: Brian Goff <[email protected]>
1 parent 324a947 commit e84a84a

2 files changed

Lines changed: 25 additions & 7 deletions

File tree

remotes/docker/scope.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,27 @@ func contextWithRepositoryScope(ctx context.Context, refspec reference.Spec, pus
5151
if err != nil {
5252
return nil, err
5353
}
54-
return context.WithValue(ctx, tokenScopesKey{}, []string{s}), nil
54+
return WithScope(ctx, s), nil
5555
}
5656

57-
// contextWithAppendPullRepositoryScope is used to append repository pull
58-
// scope into existing scopes indexed by the tokenScopesKey{}.
59-
func contextWithAppendPullRepositoryScope(ctx context.Context, repo string) context.Context {
57+
// WithScope appends a custom registry auth scope to the context.
58+
func WithScope(ctx context.Context, scope string) context.Context {
6059
var scopes []string
61-
6260
if v := ctx.Value(tokenScopesKey{}); v != nil {
63-
scopes = append(scopes, v.([]string)...)
61+
scopes = v.([]string)
62+
scopes = append(scopes, scope)
63+
} else {
64+
scopes = []string{scope}
6465
}
65-
scopes = append(scopes, fmt.Sprintf("repository:%s:pull", repo))
6666
return context.WithValue(ctx, tokenScopesKey{}, scopes)
6767
}
6868

69+
// contextWithAppendPullRepositoryScope is used to append repository pull
70+
// scope into existing scopes indexed by the tokenScopesKey{}.
71+
func contextWithAppendPullRepositoryScope(ctx context.Context, repo string) context.Context {
72+
return WithScope(ctx, fmt.Sprintf("repository:%s:pull", repo))
73+
}
74+
6975
// getTokenScopes returns deduplicated and sorted scopes from ctx.Value(tokenScopesKey{}) and common scopes.
7076
func getTokenScopes(ctx context.Context, common []string) []string {
7177
var scopes []string

remotes/docker/scope_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222

2323
"github.com/containerd/containerd/reference"
2424
"gotest.tools/assert"
25+
"gotest.tools/assert/cmp"
2526
)
2627

2728
func TestRepositoryScope(t *testing.T) {
@@ -94,3 +95,14 @@ func TestGetTokenScopes(t *testing.T) {
9495
assert.DeepEqual(t, tc.expected, actual)
9596
}
9697
}
98+
99+
func TestCustomScope(t *testing.T) {
100+
scope := "whatever:foo/bar:pull"
101+
ctx := WithScope(context.Background(), scope)
102+
ctx = contextWithAppendPullRepositoryScope(ctx, "foo/bar")
103+
104+
scopes := getTokenScopes(ctx, []string{})
105+
assert.Assert(t, cmp.Len(scopes, 2))
106+
assert.Check(t, cmp.Equal(scopes[0], "repository:foo/bar:pull"))
107+
assert.Check(t, cmp.Equal(scopes[1], scope))
108+
}

0 commit comments

Comments
 (0)