1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package security
16
17 import (
18 "context"
19 "net/http"
20 "testing"
21
22 "github.com/go-openapi/errors"
23 "github.com/stretchr/testify/assert"
24 "github.com/stretchr/testify/require"
25 )
26
27 type secTestKey uint8
28
29 const (
30 original secTestKey = iota
31 extra
32 reason
33 )
34
35 const (
36 wisdom = "The man who is swimming against the stream knows the strength of it."
37 extraWisdom = "Our greatest glory is not in never falling, but in rising every time we fall."
38 expReason = "I like the dreams of the future better than the history of the past."
39 testPassword = "123456"
40 )
41
42 func TestBasicAuth(t *testing.T) {
43 basicAuthHandler := UserPassAuthentication(func(user, pass string) (interface{}, error) {
44 if user == principal && pass == testPassword {
45 return principal, nil
46 }
47 return "", errors.Unauthenticated("basic")
48 })
49 ba := BasicAuth(basicAuthHandler)
50
51 t.Run("with valid basic auth", func(t *testing.T) {
52 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, authPath, nil)
53 require.NoError(t, err)
54 req.SetBasicAuth(principal, testPassword)
55
56 ok, usr, err := ba.Authenticate(req)
57 require.NoError(t, err)
58 assert.True(t, ok)
59 assert.Equal(t, principal, usr)
60 })
61
62 t.Run("with invalid basic auth", func(t *testing.T) {
63 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, authPath, nil)
64 require.NoError(t, err)
65 req.SetBasicAuth(principal, principal)
66
67 ok, usr, err := ba.Authenticate(req)
68 require.Error(t, err)
69 assert.True(t, ok)
70 assert.Equal(t, "", usr)
71
72 assert.NotEmpty(t, FailedBasicAuth(req))
73 assert.Equal(t, DefaultRealmName, FailedBasicAuth(req))
74 })
75
76 t.Run("with missing basic auth", func(t *testing.T) {
77 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, authPath, nil)
78 require.NoError(t, err)
79
80 ok, usr, err := ba.Authenticate(req)
81 require.NoError(t, err)
82 assert.False(t, ok)
83 assert.Nil(t, usr)
84
85 assert.NotEmpty(t, FailedBasicAuth(req))
86 assert.Equal(t, DefaultRealmName, FailedBasicAuth(req))
87 })
88
89 t.Run("basic auth without request", func(*testing.T) {
90 ok, usr, err := ba.Authenticate("token")
91 require.NoError(t, err)
92 assert.False(t, ok)
93 assert.Nil(t, usr)
94 })
95
96 t.Run("with realm, invalid basic auth", func(t *testing.T) {
97 br := BasicAuthRealm("realm", basicAuthHandler)
98
99 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, authPath, nil)
100 require.NoError(t, err)
101 req.SetBasicAuth(principal, principal)
102
103 ok, usr, err := br.Authenticate(req)
104 require.Error(t, err)
105 assert.True(t, ok)
106 assert.Equal(t, "", usr)
107 assert.Equal(t, "realm", FailedBasicAuth(req))
108 })
109
110 t.Run("with empty realm, invalid basic auth", func(t *testing.T) {
111 br := BasicAuthRealm("", basicAuthHandler)
112
113 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, authPath, nil)
114 require.NoError(t, err)
115 req.SetBasicAuth(principal, principal)
116
117 ok, usr, err := br.Authenticate(req)
118 require.Error(t, err)
119 assert.True(t, ok)
120 assert.Equal(t, "", usr)
121 assert.Equal(t, DefaultRealmName, FailedBasicAuth(req))
122 })
123 }
124
125 func TestBasicAuthCtx(t *testing.T) {
126 basicAuthHandlerCtx := UserPassAuthenticationCtx(func(ctx context.Context, user, pass string) (context.Context, interface{}, error) {
127 if user == principal && pass == testPassword {
128 return context.WithValue(ctx, extra, extraWisdom), principal, nil
129 }
130 return context.WithValue(ctx, reason, expReason), "", errors.Unauthenticated("basic")
131 })
132 ba := BasicAuthCtx(basicAuthHandlerCtx)
133 ctx := context.WithValue(context.Background(), original, wisdom)
134
135 t.Run("with valid basic auth", func(t *testing.T) {
136 req, err := http.NewRequestWithContext(ctx, http.MethodGet, authPath, nil)
137 require.NoError(t, err)
138
139 req.SetBasicAuth(principal, testPassword)
140 ok, usr, err := ba.Authenticate(req)
141 require.NoError(t, err)
142 assert.True(t, ok)
143 assert.Equal(t, principal, usr)
144
145 assert.Equal(t, wisdom, req.Context().Value(original))
146 assert.Equal(t, extraWisdom, req.Context().Value(extra))
147 assert.Nil(t, req.Context().Value(reason))
148 })
149
150 t.Run("with invalid basic auth", func(t *testing.T) {
151 req, err := http.NewRequestWithContext(ctx, http.MethodGet, authPath, nil)
152 require.NoError(t, err)
153 req.SetBasicAuth(principal, principal)
154
155 ok, usr, err := ba.Authenticate(req)
156 require.Error(t, err)
157 assert.True(t, ok)
158 assert.Equal(t, "", usr)
159
160 assert.Equal(t, wisdom, req.Context().Value(original))
161 assert.Nil(t, req.Context().Value(extra))
162 assert.Equal(t, expReason, req.Context().Value(reason))
163 })
164
165 t.Run("with missing basic auth", func(t *testing.T) {
166 req, err := http.NewRequestWithContext(ctx, http.MethodGet, authPath, nil)
167 require.NoError(t, err)
168
169 ok, usr, err := ba.Authenticate(req)
170 require.NoError(t, err)
171 assert.False(t, ok)
172 assert.Nil(t, usr)
173
174 assert.Equal(t, wisdom, req.Context().Value(original))
175 assert.Nil(t, req.Context().Value(extra))
176 assert.Nil(t, req.Context().Value(reason))
177 })
178
179 t.Run("basic auth without request", func(*testing.T) {
180 ok, usr, err := ba.Authenticate("token")
181 require.NoError(t, err)
182 assert.False(t, ok)
183 assert.Nil(t, usr)
184 })
185
186 t.Run("with realm, invalid basic auth", func(t *testing.T) {
187 br := BasicAuthRealmCtx("realm", basicAuthHandlerCtx)
188
189 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, authPath, nil)
190 require.NoError(t, err)
191 req.SetBasicAuth(principal, principal)
192
193 ok, usr, err := br.Authenticate(req)
194 require.Error(t, err)
195 assert.True(t, ok)
196 assert.Equal(t, "", usr)
197 assert.Equal(t, "realm", FailedBasicAuth(req))
198 })
199
200 t.Run("with empty realm, invalid basic auth", func(t *testing.T) {
201 br := BasicAuthRealmCtx("", basicAuthHandlerCtx)
202
203 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, authPath, nil)
204 require.NoError(t, err)
205 req.SetBasicAuth(principal, principal)
206
207 ok, usr, err := br.Authenticate(req)
208 require.Error(t, err)
209 assert.True(t, ok)
210 assert.Equal(t, "", usr)
211 assert.Equal(t, DefaultRealmName, FailedBasicAuth(req))
212 })
213 }
214
View as plain text