]> source.dussan.org Git - gitea.git/commitdiff
In basic auth check for tokens before call UserSignIn (#5725)
authormanuelluis <manuel.luis@gmail.com>
Tue, 12 Feb 2019 09:20:08 +0000 (10:20 +0100)
committerLauris BH <lauris@nix.lv>
Tue, 12 Feb 2019 09:20:08 +0000 (11:20 +0200)
* Check first if user/password is a token

* In basic auth check if user/password is a token

* Remove unnecessary else statement

* Changes of fmt

modules/auth/auth.go
routers/repo/http.go

index 4b0d4559c97c0054920824c5f6bacaf84748dc4b..f2530fa37cdc84a3730018b7254c41b03a72bb65 100644 (file)
@@ -135,15 +135,56 @@ func SignedInUser(ctx *macaron.Context, sess session.Store) (*models.User, bool)
        if len(baHead) > 0 {
                auths := strings.Fields(baHead)
                if len(auths) == 2 && auths[0] == "Basic" {
+                       var u *models.User
+
                        uname, passwd, _ := base.BasicAuthDecode(auths[1])
 
-                       u, err := models.UserSignIn(uname, passwd)
-                       if err != nil {
-                               if !models.IsErrUserNotExist(err) {
-                                       log.Error(4, "UserSignIn: %v", err)
+                       // Check if username or password is a token
+                       isUsernameToken := len(passwd) == 0 || passwd == "x-oauth-basic"
+                       // Assume username is token
+                       authToken := uname
+                       if !isUsernameToken {
+                               // Assume password is token
+                               authToken = passwd
+                       }
+                       token, err := models.GetAccessTokenBySHA(authToken)
+                       if err == nil {
+                               if isUsernameToken {
+                                       u, err = models.GetUserByID(token.UID)
+                                       if err != nil {
+                                               log.Error(4, "GetUserByID:  %v", err)
+                                               return nil, false
+                                       }
+                               } else {
+                                       u, err = models.GetUserByName(uname)
+                                       if err != nil {
+                                               log.Error(4, "GetUserByID:  %v", err)
+                                               return nil, false
+                                       }
+                                       if u.ID != token.UID {
+                                               return nil, false
+                                       }
+                               }
+                               token.UpdatedUnix = util.TimeStampNow()
+                               if err = models.UpdateAccessToken(token); err != nil {
+                                       log.Error(4, "UpdateAccessToken:  %v", err)
+                               }
+                       } else {
+                               if !models.IsErrAccessTokenNotExist(err) && !models.IsErrAccessTokenEmpty(err) {
+                                       log.Error(4, "GetAccessTokenBySha: %v", err)
                                }
-                               return nil, false
                        }
+
+                       if u == nil {
+                               u, err = models.UserSignIn(uname, passwd)
+                               if err != nil {
+                                       if !models.IsErrUserNotExist(err) {
+                                               log.Error(4, "UserSignIn: %v", err)
+                                       }
+                                       return nil, false
+                               }
+                       }
+
                        ctx.Data["IsApiToken"] = true
                        return u, true
                }
index 893401e9024e3319193b4c0e19e5861dc0493a5d..0e043803300427420353630cb09723ef76cb5362 100644 (file)
@@ -143,24 +143,24 @@ func HTTP(ctx *context.Context) {
                                return
                        }
 
-                       authUser, err = models.UserSignIn(authUsername, authPasswd)
-                       if err != nil {
-                               if !models.IsErrUserNotExist(err) {
-                                       ctx.ServerError("UserSignIn error: %v", err)
-                                       return
-                               }
+                       // Check if username or password is a token
+                       isUsernameToken := len(authPasswd) == 0 || authPasswd == "x-oauth-basic"
+                       // Assume username is token
+                       authToken := authUsername
+                       if !isUsernameToken {
+                               // Assume password is token
+                               authToken = authPasswd
                        }
-
-                       if authUser == nil {
-                               isUsernameToken := len(authPasswd) == 0 || authPasswd == "x-oauth-basic"
-
-                               // Assume username is token
-                               authToken := authUsername
-
-                               if !isUsernameToken {
-                                       // Assume password is token
-                                       authToken = authPasswd
-
+                       // Assume password is a token.
+                       token, err := models.GetAccessTokenBySHA(authToken)
+                       if err == nil {
+                               if isUsernameToken {
+                                       authUser, err = models.GetUserByID(token.UID)
+                                       if err != nil {
+                                               ctx.ServerError("GetUserByID", err)
+                                               return
+                                       }
+                               } else {
                                        authUser, err = models.GetUserByName(authUsername)
                                        if err != nil {
                                                if models.IsErrUserNotExist(err) {
@@ -170,37 +170,37 @@ func HTTP(ctx *context.Context) {
                                                }
                                                return
                                        }
-                               }
-
-                               // Assume password is a token.
-                               token, err := models.GetAccessTokenBySHA(authToken)
-                               if err != nil {
-                                       if models.IsErrAccessTokenNotExist(err) || models.IsErrAccessTokenEmpty(err) {
+                                       if authUser.ID != token.UID {
                                                ctx.HandleText(http.StatusUnauthorized, "invalid credentials")
-                                       } else {
-                                               ctx.ServerError("GetAccessTokenBySha", err)
+                                               return
                                        }
-                                       return
                                }
+                               token.UpdatedUnix = util.TimeStampNow()
+                               if err = models.UpdateAccessToken(token); err != nil {
+                                       ctx.ServerError("UpdateAccessToken", err)
+                               }
+                       } else {
+                               if !models.IsErrAccessTokenNotExist(err) && !models.IsErrAccessTokenEmpty(err) {
+                                       log.Error(4, "GetAccessTokenBySha: %v", err)
+                               }
+                       }
 
-                               if isUsernameToken {
-                                       authUser, err = models.GetUserByID(token.UID)
-                                       if err != nil {
-                                               ctx.ServerError("GetUserByID", err)
+                       if authUser == nil {
+                               // Check username and password
+                               authUser, err = models.UserSignIn(authUsername, authPasswd)
+                               if err != nil {
+                                       if !models.IsErrUserNotExist(err) {
+                                               ctx.ServerError("UserSignIn error: %v", err)
                                                return
                                        }
-                               } else if authUser.ID != token.UID {
+                               }
+
+                               if authUser == nil {
                                        ctx.HandleText(http.StatusUnauthorized, "invalid credentials")
                                        return
                                }
 
-                               token.UpdatedUnix = util.TimeStampNow()
-                               if err = models.UpdateAccessToken(token); err != nil {
-                                       ctx.ServerError("UpdateAccessToken", err)
-                               }
-                       } else {
                                _, err = models.GetTwoFactorByUID(authUser.ID)
-
                                if err == nil {
                                        // TODO: This response should be changed to "invalid credentials" for security reasons once the expectation behind it (creating an app token to authenticate) is properly documented
                                        ctx.HandleText(http.StatusUnauthorized, "Users with two-factor authentication enabled cannot perform HTTP/HTTPS operations via plain username and password. Please create and use a personal access token on the user settings page")