mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	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>
This commit is contained in:
		@@ -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,14 +5,19 @@ 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))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Status() int // used by access logger template
 | 
				
			||||||
	Size() int   // used by access logger template
 | 
						Size() int   // used by access logger template
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -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
 | 
					func RegisterResponseStatusProvider[T any](fn func(req *http.Request) types.ResponseStatusProvider) {
 | 
				
			||||||
var argTypeProvider = map[reflect.Type]func(req *http.Request) ResponseStatusProvider{
 | 
						responseStatusProviders[reflect.TypeOf((*T)(nil)).Elem()] = fn
 | 
				
			||||||
	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) {
 | 
					 | 
				
			||||||
	argTypeProvider[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/") {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								modules/web/types/response.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								modules/web/types/response.go
									
									
									
									
									
										Normal file
									
								
							@@ -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"
 | 
				
			||||||
@@ -15,8 +14,6 @@ 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"
 | 
				
			||||||
@@ -33,12 +33,11 @@ var (
 | 
				
			|||||||
	// 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)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user