containerd/remotes/docker/scope_test.go
Brian Goff e84a84a5a9 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 <cpuguy83@gmail.com>
2019-09-18 11:29:16 -07:00

109 lines
3.0 KiB
Go

/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package docker
import (
"context"
"testing"
"github.com/containerd/containerd/reference"
"gotest.tools/assert"
"gotest.tools/assert/cmp"
)
func TestRepositoryScope(t *testing.T) {
testCases := []struct {
refspec reference.Spec
push bool
expected string
}{
{
refspec: reference.Spec{
Locator: "host/foo/bar",
Object: "ignored",
},
push: false,
expected: "repository:foo/bar:pull",
},
{
refspec: reference.Spec{
Locator: "host:4242/foo/bar",
Object: "ignored",
},
push: true,
expected: "repository:foo/bar:pull,push",
},
}
for _, x := range testCases {
t.Run(x.refspec.String(), func(t *testing.T) {
actual, err := repositoryScope(x.refspec, x.push)
assert.NilError(t, err)
assert.Equal(t, x.expected, actual)
})
}
}
func TestGetTokenScopes(t *testing.T) {
testCases := []struct {
scopesInCtx []string
commonScopes []string
expected []string
}{
{
scopesInCtx: []string{},
commonScopes: []string{"repository:foo/bar:pull"},
expected: []string{"repository:foo/bar:pull"},
},
{
scopesInCtx: []string{"repository:foo/bar:pull,push"},
commonScopes: []string{},
expected: []string{"repository:foo/bar:pull,push"},
},
{
scopesInCtx: []string{"repository:foo/bar:pull"},
commonScopes: []string{"repository:foo/bar:pull"},
expected: []string{"repository:foo/bar:pull"},
},
{
scopesInCtx: []string{"repository:foo/bar:pull"},
commonScopes: []string{"repository:foo/bar:pull,push"},
expected: []string{"repository:foo/bar:pull", "repository:foo/bar:pull,push"},
},
{
scopesInCtx: []string{"repository:foo/bar:pull"},
commonScopes: []string{"repository:foo/bar:pull,push", "repository:foo/bar:pull"},
expected: []string{"repository:foo/bar:pull", "repository:foo/bar:pull,push"},
},
}
for _, tc := range testCases {
ctx := context.WithValue(context.TODO(), tokenScopesKey{}, tc.scopesInCtx)
actual := getTokenScopes(ctx, tc.commonScopes)
assert.DeepEqual(t, tc.expected, actual)
}
}
func TestCustomScope(t *testing.T) {
scope := "whatever:foo/bar:pull"
ctx := WithScope(context.Background(), scope)
ctx = contextWithAppendPullRepositoryScope(ctx, "foo/bar")
scopes := getTokenScopes(ctx, []string{})
assert.Assert(t, cmp.Len(scopes, 2))
assert.Check(t, cmp.Equal(scopes[0], "repository:foo/bar:pull"))
assert.Check(t, cmp.Equal(scopes[1], scope))
}