Skip to content

Commit

Permalink
Merge branch 'main' into admin-common-jquery-ajax
Browse files Browse the repository at this point in the history
  • Loading branch information
yardenshoham authored Feb 25, 2024
2 parents c94cfd4 + f9207b0 commit 815a31b
Show file tree
Hide file tree
Showing 62 changed files with 333 additions and 250 deletions.
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ Rui Chen <[email protected]> (@chenrui333)
Nanguan Lin <[email protected]> (@lng2020)
kerwin612 <[email protected]> (@kerwin612)
Gary Wang <[email protected]> (@BLumia)
Tim-Niclas Oelschläger <[email protected]> (@zokkis)
2 changes: 1 addition & 1 deletion docs/content/administration/mail-templates.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ the messages. Here's a list of some of them:
| `AppDomain` | - | Any | Gitea's host name |
| `EllipsisString` | string, int | Any | Truncates a string to the specified length; adds ellipsis as needed |
| `Str2html` | string | Body only | Sanitizes text by removing any HTML tags from it. |
| `Safe` | string | Body only | Takes the input as HTML; can be used for `.ReviewComments.RenderedContent`. |
| `SafeHTML` | string | Body only | Takes the input as HTML; can be used for `.ReviewComments.RenderedContent`. |

These are _functions_, not metadata, so they have to be used:

