From 08dbacd71b82ceb41047cb4ac43d5928b51da0d0 Mon Sep 17 00:00:00 2001 From: Jannis Mattheis Date: Sun, 11 Feb 2018 12:12:53 +0100 Subject: [PATCH] Adjust authentication to also send 403 --- auth/authentication.go | 33 ++++++++++++++++++--------------- auth/authentication_test.go | 10 +++++----- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/auth/authentication.go b/auth/authentication.go index 56a7248..a13605d 100644 --- a/auth/authentication.go +++ b/auth/authentication.go @@ -26,46 +26,46 @@ type Auth struct { DB Database } -type authenticate func(tokenID string, user *model.User) (success bool, userId uint) +type authenticate func(tokenID string, user *model.User) (authenticated bool, success bool, userId uint) // RequireAdmin returns a gin middleware which requires a client token or basic authentication header to be supplied // with the request. Also the authenticated user must be an administrator. func (a *Auth) RequireAdmin() gin.HandlerFunc { - return a.requireToken(func(tokenID string, user *model.User) (bool, uint) { + return a.requireToken(func(tokenID string, user *model.User) (bool, bool, uint) { if user != nil { - return user.Admin, user.ID + return true, user.Admin, user.ID } if token := a.DB.GetClientByID(tokenID); token != nil { - return a.DB.GetUserByID(token.UserID).Admin, token.UserID + return true, a.DB.GetUserByID(token.UserID).Admin, token.UserID } - return false, 0 + return false, false, 0 }) } // RequireClient returns a gin middleware which requires a client token or basic authentication header to be supplied // with the request. func (a *Auth) RequireClient() gin.HandlerFunc { - return a.requireToken(func(tokenID string, user *model.User) (bool, uint) { + return a.requireToken(func(tokenID string, user *model.User) (bool, bool, uint) { if user != nil { - return true, user.ID + return true, true, user.ID } if token := a.DB.GetClientByID(tokenID); token != nil { - return true, token.UserID + return true, true, token.UserID } - return false, 0 + return false, false, 0 }) } // RequireApplicationToken returns a gin middleware which requires an application token to be supplied with the request. func (a *Auth) RequireApplicationToken() gin.HandlerFunc { - return a.requireToken(func(tokenID string, user *model.User) (bool, uint) { + return a.requireToken(func(tokenID string, user *model.User) (bool, bool, uint) { if user != nil { - return false, 0 + return true, false, 0 } if token := a.DB.GetApplicationByID(tokenID); token != nil { - return true, token.UserID + return true, true, token.UserID } - return false, 0 + return false, false, 0 }) } @@ -104,12 +104,15 @@ func (a *Auth) requireToken(auth authenticate) gin.HandlerFunc { user := a.userFromBasicAuth(ctx) if user != nil || token != "" { - if ok, userID := auth(token, user); ok { + if authenticated, ok, userID := auth(token, user); ok { RegisterAuthentication(ctx, user, userID, token) ctx.Next() return + } else if authenticated { + ctx.AbortWithError(403, errors.New("you are not allowed to access this api")) + return } } - ctx.AbortWithError(401, errors.New("could not authenticate")) + ctx.AbortWithError(401, errors.New("you need to provide a valid access token or user credentials to access this api")) } } diff --git a/auth/authentication_test.go b/auth/authentication_test.go index 49cc381..e4ed405 100644 --- a/auth/authentication_test.go +++ b/auth/authentication_test.go @@ -66,7 +66,7 @@ func (s *AuthenticationSuite) TestQueryToken() { // clienttoken s.assertQueryRequest("token", "clienttoken", s.auth.RequireApplicationToken, 401) s.assertQueryRequest("token", "clienttoken", s.auth.RequireClient, 200) - s.assertQueryRequest("token", "clienttoken", s.auth.RequireAdmin, 401) + s.assertQueryRequest("token", "clienttoken", s.auth.RequireAdmin, 403) s.assertQueryRequest("token", "clienttoken_admin", s.auth.RequireApplicationToken, 401) s.assertQueryRequest("token", "clienttoken_admin", s.auth.RequireClient, 200) s.assertQueryRequest("token", "clienttoken_admin", s.auth.RequireAdmin, 200) @@ -120,7 +120,7 @@ func (s *AuthenticationSuite) TestHeaderApiKeyToken() { // clienttoken s.assertHeaderRequest("Authorization", "ApiKey clienttoken", s.auth.RequireApplicationToken, 401) s.assertHeaderRequest("Authorization", "ApiKey clienttoken", s.auth.RequireClient, 200) - s.assertHeaderRequest("Authorization", "ApiKey clienttoken", s.auth.RequireAdmin, 401) + s.assertHeaderRequest("Authorization", "ApiKey clienttoken", s.auth.RequireAdmin, 403) s.assertHeaderRequest("Authorization", "ApiKey clienttoken_admin", s.auth.RequireApplicationToken, 401) s.assertHeaderRequest("Authorization", "ApiKey clienttoken_admin", s.auth.RequireClient, 200) s.assertHeaderRequest("Authorization", "ApiKey clienttoken_admin", s.auth.RequireAdmin, 200) @@ -132,12 +132,12 @@ func (s *AuthenticationSuite) TestBasicAuth() { s.assertHeaderRequest("Authorization", "Basic ergerogerg", s.auth.RequireAdmin, 401) // user existing:pw - s.assertHeaderRequest("Authorization", "Basic ZXhpc3Rpbmc6cHc=", s.auth.RequireApplicationToken, 401) + s.assertHeaderRequest("Authorization", "Basic ZXhpc3Rpbmc6cHc=", s.auth.RequireApplicationToken, 403) s.assertHeaderRequest("Authorization", "Basic ZXhpc3Rpbmc6cHc=", s.auth.RequireClient, 200) - s.assertHeaderRequest("Authorization", "Basic ZXhpc3Rpbmc6cHc=", s.auth.RequireAdmin, 401) + s.assertHeaderRequest("Authorization", "Basic ZXhpc3Rpbmc6cHc=", s.auth.RequireAdmin, 403) // user admin:pw - s.assertHeaderRequest("Authorization", "Basic YWRtaW46cHc=", s.auth.RequireApplicationToken, 401) + s.assertHeaderRequest("Authorization", "Basic YWRtaW46cHc=", s.auth.RequireApplicationToken, 403) s.assertHeaderRequest("Authorization", "Basic YWRtaW46cHc=", s.auth.RequireClient, 200) s.assertHeaderRequest("Authorization", "Basic YWRtaW46cHc=", s.auth.RequireAdmin, 200)