1package token
2
3import (
4	"sync"
5)
6
7// Store is used to hold the special ACL tokens used by Consul agents. It is
8// designed to update the tokens on the fly, so the token store itself should be
9// plumbed around and used to get tokens at runtime, don't save the resulting
10// tokens.
11type Store struct {
12	// l synchronizes access to the token store.
13	l sync.RWMutex
14
15	// userToken is passed along for requests when the user didn't supply a
16	// token, and may be left blank to use the anonymous token. This will
17	// also be used for agent operations if the agent token isn't set.
18	userToken string
19
20	// agentToken is used for internal agent operations like self-registering
21	// with the catalog and anti-entropy, but should never be used for
22	// user-initiated operations.
23	agentToken string
24
25	// agentMasterToken is a special token that's only used locally for
26	// access to the /v1/agent utility operations if the servers aren't
27	// available.
28	agentMasterToken string
29
30	// aclReplicationToken is a special token that's used by servers to
31	// replicate ACLs from the ACL datacenter.
32	aclReplicationToken string
33}
34
35// UpdateUserToken replaces the current user token in the store.
36func (t *Store) UpdateUserToken(token string) {
37	t.l.Lock()
38	t.userToken = token
39	t.l.Unlock()
40}
41
42// UpdateAgentToken replaces the current agent token in the store.
43func (t *Store) UpdateAgentToken(token string) {
44	t.l.Lock()
45	t.agentToken = token
46	t.l.Unlock()
47}
48
49// UpdateAgentMasterToken replaces the current agent master token in the store.
50func (t *Store) UpdateAgentMasterToken(token string) {
51	t.l.Lock()
52	t.agentMasterToken = token
53	t.l.Unlock()
54}
55
56// UpdateACLReplicationToken replaces the current ACL replication token in the store.
57func (t *Store) UpdateACLReplicationToken(token string) {
58	t.l.Lock()
59	t.aclReplicationToken = token
60	t.l.Unlock()
61}
62
63// UserToken returns the best token to use for user operations.
64func (t *Store) UserToken() string {
65	t.l.RLock()
66	defer t.l.RUnlock()
67
68	return t.userToken
69}
70
71// AgentToken returns the best token to use for internal agent operations.
72func (t *Store) AgentToken() string {
73	t.l.RLock()
74	defer t.l.RUnlock()
75
76	if t.agentToken != "" {
77		return t.agentToken
78	}
79	return t.userToken
80}
81
82// ACLReplicationToken returns the ACL replication token.
83func (t *Store) ACLReplicationToken() string {
84	t.l.RLock()
85	defer t.l.RUnlock()
86
87	return t.aclReplicationToken
88}
89
90// IsAgentMasterToken checks to see if a given token is the agent master token.
91// This will never match an empty token for safety.
92func (t *Store) IsAgentMasterToken(token string) bool {
93	t.l.RLock()
94	defer t.l.RUnlock()
95
96	return (token != "") && (token == t.agentMasterToken)
97}
98