Expand Down
16 changes: 8 additions & 8 deletions docs/content/administration/mail-templates.zh-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,14 +242,14 @@ _主题_ 和 _邮件正文_ 由 [Golang的模板引擎](https://go.dev/pkg/text/

模板系统包含一些函数,可用于进一步处理和格式化消息。以下是其中一些函数的列表:

| 函数名 | 参数 | 可用于 | 用法 |
| ----------------- | ----------- | ------------ | --------------------------------------------------------------------------------- |
| `AppUrl` | - | 任何地方 | Gitea 的 URL |
| `AppName` | - | 任何地方 |`app.ini` 中设置,通常为 "Gitea" |
| `AppDomain` | - | 任何地方 | Gitea 的主机名 |
| `EllipsisString` | string, int | 任何地方 | 将字符串截断为指定长度;根据需要添加省略号 |
| `Str2html` | string | 仅正文部分 | 通过删除其中的 HTML 标签对文本进行清理 |
| `Safe` | string | 仅正文部分 | 将输入作为 HTML 处理;可用于 `.ReviewComments.RenderedContent` 等字段 |
| 函数名 | 参数 | 可用于 | 用法 |
|------------------| ----------- | ------------ | --------------------------------------------------------------------------------- |
| `AppUrl` | - | 任何地方 | Gitea 的 URL |
| `AppName` | - | 任何地方 |`app.ini` 中设置,通常为 "Gitea" |
| `AppDomain` | - | 任何地方 | Gitea 的主机名 |
| `EllipsisString` | string, int | 任何地方 | 将字符串截断为指定长度;根据需要添加省略号 |
| `Str2html` | string | 仅正文部分 | 通过删除其中的 HTML 标签对文本进行清理 |
| `SafeHTML` | string | 仅正文部分 | 将输入作为 HTML 处理;可用于 `.ReviewComments.RenderedContent` 等字段 |

这些都是 _函数_,而不是元数据,因此必须按以下方式使用:

Expand Down
37 changes: 22 additions & 15 deletions models/issues/comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,9 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
// Check comment type.
switch opts.Type {
case CommentTypeCode:
if err = updateAttachments(ctx, opts, comment); err != nil {
return err
}
if comment.ReviewID != 0 {
if comment.Review == nil {
if err := comment.loadReview(ctx); err != nil {
Expand All @@ -872,22 +875,9 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
}
fallthrough
case CommentTypeReview:
// Check attachments
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, opts.Attachments)
if err != nil {
return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %w", opts.Attachments, err)
}

for i := range attachments {
attachments[i].IssueID = opts.Issue.ID
attachments[i].CommentID = comment.ID
// No assign value could be 0, so ignore AllCols().
if _, err = db.GetEngine(ctx).ID(attachments[i].ID).Update(attachments[i]); err != nil {
return fmt.Errorf("update attachment [%d]: %w", attachments[i].ID, err)
}
if err = updateAttachments(ctx, opts, comment); err != nil {
return err
}

comment.Attachments = attachments
case CommentTypeReopen, CommentTypeClose:
if err = repo_model.UpdateRepoIssueNumbers(ctx, opts.Issue.RepoID, opts.Issue.IsPull, true); err != nil {
return err
Expand All @@ -897,6 +887,23 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
return UpdateIssueCols(ctx, opts.Issue, "updated_unix")
}

func updateAttachments(ctx context.Context, opts *CreateCommentOptions, comment *Comment) error {
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, opts.Attachments)
if err != nil {
return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %w", opts.Attachments, err)
}
for i := range attachments {
attachments[i].IssueID = opts.Issue.ID
attachments[i].CommentID = comment.ID
// No assign value could be 0, so ignore AllCols().
if _, err = db.GetEngine(ctx).ID(attachments[i].ID).Update(attachments[i]); err != nil {
return fmt.Errorf("update attachment [%d]: %w", attachments[i].ID, err)
}
}
comment.Attachments = attachments
return nil
}

func createDeadlineComment(ctx context.Context, doer *user_model.User, issue *Issue, newDeadlineUnix timeutil.TimeStamp) (*Comment, error) {
var content string
var commentType CommentType
Expand Down
38 changes: 20 additions & 18 deletions modules/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,18 @@ var (
// DefaultContext is the default context to run git commands in, must be initialized by git.InitXxx
DefaultContext context.Context

SupportProcReceive bool // >= 2.29
SupportHashSha256 bool // >= 2.42, SHA-256 repositories no longer an ‘experimental curiosity’
DefaultFeatures struct {
GitVersion *version.Version

gitVersion *version.Version
SupportProcReceive bool // >= 2.29
SupportHashSha256 bool // >= 2.42, SHA-256 repositories no longer an ‘experimental curiosity’
}
)

// loadGitVersion tries to get the current git version and stores it into a global variable
func loadGitVersion() error {
// doesn't need RWMutex because it's executed by Init()
if gitVersion != nil {
if DefaultFeatures.GitVersion != nil {
return nil
}

Expand All @@ -53,7 +55,7 @@ func loadGitVersion() error {

ver, err := parseGitVersionLine(strings.TrimSpace(stdout))
if err == nil {
gitVersion = ver
DefaultFeatures.GitVersion = ver
}
return err
}
Expand Down Expand Up @@ -93,7 +95,7 @@ func SetExecutablePath(path string) error {
return err
}

if gitVersion.LessThan(versionRequired) {
if DefaultFeatures.GitVersion.LessThan(versionRequired) {
moreHint := "get git: https://git-scm.com/download/"
if runtime.GOOS == "linux" {
// there are a lot of CentOS/RHEL users using old git, so we add a special hint for them
Expand All @@ -102,22 +104,22 @@ func SetExecutablePath(path string) error {
moreHint = "get git: https://git-scm.com/download/linux and https://ius.io"
}
}
return fmt.Errorf("installed git version %q is not supported, Gitea requires git version >= %q, %s", gitVersion.Original(), RequiredVersion, moreHint)
return fmt.Errorf("installed git version %q is not supported, Gitea requires git version >= %q, %s", DefaultFeatures.GitVersion.Original(), RequiredVersion, moreHint)
}

if err = checkGitVersionCompatibility(gitVersion); err != nil {
return fmt.Errorf("installed git version %s has a known compatibility issue with Gitea: %w, please upgrade (or downgrade) git", gitVersion.String(), err)
if err = checkGitVersionCompatibility(DefaultFeatures.GitVersion); err != nil {
return fmt.Errorf("installed git version %s has a known compatibility issue with Gitea: %w, please upgrade (or downgrade) git", DefaultFeatures.GitVersion.String(), err)
}
return nil
}

// VersionInfo returns git version information
func VersionInfo() string {
if gitVersion == nil {
if DefaultFeatures.GitVersion == nil {
return "(git not found)"
}
format := "%s"
args := []any{gitVersion.Original()}
args := []any{DefaultFeatures.GitVersion.Original()}
// Since git wire protocol has been released from git v2.18
if setting.Git.EnableAutoGitWireProtocol && CheckGitVersionAtLeast("2.18") == nil {
format += ", Wire Protocol %s Enabled"
Expand Down Expand Up @@ -187,9 +189,9 @@ func InitFull(ctx context.Context) (err error) {
if CheckGitVersionAtLeast("2.9") == nil {
globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=")
}
SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil
SupportHashSha256 = CheckGitVersionAtLeast("2.42") == nil && !isGogit
if SupportHashSha256 {
DefaultFeatures.SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil
DefaultFeatures.SupportHashSha256 = CheckGitVersionAtLeast("2.42") == nil && !isGogit
if DefaultFeatures.SupportHashSha256 {
SupportedObjectFormats = append(SupportedObjectFormats, Sha256ObjectFormat)
} else {
log.Warn("sha256 hash support is disabled - requires Git >= 2.42. Gogit is currently unsupported")
Expand Down Expand Up @@ -254,7 +256,7 @@ func syncGitConfig() (err error) {
}
}

if SupportProcReceive {
if DefaultFeatures.SupportProcReceive {
// set support for AGit flow
if err := configAddNonExist("receive.procReceiveRefs", "refs/for"); err != nil {
return err
Expand Down Expand Up @@ -309,15 +311,15 @@ func syncGitConfig() (err error) {

// CheckGitVersionAtLeast check git version is at least the constraint version
func CheckGitVersionAtLeast(atLeast string) error {
if gitVersion == nil {
if DefaultFeatures.GitVersion == nil {
panic("git module is not initialized") // it shouldn't happen
}
atLeastVersion, err := version.NewVersion(atLeast)
if err != nil {
return err
}
if gitVersion.Compare(atLeastVersion) < 0 {
return fmt.Errorf("installed git binary version %s is not at least %s", gitVersion.Original(), atLeast)
if DefaultFeatures.GitVersion.Compare(atLeastVersion) < 0 {
return fmt.Errorf("installed git binary version %s is not at least %s", DefaultFeatures.GitVersion.Original(), atLeast)
}
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion modules/git/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func InitRepository(ctx context.Context, repoPath string, bare bool, objectForma
if !IsValidObjectFormat(objectFormatName) {
return fmt.Errorf("invalid object format: %s", objectFormatName)
}
if SupportHashSha256 {
if DefaultFeatures.SupportHashSha256 {
cmd.AddOptionValues("--object-format", objectFormatName)
}

Expand Down
37 changes: 22 additions & 15 deletions modules/templates/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import (
"html"
"html/template"
"net/url"
"slices"
"strings"
"time"

user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/emoji"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/svg"
Expand All @@ -35,7 +35,8 @@ func NewFuncMap() template.FuncMap {
// html/template related functions
"dict": dict, // it's lowercase because this name has been widely used. Our other functions should have uppercase names.
"Eval": Eval,
"Safe": Safe,
"SafeHTML": SafeHTML,
"HTMLFormat": HTMLFormat,
"Escape": Escape,
"QueryEscape": url.QueryEscape,
"JSEscape": JSEscapeSafe,
Expand Down Expand Up @@ -159,7 +160,6 @@ func NewFuncMap() template.FuncMap {
"RenderCodeBlock": RenderCodeBlock,
"RenderIssueTitle": RenderIssueTitle,
"RenderEmoji": RenderEmoji,
"RenderEmojiPlain": RenderEmojiPlain,
"ReactionToEmoji": ReactionToEmoji,

"RenderMarkdownToHtml": RenderMarkdownToHtml,
Expand All @@ -179,8 +179,25 @@ func NewFuncMap() template.FuncMap {
}
}

// Safe render raw as HTML
func Safe(s any) template.HTML {
func HTMLFormat(s string, rawArgs ...any) template.HTML {
args := slices.Clone(rawArgs)
for i, v := range args {
switch v := v.(type) {
case nil, bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, template.HTML:
// for most basic types (including template.HTML which is safe), just do nothing and use it
case string:
args[i] = template.HTMLEscapeString(v)
case fmt.Stringer:
args[i] = template.HTMLEscapeString(v.String())
default:
args[i] = template.HTMLEscapeString(fmt.Sprint(v))
}
}
return template.HTML(fmt.Sprintf(s, args...))
}

// SafeHTML render raw as HTML
func SafeHTML(s any) template.HTML {
switch v := s.(type) {
case string:
return template.HTML(v)
Expand Down Expand Up @@ -215,16 +232,6 @@ func JSEscapeSafe(s string) template.HTML {
return template.HTML(template.JSEscapeString(s))
}

func RenderEmojiPlain(s any) any {
switch v := s.(type) {
case string:
return emoji.ReplaceAliases(v)
case template.HTML:
return template.HTML(emoji.ReplaceAliases(string(v)))
}
panic(fmt.Sprintf("unexpected type %T", s))
}

// DotEscape wraps a dots in names with ZWJ [U+200D] in order to prevent autolinkers from detecting these as urls
func DotEscape(raw string) string {
return strings.ReplaceAll(raw, ".", "\u200d.\u200d")
Expand Down
5 changes: 5 additions & 0 deletions modules/templates/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package templates

import (
"html/template"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -56,3 +57,7 @@ func TestSubjectBodySeparator(t *testing.T) {
func TestJSEscapeSafe(t *testing.T) {
assert.EqualValues(t, `\u0026\u003C\u003E\'\"`, JSEscapeSafe(`&<>'"`))
}

func TestHTMLFormat(t *testing.T) {
assert.Equal(t, template.HTML("<a>&lt; < 1</a>"), HTMLFormat("<a>%s %s %d</a>", "<", template.HTML("<"), 1))
}
1 change: 1 addition & 0 deletions routers/api/v1/repo/pull_review.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ func CreatePullReview(ctx *context.APIContext) {
true, // pending review
0, // no reply
opts.CommitID,
nil,
); err != nil {
ctx.Error(http.StatusInternalServerError, "CreateCodeComment", err)
return
Expand Down
2 changes: 1 addition & 1 deletion routers/private/hook_post_receive.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {

// post update for agit pull request
// FIXME: use pr.Flow to test whether it's an Agit PR or a GH PR
if git.SupportProcReceive && refFullName.IsPull() {
if git.DefaultFeatures.SupportProcReceive && refFullName.IsPull() {
if repo == nil {
repo = loadRepository(ctx, ownerName, repoName)
if ctx.Written() {
Expand Down
2 changes: 1 addition & 1 deletion routers/private/hook_pre_receive.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func HookPreReceive(ctx *gitea_context.PrivateContext) {
preReceiveBranch(ourCtx, oldCommitID, newCommitID, refFullName)
case refFullName.IsTag():
preReceiveTag(ourCtx, oldCommitID, newCommitID, refFullName)
case git.SupportProcReceive && refFullName.IsFor():
case git.DefaultFeatures.SupportProcReceive && refFullName.IsFor():
preReceiveFor(ourCtx, oldCommitID, newCommitID, refFullName)
default:
ourCtx.AssertCanWriteCode()
Expand Down
2 changes: 1 addition & 1 deletion routers/private/hook_proc_receive.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
// HookProcReceive proc-receive hook - only handles agit Proc-Receive requests at present
func HookProcReceive(ctx *gitea_context.PrivateContext) {
opts := web.GetForm(ctx).(*private.HookOptions)
if !git.SupportProcReceive {
if !git.DefaultFeatures.SupportProcReceive {
ctx.Status(http.StatusNotFound)
return
}
Expand Down
2 changes: 1 addition & 1 deletion routers/private/serv.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ func ServCommand(ctx *context.PrivateContext) {
}
} else {
// Because of the special ref "refs/for" we will need to delay write permission check
if git.SupportProcReceive && unitType == unit.TypeCode {
if git.DefaultFeatures.SupportProcReceive && unitType == unit.TypeCode {
mode = perm.AccessModeRead
}

Expand Down
2 changes: 1 addition & 1 deletion routers/web/misc/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
)

func SSHInfo(rw http.ResponseWriter, req *http.Request) {
if !git.SupportProcReceive {
if !git.DefaultFeatures.SupportProcReceive {
rw.WriteHeader(http.StatusNotFound)
return
}
Expand Down
2 changes: 1 addition & 1 deletion routers/web/repo/githttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ func httpBase(ctx *context.Context) *serviceHandler {

if repoExist {
// Because of special ref "refs/for" .. , need delay write permission check
if git.SupportProcReceive {
if git.DefaultFeatures.SupportProcReceive {
accessMode = perm.AccessModeRead
}

Expand Down
7 changes: 6 additions & 1 deletion routers/web/repo/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/emoji"
"code.gitea.io/gitea/modules/git"
issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
issue_template "code.gitea.io/gitea/modules/issue/template"
Expand Down Expand Up @@ -1435,7 +1436,7 @@ func ViewIssue(ctx *context.Context) {
return
}

ctx.Data["Title"] = fmt.Sprintf("#%d - %s", issue.Index, issue.Title)
ctx.Data["Title"] = fmt.Sprintf("#%d - %s", issue.Index, emoji.ReplaceAliases(issue.Title))

iw := new(issues_model.IssueWatch)
if ctx.Doer != nil {
Expand Down Expand Up @@ -1717,6 +1718,10 @@ func ViewIssue(ctx *context.Context) {
for _, codeComments := range comment.Review.CodeComments {
for _, lineComments := range codeComments {
for _, c := range lineComments {
if err := c.LoadAttachments(ctx); err != nil {
ctx.ServerError("LoadAttachments", err)
return
}
// Check tag.
role, ok = marked[c.PosterID]
if ok {
Expand Down
Loading

0 comments on commit 815a31b

Please sign in to comment.