1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package security
16
17 import (
18 "context"
19 "fmt"
20 "net/http"
21 "testing"
22
23 "github.com/go-openapi/errors"
24 "github.com/stretchr/testify/assert"
25 "github.com/stretchr/testify/require"
26 )
27
28 const (
29 apiKeyParam = "api_key"
30 apiKeyHeader = "X-API-KEY"
31 )
32
33 func TestApiKeyAuth(t *testing.T) {
34 tokenAuth := TokenAuthentication(func(token string) (interface{}, error) {
35 if token == validToken {
36 return principal, nil
37 }
38 return nil, errors.Unauthenticated("token")
39 })
40
41 t.Run("with invalid initialization", func(t *testing.T) {
42 assert.Panics(t, func() { APIKeyAuth(apiKeyParam, "qery", tokenAuth) })
43 })
44
45 t.Run("with token in query param", func(t *testing.T) {
46 ta := APIKeyAuth(apiKeyParam, query, tokenAuth)
47
48 t.Run("with valid token", func(t *testing.T) {
49 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, fmt.Sprintf("%s?%s=%s", authPath, apiKeyParam, validToken), nil)
50 require.NoError(t, err)
51
52 ok, usr, err := ta.Authenticate(req)
53 assert.True(t, ok)
54 assert.Equal(t, principal, usr)
55 require.NoError(t, err)
56 })
57
58 t.Run("with invalid token", func(t *testing.T) {
59 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, fmt.Sprintf("%s?%s=%s", authPath, apiKeyParam, invalidToken), nil)
60 require.NoError(t, err)
61
62 ok, usr, err := ta.Authenticate(req)
63 assert.True(t, ok)
64 assert.Nil(t, usr)
65 require.Error(t, err)
66 })
67
68 t.Run("with missing token", func(t *testing.T) {
69
70 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, authPath, nil)
71 require.NoError(t, err)
72 req.Header.Set(apiKeyHeader, validToken)
73
74 ok, usr, err := ta.Authenticate(req)
75 assert.False(t, ok)
76 assert.Nil(t, usr)
77 require.NoError(t, err)
78 })
79 })
80
81 t.Run("with token in header", func(t *testing.T) {
82 ta := APIKeyAuth(apiKeyHeader, header, tokenAuth)
83
84 t.Run("with valid token", func(t *testing.T) {
85 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, authPath, nil)
86 require.NoError(t, err)
87 req.Header.Set(apiKeyHeader, validToken)
88
89 ok, usr, err := ta.Authenticate(req)
90 assert.True(t, ok)
91 assert.Equal(t, principal, usr)
92 require.NoError(t, err)
93 })
94
95 t.Run("with invalid token", func(t *testing.T) {
96 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, authPath, nil)
97 require.NoError(t, err)
98 req.Header.Set(apiKeyHeader, invalidToken)
99
100 ok, usr, err := ta.Authenticate(req)
101 assert.True(t, ok)
102 assert.Nil(t, usr)
103 require.Error(t, err)
104 })
105
106 t.Run("with missing token", func(t *testing.T) {
107
108 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, fmt.Sprintf("%s?%s=%s", authPath, apiKeyParam, validToken), nil)
109 require.NoError(t, err)
110
111 ok, usr, err := ta.Authenticate(req)
112 assert.False(t, ok)
113 assert.Nil(t, usr)
114 require.NoError(t, err)
115 })
116 })
117 }
118
119 func TestApiKeyAuthCtx(t *testing.T) {
120 tokenAuthCtx := TokenAuthenticationCtx(func(ctx context.Context, token string) (context.Context, interface{}, error) {
121 if token == validToken {
122 return context.WithValue(ctx, extra, extraWisdom), principal, nil
123 }
124 return context.WithValue(ctx, reason, expReason), nil, errors.Unauthenticated("token")
125 })
126 ctx := context.WithValue(context.Background(), original, wisdom)
127
128 t.Run("with invalid initialization", func(t *testing.T) {
129 assert.Panics(t, func() { APIKeyAuthCtx(apiKeyParam, "qery", tokenAuthCtx) })
130 })
131
132 t.Run("with token in query param", func(t *testing.T) {
133 ta := APIKeyAuthCtx(apiKeyParam, query, tokenAuthCtx)
134
135 t.Run("with valid token", func(t *testing.T) {
136 req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s?%s=%s", authPath, apiKeyParam, validToken), nil)
137 require.NoError(t, err)
138 ok, usr, err := ta.Authenticate(req)
139 assert.True(t, ok)
140 assert.Equal(t, principal, usr)
141 require.NoError(t, err)
142
143 assert.Equal(t, wisdom, req.Context().Value(original))
144 assert.Equal(t, extraWisdom, req.Context().Value(extra))
145 assert.Nil(t, req.Context().Value(reason))
146 })
147
148 t.Run("with invalid token", func(t *testing.T) {
149 req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s?%s=%s", authPath, apiKeyParam, invalidToken), nil)
150 require.NoError(t, err)
151 ok, usr, err := ta.Authenticate(req)
152 assert.True(t, ok)
153 assert.Nil(t, usr)
154 require.Error(t, err)
155
156 assert.Equal(t, wisdom, req.Context().Value(original))
157 assert.Equal(t, expReason, req.Context().Value(reason))
158 assert.Nil(t, req.Context().Value(extra))
159 })
160
161 t.Run("with missing token", func(t *testing.T) {
162 req, err := http.NewRequestWithContext(ctx, http.MethodGet, authPath, nil)
163 require.NoError(t, err)
164 req.Header.Set(apiKeyHeader, validToken)
165
166 ok, usr, err := ta.Authenticate(req)
167 assert.False(t, ok)
168 assert.Nil(t, usr)
169 require.NoError(t, err)
170
171 assert.Equal(t, wisdom, req.Context().Value(original))
172 assert.Nil(t, req.Context().Value(reason))
173 assert.Nil(t, req.Context().Value(extra))
174 })
175 })
176
177 t.Run("with token in header", func(t *testing.T) {
178 ta := APIKeyAuthCtx(apiKeyHeader, header, tokenAuthCtx)
179
180 t.Run("with valid token", func(t *testing.T) {
181 req, err := http.NewRequestWithContext(ctx, http.MethodGet, authPath, nil)
182 require.NoError(t, err)
183 req.Header.Set(apiKeyHeader, validToken)
184
185 ok, usr, err := ta.Authenticate(req)
186 assert.True(t, ok)
187 assert.Equal(t, principal, usr)
188 require.NoError(t, err)
189
190 assert.Equal(t, wisdom, req.Context().Value(original))
191 assert.Equal(t, extraWisdom, req.Context().Value(extra))
192 assert.Nil(t, req.Context().Value(reason))
193 })
194
195 t.Run("with invalid token", func(t *testing.T) {
196 req, err := http.NewRequestWithContext(ctx, http.MethodGet, authPath, nil)
197 require.NoError(t, err)
198 req.Header.Set(apiKeyHeader, invalidToken)
199
200 ok, usr, err := ta.Authenticate(req)
201 assert.True(t, ok)
202 assert.Nil(t, usr)
203 require.Error(t, err)
204
205 assert.Equal(t, wisdom, req.Context().Value(original))
206 assert.Equal(t, expReason, req.Context().Value(reason))
207 assert.Nil(t, req.Context().Value(extra))
208 })
209
210 t.Run("with missing token", func(t *testing.T) {
211 req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s?%s=%s", authPath, apiKeyParam, validToken), nil)
212 require.NoError(t, err)
213
214 ok, usr, err := ta.Authenticate(req)
215 assert.False(t, ok)
216 assert.Nil(t, usr)
217 require.NoError(t, err)
218
219 assert.Equal(t, wisdom, req.Context().Value(original))
220 assert.Nil(t, req.Context().Value(reason))
221 assert.Nil(t, req.Context().Value(extra))
222 })
223 })
224 }
225
View as plain text