auth
auth/token_test.go
Add authd. Start adding our server implementation. Right now, it's very proof-of-concept stage and will almost certainly be entirely rewritten, but it gets a server up and running.
1 package auth
3 import (
4 "testing"
5 "time"
7 "code.secondbit.org/uuid"
8 )
10 var tokenStores = []tokenStore{NewMemstore()}
12 func compareTokens(token1, token2 Token) (success bool, field string, val1, val2 interface{}) {
13 if token1.AccessToken != token2.AccessToken {
14 return false, "access token", token1.AccessToken, token2.AccessToken
15 }
16 if token1.RefreshToken != token2.RefreshToken {
17 return false, "refresh token", token1.RefreshToken, token2.RefreshToken
18 }
19 if !token1.Created.Equal(token2.Created) {
20 return false, "created", token1.Created, token2.Created
21 }
22 if token1.CreatedFrom != token2.CreatedFrom {
23 return false, "created from", token1.CreatedFrom, token2.CreatedFrom
24 }
25 if token1.ExpiresIn != token2.ExpiresIn {
26 return false, "expires in", token1.ExpiresIn, token2.ExpiresIn
27 }
28 if token1.RefreshExpiresIn != token2.RefreshExpiresIn {
29 return false, "refresh expires in", token1.RefreshExpiresIn, token2.RefreshExpiresIn
30 }
31 if token1.TokenType != token2.TokenType {
32 return false, "token type", token1.TokenType, token2.TokenType
33 }
34 if token1.Scope != token2.Scope {
35 return false, "scope", token1.Scope, token2.Scope
36 }
37 if !token1.ProfileID.Equal(token2.ProfileID) {
38 return false, "profile ID", token1.ProfileID, token2.ProfileID
39 }
40 if token1.Revoked != token2.Revoked {
41 return false, "revoked", token1.Revoked, token2.Revoked
42 }
43 return true, "", nil, nil
44 }
46 func TestTokenStoreSuccess(t *testing.T) {
47 t.Parallel()
48 token := Token{
49 AccessToken: "access",
50 RefreshToken: "refresh",
51 Created: time.Now(),
52 ExpiresIn: 3600,
53 TokenType: "bearer",
54 Scope: "scope",
55 ProfileID: uuid.NewID(),
56 }
57 for _, store := range tokenStores {
58 err := store.saveToken(token)
59 if err != nil {
60 t.Errorf("Error saving token to %T: %s", store, err)
61 }
62 err = store.saveToken(token)
63 if err != ErrTokenAlreadyExists {
64 t.Errorf("Expected ErrTokenAlreadyExists from %T, got %s", store, err)
65 }
66 retrievedAccess, err := store.getToken(token.AccessToken, false)
67 if err != nil {
68 t.Errorf("Error retrieving token from %T: %s", store, err)
69 }
70 success, field, expectation, result := compareTokens(token, retrievedAccess)
71 if !success {
72 t.Errorf("Expected field %s to be %v, but got %v from %T", field, expectation, result, store)
73 }
74 retrievedRefresh, err := store.getToken(token.RefreshToken, true)
75 if err != nil {
76 t.Errorf("Error retrieving refresh token from %T: %s", store, err)
77 }
78 success, field, expectation, result = compareTokens(token, retrievedRefresh)
79 if !success {
80 t.Errorf("Expected field %s to be %v, but got %v from %T", field, expectation, result, store)
81 }
82 retrievedProfile, err := store.getTokensByProfileID(token.ProfileID, 25, 0)
83 if err != nil {
84 t.Errorf("Error retrieving token by profile from %T: %s", store, err)
85 }
86 if len(retrievedProfile) != 1 {
87 t.Errorf("Expected 1 token retrieved by profile ID from %T, got %+v", store, retrievedProfile)
88 }
89 success, field, expectation, result = compareTokens(token, retrievedProfile[0])
90 if !success {
91 t.Errorf("Expected field %s to be %v, but got %v from %T", field, expectation, result, store)
92 }
93 err = store.revokeToken(token.AccessToken, false)
94 if err != nil {
95 t.Errorf("Error revoking token in %T: %s", store, err)
96 }
97 retrievedRevoked, err := store.getToken(token.AccessToken, false)
98 if err != nil {
99 t.Errorf("Error retrieving token from %T: %s", store, err)
100 }
101 token.Revoked = true
102 success, field, expectation, result = compareTokens(token, retrievedRevoked)
103 if !success {
104 t.Errorf("Expected field %s to be %v, but got %v from %T", field, expectation, result, store)
105 }
106 // TODO(paddy): test revoking by refresh token.
107 err = store.removeToken(token.AccessToken)
108 if err != nil {
109 t.Errorf("Error removing token from %T: %s", store, err)
110 }
111 _, err = store.getToken(token.AccessToken, false)
112 if err != ErrTokenNotFound {
113 t.Errorf("Expected ErrTokenNotFound from %T, got %s", store, err)
114 }
115 _, err = store.getToken(token.RefreshToken, true)
116 if err != ErrTokenNotFound {
117 t.Errorf("Expected ErrTokenNotFound from %T, got %s", store, err)
118 }
119 retrievedProfile, err = store.getTokensByProfileID(token.ProfileID, 25, 0)
120 if err != nil {
121 t.Errorf("Error retrieving token by profile from %T: %s", store, err)
122 }
123 if len(retrievedProfile) != 0 {
124 t.Errorf("Expected list of 0 tokens from %T, got %+v", store, retrievedProfile)
125 }
126 err = store.removeToken(token.AccessToken)
127 if err != ErrTokenNotFound {
128 t.Errorf("Expected ErrTokenNotFound from %T, got %s", store, err)
129 }
130 err = store.revokeToken(token.AccessToken, false)
131 if err != ErrTokenNotFound {
132 t.Errorf("Expected ErrTokenNotFound from %T, got %s", store, err)
133 }
134 err = store.revokeToken(token.RefreshToken, true)
135 if err != ErrTokenNotFound {
136 t.Errorf("Expected ErrTokenNotFound from %T, got %s", store, err)
137 }
138 }
139 }