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 <stephen.day@docker.com>
This commit is contained in:
parent
adaa2246e7
commit
aea52c7fb5
@ -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/collections"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 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: collections.NewStringSet(ac.issuer),
|
TrustedIssuers: []string{ac.issuer},
|
||||||
AcceptedAudiences: collections.NewStringSet(ac.service),
|
AcceptedAudiences: []string{ac.service},
|
||||||
Roots: ac.rootCerts,
|
Roots: ac.rootCerts,
|
||||||
TrustedKeys: ac.trustedKeys,
|
TrustedKeys: ac.trustedKeys,
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
package collections
|
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/collections"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
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 collections.StringSet
|
TrustedIssuers []string
|
||||||
AcceptedAudiences collections.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/collections"
|
"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: collections.NewStringSet(issuer),
|
TrustedIssuers: []string{issuer},
|
||||||
AcceptedAudiences: collections.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/collections"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 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 {
|
||||||
collections.StringSet
|
stringSet
|
||||||
}
|
}
|
||||||
|
|
||||||
func newActionSet(actions ...string) actionSet {
|
func newActionSet(actions ...string) actionSet {
|
||||||
return actionSet{collections.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
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user