From 77aeede31adafc2329f78409d98cd008aa2b673e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Luis=20Sanmart=C3=ADn=20Rozada?= Date: Mon, 14 Jan 2019 12:37:29 +0100 Subject: [PATCH 1/4] Check first if user/password is a token --- routers/repo/http.go | 89 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/routers/repo/http.go b/routers/repo/http.go index ec5fbe6c0d33..95391c8b2952 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -113,24 +113,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) { @@ -140,44 +140,45 @@ 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 - } - - if isUsernameToken { - authUser, err = models.GetUserByID(token.UID) - if err != nil { - ctx.ServerError("GetUserByID", err) return } - } else if authUser.ID != token.UID { - 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 !models.IsErrAccessTokenNotExist(err) && !models.IsErrAccessTokenEmpty(err) { + log.Error(4, "GetAccessTokenBySha: %v", err) + } + } - 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") - return - } else if !models.IsErrTwoFactorNotEnrolled(err) { - ctx.ServerError("IsErrTwoFactorNotEnrolled", 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 + } + } + + if authUser == nil { + ctx.HandleText(http.StatusUnauthorized, "invalid credentials") return + } 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") + return + } else if !models.IsErrTwoFactorNotEnrolled(err) { + ctx.ServerError("IsErrTwoFactorNotEnrolled", err) + return + } } } } From e37785e9a4cf3863dd1dada50dc5c69df4b374e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Luis=20Sanmart=C3=ADn=20Rozada?= Date: Mon, 14 Jan 2019 12:40:56 +0100 Subject: [PATCH 2/4] In basic auth check if user/password is a token --- modules/auth/auth.go | 51 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/modules/auth/auth.go b/modules/auth/auth.go index 4b0d4559c97c..46814c6507da 100644 --- a/modules/auth/auth.go +++ b/modules/auth/auth.go @@ -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) + } + } + + 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 } - return nil, false } + ctx.Data["IsApiToken"] = true return u, true } From a3e63a7d0dbf66eea09dc5ced6a745b0506a31f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Luis=20Sanmart=C3=ADn=20Rozada?= Date: Mon, 14 Jan 2019 13:20:47 +0100 Subject: [PATCH 3/4] Remove unnecessary else statement --- routers/repo/http.go | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/routers/repo/http.go b/routers/repo/http.go index 95391c8b2952..280070dacf03 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -168,17 +168,16 @@ func HTTP(ctx *context.Context) { if authUser == nil { ctx.HandleText(http.StatusUnauthorized, "invalid credentials") return - } 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") - return - } else if !models.IsErrTwoFactorNotEnrolled(err) { - ctx.ServerError("IsErrTwoFactorNotEnrolled", err) - return - } + _, 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") + return + } else if !models.IsErrTwoFactorNotEnrolled(err) { + ctx.ServerError("IsErrTwoFactorNotEnrolled", err) + return } } } From ace7b0a7f8ce361085d13baef027cd3a0293e4cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Luis=20Sanmart=C3=ADn=20Rozada?= Date: Mon, 14 Jan 2019 13:24:06 +0100 Subject: [PATCH 4/4] Changes of fmt --- modules/auth/auth.go | 54 ++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/modules/auth/auth.go b/modules/auth/auth.go index 46814c6507da..f2530fa37cdc 100644 --- a/modules/auth/auth.go +++ b/modules/auth/auth.go @@ -139,41 +139,41 @@ func SignedInUser(ctx *macaron.Context, sess session.Store) (*models.User, bool) uname, passwd, _ := base.BasicAuthDecode(auths[1]) - // 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 { + // 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 { + if err != nil { log.Error(4, "GetUserByID: %v", err) return nil, false - } - } else { + } + } else { u, err = models.GetUserByName(uname) - if err != nil { + if err != nil { log.Error(4, "GetUserByID: %v", err) return nil, false - } - if u.ID != token.UID { + } + if u.ID != token.UID { return nil, false - } - } - token.UpdatedUnix = util.TimeStampNow() - if err = models.UpdateAccessToken(token); err != nil { + } + } + 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) - } - } + } + } else { + if !models.IsErrAccessTokenNotExist(err) && !models.IsErrAccessTokenEmpty(err) { + log.Error(4, "GetAccessTokenBySha: %v", err) + } + } if u == nil { u, err = models.UserSignIn(uname, passwd)