@@ -63,6 +63,9 @@ func (s *AuthenticationSuite) SetupSuite() {
6363 {Token : "clienttoken_admin_elevated" , Name : "elevated phone2" , ElevatedUntil : & elevated },
6464 },
6565 })
66+
67+ // client whose user does not exist anymore
68+ s .DB .CreateClient (& model.Client {Token : "clienttoken_orphan_elevated" , Name : "orphan phone" , UserID : 999 , ElevatedUntil : & elevated })
6669}
6770
6871func (s * AuthenticationSuite ) TearDownSuite () {
@@ -141,6 +144,11 @@ func (s *AuthenticationSuite) TestNothingProvided() {
141144 assert .Equal (s .T (), 401 , recorder .Code )
142145}
143146
147+ func (s * AuthenticationSuite ) TestOrphanedClientToken () {
148+ s .assertHeaderRequest ("X-Gotify-Key" , "clienttoken_orphan_elevated" , s .auth .RequireAdmin , 403 )
149+ s .assertHeaderRequest ("X-Gotify-Key" , "clienttoken_orphan_elevated" , s .auth .OptionalAdmin , 403 )
150+ }
151+
144152func (s * AuthenticationSuite ) TestHeaderApiKeyToken () {
145153 // not existing token
146154 s .assertHeaderRequest ("X-Gotify-Key" , "ergerogerg" , s .auth .RequireApplicationToken , 401 )
@@ -282,33 +290,47 @@ func (s *AuthenticationSuite) TestBasicAuthDisabled() {
282290 s .assertHeaderRequest ("Authorization" , "Basic YWRtaW46cHc=" , s .auth .RequireClient , 403 )
283291 s .assertHeaderRequest ("Authorization" , "Basic YWRtaW46cHc=" , s .auth .RequireAdmin , 403 )
284292 s .assertHeaderRequest ("Authorization" , "Basic YWRtaW46cHc=" , s .auth .RequireElevatedClient , 403 )
293+ s .assertHeaderRequest ("Authorization" , "Basic YWRtaW46cHc=" , s .auth .OptionalAdmin , 403 )
285294}
286295
287- func (s * AuthenticationSuite ) TestOptionalAuth () {
288- // various invalid users
289- ctx := s .assertQueryRequest ("token" , "ergerogerg" , s .auth .Optional , 200 )
290- assert .Nil (s .T (), TryGetUserID (ctx ))
291- ctx = s .assertHeaderRequest ("X-Gotify-Key" , "ergerogerg" , s .auth .Optional , 200 )
296+ func (s * AuthenticationSuite ) TestOptionalAdminAuth () {
297+ ctx := s .assertQueryRequest ("token" , "ergerogerg" , s .auth .OptionalAdmin , 200 )
292298 assert .Nil (s .T (), TryGetUserID (ctx ))
293- ctx = s .assertHeaderRequest ( "Authorization " , "Basic bm90ZXhpc3Rpbmc6cHc= " , s .auth .Optional , 200 )
299+ ctx = s .assertQueryRequest ( "token " , "apptoken_admin " , s .auth .OptionalAdmin , 200 )
294300 assert .Nil (s .T (), TryGetUserID (ctx ))
295- ctx = s .assertHeaderRequest ("Authorization" , "Basic YWRtaW46cHd4" , s .auth .Optional , 200 )
296- assert .Nil (s .T (), TryGetUserID (ctx ))
297- ctx = s .assertQueryRequest ("tokenx" , "clienttoken" , s .auth .Optional , 200 )
298- assert .Nil (s .T (), TryGetUserID (ctx ))
299- ctx = s .assertQueryRequest ("token" , "apptoken_admin" , s .auth .Optional , 200 )
301+
302+ // nothing provided
303+ ctx = s .assertRequest (s .auth .OptionalAdmin , 200 )
300304 assert .Nil (s .T (), TryGetUserID (ctx ))
301305
302- // user existing:pw
303- ctx = s .assertHeaderRequest ("Authorization" , "Basic ZXhpc3Rpbmc6cHc=" , s .auth .Optional , 200 )
304- assert .Equal (s .T (), uint (1 ), * TryGetUserID (ctx ))
305- ctx = s .assertQueryRequest ("token" , "clienttoken" , s .auth .Optional , 200 )
306- assert .Equal (s .T (), uint (1 ), * TryGetUserID (ctx ))
306+ // user existing:pw (non-admin)
307+ s .assertHeaderRequest ("Authorization" , "Basic ZXhpc3Rpbmc6cHc=" , s .auth .OptionalAdmin , 403 )
307308
308- // user admin:pw
309- ctx = s .assertHeaderRequest ("Authorization" , "Basic YWRtaW46cHc=" , s .auth .Optional , 200 )
309+ // clienttoken (non-admin, not elevated)
310+ s .assertQueryRequest ("token" , "clienttoken" , s .auth .OptionalAdmin , 403 )
311+ s .assertHeaderRequest ("X-Gotify-Key" , "clienttoken" , s .auth .OptionalAdmin , 403 )
312+ s .assertHeaderRequest ("Authorization" , "Bearer clienttoken" , s .auth .OptionalAdmin , 403 )
313+
314+ // clienttoken_elevated (non-admin, elevated)
315+ s .assertQueryRequest ("token" , "clienttoken_elevated" , s .auth .OptionalAdmin , 403 )
316+ s .assertHeaderRequest ("X-Gotify-Key" , "clienttoken_elevated" , s .auth .OptionalAdmin , 403 )
317+ s .assertHeaderRequest ("Authorization" , "Bearer clienttoken_elevated" , s .auth .OptionalAdmin , 403 )
318+
319+ // user admin:pw (basic auth counts as elevated)
320+ ctx = s .assertHeaderRequest ("Authorization" , "Basic YWRtaW46cHc=" , s .auth .OptionalAdmin , 200 )
310321 assert .Equal (s .T (), uint (2 ), * TryGetUserID (ctx ))
311- ctx = s .assertQueryRequest ("token" , "clienttoken_admin" , s .auth .Optional , 200 )
322+
323+ // clienttoken_admin (not elevated)
324+ s .assertQueryRequest ("token" , "clienttoken_admin" , s .auth .OptionalAdmin , 403 )
325+ s .assertHeaderRequest ("X-Gotify-Key" , "clienttoken_admin" , s .auth .OptionalAdmin , 403 )
326+ s .assertHeaderRequest ("Authorization" , "Bearer clienttoken_admin" , s .auth .OptionalAdmin , 403 )
327+
328+ // clienttoken_admin_elevated
329+ ctx = s .assertQueryRequest ("token" , "clienttoken_admin_elevated" , s .auth .OptionalAdmin , 200 )
330+ assert .Equal (s .T (), uint (2 ), * TryGetUserID (ctx ))
331+ ctx = s .assertHeaderRequest ("X-Gotify-Key" , "clienttoken_admin_elevated" , s .auth .OptionalAdmin , 200 )
332+ assert .Equal (s .T (), uint (2 ), * TryGetUserID (ctx ))
333+ ctx = s .assertHeaderRequest ("Authorization" , "Bearer clienttoken_admin_elevated" , s .auth .OptionalAdmin , 200 )
312334 assert .Equal (s .T (), uint (2 ), * TryGetUserID (ctx ))
313335}
314336
@@ -368,6 +390,15 @@ func (s *AuthenticationSuite) assertHeaderRequest(key, value string, f fMiddlewa
368390 return ctx
369391}
370392
393+ func (s * AuthenticationSuite ) assertRequest (f fMiddleware , code int ) (ctx * gin.Context ) {
394+ recorder := httptest .NewRecorder ()
395+ ctx , _ = gin .CreateTestContext (recorder )
396+ ctx .Request = httptest .NewRequest ("GET" , "/" , nil )
397+ f (ctx )
398+ assert .Equal (s .T (), code , recorder .Code )
399+ return ctx
400+ }
401+
371402func (s * AuthenticationSuite ) TestCookieCrossOriginProtection () {
372403 // httptest sets the request host to example.com.
373404 s .assertCsrfRequest (map [string ]string {"Origin" : "http://example.com" }, "clienttoken" , s .auth .RequireClient , 200 )
0 commit comments