Merge remote-tracking branch 'upstream/main' into limit-repo-size

This commit is contained in:
DmitryFrolovTri
2023-07-24 13:33:35 +00:00
703 changed files with 6340 additions and 3735 deletions
+1 -1
View File
@@ -217,7 +217,7 @@ func (l *LayeredFS) WatchLocalChanges(ctx context.Context, callback func()) {
}
layerDirs = append(layerDirs, ".")
for _, dir := range layerDirs {
if err = watcher.Add(util.FilePathJoinAbs(layer.localPath, dir)); err != nil {
if err = watcher.Add(util.FilePathJoinAbs(layer.localPath, dir)); err != nil && !os.IsNotExist(err) {
log.Error("Unable to watch directory %s: %v", dir, err)
}
}
+36 -23
View File
@@ -17,8 +17,7 @@ import (
"code.gitea.io/gitea/modules/avatar/identicon"
"code.gitea.io/gitea/modules/setting"
"github.com/nfnt/resize"
"github.com/oliamb/cutter"
"golang.org/x/image/draw"
_ "golang.org/x/image/webp" // for processing webp images
)
@@ -81,28 +80,10 @@ func processAvatarImage(data []byte, maxOriginSize int64) ([]byte, error) {
}
// try to crop and resize the origin image if necessary
if imgCfg.Width != imgCfg.Height {
var newSize, ax, ay int
if imgCfg.Width > imgCfg.Height {
newSize = imgCfg.Height
ax = (imgCfg.Width - imgCfg.Height) / 2
} else {
newSize = imgCfg.Width
ay = (imgCfg.Height - imgCfg.Width) / 2
}
img = cropSquare(img)
img, err = cutter.Crop(img, cutter.Config{
Width: newSize,
Height: newSize,
Anchor: image.Point{X: ax, Y: ay},
})
if err != nil {
return nil, err
}
}
targetSize := uint(DefaultAvatarSize * setting.Avatar.RenderedSizeFactor)
img = resize.Resize(targetSize, targetSize, img, resize.Bilinear)
targetSize := DefaultAvatarSize * setting.Avatar.RenderedSizeFactor
img = scale(img, targetSize, targetSize, draw.BiLinear)
// try to encode the cropped/resized image to png
bs := bytes.Buffer{}
@@ -124,3 +105,35 @@ func processAvatarImage(data []byte, maxOriginSize int64) ([]byte, error) {
func ProcessAvatarImage(data []byte) ([]byte, error) {
return processAvatarImage(data, setting.Avatar.MaxOriginSize)
}
// scale resizes the image to width x height using the given scaler.
func scale(src image.Image, width, height int, scale draw.Scaler) image.Image {
rect := image.Rect(0, 0, width, height)
dst := image.NewRGBA(rect)
scale.Scale(dst, rect, src, src.Bounds(), draw.Over, nil)
return dst
}
// cropSquare crops the largest square image from the center of the image.
// If the image is already square, it is returned unchanged.
func cropSquare(src image.Image) image.Image {
bounds := src.Bounds()
if bounds.Dx() == bounds.Dy() {
return src
}
var rect image.Rectangle
if bounds.Dx() > bounds.Dy() {
// width > height
size := bounds.Dy()
rect = image.Rect((bounds.Dx()-size)/2, 0, (bounds.Dx()+size)/2, size)
} else {
// width < height
size := bounds.Dx()
rect = image.Rect(0, (bounds.Dy()-size)/2, size, (bounds.Dy()+size)/2)
}
dst := image.NewRGBA(rect)
draw.Draw(dst, rect, src, rect.Min, draw.Src)
return dst
}
+6 -6
View File
@@ -11,13 +11,13 @@ import (
"code.gitea.io/gitea/modules/json"
mc "gitea.com/go-chi/cache"
lru "github.com/hashicorp/golang-lru"
lru "github.com/hashicorp/golang-lru/v2"
)
// TwoQueueCache represents a LRU 2Q cache adapter implementation
type TwoQueueCache struct {
lock sync.Mutex
cache *lru.TwoQueueCache
cache *lru.TwoQueueCache[string, any]
interval int
}
@@ -146,7 +146,7 @@ func (c *TwoQueueCache) Flush() error {
return nil
}
func (c *TwoQueueCache) checkAndInvalidate(key any) {
func (c *TwoQueueCache) checkAndInvalidate(key string) {
c.lock.Lock()
defer c.lock.Unlock()
cached, ok := c.cache.Peek(key)
@@ -155,7 +155,7 @@ func (c *TwoQueueCache) checkAndInvalidate(key any) {
}
item, ok := cached.(*MemoryItem)
if !ok || item.hasExpired() {
c.cache.Remove(item)
c.cache.Remove(key)
}
}
@@ -187,9 +187,9 @@ func (c *TwoQueueCache) StartAndGC(opts mc.Options) error {
GhostRatio: lru.Default2QGhostEntries,
}
_ = json.Unmarshal([]byte(opts.AdapterConfig), cfg)
c.cache, err = lru.New2QParams(cfg.Size, cfg.RecentRatio, cfg.GhostRatio)
c.cache, err = lru.New2QParams[string, any](cfg.Size, cfg.RecentRatio, cfg.GhostRatio)
} else {
c.cache, err = lru.New2Q(size)
c.cache, err = lru.New2Q[string, any](size)
}
c.interval = opts.Interval
if c.interval > 0 {
+1 -1
View File
@@ -35,7 +35,7 @@ func RequireRepoWriter(unitType unit.Type) func(ctx *Context) {
// CanEnableEditor checks if the user is allowed to write to the branch of the repo
func CanEnableEditor() func(ctx *Context) {
return func(ctx *Context) {
if !ctx.Repo.CanWriteToBranch(ctx.Doer, ctx.Repo.BranchName) {
if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) {
ctx.NotFound("CanWriteToBranch denies permission", nil)
return
}
+15 -27
View File
@@ -66,13 +66,13 @@ type Repository struct {
}
// CanWriteToBranch checks if the branch is writable by the user
func (r *Repository) CanWriteToBranch(user *user_model.User, branch string) bool {
return issues_model.CanMaintainerWriteToBranch(r.Permission, branch, user)
func (r *Repository) CanWriteToBranch(ctx context.Context, user *user_model.User, branch string) bool {
return issues_model.CanMaintainerWriteToBranch(ctx, r.Permission, branch, user)
}
// CanEnableEditor returns true if repository is editable and user has proper access level.
func (r *Repository) CanEnableEditor(user *user_model.User) bool {
return r.IsViewBranch && r.CanWriteToBranch(user, r.BranchName) && r.Repository.CanEnableEditor() && !r.Repository.IsArchived
func (r *Repository) CanEnableEditor(ctx context.Context, user *user_model.User) bool {
return r.IsViewBranch && r.CanWriteToBranch(ctx, user, r.BranchName) && r.Repository.CanEnableEditor() && !r.Repository.IsArchived
}
// CanCreateBranch returns true if repository is editable and user has proper access level.
@@ -118,7 +118,7 @@ func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.Use
sign, keyID, _, err := asymkey_service.SignCRUDAction(ctx, r.Repository.RepoPath(), doer, r.Repository.RepoPath(), git.BranchPrefix+r.BranchName)
canCommit := r.CanEnableEditor(doer) && userCanPush
canCommit := r.CanEnableEditor(ctx, doer) && userCanPush
if requireSigned {
canCommit = canCommit && sign
}
@@ -134,7 +134,7 @@ func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.Use
return CanCommitToBranchResults{
CanCommitToBranch: canCommit,
EditorEnabled: r.CanEnableEditor(doer),
EditorEnabled: r.CanEnableEditor(ctx, doer),
UserCanPush: userCanPush,
RequireSigned: requireSigned,
WillSign: sign,
@@ -660,13 +660,6 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
return cancel
}
tags, err := repo_model.GetTagNamesByRepoID(ctx, ctx.Repo.Repository.ID)
if err != nil {
ctx.ServerError("GetTagNamesByRepoID", err)
return cancel
}
ctx.Data["Tags"] = tags
branchOpts := git_model.FindBranchOptions{
RepoID: ctx.Repo.Repository.ID,
IsDeletedBranch: util.OptionalBoolFalse,
@@ -680,7 +673,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
return cancel
}
// non empty repo should have at least 1 branch, so this repository's branches haven't been synced yet
// non-empty repo should have at least 1 branch, so this repository's branches haven't been synced yet
if branchesTotal == 0 { // fallback to do a sync immediately
branchesTotal, err = repo_module.SyncRepoBranches(ctx, ctx.Repo.Repository.ID, 0)
if err != nil {
@@ -689,24 +682,19 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
}
}
// FIXME: use paganation and async loading
branchOpts.ExcludeBranchNames = []string{ctx.Repo.Repository.DefaultBranch}
brs, err := git_model.FindBranchNames(ctx, branchOpts)
if err != nil {
ctx.ServerError("GetBranches", err)
return cancel
}
// always put default branch on the top
ctx.Data["Branches"] = append(branchOpts.ExcludeBranchNames, brs...)
ctx.Data["BranchesCount"] = branchesTotal
// If not branch selected, try default one.
// If default branch doesn't exist, fall back to some other branch.
// If no branch is set in the request URL, try to guess a default one.
if len(ctx.Repo.BranchName) == 0 {
if len(ctx.Repo.Repository.DefaultBranch) > 0 && gitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) {
ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch
} else if len(brs) > 0 {
ctx.Repo.BranchName = brs[0]
} else {
ctx.Repo.BranchName, _ = gitRepo.GetDefaultBranch()
if ctx.Repo.BranchName == "" {
// If it still can't get a default branch, fall back to default branch from setting.
// Something might be wrong. Either site admin should fix the repo sync or Gitea should fix a potential bug.
ctx.Repo.BranchName = setting.Repository.DefaultBranch
}
}
ctx.Repo.RefName = ctx.Repo.BranchName
}
+2 -2
View File
@@ -22,7 +22,7 @@ import (
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
lru "github.com/hashicorp/golang-lru"
lru "github.com/hashicorp/golang-lru/v2"
"xorm.io/builder"
)
@@ -130,7 +130,7 @@ func checkEnablePushOptions(ctx context.Context, logger log.Logger, autofix bool
func checkDaemonExport(ctx context.Context, logger log.Logger, autofix bool) error {
numRepos := 0
numNeedUpdate := 0
cache, err := lru.New(512)
cache, err := lru.New[int64, any](512)
if err != nil {
logger.Critical("Unable to create cache: %v", err)
return err
+1 -1
View File
@@ -12,7 +12,7 @@ import (
"code.gitea.io/gitea/modules/util"
"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v5"
)
// NewInternalToken generate a new value intended to be used by INTERNAL_TOKEN.
-6
View File
@@ -7,12 +7,6 @@ import (
"fmt"
)
// FileBlame return the Blame object of file
func (repo *Repository) FileBlame(revision, path, file string) ([]byte, error) {
stdout, _, err := NewCommand(repo.Ctx, "blame", "--root").AddDashesAndList(file).RunStdBytes(&RunOpts{Dir: path})
return stdout, err
}
// LineBlame returns the latest commit at the given line
func (repo *Repository) LineBlame(revision, path, file string, line uint) (*Commit, error) {
res, _, err := NewCommand(repo.Ctx, "blame").
+5 -3
View File
@@ -150,11 +150,13 @@ func CloseProvidedListeners() error {
return returnableError
}
// GetListener obtains a listener for the local network address. The network must be
// DefaultGetListener obtains a listener for the local network address. The network must be
// a stream-oriented network: "tcp", "tcp4", "tcp6", "unix" or "unixpacket". It
// returns an provided net.Listener for the matching network and address, or
// creates a new one using net.Listen.
func GetListener(network, address string) (net.Listener, error) {
// creates a new one using net.Listen. This function can be replaced by changing the
// GetListener variable at the top of this file, for example to listen on an onion service using
// github.com/cretz/bine
func DefaultGetListener(network, address string) (net.Listener, error) {
// Add a deferral to say that we've tried to grab a listener
defer GetManager().InformCleanup()
switch network {
+5 -3
View File
@@ -9,9 +9,11 @@ package graceful
import "net"
// GetListener obtains a listener for the local network address.
// On windows this is basically just a shim around net.Listen.
func GetListener(network, address string) (net.Listener, error) {
// DefaultGetListener obtains a listener for the local network address.
// On windows this is basically just a shim around net.Listen. This function
// can be replaced by changing the GetListener variable at the top of this file,
// for example to listen on an onion service using github.com/cretz/bine
func DefaultGetListener(network, address string) (net.Listener, error) {
// Add a deferral to say that we've tried to grab a listener
defer GetManager().InformCleanup()
+8
View File
@@ -33,6 +33,14 @@ var (
PerWriteWriteTimeoutKbTime = 10 * time.Second
)
// GetListener returns a listener from a GetListener function, which must have the
// signature: `func FunctioName(network, address string) (net.Listener, error)`.
// This determines the implementation of net.Listener which the server will use.`
// It is implemented in this way so that downstreams may specify the type of listener
// they want to provide Gitea on by default, such as with a hidden service or a p2p network
// No need to worry about "breaking" if there would be a refactoring for the Listeners. No compatibility-guarantee for this mechanism
var GetListener = DefaultGetListener
func init() {
DefaultMaxHeaderBytes = 0 // use http.DefaultMaxHeaderBytes - which currently is 1 << 20 (1MB)
}
+3 -3
View File
@@ -23,7 +23,7 @@ import (
"github.com/alecthomas/chroma/v2/formatters/html"
"github.com/alecthomas/chroma/v2/lexers"
"github.com/alecthomas/chroma/v2/styles"
lru "github.com/hashicorp/golang-lru"
lru "github.com/hashicorp/golang-lru/v2"
)
// don't index files larger than this many bytes for performance purposes
@@ -35,7 +35,7 @@ var (
once sync.Once
cache *lru.TwoQueueCache
cache *lru.TwoQueueCache[string, any]
githubStyles = styles.Get("github")
)
@@ -46,7 +46,7 @@ func NewContext() {
highlightMapping = setting.GetHighlightMapping()
// The size 512 is simply a conservative rule of thumb
c, err := lru.New2Q(512)
c, err := lru.New2Q[string, any](512)
if err != nil {
panic(fmt.Sprintf("failed to initialize LRU cache for highlighter: %s", err))
}
+6 -1
View File
@@ -4,6 +4,8 @@
package log
import (
"io"
"code.gitea.io/gitea/modules/util/rotatingfilewriter"
)
@@ -19,7 +21,7 @@ type WriterFileOption struct {
type eventWriterFile struct {
*EventWriterBaseImpl
fileWriter *rotatingfilewriter.RotatingFileWriter
fileWriter io.WriteCloser
}
var _ EventWriter = (*eventWriterFile)(nil)
@@ -37,7 +39,10 @@ func NewEventWriterFile(name string, mode WriterMode) EventWriter {
CompressionLevel: opt.CompressionLevel,
})
if err != nil {
// if the log file can't be opened, what should it do? panic/exit? ignore logs? fallback to stderr?
// it seems that "fallback to stderr" is slightly better than others ....
FallbackErrorf("unable to open log file %q: %v", opt.FileName, err)
w.fileWriter = nopCloser{Writer: LoggerToWriter(FallbackErrorf)}
}
w.OutputWriteCloser = w.fileWriter
return w
+1 -1
View File
@@ -51,7 +51,7 @@ func (Renderer) SanitizerRules() []setting.MarkupSanitizerRule {
// Render renders orgmode rawbytes to HTML
func Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
htmlWriter := org.NewHTMLWriter()
htmlWriter.HighlightCodeBlock = func(source, lang string, inline bool) string {
htmlWriter.HighlightCodeBlock = func(source, lang string, inline bool, params map[string]string) string {
defer func() {
if err := recover(); err != nil {
log.Error("Panic in HighlightCodeBlock: %v\n%s", err, log.Stack(2))
+9
View File
@@ -6,6 +6,7 @@ package markup
import (
"io"
"net/url"
"regexp"
"sync"
@@ -79,6 +80,14 @@ func createDefaultPolicy() *bluemonday.Policy {
policy.AllowURLSchemes(setting.Markdown.CustomURLSchemes...)
} else {
policy.AllowURLSchemesMatching(allowAllRegex)
// Even if every scheme is allowed, these three are blocked for security reasons
disallowScheme := func(*url.URL) bool {
return false
}
policy.AllowURLSchemeWithCustomPolicy("javascript", disallowScheme)
policy.AllowURLSchemeWithCustomPolicy("vbscript", disallowScheme)
policy.AllowURLSchemeWithCustomPolicy("data", disallowScheme)
}
// Allow classes for anchors
+7 -2
View File
@@ -54,8 +54,13 @@ func Test_Sanitizer(t *testing.T) {
`<code style="bad-color: red">Hello World</code>`, `<code>Hello World</code>`,
// URLs
`[my custom URL scheme](cbthunderlink://somebase64string)`, `[my custom URL scheme](cbthunderlink://somebase64string)`,
`[my custom URL scheme](matrix:roomid/psumPMeAfzgAeQpXMG:feneas.org?action=join)`, `[my custom URL scheme](matrix:roomid/psumPMeAfzgAeQpXMG:feneas.org?action=join)`,
`<a href="cbthunderlink://somebase64string)">my custom URL scheme</a>`, `<a href="cbthunderlink://somebase64string)" rel="nofollow">my custom URL scheme</a>`,
`<a href="matrix:roomid/psumPMeAfzgAeQpXMG:feneas.org?action=join">my custom URL scheme</a>`, `<a href="matrix:roomid/psumPMeAfzgAeQpXMG:feneas.org?action=join" rel="nofollow">my custom URL scheme</a>`,
// Disallow dangerous url schemes
`<a href="javascript:alert('xss')">bad</a>`, `bad`,
`<a href="vbscript:no">bad</a>`, `bad`,
`<a href="data:1234">bad</a>`, `bad`,
}
for i := 0; i < len(testCases); i += 2 {
+6 -1
View File
@@ -8,6 +8,8 @@ import (
"io"
"code.gitea.io/gitea/modules/validation"
"golang.org/x/net/html/charset"
)
// Metadata represents the metadata of a Maven package
@@ -52,7 +54,10 @@ type pomStruct struct {
// ParsePackageMetaData parses the metadata of a pom file
func ParsePackageMetaData(r io.Reader) (*Metadata, error) {
var pom pomStruct
if err := xml.NewDecoder(r).Decode(&pom); err != nil {
dec := xml.NewDecoder(r)
dec.CharsetReader = charset.NewReaderLabel
if err := dec.Decode(&pom); err != nil {
return nil, err
}
+17
View File
@@ -8,6 +8,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"golang.org/x/text/encoding/charmap"
)
const (
@@ -69,4 +70,20 @@ func TestParsePackageMetaData(t *testing.T) {
assert.Equal(t, dependencyArtifactID, m.Dependencies[0].ArtifactID)
assert.Equal(t, dependencyVersion, m.Dependencies[0].Version)
})
t.Run("Encoding", func(t *testing.T) {
// UTF-8 is default but the metadata could be encoded differently
pomContent8859_1, err := charmap.ISO8859_1.NewEncoder().String(
strings.ReplaceAll(
pomContent,
`<?xml version="1.0"?>`,
`<?xml version="1.0" encoding="ISO-8859-1"?>`,
),
)
assert.NoError(t, err)
m, err := ParsePackageMetaData(strings.NewReader(pomContent8859_1))
assert.NoError(t, err)
assert.NotNil(t, m)
})
}
+10 -22
View File
@@ -28,27 +28,15 @@ func AssetFS() *assetfs.LayeredFS {
return assetfs.Layered(CustomAssets(), BuiltinAssets())
}
// AssetsHandlerFunc implements the static handler for serving custom or original assets.
func AssetsHandlerFunc(prefix string) http.HandlerFunc {
// FileHandlerFunc implements the static handler for serving files in "public" assets
func FileHandlerFunc() http.HandlerFunc {
assetFS := AssetFS()
prefix = strings.TrimSuffix(prefix, "/") + "/"
return func(resp http.ResponseWriter, req *http.Request) {
subPath := req.URL.Path
if !strings.HasPrefix(subPath, prefix) {
return
}
subPath = strings.TrimPrefix(subPath, prefix)
if req.Method != "GET" && req.Method != "HEAD" {
resp.WriteHeader(http.StatusNotFound)
return
}
if handleRequest(resp, req, assetFS, subPath) {
return
}
resp.WriteHeader(http.StatusNotFound)
handleRequest(resp, req, assetFS, req.URL.Path)
}
}
@@ -71,16 +59,17 @@ func setWellKnownContentType(w http.ResponseWriter, file string) {
}
}
func handleRequest(w http.ResponseWriter, req *http.Request, fs http.FileSystem, file string) bool {
func handleRequest(w http.ResponseWriter, req *http.Request, fs http.FileSystem, file string) {
// actually, fs (http.FileSystem) is designed to be a safe interface, relative paths won't bypass its parent directory, it's also fine to do a clean here
f, err := fs.Open(util.PathJoinRelX(file))
if err != nil {
if os.IsNotExist(err) {
return false
w.WriteHeader(http.StatusNotFound)
return
}
w.WriteHeader(http.StatusInternalServerError)
log.Error("[Static] Open %q failed: %v", file, err)
return true
return
}
defer f.Close()
@@ -88,17 +77,16 @@ func handleRequest(w http.ResponseWriter, req *http.Request, fs http.FileSystem,
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error("[Static] %q exists, but fails to open: %v", file, err)
return true
return
}
// Try to serve index file
// need to serve index file? (no at the moment)
if fi.IsDir() {
w.WriteHeader(http.StatusNotFound)
return true
return
}
serveContent(w, req, fi, fi.ModTime(), f)
return true
}
type GzipBytesProvider interface {
+3 -3
View File
@@ -8,14 +8,14 @@ import (
"code.gitea.io/gitea/modules/log"
lru "github.com/hashicorp/golang-lru"
lru "github.com/hashicorp/golang-lru/v2"
)
var lruCache *lru.Cache
var lruCache *lru.Cache[string, any]
func init() {
var err error
lruCache, err = lru.New(1000)
lruCache, err = lru.New[string, any](1000)
if err != nil {
log.Fatal("failed to new LRU cache, err: %v", err)
}
+13 -11
View File
@@ -303,21 +303,23 @@ func GenerateGitContent(ctx context.Context, templateRepo, generateRepo *repo_mo
// GenerateRepoOptions contains the template units to generate
type GenerateRepoOptions struct {
Name string
DefaultBranch string
Description string
Private bool
GitContent bool
Topics bool
GitHooks bool
Webhooks bool
Avatar bool
IssueLabels bool
Name string
DefaultBranch string
Description string
Private bool
GitContent bool
Topics bool
GitHooks bool
Webhooks bool
Avatar bool
IssueLabels bool
ProtectedBranch bool
}
// IsValid checks whether at least one option is chosen for generation
func (gro GenerateRepoOptions) IsValid() bool {
return gro.GitContent || gro.Topics || gro.GitHooks || gro.Webhooks || gro.Avatar || gro.IssueLabels // or other items as they are added
return gro.GitContent || gro.Topics || gro.GitHooks || gro.Webhooks || gro.Avatar ||
gro.IssueLabels || gro.ProtectedBranch // or other items as they are added
}
// GenerateRepository generates a repository from a template
+1 -1
View File
@@ -86,7 +86,7 @@ func decodeEnvSectionKey(encoded string) (ok bool, section, key string) {
key += remaining
}
section = strings.ToLower(section)
ok = section != "" && key != ""
ok = key != ""
if !ok {
section = ""
key = ""
+6
View File
@@ -48,6 +48,12 @@ func TestDecodeEnvironmentKey(t *testing.T) {
assert.Equal(t, "", key)
assert.False(t, file)
ok, section, key, file = decodeEnvironmentKey(prefix, suffix, "GITEA____KEY")
assert.True(t, ok)
assert.Equal(t, "", section)
assert.Equal(t, "KEY", key)
assert.False(t, file)
ok, section, key, file = decodeEnvironmentKey(prefix, suffix, "GITEA__SEC__KEY")
assert.True(t, ok)
assert.Equal(t, "sec", section)
+1 -1
View File
@@ -324,7 +324,7 @@ func deprecatedSetting(rootCfg ConfigProvider, oldSection, oldKey, newSection, n
func deprecatedSettingFatal(rootCfg ConfigProvider, oldSection, oldKey, newSection, newKey, version string) {
if rootCfg.Section(oldSection).HasKey(oldKey) {
log.Fatal("Deprecated fallback `[%s]` `%s` present. Use `[%s]` `%s` instead. This fallback will be/has been removed in %s", oldSection, oldKey, newSection, newKey, version)
log.Fatal("Deprecated fallback `[%s]` `%s` present. Use `[%s]` `%s` instead. This fallback will be/has been removed in %s. Shutting down", oldSection, oldKey, newSection, newKey, version)
}
}
+4 -2
View File
@@ -74,8 +74,10 @@ func loadPackagesFrom(rootCfg ConfigProvider) (err error) {
Packages.ChunkedUploadPath = filepath.ToSlash(filepath.Join(AppDataPath, Packages.ChunkedUploadPath))
}
if err := os.MkdirAll(Packages.ChunkedUploadPath, os.ModePerm); err != nil {
return fmt.Errorf("unable to create chunked upload directory: %s (%v)", Packages.ChunkedUploadPath, err)
if HasInstallLock(rootCfg) {
if err := os.MkdirAll(Packages.ChunkedUploadPath, os.ModePerm); err != nil {
return fmt.Errorf("unable to create chunked upload directory: %s (%v)", Packages.ChunkedUploadPath, err)
}
}
Packages.LimitTotalOwnerSize = mustBytes(sec, "LIMIT_TOTAL_OWNER_SIZE")
+1 -1
View File
@@ -17,7 +17,7 @@ var (
// AppPath represents the path to the gitea binary
AppPath string
// AppWorkPath is the "working directory" of Gitea. It maps to the environment variable GITEA_WORK_DIR.
// AppWorkPath is the "working directory" of Gitea. It maps to the: WORK_PATH in app.ini, "--work-path" flag, environment variable GITEA_WORK_DIR.
// If that is not set it is the default set here by the linker or failing that the directory of AppPath.
// It is used as the base path for several other paths.
AppWorkPath string
-5
View File
@@ -349,9 +349,4 @@ func loadServerFrom(rootCfg ConfigProvider) {
default:
LandingPageURL = LandingPage(landingPage)
}
HasRobotsTxt, err = util.IsFile(path.Join(CustomPath, "robots.txt"))
if err != nil {
log.Error("Unable to check if %s is a file. Error: %v", path.Join(CustomPath, "robots.txt"), err)
}
}
+6 -20
View File
@@ -16,26 +16,17 @@ const (
CommitStatusError CommitStatusState = "error"
// CommitStatusFailure is for when the CommitStatus is Failure
CommitStatusFailure CommitStatusState = "failure"
// CommitStatusWarning is for when the CommitStatus is Warning
CommitStatusWarning CommitStatusState = "warning"
// CommitStatusRunning is for when the CommitStatus is Running
CommitStatusRunning CommitStatusState = "running"
)
// NoBetterThan returns true if this State is no better than the given State
func (css CommitStatusState) NoBetterThan(css2 CommitStatusState) bool {
switch css {
case CommitStatusError:
return true
case CommitStatusFailure:
return css2 != CommitStatusError
case CommitStatusWarning:
return css2 != CommitStatusError && css2 != CommitStatusFailure
case CommitStatusPending:
return css2 != CommitStatusError && css2 != CommitStatusFailure && css2 != CommitStatusWarning
default:
return css2 != CommitStatusError && css2 != CommitStatusFailure && css2 != CommitStatusWarning && css2 != CommitStatusPending
commitStatusPriorities := map[CommitStatusState]int{
CommitStatusError: 0,
CommitStatusFailure: 1,
CommitStatusPending: 2,
CommitStatusSuccess: 3,
}
return commitStatusPriorities[css] <= commitStatusPriorities[css2]
}
// IsPending represents if commit status state is pending
@@ -57,8 +48,3 @@ func (css CommitStatusState) IsError() bool {
func (css CommitStatusState) IsFailure() bool {
return css == CommitStatusFailure
}
// IsWarning represents if commit status state is warning
func (css CommitStatusState) IsWarning() bool {
return css == CommitStatusWarning
}
+3 -1
View File
@@ -242,6 +242,8 @@ type GenerateRepoOption struct {
Avatar bool `json:"avatar"`
// include labels in template repo
Labels bool `json:"labels"`
// include protected branches in template repo
ProtectedBranch bool `json:"protected_branch"`
}
// CreateBranchRepoOption options when creating a branch in a repository
@@ -331,7 +333,7 @@ type MigrateRepoOptions struct {
// required: true
RepoName string `json:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
// enum: git,github,gitea,gitlab
// enum: git,github,gitea,gitlab,gogs,onedev,gitbucket,codebase
Service string `json:"service"`
AuthUsername string `json:"auth_username"`
AuthPassword string `json:"auth_password"`
+1
View File
@@ -69,4 +69,5 @@ type CommitDateOptions struct {
// CommitAffectedFiles store information about files affected by the commit
type CommitAffectedFiles struct {
Filename string `json:"filename"`
Status string `json:"status"`
}
+3 -3
View File
@@ -26,7 +26,7 @@ type CreateFileOptions struct {
FileOptions
// content must be base64 encoded
// required: true
Content string `json:"content"`
ContentBase64 string `json:"content"`
}
// Branch returns branch name
@@ -54,7 +54,7 @@ type UpdateFileOptions struct {
DeleteFileOptions
// content must be base64 encoded
// required: true
Content string `json:"content"`
ContentBase64 string `json:"content"`
// from_path (optional) is the path of the original file which will be moved/renamed to the path in the URL
FromPath string `json:"from_path" binding:"MaxSize(500)"`
}
@@ -74,7 +74,7 @@ type ChangeFileOperation struct {
// required: true
Path string `json:"path" binding:"Required;MaxSize(500)"`
// new or updated file content, must be base64 encoded
Content string `json:"content"`
ContentBase64 string `json:"content"`
// sha is the SHA for the file that already exists, required for update or delete
SHA string `json:"sha"`
// old path of the file to move
+2 -2
View File
@@ -27,7 +27,7 @@ const defaultSize = 16
// Init discovers SVGs and populates the `SVGs` variable
func Init() error {
files, err := public.AssetFS().ListFiles("img/svg")
files, err := public.AssetFS().ListFiles("assets/img/svg")
if err != nil {
return err
}
@@ -38,7 +38,7 @@ func Init() error {
if path.Ext(file) != ".svg" {
continue
}
bs, err := public.AssetFS().ReadFile("img/svg", file)
bs, err := public.AssetFS().ReadFile("assets/img/svg", file)
if err != nil {
log.Error("Failed to read SVG file %s: %v", file, err)
} else {
+4 -18
View File
@@ -5,17 +5,6 @@ package middleware
import "net/url"
// flashes enumerates all the flash types
const (
SuccessFlash = "SuccessMsg"
ErrorFlash = "ErrorMsg"
WarnFlash = "WarningMsg"
InfoFlash = "InfoMsg"
)
// FlashNow FIXME:
var FlashNow bool
// Flash represents a one time data transfer between two requests.
type Flash struct {
DataStore ContextDataStore
@@ -27,15 +16,12 @@ func (f *Flash) set(name, msg string, current ...bool) {
if f.Values == nil {
f.Values = make(map[string][]string)
}
isShow := false
if (len(current) == 0 && FlashNow) ||
(len(current) > 0 && current[0]) {
isShow = true
}
if isShow {
showInCurrentPage := len(current) > 0 && current[0]
if showInCurrentPage {
// assign it to the context data, then the template can use ".Flash.XxxMsg" to render the message
f.DataStore.GetData()["Flash"] = f
} else {
// the message map will be saved into the cookie and be shown in next response (a new page response which decodes the cookie)
f.Set(name, msg)
}
}
+9 -14
View File
@@ -101,7 +101,7 @@ func (r *Route) wrapMiddlewareAndHandler(h []any) ([]func(http.Handler) http.Han
return middlewares, handlerFunc
}
func (r *Route) Methods(method, pattern string, h []any) {
func (r *Route) Methods(method, pattern string, h ...any) {
middlewares, handlerFunc := r.wrapMiddlewareAndHandler(h)
fullPattern := r.getPattern(pattern)
if strings.Contains(method, ",") {
@@ -126,49 +126,44 @@ func (r *Route) Any(pattern string, h ...any) {
r.R.With(middlewares...).HandleFunc(r.getPattern(pattern), handlerFunc)
}
// RouteMethods delegate special methods, it is an alias of "Methods", while the "pattern" is the first parameter
func (r *Route) RouteMethods(pattern, methods string, h ...any) {
r.Methods(methods, pattern, h)
}
// Delete delegate delete method
func (r *Route) Delete(pattern string, h ...any) {
r.Methods("DELETE", pattern, h)
r.Methods("DELETE", pattern, h...)
}
// Get delegate get method
func (r *Route) Get(pattern string, h ...any) {
r.Methods("GET", pattern, h)
r.Methods("GET", pattern, h...)
}
// GetOptions delegate get and options method
func (r *Route) GetOptions(pattern string, h ...any) {
r.Methods("GET,OPTIONS", pattern, h)
r.Methods("GET,OPTIONS", pattern, h...)
}
// PostOptions delegate post and options method
func (r *Route) PostOptions(pattern string, h ...any) {
r.Methods("POST,OPTIONS", pattern, h)
r.Methods("POST,OPTIONS", pattern, h...)
}
// Head delegate head method
func (r *Route) Head(pattern string, h ...any) {
r.Methods("HEAD", pattern, h)
r.Methods("HEAD", pattern, h...)
}
// Post delegate post method
func (r *Route) Post(pattern string, h ...any) {
r.Methods("POST", pattern, h)
r.Methods("POST", pattern, h...)
}
// Put delegate put method
func (r *Route) Put(pattern string, h ...any) {
r.Methods("PUT", pattern, h)
r.Methods("PUT", pattern, h...)
}
// Patch delegate patch method
func (r *Route) Patch(pattern string, h ...any) {
r.Methods("PATCH", pattern, h)
r.Methods("PATCH", pattern, h...)
}
// ServeHTTP implements http.Handler