Merge pull request #24 from stevvooe/breakup-common
Breakup common package
This commit is contained in:
commit
fdea60af05
18 changed files with 53 additions and 51 deletions
|
@ -4,7 +4,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
"github.com/docker/distribution/common"
|
|
||||||
"github.com/docker/distribution/digest"
|
"github.com/docker/distribution/digest"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,7 +11,7 @@ var (
|
||||||
nameParameterDescriptor = ParameterDescriptor{
|
nameParameterDescriptor = ParameterDescriptor{
|
||||||
Name: "name",
|
Name: "name",
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Format: common.RepositoryNameRegexp.String(),
|
Format: RepositoryNameRegexp.String(),
|
||||||
Required: true,
|
Required: true,
|
||||||
Description: `Name of the target repository.`,
|
Description: `Name of the target repository.`,
|
||||||
}
|
}
|
||||||
|
@ -20,7 +19,7 @@ var (
|
||||||
tagParameterDescriptor = ParameterDescriptor{
|
tagParameterDescriptor = ParameterDescriptor{
|
||||||
Name: "tag",
|
Name: "tag",
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Format: common.TagNameRegexp.String(),
|
Format: TagNameRegexp.String(),
|
||||||
Required: true,
|
Required: true,
|
||||||
Description: `Tag of the target manifiest.`,
|
Description: `Tag of the target manifiest.`,
|
||||||
}
|
}
|
||||||
|
@ -377,7 +376,7 @@ var routeDescriptors = []RouteDescriptor{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: RouteNameTags,
|
Name: RouteNameTags,
|
||||||
Path: "/v2/{name:" + common.RepositoryNameRegexp.String() + "}/tags/list",
|
Path: "/v2/{name:" + RepositoryNameRegexp.String() + "}/tags/list",
|
||||||
Entity: "Tags",
|
Entity: "Tags",
|
||||||
Description: "Retrieve information about tags.",
|
Description: "Retrieve information about tags.",
|
||||||
Methods: []MethodDescriptor{
|
Methods: []MethodDescriptor{
|
||||||
|
@ -448,7 +447,7 @@ var routeDescriptors = []RouteDescriptor{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: RouteNameManifest,
|
Name: RouteNameManifest,
|
||||||
Path: "/v2/{name:" + common.RepositoryNameRegexp.String() + "}/manifests/{tag:" + common.TagNameRegexp.String() + "}",
|
Path: "/v2/{name:" + RepositoryNameRegexp.String() + "}/manifests/{tag:" + TagNameRegexp.String() + "}",
|
||||||
Entity: "Manifest",
|
Entity: "Manifest",
|
||||||
Description: "Create, update and retrieve manifests.",
|
Description: "Create, update and retrieve manifests.",
|
||||||
Methods: []MethodDescriptor{
|
Methods: []MethodDescriptor{
|
||||||
|
@ -693,7 +692,7 @@ var routeDescriptors = []RouteDescriptor{
|
||||||
|
|
||||||
{
|
{
|
||||||
Name: RouteNameBlob,
|
Name: RouteNameBlob,
|
||||||
Path: "/v2/{name:" + common.RepositoryNameRegexp.String() + "}/blobs/{digest:" + digest.DigestRegexp.String() + "}",
|
Path: "/v2/{name:" + RepositoryNameRegexp.String() + "}/blobs/{digest:" + digest.DigestRegexp.String() + "}",
|
||||||
Entity: "Blob",
|
Entity: "Blob",
|
||||||
Description: "Fetch the blob identified by `name` and `digest`. Used to fetch layers by tarsum digest.",
|
Description: "Fetch the blob identified by `name` and `digest`. Used to fetch layers by tarsum digest.",
|
||||||
Methods: []MethodDescriptor{
|
Methods: []MethodDescriptor{
|
||||||
|
@ -852,7 +851,7 @@ var routeDescriptors = []RouteDescriptor{
|
||||||
|
|
||||||
{
|
{
|
||||||
Name: RouteNameBlobUpload,
|
Name: RouteNameBlobUpload,
|
||||||
Path: "/v2/{name:" + common.RepositoryNameRegexp.String() + "}/blobs/uploads/",
|
Path: "/v2/{name:" + RepositoryNameRegexp.String() + "}/blobs/uploads/",
|
||||||
Entity: "Intiate Blob Upload",
|
Entity: "Intiate Blob Upload",
|
||||||
Description: "Initiate a blob upload. This endpoint can be used to create resumable uploads or monolithic uploads.",
|
Description: "Initiate a blob upload. This endpoint can be used to create resumable uploads or monolithic uploads.",
|
||||||
Methods: []MethodDescriptor{
|
Methods: []MethodDescriptor{
|
||||||
|
@ -964,7 +963,7 @@ var routeDescriptors = []RouteDescriptor{
|
||||||
|
|
||||||
{
|
{
|
||||||
Name: RouteNameBlobUploadChunk,
|
Name: RouteNameBlobUploadChunk,
|
||||||
Path: "/v2/{name:" + common.RepositoryNameRegexp.String() + "}/blobs/uploads/{uuid}",
|
Path: "/v2/{name:" + RepositoryNameRegexp.String() + "}/blobs/uploads/{uuid}",
|
||||||
Entity: "Blob Upload",
|
Entity: "Blob Upload",
|
||||||
Description: "Interact with blob uploads. Clients should never assemble URLs for this endpoint and should only take it through the `Location` header on related API requests. The `Location` header and its parameters should be preserved by clients, using the latest value returned via upload related API calls.",
|
Description: "Interact with blob uploads. Clients should never assemble URLs for this endpoint and should only take it through the `Location` header on related API requests. The `Location` header and its parameters should be preserved by clients, using the latest value returned via upload related API calls.",
|
||||||
Methods: []MethodDescriptor{
|
Methods: []MethodDescriptor{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package common
|
package v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -1,4 +1,4 @@
|
||||||
package common
|
package v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
|
@ -14,11 +14,11 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/distribution/api/v2"
|
"github.com/docker/distribution/api/v2"
|
||||||
"github.com/docker/distribution/common/testutil"
|
|
||||||
"github.com/docker/distribution/configuration"
|
"github.com/docker/distribution/configuration"
|
||||||
"github.com/docker/distribution/digest"
|
"github.com/docker/distribution/digest"
|
||||||
"github.com/docker/distribution/manifest"
|
"github.com/docker/distribution/manifest"
|
||||||
_ "github.com/docker/distribution/storagedriver/inmemory"
|
_ "github.com/docker/distribution/storagedriver/inmemory"
|
||||||
|
"github.com/docker/distribution/testutil"
|
||||||
"github.com/docker/libtrust"
|
"github.com/docker/libtrust"
|
||||||
"github.com/gorilla/handlers"
|
"github.com/gorilla/handlers"
|
||||||
)
|
)
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"github.com/docker/libtrust"
|
"github.com/docker/libtrust"
|
||||||
|
|
||||||
"github.com/docker/distribution/auth"
|
"github.com/docker/distribution/auth"
|
||||||
"github.com/docker/distribution/common"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// accessSet maps a typed, named resource to
|
// accessSet maps a typed, named resource to
|
||||||
|
@ -38,7 +37,7 @@ func newAccessSet(accessItems ...auth.Access) accessSet {
|
||||||
accessSet[resource] = set
|
accessSet[resource] = set
|
||||||
}
|
}
|
||||||
|
|
||||||
set.Add(access.Action)
|
set.add(access.Action)
|
||||||
}
|
}
|
||||||
|
|
||||||
return accessSet
|
return accessSet
|
||||||
|
@ -48,7 +47,7 @@ func newAccessSet(accessItems ...auth.Access) accessSet {
|
||||||
func (s accessSet) contains(access auth.Access) bool {
|
func (s accessSet) contains(access auth.Access) bool {
|
||||||
actionSet, ok := s[access.Resource]
|
actionSet, ok := s[access.Resource]
|
||||||
if ok {
|
if ok {
|
||||||
return actionSet.Contains(access.Action)
|
return actionSet.contains(access.Action)
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
@ -61,7 +60,7 @@ func (s accessSet) scopeParam() string {
|
||||||
scopes := make([]string, 0, len(s))
|
scopes := make([]string, 0, len(s))
|
||||||
|
|
||||||
for resource, actionSet := range s {
|
for resource, actionSet := range s {
|
||||||
actions := strings.Join(actionSet.Keys(), ",")
|
actions := strings.Join(actionSet.keys(), ",")
|
||||||
scopes = append(scopes, fmt.Sprintf("%s:%s:%s", resource.Type, resource.Name, actions))
|
scopes = append(scopes, fmt.Sprintf("%s:%s:%s", resource.Type, resource.Name, actions))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,8 +240,8 @@ func (ac *accessController) Authorized(req *http.Request, accessItems ...auth.Ac
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyOpts := VerifyOptions{
|
verifyOpts := VerifyOptions{
|
||||||
TrustedIssuers: common.NewStringSet(ac.issuer),
|
TrustedIssuers: []string{ac.issuer},
|
||||||
AcceptedAudiences: common.NewStringSet(ac.service),
|
AcceptedAudiences: []string{ac.service},
|
||||||
Roots: ac.rootCerts,
|
Roots: ac.rootCerts,
|
||||||
TrustedKeys: ac.trustedKeys,
|
TrustedKeys: ac.trustedKeys,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,30 @@
|
||||||
package common
|
package token
|
||||||
|
|
||||||
// StringSet is a useful type for looking up strings.
|
// StringSet is a useful type for looking up strings.
|
||||||
type StringSet map[string]struct{}
|
type stringSet map[string]struct{}
|
||||||
|
|
||||||
// NewStringSet creates a new StringSet with the given strings.
|
// NewStringSet creates a new StringSet with the given strings.
|
||||||
func NewStringSet(keys ...string) StringSet {
|
func newStringSet(keys ...string) stringSet {
|
||||||
ss := make(StringSet, len(keys))
|
ss := make(stringSet, len(keys))
|
||||||
ss.Add(keys...)
|
ss.add(keys...)
|
||||||
return ss
|
return ss
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add inserts the given keys into this StringSet.
|
// Add inserts the given keys into this StringSet.
|
||||||
func (ss StringSet) Add(keys ...string) {
|
func (ss stringSet) add(keys ...string) {
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
ss[key] = struct{}{}
|
ss[key] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contains returns whether the given key is in this StringSet.
|
// Contains returns whether the given key is in this StringSet.
|
||||||
func (ss StringSet) Contains(key string) bool {
|
func (ss stringSet) contains(key string) bool {
|
||||||
_, ok := ss[key]
|
_, ok := ss[key]
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keys returns a slice of all keys in this StringSet.
|
// Keys returns a slice of all keys in this StringSet.
|
||||||
func (ss StringSet) Keys() []string {
|
func (ss stringSet) keys() []string {
|
||||||
keys := make([]string, 0, len(ss))
|
keys := make([]string, 0, len(ss))
|
||||||
|
|
||||||
for key := range ss {
|
for key := range ss {
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"github.com/docker/libtrust"
|
"github.com/docker/libtrust"
|
||||||
|
|
||||||
"github.com/docker/distribution/auth"
|
"github.com/docker/distribution/auth"
|
||||||
"github.com/docker/distribution/common"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -71,8 +70,8 @@ type Token struct {
|
||||||
// VerifyOptions is used to specify
|
// VerifyOptions is used to specify
|
||||||
// options when verifying a JSON Web Token.
|
// options when verifying a JSON Web Token.
|
||||||
type VerifyOptions struct {
|
type VerifyOptions struct {
|
||||||
TrustedIssuers common.StringSet
|
TrustedIssuers []string
|
||||||
AcceptedAudiences common.StringSet
|
AcceptedAudiences []string
|
||||||
Roots *x509.CertPool
|
Roots *x509.CertPool
|
||||||
TrustedKeys map[string]libtrust.PublicKey
|
TrustedKeys map[string]libtrust.PublicKey
|
||||||
}
|
}
|
||||||
|
@ -132,13 +131,13 @@ func NewToken(rawToken string) (*Token, error) {
|
||||||
// Returns a nil error if the token is valid.
|
// Returns a nil error if the token is valid.
|
||||||
func (t *Token) Verify(verifyOpts VerifyOptions) error {
|
func (t *Token) Verify(verifyOpts VerifyOptions) error {
|
||||||
// Verify that the Issuer claim is a trusted authority.
|
// Verify that the Issuer claim is a trusted authority.
|
||||||
if !verifyOpts.TrustedIssuers.Contains(t.Claims.Issuer) {
|
if !contains(verifyOpts.TrustedIssuers, t.Claims.Issuer) {
|
||||||
log.Errorf("token from untrusted issuer: %q", t.Claims.Issuer)
|
log.Errorf("token from untrusted issuer: %q", t.Claims.Issuer)
|
||||||
return ErrInvalidToken
|
return ErrInvalidToken
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that the Audience claim is allowed.
|
// Verify that the Audience claim is allowed.
|
||||||
if !verifyOpts.AcceptedAudiences.Contains(t.Claims.Audience) {
|
if !contains(verifyOpts.AcceptedAudiences, t.Claims.Audience) {
|
||||||
log.Errorf("token intended for another audience: %q", t.Claims.Audience)
|
log.Errorf("token intended for another audience: %q", t.Claims.Audience)
|
||||||
return ErrInvalidToken
|
return ErrInvalidToken
|
||||||
}
|
}
|
||||||
|
@ -332,7 +331,7 @@ func (t *Token) accessSet() accessSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, action := range resourceActions.Actions {
|
for _, action := range resourceActions.Actions {
|
||||||
set.Add(action)
|
set.add(action)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/libtrust"
|
|
||||||
|
|
||||||
"github.com/docker/distribution/auth"
|
"github.com/docker/distribution/auth"
|
||||||
"github.com/docker/distribution/common"
|
"github.com/docker/libtrust"
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeRootKeys(numKeys int) ([]libtrust.PrivateKey, error) {
|
func makeRootKeys(numKeys int) ([]libtrust.PrivateKey, error) {
|
||||||
|
@ -196,8 +194,8 @@ func TestTokenVerify(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyOps := VerifyOptions{
|
verifyOps := VerifyOptions{
|
||||||
TrustedIssuers: common.NewStringSet(issuer),
|
TrustedIssuers: []string{issuer},
|
||||||
AcceptedAudiences: common.NewStringSet(audience),
|
AcceptedAudiences: []string{audience},
|
||||||
Roots: rootPool,
|
Roots: rootPool,
|
||||||
TrustedKeys: trustedKeys,
|
TrustedKeys: trustedKeys,
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,6 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/distribution/common"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// joseBase64UrlEncode encodes the given data using the standard base64 url
|
// joseBase64UrlEncode encodes the given data using the standard base64 url
|
||||||
|
@ -35,15 +33,26 @@ func joseBase64UrlDecode(s string) ([]byte, error) {
|
||||||
|
|
||||||
// actionSet is a special type of stringSet.
|
// actionSet is a special type of stringSet.
|
||||||
type actionSet struct {
|
type actionSet struct {
|
||||||
common.StringSet
|
stringSet
|
||||||
}
|
}
|
||||||
|
|
||||||
func newActionSet(actions ...string) actionSet {
|
func newActionSet(actions ...string) actionSet {
|
||||||
return actionSet{common.NewStringSet(actions...)}
|
return actionSet{newStringSet(actions...)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contains calls StringSet.Contains() for
|
// Contains calls StringSet.Contains() for
|
||||||
// either "*" or the given action string.
|
// either "*" or the given action string.
|
||||||
func (s actionSet) Contains(action string) bool {
|
func (s actionSet) contains(action string) bool {
|
||||||
return s.StringSet.Contains("*") || s.StringSet.Contains(action)
|
return s.stringSet.contains("*") || s.stringSet.contains(action)
|
||||||
|
}
|
||||||
|
|
||||||
|
// contains returns true if q is found in ss.
|
||||||
|
func contains(ss []string, q string) bool {
|
||||||
|
for _, s := range ss {
|
||||||
|
if s == q {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/distribution/common/testutil"
|
|
||||||
"github.com/docker/distribution/digest"
|
"github.com/docker/distribution/digest"
|
||||||
"github.com/docker/distribution/manifest"
|
"github.com/docker/distribution/manifest"
|
||||||
|
"github.com/docker/distribution/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type testBlob struct {
|
type testBlob struct {
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/distribution/common"
|
|
||||||
"github.com/docker/docker/pkg/tarsum"
|
"github.com/docker/docker/pkg/tarsum"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -105,7 +104,7 @@ func FromBytes(p []byte) (Digest, error) {
|
||||||
func (d Digest) Validate() error {
|
func (d Digest) Validate() error {
|
||||||
s := string(d)
|
s := string(d)
|
||||||
// Common case will be tarsum
|
// Common case will be tarsum
|
||||||
_, err := common.ParseTarSum(s)
|
_, err := ParseTarSum(s)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package common
|
package digest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -1,4 +1,4 @@
|
||||||
package common
|
package digest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/distribution/common/testutil"
|
"github.com/docker/distribution/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDigestVerifier(t *testing.T) {
|
func TestDigestVerifier(t *testing.T) {
|
||||||
|
|
|
@ -9,10 +9,10 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/distribution/common/testutil"
|
|
||||||
"github.com/docker/distribution/digest"
|
"github.com/docker/distribution/digest"
|
||||||
"github.com/docker/distribution/storagedriver"
|
"github.com/docker/distribution/storagedriver"
|
||||||
"github.com/docker/distribution/storagedriver/inmemory"
|
"github.com/docker/distribution/storagedriver/inmemory"
|
||||||
|
"github.com/docker/distribution/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestSimpleLayerUpload covers the layer upload process, exercising common
|
// TestSimpleLayerUpload covers the layer upload process, exercising common
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/distribution/common"
|
|
||||||
"github.com/docker/distribution/digest"
|
"github.com/docker/distribution/digest"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -189,7 +188,7 @@ func digestPathComoponents(dgst digest.Digest) ([]string, error) {
|
||||||
hex,
|
hex,
|
||||||
}
|
}
|
||||||
|
|
||||||
if tsi, err := common.ParseTarSum(dgst.String()); err == nil {
|
if tsi, err := digest.ParseTarSum(dgst.String()); err == nil {
|
||||||
// We have a tarsum!
|
// We have a tarsum!
|
||||||
version := tsi.Version
|
version := tsi.Version
|
||||||
if version == "" {
|
if version == "" {
|
||||||
|
|
Loading…
Reference in a new issue