Refactor web package and context package (#25298)

1. The "web" package shouldn't depends on "modules/context" package,
instead, let each "web context" register themselves to the "web"
package.
2. The old Init/Free doesn't make sense, so simplify it
* The ctx in "Init(ctx)" is never used, and shouldn't be used that way
* The "Free" is never called and shouldn't be called because the SSPI
instance is shared

---------

Co-authored-by: Giteabot <teabot@gitea.io>
pull/25266/head^2
wxiaoguang 1 year ago committed by GitHub
parent fc2115b494
commit 4e2f1ee58d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      cmd/web.go
  2. 8
      modules/context/api.go
  3. 6
      modules/context/base.go
  4. 8
      modules/context/context.go
  5. 8
      modules/context/private.go
  6. 17
      modules/context/response.go
  7. 42
      modules/test/context_tests.go
  8. 34
      modules/web/handler.go
  9. 2
      modules/web/middleware/data.go
  10. 24
      modules/web/route.go
  11. 6
      modules/web/routing/logger.go
  12. 10
      modules/web/types/response.go
  13. 3
      routers/api/actions/actions.go
  14. 3
      routers/api/actions/artifacts.go
  15. 5
      routers/api/packages/api.go
  16. 10
      routers/api/v1/api.go
  17. 58
      routers/api/v1/misc/markup_test.go
  18. 2
      routers/api/v1/repo/hook_test.go
  19. 4
      routers/api/v1/repo/repo_test.go
  20. 12
      routers/init.go
  21. 10
      routers/web/admin/users_test.go
  22. 2
      routers/web/org/projects_test.go
  23. 4
      routers/web/repo/editor_test.go
  24. 14
      routers/web/repo/issue_label_test.go
  25. 2
      routers/web/repo/projects_test.go
  26. 4
      routers/web/repo/release_test.go
  27. 22
      routers/web/repo/settings_test.go
  28. 18
      routers/web/repo/wiki_test.go
  29. 10
      routers/web/user/home_test.go
  30. 2
      routers/web/user/setting/account_test.go
  31. 9
      routers/web/web.go
  32. 34
      services/auth/group.go
  33. 15
      services/auth/interface.go
  34. 36
      services/auth/sspi_windows.go
  35. 2
      services/repository/archiver/archiver_test.go
  36. 14
      services/repository/files/content_test.go
  37. 4
      services/repository/files/diff_test.go
  38. 2
      services/repository/files/file_test.go
  39. 2
      services/repository/files/tree_test.go
  40. 2
      tests/e2e/e2e_test.go
  41. 12
      tests/integration/api_activitypub_person_test.go
  42. 5
      tests/integration/api_nodeinfo_test.go
  43. 5
      tests/integration/create_no_session_test.go
  44. 2
      tests/integration/integration_test.go
  45. 14
      tests/integration/repofiles_change_test.go

@ -191,7 +191,7 @@ func runWeb(ctx *cli.Context) error {
} }
// Set up Chi routes // Set up Chi routes
c := routers.NormalRoutes(graceful.GetManager().HammerContext()) c := routers.NormalRoutes()
err := listen(c, true) err := listen(c, true)
<-graceful.GetManager().Done() <-graceful.GetManager().Done()
log.Info("PID: %d Gitea Web Finished", os.Getpid()) log.Info("PID: %d Gitea Web Finished", os.Getpid())

@ -20,6 +20,8 @@ import (
"code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/httpcache"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/web"
web_types "code.gitea.io/gitea/modules/web/types"
"gitea.com/go-chi/cache" "gitea.com/go-chi/cache"
) )
@ -41,6 +43,12 @@ type APIContext struct {
Package *Package Package *Package
} }
func init() {
web.RegisterResponseStatusProvider[*APIContext](func(req *http.Request) web_types.ResponseStatusProvider {
return req.Context().Value(apiContextKey).(*APIContext)
})
}
// Currently, we have the following common fields in error response: // Currently, we have the following common fields in error response:
// * message: the message for end users (it shouldn't be used for error type detection) // * message: the message for end users (it shouldn't be used for error type detection)
// if we need to indicate some errors, we should introduce some new fields like ErrorCode or ErrorType // if we need to indicate some errors, we should introduce some new fields like ErrorCode or ErrorType

@ -96,7 +96,11 @@ func (b *Base) SetTotalCountHeader(total int64) {
// Written returns true if there are something sent to web browser // Written returns true if there are something sent to web browser
func (b *Base) Written() bool { func (b *Base) Written() bool {
return b.Resp.Status() > 0 return b.Resp.WrittenStatus() != 0
}
func (b *Base) WrittenStatus() int {
return b.Resp.WrittenStatus()
} }
// Status writes status code // Status writes status code

@ -21,7 +21,9 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/modules/translation"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/modules/web/middleware"
web_types "code.gitea.io/gitea/modules/web/types"
"gitea.com/go-chi/cache" "gitea.com/go-chi/cache"
"gitea.com/go-chi/session" "gitea.com/go-chi/session"
@ -58,6 +60,12 @@ type Context struct {
Package *Package Package *Package
} }
func init() {
web.RegisterResponseStatusProvider[*Context](func(req *http.Request) web_types.ResponseStatusProvider {
return req.Context().Value(WebContextKey).(*Context)
})
}
// TrHTMLEscapeArgs runs ".Locale.Tr()" but pre-escapes all arguments with html.EscapeString. // TrHTMLEscapeArgs runs ".Locale.Tr()" but pre-escapes all arguments with html.EscapeString.
// This is useful if the locale message is intended to only produce HTML content. // This is useful if the locale message is intended to only produce HTML content.
func (ctx *Context) TrHTMLEscapeArgs(msg string, args ...string) string { func (ctx *Context) TrHTMLEscapeArgs(msg string, args ...string) string {

@ -11,6 +11,8 @@ import (
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/web"
web_types "code.gitea.io/gitea/modules/web/types"
) )
// PrivateContext represents a context for private routes // PrivateContext represents a context for private routes
@ -21,6 +23,12 @@ type PrivateContext struct {
Repo *Repository Repo *Repository
} }
func init() {
web.RegisterResponseStatusProvider[*PrivateContext](func(req *http.Request) web_types.ResponseStatusProvider {
return req.Context().Value(privateContextKey).(*PrivateContext)
})
}
// Deadline is part of the interface for context.Context and we pass this to the request context // Deadline is part of the interface for context.Context and we pass this to the request context
func (ctx *PrivateContext) Deadline() (deadline time.Time, ok bool) { func (ctx *PrivateContext) Deadline() (deadline time.Time, ok bool) {
if ctx.Override != nil { if ctx.Override != nil {

@ -5,15 +5,20 @@ package context
import ( import (
"net/http" "net/http"
web_types "code.gitea.io/gitea/modules/web/types"
) )
// ResponseWriter represents a response writer for HTTP // ResponseWriter represents a response writer for HTTP
type ResponseWriter interface { type ResponseWriter interface {
http.ResponseWriter http.ResponseWriter
http.Flusher http.Flusher
Status() int web_types.ResponseStatusProvider
Before(func(ResponseWriter)) Before(func(ResponseWriter))
Size() int // used by access logger template
Status() int // used by access logger template
Size() int // used by access logger template
} }
var _ ResponseWriter = &Response{} var _ ResponseWriter = &Response{}
@ -46,6 +51,10 @@ func (r *Response) Write(bs []byte) (int, error) {
return size, nil return size, nil
} }
func (r *Response) Status() int {
return r.status
}
func (r *Response) Size() int { func (r *Response) Size() int {
return r.written return r.written
} }
@ -71,8 +80,8 @@ func (r *Response) Flush() {
} }
} }
// Status returned status code written // WrittenStatus returned status code written
func (r *Response) Status() int { func (r *Response) WrittenStatus() int {
return r.status return r.status
} }

