@@ -13,6 +13,7 @@ import (
1313 "github.com/influxdata/influxdb/v2/kit/platform/errors"
1414 "github.com/influxdata/influxdb/v2/kv"
1515 jsonp "github.com/influxdata/influxdb/v2/pkg/jsonparser"
16+ "go.uber.org/zap"
1617)
1718
1819var (
@@ -80,38 +81,42 @@ func decodeAuthorization(b []byte, a *influxdb.Authorization) error {
8081 return nil
8182}
8283
83- // verifyTokensMatch returns an error if a.Token and a.HashedToken are set
84- // but do not match.
85- func (s * Store ) verifyTokensMatch (a * influxdb.Authorization ) error {
86- if a .Token == "" || a .HashedToken == "" {
87- return nil
88- }
89-
90- // If both Token and HashedToken are set, make sure they are equivalent before continuing.
91- match , err := s .hasher .Match (a .HashedToken , a .Token )
92- if err != nil {
93- return fmt .Errorf ("error matching tokens: %w" , err )
94- }
95- if ! match {
96- return ErrHashedTokenMismatch
97- }
98- return nil
99- }
100-
101- // hashToken hashes a.Token to a.HashedToken, if needed.
102- func (s * Store ) hashToken (a * influxdb.Authorization ) error {
103- if ! s .useHashedTokens || a .HashedToken != "" || a .Token == "" {
104- // Either we're not using token hashing, the token has already been hashed,
105- // or there's no token to be hashed.
106- return nil
84+ // transformToken updates a.Token and a.HashedToken to match configuration state,
85+ // if needed. If needed, transformToken generates the a.HashedToken from a.Token when
86+ // token hashing is enabled. transformToken will also clear a.HashedToken if token
87+ // hashing is turned off and a.Token is set to the matching token. If a.HashedToken and
88+ // a.Token are both set but do not match (a.HashedToken is a hash of a.Token), then an
89+ // error is returned.
90+ func (s * Store ) transformToken (a * influxdb.Authorization ) error {
91+ // Verify Token and HashedToken match if both are set.
92+ if a .Token != "" && a .HashedToken != "" {
93+ match , err := s .hasher .Match (a .HashedToken , a .Token )
94+ if err != nil {
95+ return fmt .Errorf ("error matching tokens: %w" , err )
96+ }
97+ if ! match {
98+ return ErrHashedTokenMismatch
99+ }
107100 }
108101
109- // Hash the token. Redaction of the hashed token takes place when the record is written.
110- hashedToken , err := s .hasher .Hash (a .Token )
111- if err != nil {
112- return fmt .Errorf ("error hashing token: %w" , err )
102+ if a .Token != "" {
103+ if s .useHashedTokens {
104+ // Need to generate HashedToken from Token. Redaction of the hashed token takes
105+ // place when the record is written to the KV store. In some cases the client
106+ // code that triggered commit needs access to the raw Token, such as when a
107+ // token is initially created so it can be shown to the user.
108+ // Note that even if a.HashedToken is set, we will regenerate it here. This ensures
109+ // that a.HashedToken will be stored using the currently configured hashing algoirithm.
110+ if hashedToken , err := s .hasher .Hash (a .Token ); err != nil {
111+ return fmt .Errorf ("error hashing token: %w" , err )
112+ } else {
113+ a .HashedToken = hashedToken
114+ }
115+ } else {
116+ // Token hashing disabled, a.Token is available, clear a.HashedToken if set.
117+ a .HashedToken = ""
118+ }
113119 }
114- a .HashedToken = hashedToken
115120
116121 return nil
117122}
@@ -177,7 +182,7 @@ func (s *Store) GetAuthorizationByID(ctx context.Context, tx kv.Tx, id platform.
177182 return a , nil
178183}
179184
180- // validateToken checks if token matches tht token stored in auth. If auth.Token is set, that is
185+ // validateToken checks if token matches that token stored in auth. If auth.Token is set, that is
181186// compared first. Otherwise, auth.HashedToken is used to verify token. If neither field in auth is set, then
182187// the comparison fails.
183188func (s * Store ) validateToken (auth * influxdb.Authorization , token string ) (bool , error ) {
@@ -349,11 +354,7 @@ func (s *Store) forEachAuthorization(ctx context.Context, tx kv.Tx, pred kv.Curs
349354// and makes sure indices point to it. It does not delete any indices. The updated authorization is
350355// returned on success.
351356func (s * Store ) commitAuthorization (ctx context.Context , tx kv.Tx , a * influxdb.Authorization ) error {
352- if err := s .verifyTokensMatch (a ); err != nil {
353- return errors .ErrInternalServiceError (err , errors .WithErrorCode (errors .EInvalid ))
354- }
355-
356- if err := s .hashToken (a ); err != nil {
357+ if err := s .transformToken (a ); err != nil {
357358 return errors .ErrInternalServiceError (err , errors .WithErrorCode (errors .EInternal ))
358359 }
359360
@@ -602,7 +603,12 @@ func (s *Store) authorizationsPredicateFn(f influxdb.AuthorizationFilter) kv.Cur
602603
603604 if f .Token != nil {
604605 token := * f .Token
605- allHashes , _ := s .hasher .AllHashes (token ) // on error, allHashes is empty and we'll ignore hashedToken
606+ allHashes , err := s .hasher .AllHashes (token )
607+ if err != nil {
608+ s .log .Error ("error generating hashes in authorizationsPredicateFn" , zap .Error (err ))
609+ // On error, continue onward. allHashes is empty and we'll effectively ignore hashedToken,
610+ // but we'll still look at the unhashed Token if it is available.
611+ }
606612 return func (_ , value []byte ) bool {
607613 // it is assumed that token never has escaped string data
608614 if got , _ , _ , err := jsonparser .Get (value , "token" ); err == nil {
@@ -652,8 +658,13 @@ func (s *Store) filterAuthorizationsFn(filter influxdb.AuthorizationFilter) func
652658
653659 if filter .Token != nil {
654660 token := * filter .Token
655- // if AllHashes returns an error, allHashes will be empty and we will ignore a.HashedToken.
656- allHashes , _ := s .hasher .AllHashes (token )
661+ allHashes , err := s .hasher .AllHashes (token )
662+ if err != nil {
663+ s .log .Error ("error generating hashes in filterPredicateFn" , zap .Error (err ))
664+ // On error, continue onward. allHashes is empty and we'll effectively ignore hashedToken,
665+ // but we'll still look at the unhashed Token if it is available.
666+ }
667+
657668 return func (a * influxdb.Authorization ) bool {
658669 if a .Token == token {
659670 return true
0 commit comments