From aea52c7fb5d301131c0acef95b5a12c37532687c Mon Sep 17 00:00:00 2001 From: Stephen J Day Date: Mon, 5 Jan 2015 18:21:03 -0800 Subject: [PATCH] Remove exported StringSet type and collections package The exported StringSet type is not necessary for the current use case of validating issues and audiences. The exported fields on VerifyOptions have been changed to require string slices. The collections package has been removed and the StringSet has been moved to the token package, where it is used. Signed-off-by: Stephen J Day --- auth/token/accesscontroller.go | 11 +++++------ {collections => auth/token}/stringset.go | 16 ++++++++-------- auth/token/token.go | 11 +++++------ auth/token/token_test.go | 8 +++----- auth/token/util.go | 21 +++++++++++++++------ 5 files changed, 36 insertions(+), 31 deletions(-) rename {collections => auth/token}/stringset.go (64%) diff --git a/auth/token/accesscontroller.go b/auth/token/accesscontroller.go index b1a262f406..4bbbc3e01f 100644 --- a/auth/token/accesscontroller.go +++ b/auth/token/accesscontroller.go @@ -14,7 +14,6 @@ import ( "github.com/docker/libtrust" "github.com/docker/distribution/auth" - "github.com/docker/distribution/collections" ) // accessSet maps a typed, named resource to @@ -38,7 +37,7 @@ func newAccessSet(accessItems ...auth.Access) accessSet { accessSet[resource] = set } - set.Add(access.Action) + set.add(access.Action) } return accessSet @@ -48,7 +47,7 @@ func newAccessSet(accessItems ...auth.Access) accessSet { func (s accessSet) contains(access auth.Access) bool { actionSet, ok := s[access.Resource] if ok { - return actionSet.Contains(access.Action) + return actionSet.contains(access.Action) } return false @@ -61,7 +60,7 @@ func (s accessSet) scopeParam() string { scopes := make([]string, 0, len(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)) } @@ -241,8 +240,8 @@ func (ac *accessController) Authorized(req *http.Request, accessItems ...auth.Ac } verifyOpts := VerifyOptions{ - TrustedIssuers: collections.NewStringSet(ac.issuer), - AcceptedAudiences: collections.NewStringSet(ac.service), + TrustedIssuers: []string{ac.issuer}, + AcceptedAudiences: []string{ac.service}, Roots: ac.rootCerts, TrustedKeys: ac.trustedKeys, } diff --git a/collections/stringset.go b/auth/token/stringset.go similarity index 64% rename from collections/stringset.go rename to auth/token/stringset.go index 8ce1becbc5..1d04f104c5 100644 --- a/collections/stringset.go +++ b/auth/token/stringset.go @@ -1,30 +1,30 @@ -package collections +package token // 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. -func NewStringSet(keys ...string) StringSet { - ss := make(StringSet, len(keys)) - ss.Add(keys...) +func newStringSet(keys ...string) stringSet { + ss := make(stringSet, len(keys)) + ss.add(keys...) return ss } // Add inserts the given keys into this StringSet. -func (ss StringSet) Add(keys ...string) { +func (ss stringSet) add(keys ...string) { for _, key := range keys { ss[key] = struct{}{} } } // 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] return ok } // 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)) for key := range ss { diff --git a/auth/token/token.go b/auth/token/token.go index d63a45a141..49449f3ba0 100644 --- a/auth/token/token.go +++ b/auth/token/token.go @@ -14,7 +14,6 @@ import ( "github.com/docker/libtrust" "github.com/docker/distribution/auth" - "github.com/docker/distribution/collections" ) const ( @@ -71,8 +70,8 @@ type Token struct { // VerifyOptions is used to specify // options when verifying a JSON Web Token. type VerifyOptions struct { - TrustedIssuers collections.StringSet - AcceptedAudiences collections.StringSet + TrustedIssuers []string + AcceptedAudiences []string Roots *x509.CertPool TrustedKeys map[string]libtrust.PublicKey } @@ -132,13 +131,13 @@ func NewToken(rawToken string) (*Token, error) { // Returns a nil error if the token is valid. func (t *Token) Verify(verifyOpts VerifyOptions) error { // 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) return ErrInvalidToken } // 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) return ErrInvalidToken } @@ -332,7 +331,7 @@ func (t *Token) accessSet() accessSet { } for _, action := range resourceActions.Actions { - set.Add(action) + set.add(action) } } diff --git a/auth/token/token_test.go b/auth/token/token_test.go index e8248217fa..ba81900b51 100644 --- a/auth/token/token_test.go +++ b/auth/token/token_test.go @@ -15,10 +15,8 @@ import ( "testing" "time" - "github.com/docker/libtrust" - "github.com/docker/distribution/auth" - "github.com/docker/distribution/collections" + "github.com/docker/libtrust" ) func makeRootKeys(numKeys int) ([]libtrust.PrivateKey, error) { @@ -196,8 +194,8 @@ func TestTokenVerify(t *testing.T) { } verifyOps := VerifyOptions{ - TrustedIssuers: collections.NewStringSet(issuer), - AcceptedAudiences: collections.NewStringSet(audience), + TrustedIssuers: []string{issuer}, + AcceptedAudiences: []string{audience}, Roots: rootPool, TrustedKeys: trustedKeys, } diff --git a/auth/token/util.go b/auth/token/util.go index f907217109..bf3e01e838 100644 --- a/auth/token/util.go +++ b/auth/token/util.go @@ -4,8 +4,6 @@ import ( "encoding/base64" "errors" "strings" - - "github.com/docker/distribution/collections" ) // 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. type actionSet struct { - collections.StringSet + stringSet } func newActionSet(actions ...string) actionSet { - return actionSet{collections.NewStringSet(actions...)} + return actionSet{newStringSet(actions...)} } // Contains calls StringSet.Contains() for // either "*" or the given action string. -func (s actionSet) Contains(action string) bool { - return s.StringSet.Contains("*") || s.StringSet.Contains(action) +func (s actionSet) contains(action string) bool { + 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 }