1
0
Fork 0
forked from forgejo/forgejo

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.
This commit is contained in:
wxiaoguang 2023-05-21 09:50:53 +08:00 committed by GitHub
parent 6ba4f89723
commit 6b33152b7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 885 additions and 781 deletions

View file

@ -15,7 +15,7 @@ import (
// UserAssignmentWeb returns a middleware to handle context-user assignment for web routes
func UserAssignmentWeb() func(ctx *context.Context) {
return func(ctx *context.Context) {
userAssignment(ctx, func(status int, title string, obj interface{}) {
errorFn := func(status int, title string, obj interface{}) {
err, ok := obj.(error)
if !ok {
err = fmt.Errorf("%s", obj)
@ -25,7 +25,8 @@ func UserAssignmentWeb() func(ctx *context.Context) {
} else {
ctx.ServerError(title, err)
}
})
}
ctx.ContextUser = userAssignment(ctx.Base, ctx.Doer, errorFn)
}
}
@ -53,18 +54,18 @@ func UserIDAssignmentAPI() func(ctx *context.APIContext) {
// UserAssignmentAPI returns a middleware to handle context-user assignment for api routes
func UserAssignmentAPI() func(ctx *context.APIContext) {
return func(ctx *context.APIContext) {
userAssignment(ctx.Context, ctx.Error)
ctx.ContextUser = userAssignment(ctx.Base, ctx.Doer, ctx.Error)
}
}
func userAssignment(ctx *context.Context, errCb func(int, string, interface{})) {
func userAssignment(ctx *context.Base, doer *user_model.User, errCb func(int, string, interface{})) (contextUser *user_model.User) {
username := ctx.Params(":username")
if ctx.IsSigned && ctx.Doer.LowerName == strings.ToLower(username) {
ctx.ContextUser = ctx.Doer
if doer != nil && doer.LowerName == strings.ToLower(username) {
contextUser = doer
} else {
var err error
ctx.ContextUser, err = user_model.GetUserByName(ctx, username)
contextUser, err = user_model.GetUserByName(ctx, username)
if err != nil {
if user_model.IsErrUserNotExist(err) {
if redirectUserID, err := user_model.LookupUserRedirect(username); err == nil {
@ -79,4 +80,5 @@ func userAssignment(ctx *context.Context, errCb func(int, string, interface{}))
}
}
}
return contextUser
}