@ -9,6 +9,7 @@ import (
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
"strings"
"testing" "testing"
access_model "code.gitea.io/gitea/models/perm/access" access_model "code.gitea.io/gitea/models/perm/access"
@ -25,19 +26,26 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
// MockContext mock context for unit tests func mockRequest(t *testing.T, reqPath string) *http.Request {
// TODO: move this function to other packages, because it depends on "models" package method, path, found := strings.Cut(reqPath, " ")
func MockContext(t *testing.T, path string) *context.Context { if !found {
resp := httptest.NewRecorder() method = "GET"
path = reqPath
}
requestURL, err := url.Parse(path) requestURL, err := url.Parse(path)
assert.NoError(t, err) assert.NoError(t, err)
req := &http.Request{ req := &http.Request{Method: method, URL: requestURL, Form: url.Values{}}
URL: requestURL, req = req.WithContext(middleware.WithContextData(req.Context()))
Form: url.Values{}, return req
} }
// MockContext mock context for unit tests
// TODO: move this function to other packages, because it depends on "models" package
func MockContext(t *testing.T, reqPath string) (*context.Context, *httptest.ResponseRecorder) {
resp := httptest.NewRecorder()
req := mockRequest(t, reqPath)
base, baseCleanUp := context.NewBaseContext(resp, req) base, baseCleanUp := context.NewBaseContext(resp, req)
base.Data = middleware.ContextData{} base.Data = middleware.GetContextData(req.Context())
base.Locale = &translation.MockLocale{} base.Locale = &translation.MockLocale{}
ctx := &context.Context{ ctx := &context.Context{
Base: base, Base: base,
@ -48,29 +56,23 @@ func MockContext(t *testing.T, path string) *context.Context {
chiCtx := chi.NewRouteContext() chiCtx := chi.NewRouteContext()
ctx.Base.AppendContextValue(chi.RouteCtxKey, chiCtx) ctx.Base.AppendContextValue(chi.RouteCtxKey, chiCtx)
return ctx return ctx, resp
} }
// MockAPIContext mock context for unit tests // MockAPIContext mock context for unit tests
// TODO: move this function to other packages, because it depends on "models" package // TODO: move this function to other packages, because it depends on "models" package
func MockAPIContext(t *testing.T, path string) *context.APIContext { func MockAPIContext(t *testing.T, reqPath string) (*context.APIContext, *httptest.ResponseRecorder) {
resp := httptest.NewRecorder() resp := httptest.NewRecorder()
requestURL, err := url.Parse(path) req := mockRequest(t, reqPath)
assert.NoError(t, err)
req := &http.Request{
URL: requestURL,
Form: url.Values{},
}
base, baseCleanUp := context.NewBaseContext(resp, req) base, baseCleanUp := context.NewBaseContext(resp, req)
base.Data = middleware.ContextData{} base.Data = middleware.GetContextData(req.Context())
base.Locale = &translation.MockLocale{} base.Locale = &translation.MockLocale{}
ctx := &context.APIContext{Base: base} ctx := &context.APIContext{Base: base}
_ = baseCleanUp // during test, it doesn't need to do clean up. TODO: this can be improved later _ = baseCleanUp // during test, it doesn't need to do clean up. TODO: this can be improved later
chiCtx := chi.NewRouteContext() chiCtx := chi.NewRouteContext()
ctx.Base.AppendContextValue(chi.RouteCtxKey, chiCtx) ctx.Base.AppendContextValue(chi.RouteCtxKey, chiCtx)
return ctx return ctx, resp
} }
// LoadRepo load a repo into a test context. // LoadRepo load a repo into a test context.

@ -9,25 +9,15 @@ import (
"net/http" "net/http"
"reflect" "reflect"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/web/routing" "code.gitea.io/gitea/modules/web/routing"
"code.gitea.io/gitea/modules/web/types"
) )
// ResponseStatusProvider is an interface to check whether the response has been written by the handler var responseStatusProviders = map[reflect.Type]func(req *http.Request) types.ResponseStatusProvider{}
type ResponseStatusProvider interface {
Written() bool
}
// TODO: decouple this from the context package, let the context package register these providers
var argTypeProvider = map[reflect.Type]func(req *http.Request) ResponseStatusProvider{
reflect.TypeOf(&context.APIContext{}): func(req *http.Request) ResponseStatusProvider { return context.GetAPIContext(req) },
reflect.TypeOf(&context.Context{}): func(req *http.Request) ResponseStatusProvider { return context.GetWebContext(req) },
reflect.TypeOf(&context.PrivateContext{}): func(req *http.Request) ResponseStatusProvider { return context.GetPrivateContext(req) },
}
func RegisterHandleTypeProvider[T any](fn func(req *http.Request) ResponseStatusProvider) { func RegisterResponseStatusProvider[T any](fn func(req *http.Request) types.ResponseStatusProvider) {
argTypeProvider[reflect.TypeOf((*T)(nil)).Elem()] = fn responseStatusProviders[reflect.TypeOf((*T)(nil)).Elem()] = fn
} }
// responseWriter is a wrapper of http.ResponseWriter, to check whether the response has been written // responseWriter is a wrapper of http.ResponseWriter, to check whether the response has been written
@ -36,10 +26,10 @@ type responseWriter struct {
status int status int
} }
var _ ResponseStatusProvider = (*responseWriter)(nil) var _ types.ResponseStatusProvider = (*responseWriter)(nil)
func (r *responseWriter) Written() bool { func (r *responseWriter) WrittenStatus() int {
return r.status > 0 return r.status
} }
func (r *responseWriter) Header() http.Header { func (r *responseWriter) Header() http.Header {
@ -68,7 +58,7 @@ var (
func preCheckHandler(fn reflect.Value, argsIn []reflect.Value) { func preCheckHandler(fn reflect.Value, argsIn []reflect.Value) {
hasStatusProvider := false hasStatusProvider := false
for _, argIn := range argsIn { for _, argIn := range argsIn {
if _, hasStatusProvider = argIn.Interface().(ResponseStatusProvider); hasStatusProvider { if _, hasStatusProvider = argIn.Interface().(types.ResponseStatusProvider); hasStatusProvider {
break break
} }
} }
@ -101,7 +91,7 @@ func prepareHandleArgsIn(resp http.ResponseWriter, req *http.Request, fn reflect
case httpReqType: case httpReqType:
argsIn[i] = reflect.ValueOf(req) argsIn[i] = reflect.ValueOf(req)
default: default:
if argFn, ok := argTypeProvider[argTyp]; ok { if argFn, ok := responseStatusProviders[argTyp]; ok {
if isPreCheck { if isPreCheck {
argsIn[i] = reflect.ValueOf(&responseWriter{}) argsIn[i] = reflect.ValueOf(&responseWriter{})
} else { } else {
@ -129,8 +119,8 @@ func handleResponse(fn reflect.Value, ret []reflect.Value) goctx.CancelFunc {
func hasResponseBeenWritten(argsIn []reflect.Value) bool { func hasResponseBeenWritten(argsIn []reflect.Value) bool {
for _, argIn := range argsIn { for _, argIn := range argsIn {
if statusProvider, ok := argIn.Interface().(ResponseStatusProvider); ok { if statusProvider, ok := argIn.Interface().(types.ResponseStatusProvider); ok {
if statusProvider.Written() { if statusProvider.WrittenStatus() != 0 {
return true return true
} }
} }
@ -161,7 +151,7 @@ func toHandlerProvider(handler any) func(next http.Handler) http.Handler {
return http.HandlerFunc(func(respOrig http.ResponseWriter, req *http.Request) { return http.HandlerFunc(func(respOrig http.ResponseWriter, req *http.Request) {
// wrap the response writer to check whether the response has been written // wrap the response writer to check whether the response has been written
resp := respOrig resp := respOrig
if _, ok := resp.(ResponseStatusProvider); !ok { if _, ok := resp.(types.ResponseStatusProvider); !ok {
resp = &responseWriter{respWriter: resp} resp = &responseWriter{respWriter: resp}
} }

@ -17,7 +17,7 @@ type ContextDataStore interface {
type ContextData map[string]any type ContextData map[string]any
func (ds ContextData) GetData() map[string]any { func (ds ContextData) GetData() ContextData {
return ds return ds
} }

@ -7,31 +7,31 @@ import (
"net/http" "net/http"
"strings" "strings"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/modules/web/middleware"
"gitea.com/go-chi/binding" "gitea.com/go-chi/binding"
chi "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
) )
// Bind binding an obj to a handler // Bind binding an obj to a handler's context data
func Bind[T any](_ T) any { func Bind[T any](_ T) http.HandlerFunc {
return func(ctx *context.Context) { return func(resp http.ResponseWriter, req *http.Request) {
theObj := new(T) // create a new form obj for every request but not use obj directly theObj := new(T) // create a new form obj for every request but not use obj directly
binding.Bind(ctx.Req, theObj) data := middleware.GetContextData(req.Context())
SetForm(ctx, theObj) binding.Bind(req, theObj)
middleware.AssignForm(theObj, ctx.Data) SetForm(data, theObj)
middleware.AssignForm(theObj, data)
} }
} }
// SetForm set the form object // SetForm set the form object
func SetForm(data middleware.ContextDataStore, obj interface{}) { func SetForm(dataStore middleware.ContextDataStore, obj interface{}) {
data.GetData()["__form"] = obj dataStore.GetData()["__form"] = obj
} }
// GetForm returns the validate form information // GetForm returns the validate form information
func GetForm(data middleware.ContextDataStore) interface{} { func GetForm(dataStore middleware.ContextDataStore) interface{} {
return data.GetData()["__form"] return dataStore.GetData()["__form"]
} }
// Route defines a route based on chi's router // Route defines a route based on chi's router

@ -8,8 +8,8 @@ import (
"strings" "strings"
"time" "time"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/web/types"
) )
// NewLoggerHandler is a handler that will log routing to the router log taking account of // NewLoggerHandler is a handler that will log routing to the router log taking account of
@ -86,8 +86,8 @@ func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) {
} }
var status int var status int
if v, ok := record.responseWriter.(context.ResponseWriter); ok { if v, ok := record.responseWriter.(types.ResponseStatusProvider); ok {
status = v.Status() status = v.WrittenStatus()
} }
logf := log.Info logf := log.Info
if strings.HasPrefix(req.RequestURI, "/assets/") { if strings.HasPrefix(req.RequestURI, "/assets/") {

@ -0,0 +1,10 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package types
// ResponseStatusProvider is an interface to get the written status in the response
// Many packages need this interface, so put it in the separate package to avoid import cycle
type ResponseStatusProvider interface {
WrittenStatus() int
}

@ -4,7 +4,6 @@
package actions package actions
import ( import (
"context"
"net/http" "net/http"
"code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web"
@ -12,7 +11,7 @@ import (
"code.gitea.io/gitea/routers/api/actions/runner" "code.gitea.io/gitea/routers/api/actions/runner"
) )
func Routes(_ context.Context, prefix string) *web.Route { func Routes(prefix string) *web.Route {
m := web.NewRoute() m := web.NewRoute()
path, handler := ping.NewPingServiceHandler() path, handler := ping.NewPingServiceHandler()

@ -82,6 +82,7 @@ import (
"code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/storage"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web"
web_types "code.gitea.io/gitea/modules/web/types"
) )
const ( const (
@ -102,7 +103,7 @@ type ArtifactContext struct {
} }
func init() { func init() {
web.RegisterHandleTypeProvider[*ArtifactContext](func(req *http.Request) web.ResponseStatusProvider { web.RegisterResponseStatusProvider[*ArtifactContext](func(req *http.Request) web_types.ResponseStatusProvider {
return req.Context().Value(artifactContextKey).(*ArtifactContext) return req.Context().Value(artifactContextKey).(*ArtifactContext)
}) })
} }

@ -4,7 +4,6 @@
package packages package packages
import ( import (
gocontext "context"
"net/http" "net/http"
"regexp" "regexp"
"strings" "strings"
@ -96,7 +95,7 @@ func verifyAuth(r *web.Route, authMethods []auth.Method) {
// CommonRoutes provide endpoints for most package managers (except containers - see below) // CommonRoutes provide endpoints for most package managers (except containers - see below)
// These are mounted on `/api/packages` (not `/api/v1/packages`) // These are mounted on `/api/packages` (not `/api/v1/packages`)
func CommonRoutes(ctx gocontext.Context) *web.Route { func CommonRoutes() *web.Route {
r := web.NewRoute() r := web.NewRoute()
r.Use(context.PackageContexter()) r.Use(context.PackageContexter())
@ -590,7 +589,7 @@ func CommonRoutes(ctx gocontext.Context) *web.Route {
// ContainerRoutes provides endpoints that implement the OCI API to serve containers // ContainerRoutes provides endpoints that implement the OCI API to serve containers
// These have to be mounted on `/v2/...` to comply with the OCI spec: // These have to be mounted on `/v2/...` to comply with the OCI spec:
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md // https://github.com/opencontainers/distribution-spec/blob/main/spec.md
func ContainerRoutes(ctx gocontext.Context) *web.Route { func ContainerRoutes() *web.Route {
r := web.NewRoute() r := web.NewRoute()
r.Use(context.PackageContexter()) r.Use(context.PackageContexter())

@ -64,7 +64,6 @@
package v1 package v1
import ( import (
gocontext "context"
"fmt" "fmt"
"net/http" "net/http"
"strings" "strings"
@ -705,7 +704,7 @@ func buildAuthGroup() *auth.Group {
} }
// Routes registers all v1 APIs routes to web application. // Routes registers all v1 APIs routes to web application.
func Routes(ctx gocontext.Context) *web.Route { func Routes() *web.Route {
m := web.NewRoute() m := web.NewRoute()
m.Use(securityHeaders()) m.Use(securityHeaders())
@ -722,13 +721,8 @@ func Routes(ctx gocontext.Context) *web.Route {
} }
m.Use(context.APIContexter()) m.Use(context.APIContexter())
group := buildAuthGroup()
if err := group.Init(ctx); err != nil {
log.Error("Could not initialize '%s' auth method, error: %s", group.Name(), err)
}
// Get user from session if logged in. // Get user from session if logged in.
m.Use(auth.APIAuth(group)) m.Use(auth.APIAuth(buildAuthGroup()))
m.Use(auth.VerifyAuthWithOptionsAPI(&auth.VerifyOptions{ m.Use(auth.VerifyAuthWithOptionsAPI(&auth.VerifyOptions{
SignInRequired: setting.Service.RequireSignInView, SignInRequired: setting.Service.RequireSignInView,

@ -7,18 +7,14 @@ import (
go_context "context" go_context "context"
"io" "io"
"net/http" "net/http"
"net/http/httptest"
"net/url"
"strings" "strings"
"testing" "testing"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/modules/web/middleware"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -29,34 +25,16 @@ const (
AppSubURL = AppURL + Repo + "/" AppSubURL = AppURL + Repo + "/"
) )
func createAPIContext(req *http.Request) (*context.APIContext, *httptest.ResponseRecorder) {
resp := httptest.NewRecorder()
base, baseCleanUp := context.NewBaseContext(resp, req)
base.Data = middleware.ContextData{}
c := &context.APIContext{Base: base}
_ = baseCleanUp // during test, it doesn't need to do clean up. TODO: this can be improved later
return c, resp
}
func testRenderMarkup(t *testing.T, mode, filePath, text, responseBody string, responseCode int) { func testRenderMarkup(t *testing.T, mode, filePath, text, responseBody string, responseCode int) {
setting.AppURL = AppURL setting.AppURL = AppURL
options := api.MarkupOption{ options := api.MarkupOption{
Mode: mode, Mode: mode,
Text: "", Text: text,
Context: Repo, Context: Repo,
Wiki: true, Wiki: true,
FilePath: filePath, FilePath: filePath,
} }
requrl, _ := url.Parse(util.URLJoin(AppURL, "api", "v1", "markup")) ctx, resp := test.MockAPIContext(t, "POST /api/v1/markup")
req := &http.Request{
Method: "POST",
URL: requrl,
}
ctx, resp := createAPIContext(req)
options.Text = text
web.SetForm(ctx, &options) web.SetForm(ctx, &options)
Markup(ctx) Markup(ctx)
assert.Equal(t, responseBody, resp.Body.String()) assert.Equal(t, responseBody, resp.Body.String())
@ -66,21 +44,13 @@ func testRenderMarkup(t *testing.T, mode, filePath, text, responseBody string, r
func testRenderMarkdown(t *testing.T, mode, text, responseBody string, responseCode int) { func testRenderMarkdown(t *testing.T, mode, text, responseBody string, responseCode int) {
setting.AppURL = AppURL setting.AppURL = AppURL
options := api.MarkdownOption{ options := api.MarkdownOption{
Mode: mode, Mode: mode,
Text: "", Text: text,
Context: Repo, Context: Repo,
Wiki: true, Wiki: true,
} }
requrl, _ := url.Parse(util.URLJoin(AppURL, "api", "v1", "markdown")) ctx, resp := test.MockAPIContext(t, "POST /api/v1/markdown")
req := &http.Request{
Method: "POST",
URL: requrl,
}
ctx, resp := createAPIContext(req)
options.Text = text
web.SetForm(ctx, &options) web.SetForm(ctx, &options)
Markdown(ctx) Markdown(ctx)
assert.Equal(t, responseBody, resp.Body.String()) assert.Equal(t, responseBody, resp.Body.String())
@ -187,19 +157,12 @@ var simpleCases = []string{
func TestAPI_RenderSimple(t *testing.T) { func TestAPI_RenderSimple(t *testing.T) {
setting.AppURL = AppURL setting.AppURL = AppURL
options := api.MarkdownOption{ options := api.MarkdownOption{
Mode: "markdown", Mode: "markdown",
Text: "", Text: "",
Context: Repo, Context: Repo,
} }
requrl, _ := url.Parse(util.URLJoin(AppURL, "api", "v1", "markdown")) ctx, resp := test.MockAPIContext(t, "POST /api/v1/markdown")
req := &http.Request{
Method: "POST",
URL: requrl,
}
ctx, resp := createAPIContext(req)
for i := 0; i < len(simpleCases); i += 2 { for i := 0; i < len(simpleCases); i += 2 {
options.Text = simpleCases[i] options.Text = simpleCases[i]
web.SetForm(ctx, &options) web.SetForm(ctx, &options)
@ -211,14 +174,7 @@ func TestAPI_RenderSimple(t *testing.T) {
func TestAPI_RenderRaw(t *testing.T) { func TestAPI_RenderRaw(t *testing.T) {
setting.AppURL = AppURL setting.AppURL = AppURL
ctx, resp := test.MockAPIContext(t, "POST /api/v1/markdown")
requrl, _ := url.Parse(util.URLJoin(AppURL, "api", "v1", "markdown"))
req := &http.Request{
Method: "POST",
URL: requrl,
}
ctx, resp := createAPIContext(req)
for i := 0; i < len(simpleCases); i += 2 { for i := 0; i < len(simpleCases); i += 2 {
ctx.Req.Body = io.NopCloser(strings.NewReader(simpleCases[i])) ctx.Req.Body = io.NopCloser(strings.NewReader(simpleCases[i]))
MarkdownRaw(ctx) MarkdownRaw(ctx)

@ -17,7 +17,7 @@ import (
func TestTestHook(t *testing.T) { func TestTestHook(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockAPIContext(t, "user2/repo1/wiki/_pages") ctx, _ := test.MockAPIContext(t, "user2/repo1/wiki/_pages")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)

@ -19,7 +19,7 @@ import (
func TestRepoEdit(t *testing.T) { func TestRepoEdit(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockAPIContext(t, "user2/repo1") ctx, _ := test.MockAPIContext(t, "user2/repo1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
ctx.Repo.Owner = ctx.Doer ctx.Repo.Owner = ctx.Doer
@ -65,7 +65,7 @@ func TestRepoEdit(t *testing.T) {
func TestRepoEditNameChange(t *testing.T) { func TestRepoEditNameChange(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockAPIContext(t, "user2/repo1") ctx, _ := test.MockAPIContext(t, "user2/repo1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
ctx.Repo.Owner = ctx.Doer ctx.Repo.Owner = ctx.Doer

@ -174,27 +174,27 @@ func GlobalInitInstalled(ctx context.Context) {
} }
// NormalRoutes represents non install routes // NormalRoutes represents non install routes
func NormalRoutes(ctx context.Context) *web.Route { func NormalRoutes() *web.Route {
_ = templates.HTMLRenderer() _ = templates.HTMLRenderer()
r := web.NewRoute() r := web.NewRoute()
r.Use(common.ProtocolMiddlewares()...) r.Use(common.ProtocolMiddlewares()...)
r.Mount("/", web_routers.Routes(ctx)) r.Mount("/", web_routers.Routes())
r.Mount("/api/v1", apiv1.Routes(ctx)) r.Mount("/api/v1", apiv1.Routes())
r.Mount("/api/internal", private.Routes()) r.Mount("/api/internal", private.Routes())
r.Post("/-/fetch-redirect", common.FetchRedirectDelegate) r.Post("/-/fetch-redirect", common.FetchRedirectDelegate)
if setting.Packages.Enabled { if setting.Packages.Enabled {
// This implements package support for most package managers // This implements package support for most package managers
r.Mount("/api/packages", packages_router.CommonRoutes(ctx)) r.Mount("/api/packages", packages_router.CommonRoutes())
// This implements the OCI API (Note this is not preceded by /api but is instead /v2) // This implements the OCI API (Note this is not preceded by /api but is instead /v2)
r.Mount("/v2", packages_router.ContainerRoutes(ctx)) r.Mount("/v2", packages_router.ContainerRoutes())
} }
if setting.Actions.Enabled { if setting.Actions.Enabled {
prefix := "/api/actions" prefix := "/api/actions"
r.Mount(prefix, actions_router.Routes(ctx, prefix)) r.Mount(prefix, actions_router.Routes(prefix))
// TODO: Pipeline api used for runner internal communication with gitea server. but only artifact is used for now. // TODO: Pipeline api used for runner internal communication with gitea server. but only artifact is used for now.
// In Github, it uses ACTIONS_RUNTIME_URL=https://pipelines.actions.githubusercontent.com/fLgcSHkPGySXeIFrg8W8OBSfeg3b5Fls1A1CwX566g8PayEGlg/ // In Github, it uses ACTIONS_RUNTIME_URL=https://pipelines.actions.githubusercontent.com/fLgcSHkPGySXeIFrg8W8OBSfeg3b5Fls1A1CwX566g8PayEGlg/

@ -19,7 +19,7 @@ import (
func TestNewUserPost_MustChangePassword(t *testing.T) { func TestNewUserPost_MustChangePassword(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "admin/users/new") ctx, _ := test.MockContext(t, "admin/users/new")
u := unittest.AssertExistsAndLoadBean(t, &user_model.User{ u := unittest.AssertExistsAndLoadBean(t, &user_model.User{
IsAdmin: true, IsAdmin: true,
@ -56,7 +56,7 @@ func TestNewUserPost_MustChangePassword(t *testing.T) {
func TestNewUserPost_MustChangePasswordFalse(t *testing.T) { func TestNewUserPost_MustChangePasswordFalse(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "admin/users/new") ctx, _ := test.MockContext(t, "admin/users/new")
u := unittest.AssertExistsAndLoadBean(t, &user_model.User{ u := unittest.AssertExistsAndLoadBean(t, &user_model.User{
IsAdmin: true, IsAdmin: true,
@ -93,7 +93,7 @@ func TestNewUserPost_MustChangePasswordFalse(t *testing.T) {
func TestNewUserPost_InvalidEmail(t *testing.T) { func TestNewUserPost_InvalidEmail(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "admin/users/new") ctx, _ := test.MockContext(t, "admin/users/new")
u := unittest.AssertExistsAndLoadBean(t, &user_model.User{ u := unittest.AssertExistsAndLoadBean(t, &user_model.User{
IsAdmin: true, IsAdmin: true,
@ -123,7 +123,7 @@ func TestNewUserPost_InvalidEmail(t *testing.T) {
func TestNewUserPost_VisibilityDefaultPublic(t *testing.T) { func TestNewUserPost_VisibilityDefaultPublic(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "admin/users/new") ctx, _ := test.MockContext(t, "admin/users/new")
u := unittest.AssertExistsAndLoadBean(t, &user_model.User{ u := unittest.AssertExistsAndLoadBean(t, &user_model.User{
IsAdmin: true, IsAdmin: true,
@ -161,7 +161,7 @@ func TestNewUserPost_VisibilityDefaultPublic(t *testing.T) {
func TestNewUserPost_VisibilityPrivate(t *testing.T) { func TestNewUserPost_VisibilityPrivate(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "admin/users/new") ctx, _ := test.MockContext(t, "admin/users/new")
u := unittest.AssertExistsAndLoadBean(t, &user_model.User{ u := unittest.AssertExistsAndLoadBean(t, &user_model.User{
IsAdmin: true, IsAdmin: true,

@ -15,7 +15,7 @@ import (
func TestCheckProjectBoardChangePermissions(t *testing.T) { func TestCheckProjectBoardChangePermissions(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/-/projects/4/4") ctx, _ := test.MockContext(t, "user2/-/projects/4/4")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
ctx.ContextUser = ctx.Doer // user2 ctx.ContextUser = ctx.Doer // user2
ctx.SetParams(":id", "4") ctx.SetParams(":id", "4")

@ -41,7 +41,7 @@ func TestCleanUploadName(t *testing.T) {
func TestGetUniquePatchBranchName(t *testing.T) { func TestGetUniquePatchBranchName(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
@ -56,7 +56,7 @@ func TestGetUniquePatchBranchName(t *testing.T) {
func TestGetClosestParentWithFiles(t *testing.T) { func TestGetClosestParentWithFiles(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)

@ -32,7 +32,7 @@ func int64SliceToCommaSeparated(a []int64) string {
func TestInitializeLabels(t *testing.T) { func TestInitializeLabels(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
assert.NoError(t, repository.LoadRepoConfig()) assert.NoError(t, repository.LoadRepoConfig())
ctx := test.MockContext(t, "user2/repo1/labels/initialize") ctx, _ := test.MockContext(t, "user2/repo1/labels/initialize")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 2) test.LoadRepo(t, ctx, 2)
web.SetForm(ctx, &forms.InitializeLabelsForm{TemplateName: "Default"}) web.SetForm(ctx, &forms.InitializeLabelsForm{TemplateName: "Default"})
@ -57,7 +57,7 @@ func TestRetrieveLabels(t *testing.T) {
{1, "leastissues", []int64{2, 1}}, {1, "leastissues", []int64{2, 1}},
{2, "", []int64{}}, {2, "", []int64{}},
} { } {
ctx := test.MockContext(t, "user/repo/issues") ctx, _ := test.MockContext(t, "user/repo/issues")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, testCase.RepoID) test.LoadRepo(t, ctx, testCase.RepoID)
ctx.Req.Form.Set("sort", testCase.Sort) ctx.Req.Form.Set("sort", testCase.Sort)
@ -75,7 +75,7 @@ func TestRetrieveLabels(t *testing.T) {
func TestNewLabel(t *testing.T) { func TestNewLabel(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/labels/edit") ctx, _ := test.MockContext(t, "user2/repo1/labels/edit")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
web.SetForm(ctx, &forms.CreateLabelForm{ web.SetForm(ctx, &forms.CreateLabelForm{
@ -93,7 +93,7 @@ func TestNewLabel(t *testing.T) {
func TestUpdateLabel(t *testing.T) { func TestUpdateLabel(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/labels/edit") ctx, _ := test.MockContext(t, "user2/repo1/labels/edit")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
web.SetForm(ctx, &forms.CreateLabelForm{ web.SetForm(ctx, &forms.CreateLabelForm{
@ -113,7 +113,7 @@ func TestUpdateLabel(t *testing.T) {
func TestDeleteLabel(t *testing.T) { func TestDeleteLabel(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/labels/delete") ctx, _ := test.MockContext(t, "user2/repo1/labels/delete")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
ctx.Req.Form.Set("id", "2") ctx.Req.Form.Set("id", "2")
@ -126,7 +126,7 @@ func TestDeleteLabel(t *testing.T) {
func TestUpdateIssueLabel_Clear(t *testing.T) { func TestUpdateIssueLabel_Clear(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/issues/labels") ctx, _ := test.MockContext(t, "user2/repo1/issues/labels")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
ctx.Req.Form.Set("issue_ids", "1,3") ctx.Req.Form.Set("issue_ids", "1,3")
@ -151,7 +151,7 @@ func TestUpdateIssueLabel_Toggle(t *testing.T) {
{"toggle", []int64{1, 2}, 2, true}, {"toggle", []int64{1, 2}, 2, true},
} { } {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/issues/labels") ctx, _ := test.MockContext(t, "user2/repo1/issues/labels")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
ctx.Req.Form.Set("issue_ids", int64SliceToCommaSeparated(testCase.IssueIDs)) ctx.Req.Form.Set("issue_ids", int64SliceToCommaSeparated(testCase.IssueIDs))

@ -14,7 +14,7 @@ import (
func TestCheckProjectBoardChangePermissions(t *testing.T) { func TestCheckProjectBoardChangePermissions(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/projects/1/2") ctx, _ := test.MockContext(t, "user2/repo1/projects/1/2")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")

@ -47,7 +47,7 @@ func TestNewReleasePost(t *testing.T) {
} { } {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/releases/new") ctx, _ := test.MockContext(t, "user2/repo1/releases/new")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)
@ -67,7 +67,7 @@ func TestNewReleasePost(t *testing.T) {
func TestNewReleasesList(t *testing.T) { func TestNewReleasesList(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo-release/releases") ctx, _ := test.MockContext(t, "user2/repo-release/releases")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 57) test.LoadRepo(t, ctx, 57)
test.LoadGitRepo(t, ctx) test.LoadGitRepo(t, ctx)

@ -42,7 +42,7 @@ func TestAddReadOnlyDeployKey(t *testing.T) {
} }
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/settings/keys") ctx, _ := test.MockContext(t, "user2/repo1/settings/keys")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 2) test.LoadRepo(t, ctx, 2)
@ -71,7 +71,7 @@ func TestAddReadWriteOnlyDeployKey(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/settings/keys") ctx, _ := test.MockContext(t, "user2/repo1/settings/keys")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 2) test.LoadRepo(t, ctx, 2)
@ -94,7 +94,7 @@ func TestAddReadWriteOnlyDeployKey(t *testing.T) {
func TestCollaborationPost(t *testing.T) { func TestCollaborationPost(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/issues/labels") ctx, _ := test.MockContext(t, "user2/repo1/issues/labels")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadUser(t, ctx, 4) test.LoadUser(t, ctx, 4)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
@ -129,7 +129,7 @@ func TestCollaborationPost(t *testing.T) {
func TestCollaborationPost_InactiveUser(t *testing.T) { func TestCollaborationPost_InactiveUser(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/issues/labels") ctx, _ := test.MockContext(t, "user2/repo1/issues/labels")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadUser(t, ctx, 9) test.LoadUser(t, ctx, 9)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
@ -152,7 +152,7 @@ func TestCollaborationPost_InactiveUser(t *testing.T) {
func TestCollaborationPost_AddCollaboratorTwice(t *testing.T) { func TestCollaborationPost_AddCollaboratorTwice(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/issues/labels") ctx, _ := test.MockContext(t, "user2/repo1/issues/labels")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadUser(t, ctx, 4) test.LoadUser(t, ctx, 4)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
@ -193,7 +193,7 @@ func TestCollaborationPost_AddCollaboratorTwice(t *testing.T) {
func TestCollaborationPost_NonExistentUser(t *testing.T) { func TestCollaborationPost_NonExistentUser(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/issues/labels") ctx, _ := test.MockContext(t, "user2/repo1/issues/labels")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
@ -215,7 +215,7 @@ func TestCollaborationPost_NonExistentUser(t *testing.T) {
func TestAddTeamPost(t *testing.T) { func TestAddTeamPost(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "org26/repo43") ctx, _ := test.MockContext(t, "org26/repo43")
ctx.Req.Form.Set("team", "team11") ctx.Req.Form.Set("team", "team11")
@ -255,7 +255,7 @@ func TestAddTeamPost(t *testing.T) {
func TestAddTeamPost_NotAllowed(t *testing.T) { func TestAddTeamPost_NotAllowed(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "org26/repo43") ctx, _ := test.MockContext(t, "org26/repo43")
ctx.Req.Form.Set("team", "team11") ctx.Req.Form.Set("team", "team11")
@ -295,7 +295,7 @@ func TestAddTeamPost_NotAllowed(t *testing.T) {
func TestAddTeamPost_AddTeamTwice(t *testing.T) { func TestAddTeamPost_AddTeamTwice(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "org26/repo43") ctx, _ := test.MockContext(t, "org26/repo43")
ctx.Req.Form.Set("team", "team11") ctx.Req.Form.Set("team", "team11")
@ -336,7 +336,7 @@ func TestAddTeamPost_AddTeamTwice(t *testing.T) {
func TestAddTeamPost_NonExistentTeam(t *testing.T) { func TestAddTeamPost_NonExistentTeam(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "org26/repo43") ctx, _ := test.MockContext(t, "org26/repo43")
ctx.Req.Form.Set("team", "team-non-existent") ctx.Req.Form.Set("team", "team-non-existent")
@ -369,7 +369,7 @@ func TestAddTeamPost_NonExistentTeam(t *testing.T) {
func TestDeleteTeam(t *testing.T) { func TestDeleteTeam(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "org3/team1/repo3") ctx, _ := test.MockContext(t, "org3/team1/repo3")
ctx.Req.Form.Set("id", "2") ctx.Req.Form.Set("id", "2")

@ -78,7 +78,7 @@ func assertPagesMetas(t *testing.T, expectedNames []string, metas interface{}) {
func TestWiki(t *testing.T) { func TestWiki(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/wiki/?action=_pages") ctx, _ := test.MockContext(t, "user2/repo1/wiki/?action=_pages")
ctx.SetParams("*", "Home") ctx.SetParams("*", "Home")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
Wiki(ctx) Wiki(ctx)
@ -90,7 +90,7 @@ func TestWiki(t *testing.T) {
func TestWikiPages(t *testing.T) { func TestWikiPages(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/wiki/?action=_pages") ctx, _ := test.MockContext(t, "user2/repo1/wiki/?action=_pages")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
WikiPages(ctx) WikiPages(ctx)
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
@ -100,7 +100,7 @@ func TestWikiPages(t *testing.T) {
func TestNewWiki(t *testing.T) { func TestNewWiki(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/wiki/?action=_new") ctx, _ := test.MockContext(t, "user2/repo1/wiki/?action=_new")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
NewWiki(ctx) NewWiki(ctx)
@ -115,7 +115,7 @@ func TestNewWikiPost(t *testing.T) {
} { } {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/wiki/?action=_new") ctx, _ := test.MockContext(t, "user2/repo1/wiki/?action=_new")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
web.SetForm(ctx, &forms.NewWikiForm{ web.SetForm(ctx, &forms.NewWikiForm{
@ -133,7 +133,7 @@ func TestNewWikiPost(t *testing.T) {
func TestNewWikiPost_ReservedName(t *testing.T) { func TestNewWikiPost_ReservedName(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/wiki/?action=_new") ctx, _ := test.MockContext(t, "user2/repo1/wiki/?action=_new")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
web.SetForm(ctx, &forms.NewWikiForm{ web.SetForm(ctx, &forms.NewWikiForm{
@ -150,7 +150,7 @@ func TestNewWikiPost_ReservedName(t *testing.T) {
func TestEditWiki(t *testing.T) { func TestEditWiki(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/wiki/Home?action=_edit") ctx, _ := test.MockContext(t, "user2/repo1/wiki/Home?action=_edit")
ctx.SetParams("*", "Home") ctx.SetParams("*", "Home")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
@ -166,7 +166,7 @@ func TestEditWikiPost(t *testing.T) {
"New/<page>", "New/<page>",
} { } {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/wiki/Home?action=_new") ctx, _ := test.MockContext(t, "user2/repo1/wiki/Home?action=_new")
ctx.SetParams("*", "Home") ctx.SetParams("*", "Home")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
@ -188,7 +188,7 @@ func TestEditWikiPost(t *testing.T) {
func TestDeleteWikiPagePost(t *testing.T) { func TestDeleteWikiPagePost(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/wiki/Home?action=_delete") ctx, _ := test.MockContext(t, "user2/repo1/wiki/Home?action=_delete")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
DeleteWikiPagePost(ctx) DeleteWikiPagePost(ctx)
@ -207,7 +207,7 @@ func TestWikiRaw(t *testing.T) {
} { } {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1/wiki/raw/"+url.PathEscape(filepath)) ctx, _ := test.MockContext(t, "user2/repo1/wiki/raw/"+url.PathEscape(filepath))
ctx.SetParams("*", filepath) ctx.SetParams("*", filepath)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)

@ -20,7 +20,7 @@ func TestArchivedIssues(t *testing.T) {
setting.UI.IssuePagingNum = 1 setting.UI.IssuePagingNum = 1
assert.NoError(t, unittest.LoadFixtures()) assert.NoError(t, unittest.LoadFixtures())
ctx := test.MockContext(t, "issues") ctx, _ := test.MockContext(t, "issues")
test.LoadUser(t, ctx, 30) test.LoadUser(t, ctx, 30)
ctx.Req.Form.Set("state", "open") ctx.Req.Form.Set("state", "open")
@ -53,7 +53,7 @@ func TestIssues(t *testing.T) {
setting.UI.IssuePagingNum = 1 setting.UI.IssuePagingNum = 1
assert.NoError(t, unittest.LoadFixtures()) assert.NoError(t, unittest.LoadFixtures())
ctx := test.MockContext(t, "issues") ctx, _ := test.MockContext(t, "issues")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
ctx.Req.Form.Set("state", "closed") ctx.Req.Form.Set("state", "closed")
Issues(ctx) Issues(ctx)
@ -69,7 +69,7 @@ func TestPulls(t *testing.T) {
setting.UI.IssuePagingNum = 20 setting.UI.IssuePagingNum = 20
assert.NoError(t, unittest.LoadFixtures()) assert.NoError(t, unittest.LoadFixtures())
ctx := test.MockContext(t, "pulls") ctx, _ := test.MockContext(t, "pulls")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
ctx.Req.Form.Set("state", "open") ctx.Req.Form.Set("state", "open")
Pulls(ctx) Pulls(ctx)
@ -82,7 +82,7 @@ func TestMilestones(t *testing.T) {
setting.UI.IssuePagingNum = 1 setting.UI.IssuePagingNum = 1
assert.NoError(t, unittest.LoadFixtures()) assert.NoError(t, unittest.LoadFixtures())
ctx := test.MockContext(t, "milestones") ctx, _ := test.MockContext(t, "milestones")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
ctx.SetParams("sort", "issues") ctx.SetParams("sort", "issues")
ctx.Req.Form.Set("state", "closed") ctx.Req.Form.Set("state", "closed")
@ -101,7 +101,7 @@ func TestMilestonesForSpecificRepo(t *testing.T) {
setting.UI.IssuePagingNum = 1 setting.UI.IssuePagingNum = 1
assert.NoError(t, unittest.LoadFixtures()) assert.NoError(t, unittest.LoadFixtures())
ctx := test.MockContext(t, "milestones") ctx, _ := test.MockContext(t, "milestones")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
ctx.SetParams("sort", "issues") ctx.SetParams("sort", "issues")
ctx.SetParams("repo", "1") ctx.SetParams("repo", "1")

@ -83,7 +83,7 @@ func TestChangePassword(t *testing.T) {
t.Run(req.OldPassword+"__"+req.NewPassword, func(t *testing.T) { t.Run(req.OldPassword+"__"+req.NewPassword, func(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
setting.PasswordComplexity = req.PasswordComplexity setting.PasswordComplexity = req.PasswordComplexity
ctx := test.MockContext(t, "user/settings/security") ctx, _ := test.MockContext(t, "user/settings/security")
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)

@ -104,7 +104,7 @@ func ctxDataSet(args ...any) func(ctx *context.Context) {
} }
// Routes returns all web routes // Routes returns all web routes
func Routes(ctx gocontext.Context) *web.Route { func Routes() *web.Route {
routes := web.NewRoute() routes := web.NewRoute()
routes.Head("/", misc.DummyOK) // for health check - doesn't need to be passed through gzip handler routes.Head("/", misc.DummyOK) // for health check - doesn't need to be passed through gzip handler
@ -146,13 +146,8 @@ func Routes(ctx gocontext.Context) *web.Route {
mid = append(mid, common.Sessioner(), context.Contexter()) mid = append(mid, common.Sessioner(), context.Contexter())
group := buildAuthGroup()
if err := group.Init(ctx); err != nil {
log.Error("Could not initialize '%s' auth method, error: %s", group.Name(), err)
}
// Get user from session if logged in. // Get user from session if logged in.
mid = append(mid, auth_service.Auth(group)) mid = append(mid, auth_service.Auth(buildAuthGroup()))
// GetHead allows a HEAD request redirect to GET if HEAD method is not defined for that route // GetHead allows a HEAD request redirect to GET if HEAD method is not defined for that route
mid = append(mid, middleware.GetHead) mid = append(mid, middleware.GetHead)

@ -4,7 +4,6 @@
package auth package auth
import ( import (
"context"
"net/http" "net/http"
"reflect" "reflect"
"strings" "strings"
@ -14,9 +13,7 @@ import (
// Ensure the struct implements the interface. // Ensure the struct implements the interface.
var ( var (
_ Method = &Group{} _ Method = &Group{}
_ Initializable = &Group{}
_ Freeable = &Group{}
) )
// Group implements the Auth interface with serval Auth. // Group implements the Auth interface with serval Auth.
@ -49,35 +46,6 @@ func (b *Group) Name() string {
return strings.Join(names, ",") return strings.Join(names, ",")
} }
// Init does nothing as the Basic implementation does not need to allocate any resources
func (b *Group) Init(ctx context.Context) error {
for _, method := range b.methods {
initializable, ok := method.(Initializable)
if !ok {
continue
}
if err := initializable.Init(ctx); err != nil {
return err
}
}
return nil
}
// Free does nothing as the Basic implementation does not have to release any resources
func (b *Group) Free() error {
for _, method := range b.methods {
freeable, ok := method.(Freeable)
if !ok {
continue
}
if err := freeable.Free(); err != nil {
return err
}
}
return nil
}
// Verify extracts and validates // Verify extracts and validates
func (b *Group) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) { func (b *Group) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) {
// Try to sign in with each of the enabled plugins // Try to sign in with each of the enabled plugins

@ -29,26 +29,11 @@ type Method interface {
Verify(http *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) Verify(http *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error)
} }
// Initializable represents a structure that requires initialization
// It usually should only be called once before anything else is called
type Initializable interface {
// Init should be called exactly once before using any of the other methods,
// in order to allow the plugin to allocate necessary resources
Init(ctx context.Context) error
}
// Named represents a named thing // Named represents a named thing
type Named interface { type Named interface {
Name() string Name() string
} }
// Freeable represents a structure that is required to be freed
type Freeable interface {
// Free should be called exactly once before application closes, in order to
// give chance to the plugin to free any allocated resources
Free() error
}
// PasswordAuthenticator represents a source of authentication // PasswordAuthenticator represents a source of authentication
type PasswordAuthenticator interface { type PasswordAuthenticator interface {
Authenticate(user *user_model.User, login, password string) (*user_model.User, error) Authenticate(user *user_model.User, login, password string) (*user_model.User, error)

@ -4,10 +4,10 @@
package auth package auth
import ( import (
"context"
"errors" "errors"
"net/http" "net/http"
"strings" "strings"
"sync"
"code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/avatars" "code.gitea.io/gitea/models/avatars"
@ -32,13 +32,12 @@ var (
// sspiAuth is a global instance of the websspi authentication package, // sspiAuth is a global instance of the websspi authentication package,
// which is used to avoid acquiring the server credential handle on // which is used to avoid acquiring the server credential handle on
// every request // every request
sspiAuth *websspi.Authenticator sspiAuth *websspi.Authenticator
sspiAuthOnce sync.Once
// Ensure the struct implements the interface. // Ensure the struct implements the interface.
_ Method = &SSPI{} _ Method = &SSPI{}
_ Named = &SSPI{} _ Named = &SSPI{}
_ Initializable = &SSPI{}
_ Freeable = &SSPI{}
) )
// SSPI implements the SingleSignOn interface and authenticates requests // SSPI implements the SingleSignOn interface and authenticates requests
@ -47,32 +46,25 @@ var (
// Returns nil if authentication fails. // Returns nil if authentication fails.
type SSPI struct{} type SSPI struct{}
// Init creates a new global websspi.Authenticator object
func (s *SSPI) Init(ctx context.Context) error {
config := websspi.NewConfig()
var err error
sspiAuth, err = websspi.New(config)
if err != nil {
return err
}
return nil
}
// Name represents the name of auth method // Name represents the name of auth method
func (s *SSPI) Name() string { func (s *SSPI) Name() string {
return "sspi" return "sspi"
} }
// Free releases resources used by the global websspi.Authenticator object
func (s *SSPI) Free() error {
return sspiAuth.Free()
}
// Verify uses SSPI (Windows implementation of SPNEGO) to authenticate the request. // Verify uses SSPI (Windows implementation of SPNEGO) to authenticate the request.
// If authentication is successful, returns the corresponding user object. // If authentication is successful, returns the corresponding user object.
// If negotiation should continue or authentication fails, immediately returns a 401 HTTP // If negotiation should continue or authentication fails, immediately returns a 401 HTTP
// response code, as required by the SPNEGO protocol. // response code, as required by the SPNEGO protocol.
func (s *SSPI) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) { func (s *SSPI) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) {
var errInit error
sspiAuthOnce.Do(func() {
config := websspi.NewConfig()
sspiAuth, errInit = websspi.New(config)
})
if errInit != nil {
return nil, errInit
}
if !s.shouldAuthenticate(req) { if !s.shouldAuthenticate(req) {
return nil, nil return nil, nil
} }

@ -24,7 +24,7 @@ func TestMain(m *testing.M) {
func TestArchive_Basic(t *testing.T) { func TestArchive_Basic(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
ctx := test.MockContext(t, "user27/repo49") ctx, _ := test.MockContext(t, "user27/repo49")
firstCommit, secondCommit := "51f84af23134", "aacbdfe9e1c4" firstCommit, secondCommit := "51f84af23134", "aacbdfe9e1c4"
test.LoadRepo(t, ctx, 49) test.LoadRepo(t, ctx, 49)

@ -54,7 +54,7 @@ func getExpectedReadmeContentsResponse() *api.ContentsResponse {
func TestGetContents(t *testing.T) { func TestGetContents(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
@ -82,7 +82,7 @@ func TestGetContents(t *testing.T) {
func TestGetContentsOrListForDir(t *testing.T) { func TestGetContentsOrListForDir(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
@ -117,7 +117,7 @@ func TestGetContentsOrListForDir(t *testing.T) {
func TestGetContentsOrListForFile(t *testing.T) { func TestGetContentsOrListForFile(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
@ -145,7 +145,7 @@ func TestGetContentsOrListForFile(t *testing.T) {
func TestGetContentsErrors(t *testing.T) { func TestGetContentsErrors(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
@ -176,7 +176,7 @@ func TestGetContentsErrors(t *testing.T) {
func TestGetContentsOrListErrors(t *testing.T) { func TestGetContentsOrListErrors(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
@ -207,7 +207,7 @@ func TestGetContentsOrListErrors(t *testing.T) {
func TestGetContentsOrListOfEmptyRepos(t *testing.T) { func TestGetContentsOrListOfEmptyRepos(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user30/empty") ctx, _ := test.MockContext(t, "user30/empty")
ctx.SetParams(":id", "52") ctx.SetParams(":id", "52")
test.LoadRepo(t, ctx, 52) test.LoadRepo(t, ctx, 52)
test.LoadUser(t, ctx, 30) test.LoadUser(t, ctx, 30)
@ -225,7 +225,7 @@ func TestGetContentsOrListOfEmptyRepos(t *testing.T) {
func TestGetBlobBySHA(t *testing.T) { func TestGetBlobBySHA(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)

@ -17,7 +17,7 @@ import (
func TestGetDiffPreview(t *testing.T) { func TestGetDiffPreview(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
@ -139,7 +139,7 @@ func TestGetDiffPreview(t *testing.T) {
func TestGetDiffPreviewErrors(t *testing.T) { func TestGetDiffPreviewErrors(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)

@ -98,7 +98,7 @@ func getExpectedFileResponse() *api.FileResponse {
func TestGetFileResponseFromCommit(t *testing.T) { func TestGetFileResponseFromCommit(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)

@ -15,7 +15,7 @@ import (
func TestGetTreeBySHA(t *testing.T) { func TestGetTreeBySHA(t *testing.T) {
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
test.LoadUser(t, ctx, 2) test.LoadUser(t, ctx, 2)

@ -38,7 +38,7 @@ func TestMain(m *testing.M) {
defer cancel() defer cancel()
tests.InitTest(false) tests.InitTest(false)
c = routers.NormalRoutes(context.TODO()) c = routers.NormalRoutes()
os.Unsetenv("GIT_AUTHOR_NAME") os.Unsetenv("GIT_AUTHOR_NAME")
os.Unsetenv("GIT_AUTHOR_EMAIL") os.Unsetenv("GIT_AUTHOR_EMAIL")

@ -22,10 +22,10 @@ import (
func TestActivityPubPerson(t *testing.T) { func TestActivityPubPerson(t *testing.T) {
setting.Federation.Enabled = true setting.Federation.Enabled = true
c = routers.NormalRoutes(context.TODO()) c = routers.NormalRoutes()
defer func() { defer func() {
setting.Federation.Enabled = false setting.Federation.Enabled = false
c = routers.NormalRoutes(context.TODO()) c = routers.NormalRoutes()
}() }()
onGiteaRun(t, func(*testing.T, *url.URL) { onGiteaRun(t, func(*testing.T, *url.URL) {
@ -60,10 +60,10 @@ func TestActivityPubPerson(t *testing.T) {
func TestActivityPubMissingPerson(t *testing.T) { func TestActivityPubMissingPerson(t *testing.T) {
setting.Federation.Enabled = true setting.Federation.Enabled = true
c = routers.NormalRoutes(context.TODO()) c = routers.NormalRoutes()
defer func() { defer func() {
setting.Federation.Enabled = false setting.Federation.Enabled = false
c = routers.NormalRoutes(context.TODO()) c = routers.NormalRoutes()
}() }()
onGiteaRun(t, func(*testing.T, *url.URL) { onGiteaRun(t, func(*testing.T, *url.URL) {
@ -75,10 +75,10 @@ func TestActivityPubMissingPerson(t *testing.T) {
func TestActivityPubPersonInbox(t *testing.T) { func TestActivityPubPersonInbox(t *testing.T) {
setting.Federation.Enabled = true setting.Federation.Enabled = true
c = routers.NormalRoutes(context.TODO()) c = routers.NormalRoutes()
defer func() { defer func() {
setting.Federation.Enabled = false setting.Federation.Enabled = false
c = routers.NormalRoutes(context.TODO()) c = routers.NormalRoutes()
}() }()
srv := httptest.NewServer(c) srv := httptest.NewServer(c)

@ -4,7 +4,6 @@
package integration package integration
import ( import (
"context"
"net/http" "net/http"
"net/url" "net/url"
"testing" "testing"
@ -18,10 +17,10 @@ import (
func TestNodeinfo(t *testing.T) { func TestNodeinfo(t *testing.T) {
setting.Federation.Enabled = true setting.Federation.Enabled = true
c = routers.NormalRoutes(context.TODO()) c = routers.NormalRoutes()
defer func() { defer func() {
setting.Federation.Enabled = false setting.Federation.Enabled = false
c = routers.NormalRoutes(context.TODO()) c = routers.NormalRoutes()
}() }()
onGiteaRun(t, func(*testing.T, *url.URL) { onGiteaRun(t, func(*testing.T, *url.URL) {

@ -4,7 +4,6 @@
package integration package integration
import ( import (
"context"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"os" "os"
@ -57,7 +56,7 @@ func TestSessionFileCreation(t *testing.T) {
oldSessionConfig := setting.SessionConfig.ProviderConfig oldSessionConfig := setting.SessionConfig.ProviderConfig
defer func() { defer func() {
setting.SessionConfig.ProviderConfig = oldSessionConfig setting.SessionConfig.ProviderConfig = oldSessionConfig
c = routers.NormalRoutes(context.TODO()) c = routers.NormalRoutes()
}() }()
var config session.Options var config session.Options
@ -76,7 +75,7 @@ func TestSessionFileCreation(t *testing.T) {
setting.SessionConfig.ProviderConfig = string(newConfigBytes) setting.SessionConfig.ProviderConfig = string(newConfigBytes)
c = routers.NormalRoutes(context.TODO()) c = routers.NormalRoutes()
t.Run("NoSessionOnViewIssue", func(t *testing.T) { t.Run("NoSessionOnViewIssue", func(t *testing.T) {
defer tests.PrintCurrentTest(t)() defer tests.PrintCurrentTest(t)()

@ -87,7 +87,7 @@ func TestMain(m *testing.M) {
defer cancel() defer cancel()
tests.InitTest(true) tests.InitTest(true)
c = routers.NormalRoutes(context.TODO()) c = routers.NormalRoutes()
// integration test settings... // integration test settings...
if setting.CfgProvider != nil { if setting.CfgProvider != nil {

@ -244,7 +244,7 @@ func getExpectedFileResponseForRepofilesUpdate(commitID, filename, lastCommitSHA
func TestChangeRepoFilesForCreate(t *testing.T) { func TestChangeRepoFilesForCreate(t *testing.T) {
// setup // setup
onGiteaRun(t, func(t *testing.T, u *url.URL) { onGiteaRun(t, func(t *testing.T, u *url.URL) {
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
@ -281,7 +281,7 @@ func TestChangeRepoFilesForCreate(t *testing.T) {
func TestChangeRepoFilesForUpdate(t *testing.T) { func TestChangeRepoFilesForUpdate(t *testing.T) {
// setup // setup
onGiteaRun(t, func(t *testing.T, u *url.URL) { onGiteaRun(t, func(t *testing.T, u *url.URL) {
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
@ -315,7 +315,7 @@ func TestChangeRepoFilesForUpdate(t *testing.T) {
func TestChangeRepoFilesForUpdateWithFileMove(t *testing.T) { func TestChangeRepoFilesForUpdateWithFileMove(t *testing.T) {
// setup // setup
onGiteaRun(t, func(t *testing.T, u *url.URL) { onGiteaRun(t, func(t *testing.T, u *url.URL) {
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
@ -366,7 +366,7 @@ func TestChangeRepoFilesForUpdateWithFileMove(t *testing.T) {
func TestChangeRepoFilesWithoutBranchNames(t *testing.T) { func TestChangeRepoFilesWithoutBranchNames(t *testing.T) {
// setup // setup
onGiteaRun(t, func(t *testing.T, u *url.URL) { onGiteaRun(t, func(t *testing.T, u *url.URL) {
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
@ -402,7 +402,7 @@ func TestChangeRepoFilesForDelete(t *testing.T) {
func testDeleteRepoFiles(t *testing.T, u *url.URL) { func testDeleteRepoFiles(t *testing.T, u *url.URL) {
// setup // setup
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
@ -441,7 +441,7 @@ func TestChangeRepoFilesForDeleteWithoutBranchNames(t *testing.T) {
func testDeleteRepoFilesWithoutBranchNames(t *testing.T, u *url.URL) { func testDeleteRepoFilesWithoutBranchNames(t *testing.T, u *url.URL) {
// setup // setup
unittest.PrepareTestEnv(t) unittest.PrepareTestEnv(t)
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)
@ -471,7 +471,7 @@ func testDeleteRepoFilesWithoutBranchNames(t *testing.T, u *url.URL) {
func TestChangeRepoFilesErrors(t *testing.T) { func TestChangeRepoFilesErrors(t *testing.T) {
// setup // setup
onGiteaRun(t, func(t *testing.T, u *url.URL) { onGiteaRun(t, func(t *testing.T, u *url.URL) {
ctx := test.MockContext(t, "user2/repo1") ctx, _ := test.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
test.LoadRepo(t, ctx, 1) test.LoadRepo(t, ctx, 1)
test.LoadRepoCommit(t, ctx) test.LoadRepoCommit(t, ctx)

Loading…
Cancel
Save