github.com/bigcommerce/nomad@v0.9.3-bc/nomad/acl.go (about) 1 package nomad 2 3 import ( 4 "time" 5 6 metrics "github.com/armon/go-metrics" 7 lru "github.com/hashicorp/golang-lru" 8 "github.com/hashicorp/nomad/acl" 9 "github.com/hashicorp/nomad/nomad/state" 10 "github.com/hashicorp/nomad/nomad/structs" 11 ) 12 13 // ResolveToken is used to translate an ACL Token Secret ID into 14 // an ACL object, nil if ACLs are disabled, or an error. 15 func (s *Server) ResolveToken(secretID string) (*acl.ACL, error) { 16 // Fast-path if ACLs are disabled 17 if !s.config.ACLEnabled { 18 return nil, nil 19 } 20 defer metrics.MeasureSince([]string{"nomad", "acl", "resolveToken"}, time.Now()) 21 22 // Check if the secret ID is the leader secret ID, in which case treat it as 23 // a management token. 24 if leaderAcl := s.getLeaderAcl(); leaderAcl != "" && secretID == leaderAcl { 25 return acl.ManagementACL, nil 26 } 27 28 // Snapshot the state 29 snap, err := s.fsm.State().Snapshot() 30 if err != nil { 31 return nil, err 32 } 33 34 // Resolve the ACL 35 return resolveTokenFromSnapshotCache(snap, s.aclCache, secretID) 36 } 37 38 // resolveTokenFromSnapshotCache is used to resolve an ACL object from a snapshot of state, 39 // using a cache to avoid parsing and ACL construction when possible. It is split from resolveToken 40 // to simplify testing. 41 func resolveTokenFromSnapshotCache(snap *state.StateSnapshot, cache *lru.TwoQueueCache, secretID string) (*acl.ACL, error) { 42 // Lookup the ACL Token 43 var token *structs.ACLToken 44 var err error 45 46 // Handle anonymous requests 47 if secretID == "" { 48 token = structs.AnonymousACLToken 49 } else { 50 token, err = snap.ACLTokenBySecretID(nil, secretID) 51 if err != nil { 52 return nil, err 53 } 54 if token == nil { 55 return nil, structs.ErrTokenNotFound 56 } 57 } 58 59 // Check if this is a management token 60 if token.Type == structs.ACLManagementToken { 61 return acl.ManagementACL, nil 62 } 63 64 // Get all associated policies 65 policies := make([]*structs.ACLPolicy, 0, len(token.Policies)) 66 for _, policyName := range token.Policies { 67 policy, err := snap.ACLPolicyByName(nil, policyName) 68 if err != nil { 69 return nil, err 70 } 71 if policy == nil { 72 // Ignore policies that don't exist, since they don't grant any more privilege 73 continue 74 } 75 76 // Save the policy and update the cache key 77 policies = append(policies, policy) 78 } 79 80 // Compile and cache the ACL object 81 aclObj, err := structs.CompileACLObject(cache, policies) 82 if err != nil { 83 return nil, err 84 } 85 return aclObj, nil 86 }