Skip to content

Commit 5279970

Browse files
committed
fix: prevent duplicate tokens from being created
Create duplicate tokens from being created. This is a bug introduced earlier in this PR. Also improve tests so they detect the bug and use testify throughout.
1 parent 9a87ce1 commit 5279970

File tree

2 files changed

+113
-78
lines changed

2 files changed

+113
-78
lines changed

authorization/storage_authorization.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ func (s *Store) CreateAuthorization(ctx context.Context, tx kv.Tx, a *influxdb.A
135135
a.ID = id
136136
}
137137

138+
// Token must be unique to create authorization.
139+
if err := s.uniqueAuthToken(ctx, tx, a); err != nil {
140+
return err
141+
}
142+
138143
return s.commitAuthorization(ctx, tx, a)
139144
}
140145

authorization/storage_authorization_test.go

Lines changed: 108 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package authorization_test
33
import (
44
"context"
55
"fmt"
6-
"reflect"
76
"testing"
87

98
"github.com/influxdata/influxdb/v2"
@@ -17,7 +16,30 @@ import (
1716
)
1817

1918
func TestAuth(t *testing.T) {
20-
setup := func(t *testing.T, store *authorization.Store, tx kv.Tx) {
19+
checkIndexCounts := func(t *testing.T, tx kv.Tx, expAuthIndexCount, expHashedAuthIndexCount int) {
20+
t.Helper()
21+
22+
const (
23+
authIndexName = "authorizationindexv1"
24+
hashedAuthIndexName = "authorizationhashedindexv1"
25+
)
26+
27+
indexCount := make(map[string]int)
28+
for _, indexName := range []string{authIndexName, hashedAuthIndexName} {
29+
index, err := tx.Bucket([]byte(indexName))
30+
require.NoError(t, err)
31+
cur, err := index.Cursor()
32+
require.NoError(t, err)
33+
for k, _ := cur.First(); k != nil; k, _ = cur.Next() {
34+
indexCount[indexName]++
35+
}
36+
}
37+
38+
require.Equal(t, expAuthIndexCount, indexCount[authIndexName])
39+
require.Equal(t, expHashedAuthIndexCount, indexCount[hashedAuthIndexName])
40+
}
41+
42+
setup := func(t *testing.T, useHashedTokens bool, store *authorization.Store, hasher *authorization.AuthorizationHasher, tx kv.Tx) {
2143
for i := 1; i <= 10; i++ {
2244
err := store.CreateAuthorization(context.Background(), tx, &influxdb.Authorization{
2345
ID: platform.ID(i),
@@ -26,31 +48,57 @@ func TestAuth(t *testing.T) {
2648
UserID: platform.ID(i),
2749
Status: influxdb.Active,
2850
})
51+
require.NoError(t, err)
52+
}
2953

30-
if err != nil {
31-
t.Fatal(err)
54+
// Perform sanity checks on Token vs HashedToken and indices.
55+
for i := 1; i <= 10; i++ {
56+
expToken := fmt.Sprintf("randomtoken%d", i)
57+
a, err := store.GetAuthorizationByToken(context.Background(), tx, expToken)
58+
require.NoError(t, err)
59+
if useHashedTokens {
60+
require.Empty(t, a.Token)
61+
hashedToken, err := hasher.Hash(expToken)
62+
require.NoError(t, err)
63+
require.Equal(t, hashedToken, a.HashedToken)
64+
} else {
65+
require.Equal(t, expToken, a.Token)
66+
require.Empty(t, a.HashedToken)
3267
}
3368
}
69+
70+
var expAuthIndexCount, expHashedAuthIndexCount int
71+
if useHashedTokens {
72+
expHashedAuthIndexCount = 10
73+
} else {
74+
expAuthIndexCount = 10
75+
}
76+
checkIndexCounts(t, tx, expAuthIndexCount, expHashedAuthIndexCount)
3477
}
3578

3679
tt := []struct {
3780
name string
38-
setup func(*testing.T, *authorization.Store, kv.Tx)
81+
setup func(*testing.T, bool, *authorization.Store, *authorization.AuthorizationHasher, kv.Tx)
3982
update func(*testing.T, *authorization.Store, kv.Tx)
4083
results func(*testing.T, bool, *authorization.Store, *authorization.AuthorizationHasher, kv.Tx)
4184
}{
4285
{
43-
name: "create",
86+
name: "create duplicate token",
4487
setup: setup,
88+
update: func(t *testing.T, store *authorization.Store, tx kv.Tx) {
89+
// should not be able to create two authorizations with identical tokens
90+
err := store.CreateAuthorization(context.Background(), tx, &influxdb.Authorization{
91+
ID: platform.ID(1),
92+
Token: fmt.Sprintf("randomtoken%d", 1),
93+
OrgID: platform.ID(1),
94+
UserID: platform.ID(1),
95+
})
96+
require.ErrorIs(t, err, influxdb.ErrUnableToCreateToken)
97+
},
4598
results: func(t *testing.T, useHashedTokens bool, store *authorization.Store, hasher *authorization.AuthorizationHasher, tx kv.Tx) {
4699
auths, err := store.ListAuthorizations(context.Background(), tx, influxdb.AuthorizationFilter{})
47-
if err != nil {
48-
t.Fatal(err)
49-
}
50-
51-
if len(auths) != 10 {
52-
t.Fatalf("expected 10 authorizations, got: %d", len(auths))
53-
}
100+
require.NoError(t, err)
101+
require.Len(t, auths, 10)
54102

55103
expected := []*influxdb.Authorization{}
56104
for i := 1; i <= 10; i++ {
@@ -69,20 +117,15 @@ func TestAuth(t *testing.T) {
69117
}
70118
expected = append(expected, a)
71119
}
72-
if !reflect.DeepEqual(auths, expected) {
73-
t.Fatalf("expected identical authorizations: \n%+v\n%+v", auths, expected)
74-
}
120+
require.Equal(t, auths, expected)
75121

76-
// should not be able to create two authorizations with identical tokens
77-
err = store.CreateAuthorization(context.Background(), tx, &influxdb.Authorization{
78-
ID: platform.ID(1),
79-
Token: fmt.Sprintf("randomtoken%d", 1),
80-
OrgID: platform.ID(1),
81-
UserID: platform.ID(1),
82-
})
83-
if err == nil {
84-
t.Fatalf("expected to be unable to create authorizations with identical tokens")
122+
var expAuthIndexCount, expHashedAuthIndexCount int
123+
if useHashedTokens {
124+
expHashedAuthIndexCount = 10
125+
} else {
126+
expAuthIndexCount = 10
85127
}
128+
checkIndexCounts(t, tx, expAuthIndexCount, expHashedAuthIndexCount)
86129
},
87130
},
88131
{
@@ -105,24 +148,21 @@ func TestAuth(t *testing.T) {
105148
}
106149

107150
authByID, err := store.GetAuthorizationByID(context.Background(), tx, platform.ID(i))
108-
if err != nil {
109-
t.Fatalf("Unexpectedly could not acquire Authorization by ID [Error]: %v", err)
110-
}
111-
112-
if !reflect.DeepEqual(authByID, expectedAuth) {
113-
t.Fatalf("ID TEST: expected identical authorizations:\n[Expected]: %+#v\n[Got]: %+#v", expectedAuth, authByID)
114-
}
151+
require.NoError(t, err)
152+
require.Equal(t, expectedAuth, authByID)
115153

116154
authByToken, err := store.GetAuthorizationByToken(context.Background(), tx, fmt.Sprintf("randomtoken%d", i))
117-
if err != nil {
118-
t.Fatalf("cannot get authorization by Token [Error]: %v", err)
119-
}
120-
121-
if !reflect.DeepEqual(authByToken, expectedAuth) {
122-
t.Fatalf("TOKEN TEST: expected identical authorizations:\n[Expected]: %+#v\n[Got]: %+#v", expectedAuth, authByToken)
123-
}
155+
require.NoError(t, err)
156+
require.Equal(t, expectedAuth, authByToken)
124157
}
125158

159+
var expAuthIndexCount, expHashedAuthIndexCount int
160+
if useHashedTokens {
161+
expHashedAuthIndexCount = 10
162+
} else {
163+
expAuthIndexCount = 10
164+
}
165+
checkIndexCounts(t, tx, expAuthIndexCount, expHashedAuthIndexCount)
126166
},
127167
},
128168
{
@@ -131,25 +171,22 @@ func TestAuth(t *testing.T) {
131171
update: func(t *testing.T, store *authorization.Store, tx kv.Tx) {
132172
for i := 1; i <= 10; i++ {
133173
auth, err := store.GetAuthorizationByID(context.Background(), tx, platform.ID(i))
134-
if err != nil {
135-
t.Fatalf("Could not get authorization [Error]: %v", err)
136-
}
174+
require.NoError(t, err)
137175

138176
auth.Status = influxdb.Inactive
177+
copyAuth := *auth
139178

140-
_, err = store.UpdateAuthorization(context.Background(), tx, platform.ID(i), auth)
141-
if err != nil {
142-
t.Fatalf("Could not get updated authorization [Error]: %v", err)
143-
}
179+
updatedAuth, err := store.UpdateAuthorization(context.Background(), tx, platform.ID(i), auth)
180+
require.NoError(t, err)
181+
require.Equal(t, auth, updatedAuth) /* should be the same pointer */
182+
require.Equal(t, copyAuth, *auth) /* should be the same contents */
144183
}
145184
},
146185
results: func(t *testing.T, useHashedTokens bool, store *authorization.Store, hasher *authorization.AuthorizationHasher, tx kv.Tx) {
147186

148187
for i := 1; i <= 10; i++ {
149188
auth, err := store.GetAuthorizationByID(context.Background(), tx, platform.ID(i))
150-
if err != nil {
151-
t.Fatalf("Could not get authorization [Error]: %v", err)
152-
}
189+
require.NoError(t, err)
153190

154191
expectedAuth := &influxdb.Authorization{
155192
ID: platform.ID(i),
@@ -165,10 +202,15 @@ func TestAuth(t *testing.T) {
165202
expectedAuth.Token = ""
166203
}
167204

168-
if !reflect.DeepEqual(auth, expectedAuth) {
169-
t.Fatalf("expected identical authorizations:\n[Expected] %+#v\n[Got] %+#v", expectedAuth, auth)
170-
}
205+
require.Equal(t, expectedAuth, auth)
171206
}
207+
var expAuthIndexCount, expHashedAuthIndexCount int
208+
if useHashedTokens {
209+
expHashedAuthIndexCount = 10
210+
} else {
211+
expAuthIndexCount = 10
212+
}
213+
checkIndexCounts(t, tx, expAuthIndexCount, expHashedAuthIndexCount)
172214
},
173215
},
174216
{
@@ -177,18 +219,16 @@ func TestAuth(t *testing.T) {
177219
update: func(t *testing.T, store *authorization.Store, tx kv.Tx) {
178220
for i := 1; i <= 10; i++ {
179221
err := store.DeleteAuthorization(context.Background(), tx, platform.ID(i))
180-
if err != nil {
181-
t.Fatalf("Could not delete authorization [Error]: %v", err)
182-
}
222+
require.NoError(t, err)
183223
}
184224
},
185225
results: func(t *testing.T, useHashedTokens bool, store *authorization.Store, hasher *authorization.AuthorizationHasher, tx kv.Tx) {
186226
for i := 1; i <= 10; i++ {
187-
_, err := store.GetAuthorizationByID(context.Background(), tx, platform.ID(i))
188-
if err == nil {
189-
t.Fatal("Authorization was not deleted correctly")
190-
}
227+
a, err := store.GetAuthorizationByID(context.Background(), tx, platform.ID(i))
228+
require.ErrorIs(t, err, authorization.ErrAuthNotFound)
229+
require.Nil(t, a)
191230
}
231+
checkIndexCounts(t, tx, 0, 0)
192232
},
193233
},
194234
}
@@ -198,28 +238,24 @@ func TestAuth(t *testing.T) {
198238

199239
t.Run(testScenario.name, func(t *testing.T) {
200240
store := inmem.NewKVStore()
201-
if err := all.Up(context.Background(), zaptest.NewLogger(t), store); err != nil {
202-
t.Fatal(err)
203-
}
241+
err := all.Up(context.Background(), zaptest.NewLogger(t), store)
242+
require.NoError(t, err)
204243

205244
hasher, err := authorization.NewAuthorizationHasher()
206245
require.NoError(t, err)
246+
require.NotNil(t, hasher)
207247

208248
ts, err := authorization.NewStore(context.Background(), store, useHashedTokens, authorization.WithAuthorizationHasher(hasher))
209-
if err != nil {
210-
t.Fatal(err)
211-
}
249+
require.NoError(t, err)
250+
require.NotNil(t, ts)
212251

213252
// setup
214253
if testScenario.setup != nil {
215254
err := ts.Update(context.Background(), func(tx kv.Tx) error {
216-
testScenario.setup(t, ts, tx)
255+
testScenario.setup(t, useHashedTokens, ts, hasher, tx)
217256
return nil
218257
})
219-
220-
if err != nil {
221-
t.Fatal(err)
222-
}
258+
require.NoError(t, err)
223259
}
224260

225261
// update
@@ -228,10 +264,7 @@ func TestAuth(t *testing.T) {
228264
testScenario.update(t, ts, tx)
229265
return nil
230266
})
231-
232-
if err != nil {
233-
t.Fatal(err)
234-
}
267+
require.NoError(t, err)
235268
}
236269

237270
// results
@@ -240,10 +273,7 @@ func TestAuth(t *testing.T) {
240273
testScenario.results(t, useHashedTokens, ts, hasher, tx)
241274
return nil
242275
})
243-
244-
if err != nil {
245-
t.Fatal(err)
246-
}
276+
require.NoError(t, err)
247277
}
248278
})
249279
}

0 commit comments

Comments
 (0)