浏览代码

route: no session for routes without UI (#6066)

Not all routes need session, register session and CSRF middleware as global is a waste of resource, and creating a lot one-time off yet never used session records.
ᴜɴᴋɴᴡᴏɴ 5 年之前
父节点
当前提交
bced406fc2

+ 3 - 5
internal/app/api.go

@@ -9,8 +9,6 @@ import (
 
 	"github.com/microcosm-cc/bluemonday"
 	"gopkg.in/macaron.v1"
-
-	"github.com/G-Node/gogs/internal/context"
 )
 
 func ipynbSanitizer() *bluemonday.Policy {
@@ -24,13 +22,13 @@ func ipynbSanitizer() *bluemonday.Policy {
 func SanitizeIpynb() macaron.Handler {
 	p := ipynbSanitizer()
 
-	return func(c *context.Context) {
+	return func(c *macaron.Context) {
 		html, err := c.Req.Body().String()
 		if err != nil {
-			c.Error(err, "read body")
+			c.Error(http.StatusInternalServerError, "read body")
 			return
 		}
 
-		c.PlainText(http.StatusOK, p.Sanitize(html))
+		c.PlainText(http.StatusOK, []byte(p.Sanitize(html)))
 	}
 }

+ 8 - 4
internal/app/metrics.go

@@ -9,14 +9,14 @@ import (
 
 	"gopkg.in/macaron.v1"
 
+	"github.com/G-Node/gogs/internal/authutil"
 	"github.com/G-Node/gogs/internal/conf"
-	"github.com/G-Node/gogs/internal/context"
 )
 
 func MetricsFilter() macaron.Handler {
-	return func(c *context.Context) {
+	return func(w http.ResponseWriter, r *http.Request) {
 		if !conf.Prometheus.Enabled {
-			c.Status(http.StatusNotFound)
+			w.WriteHeader(http.StatusNotFound)
 			return
 		}
 
@@ -24,6 +24,10 @@ func MetricsFilter() macaron.Handler {
 			return
 		}
 
-		c.RequireBasicAuth(conf.Prometheus.BasicAuthUsername, conf.Prometheus.BasicAuthPassword)
+		username, password := authutil.DecodeBasic(r.Header)
+		if username != conf.Prometheus.BasicAuthUsername || password != conf.Prometheus.BasicAuthPassword {
+			w.WriteHeader(http.StatusForbidden)
+			return
+		}
 	}
 }

文件差异内容过多而无法显示
+ 468 - 463
internal/cmd/web.go


+ 0 - 17
internal/context/auth.go

@@ -7,14 +7,12 @@ package context
 import (
 	"net/http"
 	"net/url"
-	"strings"
 
 	"github.com/go-macaron/csrf"
 	"gopkg.in/macaron.v1"
 
 	"github.com/G-Node/gogs/internal/auth"
 	"github.com/G-Node/gogs/internal/conf"
-	"github.com/G-Node/gogs/internal/tool"
 )
 
 type ToggleOptions struct {
@@ -95,18 +93,3 @@ func Toggle(options *ToggleOptions) macaron.Handler {
 		}
 	}
 }
-
-// RequireBasicAuth verifies HTTP Basic Authentication header with given credentials.
-func (c *Context) RequireBasicAuth(username, password string) {
-	fields := strings.Fields(c.Req.Header.Get("Authorization"))
-	if len(fields) != 2 || fields[0] != "Basic" {
-		c.Status(http.StatusUnauthorized)
-		return
-	}
-
-	uname, passwd, _ := tool.BasicAuthDecode(fields[1])
-	if uname != username || passwd != password {
-		c.Status(http.StatusForbidden)
-		return
-	}
-}

+ 1 - 1
internal/db/access.go

@@ -93,7 +93,7 @@ func hasAccess(e Engine, userID int64, repo *Repository, testMode AccessMode) (b
 }
 
 // HasAccess returns true if someone has the request access level. User can be nil!
-// Deprecated: Use Perms.HasAccess instead.
+// Deprecated: Use Perms.Authorize instead.
 func HasAccess(userID int64, repo *Repository, testMode AccessMode) (bool, error) {
 	return hasAccess(x, userID, repo, testMode)
 }

+ 1 - 1
internal/lfsutil/oid.go

@@ -5,7 +5,7 @@
 package lfsutil
 
 import (
-	"gogs.io/gogs/internal/lazyregexp"
+	"github.com/G-Node/gogs/internal/lazyregexp"
 )
 
 // OID is an LFS object ID.

+ 8 - 3
internal/route/home.go

@@ -5,7 +5,12 @@
 package route
 
 import (
+	"fmt"
+	"net/http"
+
+	"github.com/go-macaron/i18n"
 	"github.com/unknwon/paginater"
+	"gopkg.in/macaron.v1"
 
 	"github.com/G-Node/gogs/internal/conf"
 	"github.com/G-Node/gogs/internal/context"
@@ -157,7 +162,7 @@ func ExploreOrganizations(c *context.Context) {
 	})
 }
 
-func NotFound(c *context.Context) {
-	c.Data["Title"] = "Page Not Found"
-	c.NotFound()
+func NotFound(c *macaron.Context, l i18n.Locale) {
+	c.Data["Title"] = l.Tr("status.page_not_found")
+	c.HTML(http.StatusNotFound, fmt.Sprintf("status/%d", http.StatusNotFound))
 }

+ 4 - 4
internal/route/lfs/basic.go

@@ -12,10 +12,10 @@ import (
 	"os"
 	"strconv"
 
+	"gopkg.in/macaron.v1"
 	log "unknwon.dev/clog/v2"
 
 	"github.com/G-Node/gogs/internal/conf"
-	"github.com/G-Node/gogs/internal/context"
 	"github.com/G-Node/gogs/internal/db"
 	"github.com/G-Node/gogs/internal/lfsutil"
 	"github.com/G-Node/gogs/internal/strutil"
@@ -28,7 +28,7 @@ const (
 )
 
 // GET /{owner}/{repo}.git/info/lfs/object/basic/{oid}
-func serveBasicDownload(c *context.Context, repo *db.Repository, oid lfsutil.OID) {
+func serveBasicDownload(c *macaron.Context, repo *db.Repository, oid lfsutil.OID) {
 	object, err := db.LFS.GetObjectByOID(repo.ID, oid)
 	if err != nil {
 		if db.IsErrLFSObjectNotExist(err) {
@@ -63,7 +63,7 @@ func serveBasicDownload(c *context.Context, repo *db.Repository, oid lfsutil.OID
 }
 
 // PUT /{owner}/{repo}.git/info/lfs/object/basic/{oid}
-func serveBasicUpload(c *context.Context, repo *db.Repository, oid lfsutil.OID) {
+func serveBasicUpload(c *macaron.Context, repo *db.Repository, oid lfsutil.OID) {
 	// NOTE: LFS client will retry upload the same object if there was a partial failure,
 	// therefore we would like to skip ones that already exist.
 	_, err := db.LFS.GetObjectByOID(repo.ID, oid)
@@ -91,7 +91,7 @@ func serveBasicUpload(c *context.Context, repo *db.Repository, oid lfsutil.OID)
 }
 
 // POST /{owner}/{repo}.git/info/lfs/object/basic/verify
-func serveBasicVerify(c *context.Context, repo *db.Repository) {
+func serveBasicVerify(c *macaron.Context, repo *db.Repository) {
 	var request basicVerifyRequest
 	defer c.Req.Request.Body.Close()
 	err := json.NewDecoder(c.Req.Request.Body).Decode(&request)

+ 2 - 2
internal/route/lfs/batch.go

@@ -9,17 +9,17 @@ import (
 	"net/http"
 
 	jsoniter "github.com/json-iterator/go"
+	"gopkg.in/macaron.v1"
 	log "unknwon.dev/clog/v2"
 
 	"github.com/G-Node/gogs/internal/conf"
-	"github.com/G-Node/gogs/internal/context"
 	"github.com/G-Node/gogs/internal/db"
 	"github.com/G-Node/gogs/internal/lfsutil"
 	"github.com/G-Node/gogs/internal/strutil"
 )
 
 // POST /{owner}/{repo}.git/info/lfs/object/batch
-func serveBatch(c *context.Context, owner *db.User, repo *db.Repository) {
+func serveBatch(c *macaron.Context, owner *db.User, repo *db.Repository) {
 	var request batchRequest
 	defer c.Req.Request.Body.Close()
 	err := jsoniter.NewDecoder(c.Req.Request.Body).Decode(&request)

+ 6 - 7
internal/route/lfs/route.go

@@ -13,7 +13,6 @@ import (
 	log "unknwon.dev/clog/v2"
 
 	"github.com/G-Node/gogs/internal/authutil"
-	"github.com/G-Node/gogs/internal/context"
 	"github.com/G-Node/gogs/internal/db"
 	"github.com/G-Node/gogs/internal/lfsutil"
 )
@@ -44,7 +43,7 @@ func authenticate() macaron.Handler {
 		})
 	}
 
-	return func(c *context.Context) {
+	return func(c *macaron.Context) {
 		username, password := authutil.DecodeBasic(c.Req.Header)
 		if username == "" {
 			askCredentials(c.Resp)
@@ -59,7 +58,7 @@ func authenticate() macaron.Handler {
 		}
 
 		if err == nil && user.IsEnabledTwoFactor() {
-			c.PlainText(http.StatusBadRequest, `Users with 2FA enabled are not allowed to authenticate via username and password.`)
+			c.Error(http.StatusBadRequest, `Users with 2FA enabled are not allowed to authenticate via username and password.`)
 			return
 		}
 
@@ -98,7 +97,7 @@ func authenticate() macaron.Handler {
 
 // authorize tries to authorize the user to the context repository with given access mode.
 func authorize(mode db.AccessMode) macaron.Handler {
-	return func(c *context.Context, user *db.User) {
+	return func(c *macaron.Context, user *db.User) {
 		username := c.Params(":username")
 		reponame := strings.TrimSuffix(c.Params(":reponame"), ".git")
 
@@ -137,7 +136,7 @@ func authorize(mode db.AccessMode) macaron.Handler {
 // verifyHeader checks if the HTTP header contains given value.
 // When not, response given "failCode" as status code.
 func verifyHeader(key, value string, failCode int) macaron.Handler {
-	return func(c *context.Context) {
+	return func(c *macaron.Context) {
 		if !strings.Contains(c.Req.Header.Get(key), value) {
 			c.Status(failCode)
 			return
@@ -147,10 +146,10 @@ func verifyHeader(key, value string, failCode int) macaron.Handler {
 
 // verifyOID checks if the ":oid" URL parameter is valid.
 func verifyOID() macaron.Handler {
-	return func(c *context.Context) {
+	return func(c *macaron.Context) {
 		oid := lfsutil.OID(c.Params(":oid"))
 		if !lfsutil.ValidOID(oid) {
-			c.PlainText(http.StatusBadRequest, "Invalid oid")
+			c.Error(http.StatusBadRequest, "Invalid oid")
 			return
 		}
 

+ 32 - 24
internal/route/repo/http.go

@@ -21,14 +21,13 @@ import (
 	log "unknwon.dev/clog/v2"
 
 	"github.com/G-Node/gogs/internal/conf"
-	"github.com/G-Node/gogs/internal/context"
 	"github.com/G-Node/gogs/internal/db"
 	"github.com/G-Node/gogs/internal/lazyregexp"
 	"github.com/G-Node/gogs/internal/tool"
 )
 
 type HTTPContext struct {
-	*context.Context
+	*macaron.Context
 	OwnerName string
 	OwnerSalt string
 	RepoID    int64
@@ -37,17 +36,17 @@ type HTTPContext struct {
 }
 
 // askCredentials responses HTTP header and status which informs client to provide credentials.
-func askCredentials(c *context.Context, status int, text string) {
-	c.Resp.Header().Set("WWW-Authenticate", "Basic realm=\".\"")
-	c.PlainText(status, text)
+func askCredentials(c *macaron.Context, status int, text string) {
+	c.Header().Set("WWW-Authenticate", "Basic realm=\".\"")
+	c.Error(status, text)
 }
 
 func HTTPContexter() macaron.Handler {
-	return func(c *context.Context) {
+	return func(c *macaron.Context) {
 		if len(conf.HTTP.AccessControlAllowOrigin) > 0 {
 			// Set CORS headers for browser-based git clients
-			c.Resp.Header().Set("Access-Control-Allow-Origin", conf.HTTP.AccessControlAllowOrigin)
-			c.Resp.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, User-Agent")
+			c.Header().Set("Access-Control-Allow-Origin", conf.HTTP.AccessControlAllowOrigin)
+			c.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, User-Agent")
 
 			// Handle preflight OPTIONS request
 			if c.Req.Method == "OPTIONS" {
@@ -64,15 +63,25 @@ func HTTPContexter() macaron.Handler {
 			strings.HasSuffix(c.Req.URL.Path, "git-upload-pack") ||
 			c.Req.Method == "GET"
 
-		owner, err := db.GetUserByName(ownerName)
+		owner, err := db.Users.GetByUsername(ownerName)
 		if err != nil {
-			c.NotFoundOrError(err, "get user by name")
+			if db.IsErrUserNotExist(err) {
+				c.Status(http.StatusNotFound)
+			} else {
+				c.Status(http.StatusInternalServerError)
+				log.Error("Failed to get user [name: %s]: %v", ownerName, err)
+			}
 			return
 		}
 
-		repo, err := db.GetRepositoryByName(owner.ID, repoName)
+		repo, err := db.Repos.GetByName(owner.ID, repoName)
 		if err != nil {
-			c.NotFoundOrError(err, "get repository by name")
+			if db.IsErrRepoNotExist(err) {
+				c.Status(http.StatusNotFound)
+			} else {
+				c.Status(http.StatusInternalServerError)
+				log.Error("Failed to get repository [owner_id: %d, name: %s]: %v", owner.ID, repoName, err)
+			}
 			return
 		}
 
@@ -114,7 +123,8 @@ func HTTPContexter() macaron.Handler {
 
 		authUser, err := db.Users.Authenticate(authUsername, authPassword, -1)
 		if err != nil && !db.IsErrUserNotExist(err) {
-			c.Error(err, "authenticate user")
+			c.Status(http.StatusInternalServerError)
+			log.Error("Failed to authenticate user [name: %s]: %v", authUsername, err)
 			return
 		}
 
@@ -125,7 +135,8 @@ func HTTPContexter() macaron.Handler {
 				if db.IsErrAccessTokenNotExist(err) {
 					askCredentials(c, http.StatusUnauthorized, "")
 				} else {
-					c.Error(err, "get access token by SHA")
+					c.Status(http.StatusInternalServerError)
+					log.Error("Failed to get access token [sha: %s]: %v", authUsername, err)
 				}
 				return
 			}
@@ -134,11 +145,12 @@ func HTTPContexter() macaron.Handler {
 				log.Error("Failed to update access token: %v", err)
 			}
 
-			authUser, err = db.GetUserByID(token.UserID)
+			authUser, err = db.Users.GetByID(token.UserID)
 			if err != nil {
 				// Once we found token, we're supposed to find its related user,
 				// thus any error is unexpected.
-				c.Error(err, "get user by ID")
+				c.Status(http.StatusInternalServerError)
+				log.Error("Failed to get user [id: %d]: %v", token.UserID, err)
 				return
 			}
 		} else if authUser.IsEnabledTwoFactor() {
@@ -147,23 +159,19 @@ Please create and use personal access token on user settings page`)
 			return
 		}
 
-		log.Trace("HTTPGit - Authenticated user: %s", authUser.Name)
+		log.Trace("[Git] Authenticated user: %s", authUser.Name)
 
 		mode := db.AccessModeWrite
 		if isPull {
 			mode = db.AccessModeRead
 		}
-		has, err := db.HasAccess(authUser.ID, repo, mode)
-		if err != nil {
-			c.Error(err, "check access")
-			return
-		} else if !has {
+		if !db.Perms.Authorize(authUser.ID, repo, mode) {
 			askCredentials(c, http.StatusForbidden, "User permission denied")
 			return
 		}
 
 		if !isPull && repo.IsMirror {
-			c.PlainText(http.StatusForbidden, "Mirror repository is read-only")
+			c.Error(http.StatusForbidden, "Mirror repository is read-only")
 			return
 		}
 
@@ -390,7 +398,7 @@ func HTTP(c *HTTPContext) {
 		// but we only want to output this message only if user is really trying to access
 		// Git HTTP endpoints.
 		if conf.Repository.DisableHTTPGit {
-			c.PlainText(http.StatusForbidden, "Interacting with repositories by HTTP protocol is disabled")
+			c.Error(http.StatusForbidden, "Interacting with repositories by HTTP protocol is disabled")
 			return
 		}
 

部分文件因为文件数量过多而无法显示