mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-20 14:31:19 +02:00
fix migrations.go conflict
This commit is contained in:
@@ -5,9 +5,15 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/hcaptcha"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/mcaptcha"
|
||||
"code.gitea.io/gitea/modules/recaptcha"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"gitea.com/go-chi/captcha"
|
||||
@@ -28,3 +34,56 @@ func GetImageCaptcha() *captcha.Captcha {
|
||||
})
|
||||
return cpt
|
||||
}
|
||||
|
||||
// SetCaptchaData sets common captcha data
|
||||
func SetCaptchaData(ctx *Context) {
|
||||
if !setting.Service.EnableCaptcha {
|
||||
return
|
||||
}
|
||||
ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha
|
||||
ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL
|
||||
ctx.Data["Captcha"] = GetImageCaptcha()
|
||||
ctx.Data["CaptchaType"] = setting.Service.CaptchaType
|
||||
ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey
|
||||
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
|
||||
ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
|
||||
ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
|
||||
}
|
||||
|
||||
const (
|
||||
gRecaptchaResponseField = "g-recaptcha-response"
|
||||
hCaptchaResponseField = "h-captcha-response"
|
||||
mCaptchaResponseField = "m-captcha-response"
|
||||
)
|
||||
|
||||
// VerifyCaptcha verifies Captcha data
|
||||
// No-op if captchas are not enabled
|
||||
func VerifyCaptcha(ctx *Context, tpl base.TplName, form interface{}) {
|
||||
if !setting.Service.EnableCaptcha {
|
||||
return
|
||||
}
|
||||
|
||||
var valid bool
|
||||
var err error
|
||||
switch setting.Service.CaptchaType {
|
||||
case setting.ImageCaptcha:
|
||||
valid = GetImageCaptcha().VerifyReq(ctx.Req)
|
||||
case setting.ReCaptcha:
|
||||
valid, err = recaptcha.Verify(ctx, ctx.Req.Form.Get(gRecaptchaResponseField))
|
||||
case setting.HCaptcha:
|
||||
valid, err = hcaptcha.Verify(ctx, ctx.Req.Form.Get(hCaptchaResponseField))
|
||||
case setting.MCaptcha:
|
||||
valid, err = mcaptcha.Verify(ctx, ctx.Req.Form.Get(mCaptchaResponseField))
|
||||
default:
|
||||
ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType))
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Debug("%v", err)
|
||||
}
|
||||
|
||||
if !valid {
|
||||
ctx.Data["Err_Captcha"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tpl, form)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,9 +349,11 @@ func (ctx *Context) RespHeader() http.Header {
|
||||
type ServeHeaderOptions struct {
|
||||
ContentType string // defaults to "application/octet-stream"
|
||||
ContentTypeCharset string
|
||||
ContentLength *int64
|
||||
Disposition string // defaults to "attachment"
|
||||
Filename string
|
||||
CacheDuration time.Duration // defaults to 5 minutes
|
||||
LastModified time.Time
|
||||
}
|
||||
|
||||
// SetServeHeaders sets necessary content serve headers
|
||||
@@ -369,6 +371,10 @@ func (ctx *Context) SetServeHeaders(opts *ServeHeaderOptions) {
|
||||
header.Set("Content-Type", contentType)
|
||||
header.Set("X-Content-Type-Options", "nosniff")
|
||||
|
||||
if opts.ContentLength != nil {
|
||||
header.Set("Content-Length", strconv.FormatInt(*opts.ContentLength, 10))
|
||||
}
|
||||
|
||||
if opts.Filename != "" {
|
||||
disposition := opts.Disposition
|
||||
if disposition == "" {
|
||||
@@ -385,14 +391,16 @@ func (ctx *Context) SetServeHeaders(opts *ServeHeaderOptions) {
|
||||
duration = 5 * time.Minute
|
||||
}
|
||||
httpcache.AddCacheControlToHeader(header, duration)
|
||||
|
||||
if !opts.LastModified.IsZero() {
|
||||
header.Set("Last-Modified", opts.LastModified.UTC().Format(http.TimeFormat))
|
||||
}
|
||||
}
|
||||
|
||||
// ServeContent serves content to http request
|
||||
func (ctx *Context) ServeContent(name string, r io.ReadSeeker, modTime time.Time) {
|
||||
ctx.SetServeHeaders(&ServeHeaderOptions{
|
||||
Filename: name,
|
||||
})
|
||||
http.ServeContent(ctx.Resp, ctx.Req, name, modTime, r)
|
||||
func (ctx *Context) ServeContent(r io.ReadSeeker, opts *ServeHeaderOptions) {
|
||||
ctx.SetServeHeaders(opts)
|
||||
http.ServeContent(ctx.Resp, ctx.Req, opts.Filename, opts.LastModified, r)
|
||||
}
|
||||
|
||||
// UploadStream returns the request body or the first form file
|
||||
|
||||
@@ -441,8 +441,10 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
|
||||
userName := ctx.Params(":username")
|
||||
repoName := ctx.Params(":reponame")
|
||||
repoName = strings.TrimSuffix(repoName, ".git")
|
||||
repoName = strings.TrimSuffix(repoName, ".rss")
|
||||
repoName = strings.TrimSuffix(repoName, ".atom")
|
||||
if setting.EnableFeed {
|
||||
repoName = strings.TrimSuffix(repoName, ".rss")
|
||||
repoName = strings.TrimSuffix(repoName, ".atom")
|
||||
}
|
||||
|
||||
// Check if the user is the same as the repository owner
|
||||
if ctx.IsSigned && ctx.Doer.LowerName == strings.ToLower(userName) {
|
||||
@@ -1087,6 +1089,9 @@ func (ctx *Context) IssueTemplatesErrorsFromDefaultBranch() ([]*api.IssueTemplat
|
||||
if it, err := template.UnmarshalFromEntry(entry, dirName); err != nil {
|
||||
invalidFiles[fullName] = err
|
||||
} else {
|
||||
if !strings.HasPrefix(it.Ref, "refs/") { // Assume that the ref intended is always a branch - for tags users should use refs/tags/<ref>
|
||||
it.Ref = git.BranchPrefix + it.Ref
|
||||
}
|
||||
issueTemplates = append(issueTemplates, it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ package git
|
||||
import (
|
||||
"bytes"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-git/go-git/v5/plumbing/object"
|
||||
@@ -30,7 +31,9 @@ type Signature = object.Signature
|
||||
func newSignatureFromCommitline(line []byte) (_ *Signature, err error) {
|
||||
sig := new(Signature)
|
||||
emailStart := bytes.IndexByte(line, '<')
|
||||
sig.Name = string(line[:emailStart-1])
|
||||
if emailStart > 0 { // Empty name has already occurred, even if it shouldn't
|
||||
sig.Name = strings.TrimSpace(string(line[:emailStart-1]))
|
||||
}
|
||||
emailEnd := bytes.IndexByte(line, '>')
|
||||
sig.Email = string(line[emailStart+1 : emailEnd])
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -51,7 +52,9 @@ func newSignatureFromCommitline(line []byte) (sig *Signature, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
sig.Name = string(line[:emailStart-1])
|
||||
if emailStart > 0 { // Empty name has already occurred, even if it shouldn't
|
||||
sig.Name = strings.TrimSpace(string(line[:emailStart-1]))
|
||||
}
|
||||
sig.Email = string(line[emailStart+1 : emailEnd])
|
||||
|
||||
hasTime := emailEnd+2 < len(line)
|
||||
|
||||
@@ -100,6 +100,9 @@ func RefURL(repoURL, ref string) string {
|
||||
return repoURL + "/src/branch/" + refName
|
||||
case strings.HasPrefix(ref, TagPrefix):
|
||||
return repoURL + "/src/tag/" + refName
|
||||
case !IsValidSHAPattern(ref):
|
||||
// assume they mean a branch
|
||||
return repoURL + "/src/branch/" + refName
|
||||
default:
|
||||
return repoURL + "/src/commit/" + refName
|
||||
}
|
||||
|
||||
@@ -8,12 +8,13 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
||||
"github.com/santhosh-tekuri/jsonschema/v5"
|
||||
"gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Load project data from file, with optional validation
|
||||
@@ -84,13 +85,9 @@ func validate(bs []byte, datatype interface{}, isJSON bool) error {
|
||||
func toStringKeys(val interface{}) (interface{}, error) {
|
||||
var err error
|
||||
switch val := val.(type) {
|
||||
case map[interface{}]interface{}:
|
||||
case map[string]interface{}:
|
||||
m := make(map[string]interface{})
|
||||
for k, v := range val {
|
||||
k, ok := k.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("found non-string key %T %s", k, k)
|
||||
}
|
||||
m[k], err = toStringKeys(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -106,6 +103,8 @@ func toStringKeys(val interface{}) (interface{}, error) {
|
||||
}
|
||||
}
|
||||
return l, nil
|
||||
case time.Time:
|
||||
return val.Format(time.RFC3339), nil
|
||||
default:
|
||||
return val, nil
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/validation"
|
||||
|
||||
"github.com/hashicorp/go-version"
|
||||
"gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/validation"
|
||||
|
||||
"github.com/hashicorp/go-version"
|
||||
"gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/modules/validation"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -120,7 +120,7 @@ func (r requirement) AsVersionRequirement() []VersionRequirement {
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
vm, ok := req[1].(map[interface{}]interface{})
|
||||
vm, ok := req[1].(map[string]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ var Service = struct {
|
||||
EnableReverseProxyEmail bool
|
||||
EnableReverseProxyFullName bool
|
||||
EnableCaptcha bool
|
||||
RequireCaptchaForLogin bool
|
||||
RequireExternalRegistrationCaptcha bool
|
||||
RequireExternalRegistrationPassword bool
|
||||
CaptchaType string
|
||||
@@ -130,6 +131,7 @@ func newService() {
|
||||
Service.EnableReverseProxyEmail = sec.Key("ENABLE_REVERSE_PROXY_EMAIL").MustBool()
|
||||
Service.EnableReverseProxyFullName = sec.Key("ENABLE_REVERSE_PROXY_FULL_NAME").MustBool()
|
||||
Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool(false)
|
||||
Service.RequireCaptchaForLogin = sec.Key("REQUIRE_CAPTCHA_FOR_LOGIN").MustBool(false)
|
||||
Service.RequireExternalRegistrationCaptcha = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA").MustBool(Service.EnableCaptcha)
|
||||
Service.RequireExternalRegistrationPassword = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_PASSWORD").MustBool()
|
||||
Service.CaptchaType = sec.Key("CAPTCHA_TYPE").MustString(ImageCaptcha)
|
||||
|
||||
@@ -440,6 +440,7 @@ var (
|
||||
ShowFooterBranding bool
|
||||
ShowFooterVersion bool
|
||||
ShowFooterTemplateLoadTime bool
|
||||
EnableFeed bool
|
||||
|
||||
// Global setting objects
|
||||
Cfg *ini.File
|
||||
@@ -1102,6 +1103,7 @@ func loadFromConf(allowEmpty bool, extraConfig string) {
|
||||
ShowFooterVersion = Cfg.Section("other").Key("SHOW_FOOTER_VERSION").MustBool(true)
|
||||
ShowFooterTemplateLoadTime = Cfg.Section("other").Key("SHOW_FOOTER_TEMPLATE_LOAD_TIME").MustBool(true)
|
||||
EnableSitemap = Cfg.Section("other").Key("ENABLE_SITEMAP").MustBool(true)
|
||||
EnableFeed = Cfg.Section("other").Key("ENABLE_FEED").MustBool(true)
|
||||
|
||||
UI.ShowUserEmail = Cfg.Section("ui").Key("SHOW_USER_EMAIL").MustBool(true)
|
||||
UI.DefaultShowFullName = Cfg.Section("ui").Key("DEFAULT_SHOW_FULL_NAME").MustBool(false)
|
||||
|
||||
@@ -607,7 +607,7 @@ func AvatarHTML(src string, size int, class, name string) template.HTML {
|
||||
|
||||
// Avatar renders user avatars. args: user, size (int), class (string)
|
||||
func Avatar(item interface{}, others ...interface{}) template.HTML {
|
||||
size, class := gitea_html.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, "ui avatar vm", others...)
|
||||
size, class := gitea_html.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, avatars.DefaultAvatarClass, others...)
|
||||
|
||||
switch t := item.(type) {
|
||||
case *user_model.User:
|
||||
@@ -638,7 +638,7 @@ func AvatarByAction(action *activities_model.Action, others ...interface{}) temp
|
||||
|
||||
// RepoAvatar renders repo avatars. args: repo, size(int), class (string)
|
||||
func RepoAvatar(repo *repo_model.Repository, others ...interface{}) template.HTML {
|
||||
size, class := gitea_html.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, "ui avatar", others...)
|
||||
size, class := gitea_html.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, avatars.DefaultAvatarClass, others...)
|
||||
|
||||
src := repo.RelAvatarLink()
|
||||
if src != "" {
|
||||
@@ -649,7 +649,7 @@ func RepoAvatar(repo *repo_model.Repository, others ...interface{}) template.HTM
|
||||
|
||||
// AvatarByEmail renders avatars by email address. args: email, name, size (int), class (string)
|
||||
func AvatarByEmail(email, name string, others ...interface{}) template.HTML {
|
||||
size, class := gitea_html.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, "ui avatar", others...)
|
||||
size, class := gitea_html.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, avatars.DefaultAvatarClass, others...)
|
||||
src := avatars.GenerateEmailAvatarFastLink(email, size*setting.Avatar.RenderedSizeFactor)
|
||||
|
||||
if src != "" {
|
||||
|
||||
Reference in New Issue
Block a user