Refactor auth stringSet into common.StringSet
Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)master
							parent
							
								
									56f685c0dd
								
							
						
					
					
						commit
						88de2e11fb
					
				| 
						 | 
					@ -12,8 +12,10 @@ import (
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/docker/docker-registry/auth"
 | 
					 | 
				
			||||||
	"github.com/docker/libtrust"
 | 
						"github.com/docker/libtrust"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/docker/docker-registry/auth"
 | 
				
			||||||
 | 
						"github.com/docker/docker-registry/common"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// accessSet maps a typed, named resource to
 | 
					// accessSet maps a typed, named resource to
 | 
				
			||||||
| 
						 | 
					@ -31,13 +33,13 @@ func newAccessSet(accessItems ...auth.Access) accessSet {
 | 
				
			||||||
			Name: access.Name,
 | 
								Name: access.Name,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		set := accessSet[resource]
 | 
							set, exists := accessSet[resource]
 | 
				
			||||||
		if set == nil {
 | 
							if !exists {
 | 
				
			||||||
			set = make(actionSet)
 | 
								set = newActionSet()
 | 
				
			||||||
			accessSet[resource] = set
 | 
								accessSet[resource] = set
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		set[access.Action] = struct{}{}
 | 
							set.Add(access.Action)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return accessSet
 | 
						return accessSet
 | 
				
			||||||
| 
						 | 
					@ -47,7 +49,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
 | 
				
			||||||
| 
						 | 
					@ -60,7 +62,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))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -240,8 +242,8 @@ func (ac *accessController) Authorized(req *http.Request, accessItems ...auth.Ac
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	verifyOpts := VerifyOptions{
 | 
						verifyOpts := VerifyOptions{
 | 
				
			||||||
		TrustedIssuers:    newStringSet(ac.issuer),
 | 
							TrustedIssuers:    common.NewStringSet(ac.issuer),
 | 
				
			||||||
		AccpetedAudiences: newStringSet(ac.service),
 | 
							AccpetedAudiences: common.NewStringSet(ac.service),
 | 
				
			||||||
		Roots:             ac.rootCerts,
 | 
							Roots:             ac.rootCerts,
 | 
				
			||||||
		TrustedKeys:       ac.trustedKeys,
 | 
							TrustedKeys:       ac.trustedKeys,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@ import (
 | 
				
			||||||
	"github.com/docker/libtrust"
 | 
						"github.com/docker/libtrust"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/docker/docker-registry/auth"
 | 
						"github.com/docker/docker-registry/auth"
 | 
				
			||||||
 | 
						"github.com/docker/docker-registry/common"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
| 
						 | 
					@ -85,8 +86,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    stringSet
 | 
						TrustedIssuers    common.StringSet
 | 
				
			||||||
	AccpetedAudiences stringSet
 | 
						AccpetedAudiences common.StringSet
 | 
				
			||||||
	Roots             *x509.CertPool
 | 
						Roots             *x509.CertPool
 | 
				
			||||||
	TrustedKeys       map[string]libtrust.PublicKey
 | 
						TrustedKeys       map[string]libtrust.PublicKey
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -155,13 +156,13 @@ 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 !verifyOpts.TrustedIssuers.Contains(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.AccpetedAudiences.contains(t.Claims.Audience) {
 | 
						if !verifyOpts.AccpetedAudiences.Contains(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
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -319,14 +320,14 @@ func (t *Token) accessSet() accessSet {
 | 
				
			||||||
			Name: resourceActions.Name,
 | 
								Name: resourceActions.Name,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		set := accessSet[resource]
 | 
							set, exists := accessSet[resource]
 | 
				
			||||||
		if set == nil {
 | 
							if !exists {
 | 
				
			||||||
			set = make(actionSet)
 | 
								set = newActionSet()
 | 
				
			||||||
			accessSet[resource] = set
 | 
								accessSet[resource] = set
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for _, action := range resourceActions.Actions {
 | 
							for _, action := range resourceActions.Actions {
 | 
				
			||||||
			set[action] = struct{}{}
 | 
								set.Add(action)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,8 +15,10 @@ import (
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/docker/docker-registry/auth"
 | 
					 | 
				
			||||||
	"github.com/docker/libtrust"
 | 
						"github.com/docker/libtrust"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/docker/docker-registry/auth"
 | 
				
			||||||
 | 
						"github.com/docker/docker-registry/common"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func makeRootKeys(numKeys int) ([]libtrust.PrivateKey, error) {
 | 
					func makeRootKeys(numKeys int) ([]libtrust.PrivateKey, error) {
 | 
				
			||||||
| 
						 | 
					@ -194,8 +196,8 @@ func TestTokenVerify(t *testing.T) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	verifyOps := VerifyOptions{
 | 
						verifyOps := VerifyOptions{
 | 
				
			||||||
		TrustedIssuers:    newStringSet(issuer),
 | 
							TrustedIssuers:    common.NewStringSet(issuer),
 | 
				
			||||||
		AccpetedAudiences: newStringSet(audience),
 | 
							AccpetedAudiences: common.NewStringSet(audience),
 | 
				
			||||||
		Roots:             rootPool,
 | 
							Roots:             rootPool,
 | 
				
			||||||
		TrustedKeys:       trustedKeys,
 | 
							TrustedKeys:       trustedKeys,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,8 @@ import (
 | 
				
			||||||
	"encoding/base64"
 | 
						"encoding/base64"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/docker/docker-registry/common"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// joseBase64UrlEncode encodes the given data using the standard base64 url
 | 
					// joseBase64UrlEncode encodes the given data using the standard base64 url
 | 
				
			||||||
| 
						 | 
					@ -31,47 +33,17 @@ func joseBase64UrlDecode(s string) ([]byte, error) {
 | 
				
			||||||
	return base64.URLEncoding.DecodeString(s)
 | 
						return base64.URLEncoding.DecodeString(s)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// stringSet is a useful type for looking up strings.
 | 
					 | 
				
			||||||
type stringSet map[string]struct{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newStringSet(strs ...string) stringSet {
 | 
					 | 
				
			||||||
	set := make(stringSet, len(strs))
 | 
					 | 
				
			||||||
	for _, str := range strs {
 | 
					 | 
				
			||||||
		set[str] = struct{}{}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return set
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// contains returns whether the given key is in this StringSet.
 | 
					 | 
				
			||||||
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 {
 | 
					 | 
				
			||||||
	keys := make([]string, 0, len(ss))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for key := range ss {
 | 
					 | 
				
			||||||
		keys = append(keys, key)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return keys
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// actionSet is a special type of stringSet.
 | 
					// actionSet is a special type of stringSet.
 | 
				
			||||||
type actionSet stringSet
 | 
					type actionSet struct {
 | 
				
			||||||
 | 
						common.StringSet
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// contains calls stringSet.contains() for
 | 
					func newActionSet(actions ...string) actionSet {
 | 
				
			||||||
 | 
						return actionSet{common.NewStringSet(actions...)}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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 {
 | 
				
			||||||
	ss := stringSet(s)
 | 
						return s.StringSet.Contains("*") || s.StringSet.Contains(action)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ss.contains("*") || ss.contains(action)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// keys wraps stringSet.keys()
 | 
					 | 
				
			||||||
func (s actionSet) keys() []string {
 | 
					 | 
				
			||||||
	return stringSet(s).keys()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					package common
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// StringSet is a useful type for looking up strings.
 | 
				
			||||||
 | 
					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...)
 | 
				
			||||||
 | 
						return ss
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Add inserts the given keys into this StringSet.
 | 
				
			||||||
 | 
					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 {
 | 
				
			||||||
 | 
						_, ok := ss[key]
 | 
				
			||||||
 | 
						return ok
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Keys returns a slice of all keys in this StringSet.
 | 
				
			||||||
 | 
					func (ss StringSet) Keys() []string {
 | 
				
			||||||
 | 
						keys := make([]string, 0, len(ss))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for key := range ss {
 | 
				
			||||||
 | 
							keys = append(keys, key)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return keys
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue