summaryrefslogtreecommitdiffstats
path: root/services/auth
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2023-05-21 09:50:53 +0800
committerGitHub <noreply@github.com>2023-05-21 09:50:53 +0800
commit6b33152b7dc81b38e5832a30c52cfad1902e86d0 (patch)
tree020272cc3b2d0566d286ed01f85ae74a9f48c177 /services/auth
parent6ba4f897231229c06ac98bf2e067665e3ef0bf23 (diff)
downloadgitea-6b33152b7dc81b38e5832a30c52cfad1902e86d0.tar.gz
gitea-6b33152b7dc81b38e5832a30c52cfad1902e86d0.zip
Decouple the different contexts from each other (#24786)
Replace #16455 Close #21803 Mixing different Gitea contexts together causes some problems: 1. Unable to respond proper content when error occurs, eg: Web should respond HTML while API should respond JSON 2. Unclear dependency, eg: it's unclear when Context is used in APIContext, which fields should be initialized, which methods are necessary. To make things clear, this PR introduces a Base context, it only provides basic Req/Resp/Data features. This PR mainly moves code. There are still many legacy problems and TODOs in code, leave unrelated changes to future PRs.
Diffstat (limited to 'services/auth')
-rw-r--r--services/auth/middleware.go52
1 files changed, 34 insertions, 18 deletions
diff --git a/services/auth/middleware.go b/services/auth/middleware.go
index 3b2f883d00..d1955a4c90 100644
--- a/services/auth/middleware.go
+++ b/services/auth/middleware.go
@@ -8,6 +8,7 @@ import (
"strings"
"code.gitea.io/gitea/models/auth"
+ user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
@@ -17,11 +18,15 @@ import (
// Auth is a middleware to authenticate a web user
func Auth(authMethod Method) func(*context.Context) {
return func(ctx *context.Context) {
- if err := authShared(ctx, authMethod); err != nil {
+ ar, err := authShared(ctx.Base, ctx.Session, authMethod)
+ if err != nil {
log.Error("Failed to verify user: %v", err)
ctx.Error(http.StatusUnauthorized, "Verify")
return
}
+ ctx.Doer = ar.Doer
+ ctx.IsSigned = ar.Doer != nil
+ ctx.IsBasicAuth = ar.IsBasicAuth
if ctx.Doer == nil {
// ensure the session uid is deleted
_ = ctx.Session.Delete("uid")
@@ -32,32 +37,41 @@ func Auth(authMethod Method) func(*context.Context) {
// APIAuth is a middleware to authenticate an api user
func APIAuth(authMethod Method) func(*context.APIContext) {
return func(ctx *context.APIContext) {
- if err := authShared(ctx.Context, authMethod); err != nil {
+ ar, err := authShared(ctx.Base, nil, authMethod)
+ if err != nil {
ctx.Error(http.StatusUnauthorized, "APIAuth", err)
+ return
}
+ ctx.Doer = ar.Doer
+ ctx.IsSigned = ar.Doer != nil
+ ctx.IsBasicAuth = ar.IsBasicAuth
}
}
-func authShared(ctx *context.Context, authMethod Method) error {
- var err error
- ctx.Doer, err = authMethod.Verify(ctx.Req, ctx.Resp, ctx, ctx.Session)
+type authResult struct {
+ Doer *user_model.User
+ IsBasicAuth bool
+}
+
+func authShared(ctx *context.Base, sessionStore SessionStore, authMethod Method) (ar authResult, err error) {
+ ar.Doer, err = authMethod.Verify(ctx.Req, ctx.Resp, ctx, sessionStore)
if err != nil {
- return err
+ return ar, err
}
- if ctx.Doer != nil {
- if ctx.Locale.Language() != ctx.Doer.Language {
+ if ar.Doer != nil {
+ if ctx.Locale.Language() != ar.Doer.Language {
ctx.Locale = middleware.Locale(ctx.Resp, ctx.Req)
}
- ctx.IsBasicAuth = ctx.Data["AuthedMethod"].(string) == BasicMethodName
- ctx.IsSigned = true
- ctx.Data["IsSigned"] = ctx.IsSigned
- ctx.Data[middleware.ContextDataKeySignedUser] = ctx.Doer
- ctx.Data["SignedUserID"] = ctx.Doer.ID
- ctx.Data["IsAdmin"] = ctx.Doer.IsAdmin
+ ar.IsBasicAuth = ctx.Data["AuthedMethod"].(string) == BasicMethodName
+
+ ctx.Data["IsSigned"] = true
+ ctx.Data[middleware.ContextDataKeySignedUser] = ar.Doer
+ ctx.Data["SignedUserID"] = ar.Doer.ID
+ ctx.Data["IsAdmin"] = ar.Doer.IsAdmin
} else {
ctx.Data["SignedUserID"] = int64(0)
}
- return nil
+ return ar, nil
}
// VerifyOptions contains required or check options
@@ -68,7 +82,7 @@ type VerifyOptions struct {
DisableCSRF bool
}
-// Checks authentication according to options
+// VerifyAuthWithOptions checks authentication according to options
func VerifyAuthWithOptions(options *VerifyOptions) func(ctx *context.Context) {
return func(ctx *context.Context) {
// Check prohibit login users.
@@ -153,7 +167,7 @@ func VerifyAuthWithOptions(options *VerifyOptions) func(ctx *context.Context) {
}
}
-// Checks authentication according to options
+// VerifyAuthWithOptionsAPI checks authentication according to options
func VerifyAuthWithOptionsAPI(options *VerifyOptions) func(ctx *context.APIContext) {
return func(ctx *context.APIContext) {
// Check prohibit login users.
@@ -197,7 +211,9 @@ func VerifyAuthWithOptionsAPI(options *VerifyOptions) func(ctx *context.APIConte
return
} else if !ctx.Doer.IsActive && setting.Service.RegisterEmailConfirm {
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
- ctx.HTML(http.StatusOK, "user/auth/activate")
+ ctx.JSON(http.StatusForbidden, map[string]string{
+ "message": "This account is not activated.",
+ })
return
}
if ctx.IsSigned && ctx.IsBasicAuth {