Skip to content

Commit 1baa54e

Browse files
committed
chore: abstract checking if tokens are clear or set for readability
Also add some clarifying comments.
1 parent cb60ffd commit 1baa54e

File tree

5 files changed

+84
-22
lines changed

5 files changed

+84
-22
lines changed

auth.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,60 @@ type AuthorizationUpdate struct {
3636
Description *string `json:"description,omitempty"`
3737
}
3838

39+
const (
40+
// authTokenClearValue is used to indicate Token or HashedToken are cleared (not set).
41+
authTokenClearValue = ""
42+
)
43+
44+
// IsAuthTokenSet returns true if token is considered set. Applies
45+
// to be both unhashed tokens (Authorization.Token) and
46+
// hashed tokens (Authorization.HashedToken).
47+
func IsAuthTokenSet(token string) bool {
48+
return token != authTokenClearValue
49+
}
50+
51+
// IsTokenSet returns true if Token is set.
52+
func (a *Authorization) IsTokenSet() bool {
53+
return IsAuthTokenSet(a.Token)
54+
}
55+
56+
// IsTokenClear returns true if Token is unset.
57+
func (a *Authorization) IsTokenClear() bool {
58+
return !a.IsTokenSet()
59+
}
60+
61+
// ClearToken clears Token.
62+
func (a *Authorization) ClearToken() {
63+
a.Token = authTokenClearValue
64+
}
65+
66+
// IsHashedTokenSet returns true if HashedToken is set.
67+
func (a *Authorization) IsHashedTokenSet() bool {
68+
return IsAuthTokenSet(a.HashedToken)
69+
}
70+
71+
// IsHashedTokenClear returns true if Token is unset.
72+
func (a *Authorization) IsHashedTokenClear() bool {
73+
return !a.IsHashedTokenSet()
74+
}
75+
76+
// ClearToken clears HashedToken.
77+
func (a *Authorization) ClearHashedToken() {
78+
a.HashedToken = authTokenClearValue
79+
}
80+
81+
// NoTokensSet returns true if neither Token nor HashedToken is set.
82+
func (a *Authorization) NoTokensSet() bool {
83+
return a.IsTokenClear() && a.IsHashedTokenClear()
84+
}
85+
86+
// BothTokensSet returns true if both Token and Hashed token is set.
87+
func (a *Authorization) BothTokensSet() bool {
88+
return a.IsTokenSet() && a.IsHashedTokenSet()
89+
}
90+
3991
// Valid ensures that the authorization is valid.
92+
// Valid does not check if tokens are set properly.
4093
func (a *Authorization) Valid() error {
4194
for _, p := range a.Permissions {
4295
if p.Resource.OrgID != nil && *p.Resource.OrgID != a.OrgID {

authorization/service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func (s *Service) CreateAuthorization(ctx context.Context, a *influxdb.Authoriza
5353
return ErrTokenAlreadyExistsError
5454
}
5555

56-
if a.Token == "" && a.HashedToken == "" {
56+
if a.NoTokensSet() {
5757
token, err := s.tokenGenerator.Token()
5858
if err != nil {
5959
return &errors.Error{

authorization/storage.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ func (s *Store) findHashVariants(ctx context.Context) ([]influxdb2_algo.Variant,
252252

253253
foundVariants := make(map[influxdb2_algo.Variant]struct{})
254254
for _, a := range auths {
255-
if a.HashedToken != "" {
255+
if a.IsHashedTokenSet() {
256256
digest, err := tempDecoder.Decode(a.HashedToken)
257257
if err == nil {
258258
if influxdbDigest, ok := digest.(*influxdb2_algo.Digest); ok {
@@ -301,8 +301,8 @@ func (s *Store) hashedTokenMigration(ctx context.Context) error {
301301
var authsNeedingUpdate []*influxdb.Authorization
302302
err := s.View(ctx, func(tx kv.Tx) error {
303303
s.forEachAuthorization(ctx, tx, nil, func(a *influxdb.Authorization) bool {
304-
if a.HashedToken == "" {
305-
if a.Token != "" {
304+
if a.IsHashedTokenClear() {
305+
if a.IsTokenSet() {
306306
authsNeedingUpdate = append(authsNeedingUpdate, a)
307307
} else {
308308
s.log.Warn("found authorization without any token set during hashed token migration", zap.Uint64("ID", uint64(a.ID)), zap.String("description", a.Description))

authorization/storage_authorization.go

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func (s *Store) encodeAuthorization(a *influxdb.Authorization) ([]byte, error) {
7373
// user-facing output. The empty string signals that the plaintext token is not available and that
7474
// the hashed token should be used instead.
7575
redactedAuth := *a
76-
redactedAuth.Token = ""
76+
redactedAuth.ClearToken()
7777
a = &redactedAuth
7878
}
7979
if d, err := json.Marshal(a); err == nil {
@@ -105,7 +105,7 @@ func decodeAuthorization(b []byte, a *influxdb.Authorization) error {
105105
// error is returned.
106106
func (s *Store) transformToken(a *influxdb.Authorization) error {
107107
// Verify Token and HashedToken match if both are set.
108-
if a.Token != "" && a.HashedToken != "" {
108+
if a.BothTokensSet() {
109109
match, err := s.hasher.Match(a.HashedToken, a.Token)
110110
if err != nil {
111111
return fmt.Errorf("transformToken: error matching tokens: %w", err)
@@ -115,7 +115,7 @@ func (s *Store) transformToken(a *influxdb.Authorization) error {
115115
}
116116
}
117117

118-
if a.Token != "" {
118+
if a.IsTokenSet() {
119119
if s.useHashedTokens {
120120
// Need to generate HashedToken from Token. Redaction of the hashed token takes
121121
// place when the record is written to the KV store. In some cases the client
@@ -130,7 +130,7 @@ func (s *Store) transformToken(a *influxdb.Authorization) error {
130130
}
131131
} else {
132132
// Token hashing disabled, a.Token is available, clear a.HashedToken if set.
133-
a.HashedToken = ""
133+
a.ClearHashedToken()
134134
}
135135
}
136136

@@ -208,11 +208,11 @@ func (s *Store) GetAuthorizationByID(ctx context.Context, tx kv.Tx, id platform.
208208
// compared first. Otherwise, auth.HashedToken is used to verify token. If neither field in auth is set, then
209209
// the comparison fails.
210210
func (s *Store) validateToken(auth *influxdb.Authorization, token string) (bool, error) {
211-
if auth.Token != "" {
211+
if auth.IsTokenSet() {
212212
return subtle.ConstantTimeCompare([]byte(auth.Token), []byte(token)) == 1, nil
213213
}
214214

215-
if auth.HashedToken != "" {
215+
if auth.IsHashedTokenSet() {
216216
match, err := s.hasher.Match(auth.HashedToken, token)
217217
if err != nil {
218218
return false, fmt.Errorf("error matching hashed token %d (%s) for validation: %w", auth.ID, auth.Description, err)
@@ -380,6 +380,11 @@ func (s *Store) commitAuthorization(ctx context.Context, tx kv.Tx, a *influxdb.A
380380
return errors.ErrInternalServiceError(err, errors.WithErrorCode(errors.EInternal))
381381
}
382382

383+
// Sanity check that a is actually set. Shouldn't be possible during normal operation.
384+
if a.NoTokensSet() {
385+
return fmt.Errorf("commitAuthorization: %w", ErrNoTokenAvailable)
386+
}
387+
383388
v, err := s.encodeAuthorization(a)
384389
if err != nil {
385390
return errors.ErrInternalServiceError(err, errors.WithErrorCode(errors.EInvalid))
@@ -390,7 +395,7 @@ func (s *Store) commitAuthorization(ctx context.Context, tx kv.Tx, a *influxdb.A
390395
return errors.ErrInternalServiceError(err, errors.WithErrorCode(errors.ENotFound))
391396
}
392397

393-
if !s.useHashedTokens && a.Token != "" {
398+
if !s.useHashedTokens && a.IsTokenSet() {
394399
idx, err := authIndexBucket(tx)
395400
if err != nil {
396401
return errors.ErrInternalServiceError(err, errors.WithErrorCode(errors.EInternal))
@@ -401,7 +406,11 @@ func (s *Store) commitAuthorization(ctx context.Context, tx kv.Tx, a *influxdb.A
401406
}
402407
}
403408

404-
if a.HashedToken != "" {
409+
// If we have a hashed token, we need to add it to the index even if hashed tokens are not
410+
// available. This is because if hashed tokens are enabled and then disabled, we will
411+
// only have hashed tokens available for some authorization records. They would be unusable
412+
// if we did not maintain their hashed indices.
413+
if a.IsHashedTokenSet() {
405414
idx, err := hashedAuthIndexBucket(tx)
406415
// Don't ignore a missing index here, we want an error.
407416
if err != nil {
@@ -438,13 +447,13 @@ func (s *Store) deleteIndices(ctx context.Context, tx kv.Tx, token, hashedToken
438447
return err
439448
}
440449

441-
if token != "" {
450+
if influxdb.IsAuthTokenSet(token) {
442451
if err := authIdx.Delete([]byte(token)); err != nil {
443452
return fmt.Errorf("deleteIndices: error deleting from authIndex: %w", err)
444453
}
445454
}
446455

447-
if hashedToken != "" {
456+
if influxdb.IsAuthTokenSet(hashedToken) {
448457
if err := hashedAuthIdx.Delete([]byte(hashedToken)); err != nil {
449458
return fmt.Errorf("deleteIndices: error deleting from hashedAuthIndex: %w", err)
450459
}
@@ -472,12 +481,12 @@ func (s *Store) UpdateAuthorization(ctx context.Context, tx kv.Tx, id platform.I
472481

473482
// Delete dangling indices from old raw tokens or hashed tokens.
474483
var removedToken string
475-
if initialToken != "" && (a.Token != initialToken || s.useHashedTokens) {
484+
if influxdb.IsAuthTokenSet(initialToken) && (a.Token != initialToken || s.useHashedTokens) {
476485
removedToken = initialToken
477486
}
478487

479488
var removedHashedToken string
480-
if initialHashedToken != "" && a.HashedToken != initialHashedToken {
489+
if influxdb.IsAuthTokenSet(initialHashedToken) && a.HashedToken != initialHashedToken {
481490
removedHashedToken = initialHashedToken
482491
}
483492

@@ -535,7 +544,7 @@ func (s *Store) uniqueAuthTokenByIndex(ctx context.Context, tx kv.Tx, index, key
535544

536545
func (s *Store) uniqueAuthToken(ctx context.Context, tx kv.Tx, a *influxdb.Authorization) error {
537546
// Check if the raw token is unique.
538-
if a.Token != "" {
547+
if a.IsTokenSet() {
539548
if err := s.uniqueAuthTokenByIndex(ctx, tx, authIndexName, authIndexKey(a.Token)); err != nil {
540549
return err
541550
}
@@ -544,10 +553,10 @@ func (s *Store) uniqueAuthToken(ctx context.Context, tx kv.Tx, a *influxdb.Autho
544553
// If Token is available, check for the uniqueness of the hashed version of Token using all
545554
// potential hashing schemes. If HashedToken was directly given, we must also check for it.
546555
allHashedTokens := make([]string, 0, s.hasher.AllHashesCount()+1)
547-
if a.HashedToken != "" {
556+
if a.IsHashedTokenSet() {
548557
allHashedTokens = append(allHashedTokens, a.HashedToken)
549558
}
550-
if a.Token != "" {
559+
if a.IsTokenSet() {
551560
allRawHashes, err := s.hasher.AllHashes(a.Token)
552561
if err != nil {
553562
return err

authorization/storage_authorization_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ func TestAuth(t *testing.T) {
117117
hashedToken, err := hasher.Hash(a.Token)
118118
require.NoError(t, err)
119119
a.HashedToken = hashedToken
120-
a.Token = ""
120+
a.ClearToken()
121121
}
122122
expected = append(expected, a)
123123
}
@@ -148,7 +148,7 @@ func TestAuth(t *testing.T) {
148148
hashedToken, err := hasher.Hash(expectedAuth.Token)
149149
require.NoError(t, err)
150150
expectedAuth.HashedToken = hashedToken
151-
expectedAuth.Token = ""
151+
expectedAuth.ClearToken()
152152
}
153153

154154
authByID, err := store.GetAuthorizationByID(context.Background(), tx, platform.ID(i))
@@ -203,7 +203,7 @@ func TestAuth(t *testing.T) {
203203
hashedToken, err := hasher.Hash(expectedAuth.Token)
204204
require.NoError(t, err)
205205
expectedAuth.HashedToken = hashedToken
206-
expectedAuth.Token = ""
206+
expectedAuth.ClearToken()
207207
}
208208

209209
require.Equal(t, expectedAuth, auth)

0 commit comments

Comments
 (0)