From 66bae322b404ab6b96496414ea79f9a34002aa50 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Sat, 17 Feb 2024 19:51:35 +0200 Subject: [PATCH 01/18] Remove unneccesary `initUserAuthLinkAccountView` from "link account" page (#29217) Signed-off-by: Yarden Shoham Co-authored-by: wxiaoguang (cherry picked from commit 3da2c63354eb3804c7aec3c688b066b044f2c30e) --- web_src/js/features/user-auth.js | 28 ---------------------------- web_src/js/index.js | 3 +-- 2 files changed, 1 insertion(+), 30 deletions(-) diff --git a/web_src/js/features/user-auth.js b/web_src/js/features/user-auth.js index af380dcfc7..60d186e699 100644 --- a/web_src/js/features/user-auth.js +++ b/web_src/js/features/user-auth.js @@ -1,4 +1,3 @@ -import $ from 'jquery'; import {checkAppUrl} from './common-global.js'; export function initUserAuthOauth2() { @@ -21,30 +20,3 @@ export function initUserAuthOauth2() { }); } } - -export function initUserAuthLinkAccountView() { - const $lnkUserPage = $('.page-content.user.link-account'); - if ($lnkUserPage.length === 0) { - return false; - } - - const $signinTab = $lnkUserPage.find('.item[data-tab="auth-link-signin-tab"]'); - const $signUpTab = $lnkUserPage.find('.item[data-tab="auth-link-signup-tab"]'); - const $signInView = $lnkUserPage.find('.tab[data-tab="auth-link-signin-tab"]'); - const $signUpView = $lnkUserPage.find('.tab[data-tab="auth-link-signup-tab"]'); - - $signUpTab.on('click', () => { - $signinTab.removeClass('active'); - $signInView.removeClass('active'); - $signUpTab.addClass('active'); - $signUpView.addClass('active'); - return false; - }); - - $signinTab.on('click', () => { - $signUpTab.removeClass('active'); - $signUpView.removeClass('active'); - $signinTab.addClass('active'); - $signInView.addClass('active'); - }); -} diff --git a/web_src/js/index.js b/web_src/js/index.js index 078f9fc9df..117279c3c4 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -23,7 +23,7 @@ import {initFindFileInRepo} from './features/repo-findfile.js'; import {initCommentContent, initMarkupContent} from './markup/content.js'; import {initPdfViewer} from './render/pdf.js'; -import {initUserAuthLinkAccountView, initUserAuthOauth2} from './features/user-auth.js'; +import {initUserAuthOauth2} from './features/user-auth.js'; import { initRepoIssueDue, initRepoIssueReferenceRepositorySearch, @@ -178,7 +178,6 @@ onDomReady(() => { initCommitStatuses(); initCaptcha(); - initUserAuthLinkAccountView(); initUserAuthOauth2(); initUserAuthWebAuthn(); initUserAuthWebAuthnRegister(); From ca46f7f7e0ee98472cd82a5c9b23c22fa790a2f5 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Sat, 17 Feb 2024 22:07:47 +0200 Subject: [PATCH 02/18] Remove jQuery from repo migrate page (#29219) - Switched to plain JavaScript - Tested the repo migrate functionality and it works as before # Demo using JavaScript without jQuery ![action](https://github.com/go-gitea/gitea/assets/20454870/44ad134b-832e-44b8-8e77-7cc8603d95fe) --------- Signed-off-by: Yarden Shoham Co-authored-by: silverwind (cherry picked from commit 5e1bf3efe2ad3ba6cd30db187ca59b94c3fcdafa) --- web_src/js/features/repo-migrate.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/web_src/js/features/repo-migrate.js b/web_src/js/features/repo-migrate.js index cae28fdd1b..490e7df0e4 100644 --- a/web_src/js/features/repo-migrate.js +++ b/web_src/js/features/repo-migrate.js @@ -1,18 +1,17 @@ -import $ from 'jquery'; import {hideElem, showElem} from '../utils/dom.js'; import {GET, POST} from '../modules/fetch.js'; const {appSubUrl} = window.config; export function initRepoMigrationStatusChecker() { - const $repoMigrating = $('#repo_migrating'); - if (!$repoMigrating.length) return; + const repoMigrating = document.getElementById('repo_migrating'); + if (!repoMigrating) return; - $('#repo_migrating_retry').on('click', doMigrationRetry); + document.getElementById('repo_migrating_retry').addEventListener('click', doMigrationRetry); - const task = $repoMigrating.attr('data-migrating-task-id'); + const task = repoMigrating.getAttribute('data-migrating-task-id'); - // returns true if the refresh still need to be called after a while + // returns true if the refresh still needs to be called after a while const refresh = async () => { const res = await GET(`${appSubUrl}/user/task/${task}`); if (res.status !== 200) return true; // continue to refresh if network error occurs @@ -21,7 +20,7 @@ export function initRepoMigrationStatusChecker() { // for all status if (data.message) { - $('#repo_migrating_progress_message').text(data.message); + document.getElementById('repo_migrating_progress_message').textContent = data.message; } // TaskStatusFinished @@ -37,7 +36,7 @@ export function initRepoMigrationStatusChecker() { showElem('#repo_migrating_retry'); showElem('#repo_migrating_failed'); showElem('#repo_migrating_failed_image'); - $('#repo_migrating_failed_error').text(data.message); + document.getElementById('repo_migrating_failed_error').textContent = data.message; return false; } @@ -59,6 +58,6 @@ export function initRepoMigrationStatusChecker() { } async function doMigrationRetry(e) { - await POST($(e.target).attr('data-migrating-task-retry-url')); + await POST(e.target.getAttribute('data-migrating-task-retry-url')); window.location.reload(); } From bdf470785d22c4679c0a8ef278a532a717f9486c Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 18 Feb 2024 09:48:59 +0800 Subject: [PATCH 03/18] Use "Safe" modifier for manually constructed safe HTML strings in templates (#29227) Follow #29165. These HTML strings are safe to be rendered directly, to avoid double-escaping. (cherry picked from commit a784ed3d6c6946fd9bf95f2e910f52f549326fe2) --- templates/admin/packages/list.tmpl | 2 +- templates/admin/repo/list.tmpl | 2 +- templates/admin/stacktrace.tmpl | 2 +- templates/org/member/members.tmpl | 4 ++-- templates/org/team/members.tmpl | 2 +- templates/org/team/sidebar.tmpl | 2 +- templates/org/team/teams.tmpl | 2 +- templates/repo/commit_page.tmpl | 4 ++-- templates/repo/issue/view_content/comments.tmpl | 4 ++-- templates/repo/issue/view_content/pull.tmpl | 2 +- templates/repo/settings/webhook/settings.tmpl | 2 +- templates/user/settings/organization.tmpl | 2 +- 12 files changed, 15 insertions(+), 15 deletions(-) diff --git a/templates/admin/packages/list.tmpl b/templates/admin/packages/list.tmpl index 5cfd9ddefa..04f76748d0 100644 --- a/templates/admin/packages/list.tmpl +++ b/templates/admin/packages/list.tmpl @@ -88,7 +88,7 @@ {{ctx.Locale.Tr "packages.settings.delete"}}
- {{ctx.Locale.Tr "packages.settings.delete.notice" `` `` | Safe}} + {{ctx.Locale.Tr "packages.settings.delete.notice" (``|Safe) (``|Safe)}}
{{template "base/modal_actions_confirm" .}} diff --git a/templates/admin/repo/list.tmpl b/templates/admin/repo/list.tmpl index fdba0734a2..c7a6ec7e4e 100644 --- a/templates/admin/repo/list.tmpl +++ b/templates/admin/repo/list.tmpl @@ -101,7 +101,7 @@

{{ctx.Locale.Tr "repo.settings.delete_desc"}}

- {{ctx.Locale.Tr "repo.settings.delete_notices_2" `` | Safe}}
+ {{ctx.Locale.Tr "repo.settings.delete_notices_2" (``|Safe)}}
{{ctx.Locale.Tr "repo.settings.delete_notices_fork_1"}}
{{template "base/modal_actions_confirm" .}} diff --git a/templates/admin/stacktrace.tmpl b/templates/admin/stacktrace.tmpl index 894e41f8d7..aa5e810cd7 100644 --- a/templates/admin/stacktrace.tmpl +++ b/templates/admin/stacktrace.tmpl @@ -39,7 +39,7 @@ {{ctx.Locale.Tr "admin.monitor.process.cancel"}}
-

{{ctx.Locale.Tr "admin.monitor.process.cancel_notices" `` | Safe}}

+

{{ctx.Locale.Tr "admin.monitor.process.cancel_notices" (``|Safe)}}

{{ctx.Locale.Tr "admin.monitor.process.cancel_desc"}}

{{template "base/modal_actions_confirm" .}} diff --git a/templates/org/member/members.tmpl b/templates/org/member/members.tmpl index e4ddb69805..03509ec93e 100644 --- a/templates/org/member/members.tmpl +++ b/templates/org/member/members.tmpl @@ -73,7 +73,7 @@ {{ctx.Locale.Tr "org.members.leave"}}
-

{{ctx.Locale.Tr "org.members.leave.detail" `` | Safe}}

+

{{ctx.Locale.Tr "org.members.leave.detail" (``|Safe)}}

{{template "base/modal_actions_confirm" .}} @@ -82,7 +82,7 @@ {{ctx.Locale.Tr "org.members.remove"}}
-

{{ctx.Locale.Tr "org.members.remove.detail" `` `` | Safe}}

+

{{ctx.Locale.Tr "org.members.remove.detail" (``|Safe) (``|Safe)}}

{{template "base/modal_actions_confirm" .}} diff --git a/templates/org/team/members.tmpl b/templates/org/team/members.tmpl index da63d82967..dd4ece1433 100644 --- a/templates/org/team/members.tmpl +++ b/templates/org/team/members.tmpl @@ -81,7 +81,7 @@ {{ctx.Locale.Tr "org.members.remove"}}
-

{{ctx.Locale.Tr "org.members.remove.detail" `` `` | Safe}}

+

{{ctx.Locale.Tr "org.members.remove.detail" (``|Safe) (``|Safe)}}

{{template "base/modal_actions_confirm" .}} diff --git a/templates/org/team/sidebar.tmpl b/templates/org/team/sidebar.tmpl index 29e7cf7cdd..37550ab71f 100644 --- a/templates/org/team/sidebar.tmpl +++ b/templates/org/team/sidebar.tmpl @@ -88,7 +88,7 @@ {{ctx.Locale.Tr "org.teams.leave"}}
-

{{ctx.Locale.Tr "org.teams.leave.detail" `` | Safe}}

+

{{ctx.Locale.Tr "org.teams.leave.detail" (``|Safe)}}

{{template "base/modal_actions_confirm" .}} diff --git a/templates/org/team/teams.tmpl b/templates/org/team/teams.tmpl index f4ceada2a7..b518d7d9d7 100644 --- a/templates/org/team/teams.tmpl +++ b/templates/org/team/teams.tmpl @@ -49,7 +49,7 @@ {{ctx.Locale.Tr "org.teams.leave"}}
-

{{ctx.Locale.Tr "org.teams.leave.detail" `` | Safe}}

+

{{ctx.Locale.Tr "org.teams.leave.detail" (``|Safe)}}

{{template "base/modal_actions_confirm" .}} diff --git a/templates/repo/commit_page.tmpl b/templates/repo/commit_page.tmpl index 01fa45babe..ce9fcecd8b 100644 --- a/templates/repo/commit_page.tmpl +++ b/templates/repo/commit_page.tmpl @@ -88,7 +88,7 @@ {{.CsrfTokenHtml}}
@@ -113,7 +113,7 @@
diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index f71ee2f11b..9e50ee4d94 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -112,9 +112,9 @@ {{template "shared/user/authorlink" .Poster}} {{$link := printf "%s/commit/%s" $.Repository.Link ($.Issue.PullRequest.MergedCommitID|PathEscape)}} {{if eq $.Issue.PullRequest.Status 3}} - {{ctx.Locale.Tr "repo.issues.comment_manually_pull_merged_at" (printf `%[2]s` ($link|Escape) (ShortSha $.Issue.PullRequest.MergedCommitID)) (printf "%[1]s" ($.BaseTarget|Escape)) $createdStr | Safe}} + {{ctx.Locale.Tr "repo.issues.comment_manually_pull_merged_at" (printf `%[2]s` ($link|Escape) (ShortSha $.Issue.PullRequest.MergedCommitID) | Safe) (printf "%[1]s" ($.BaseTarget|Escape) | Safe) $createdStr}} {{else}} - {{ctx.Locale.Tr "repo.issues.comment_pull_merged_at" (printf `%[2]s` ($link|Escape) (ShortSha $.Issue.PullRequest.MergedCommitID)) (printf "%[1]s" ($.BaseTarget|Escape)) $createdStr | Safe}} + {{ctx.Locale.Tr "repo.issues.comment_pull_merged_at" (printf `%[2]s` ($link|Escape) (ShortSha $.Issue.PullRequest.MergedCommitID) | Safe) (printf "%[1]s" ($.BaseTarget|Escape) | Safe) $createdStr}} {{end}}
diff --git a/templates/repo/issue/view_content/pull.tmpl b/templates/repo/issue/view_content/pull.tmpl index f1ab53eb67..a28b849f98 100644 --- a/templates/repo/issue/view_content/pull.tmpl +++ b/templates/repo/issue/view_content/pull.tmpl @@ -38,7 +38,7 @@ {{ctx.Locale.Tr "repo.pulls.merged_success"}}
diff --git a/templates/repo/settings/webhook/settings.tmpl b/templates/repo/settings/webhook/settings.tmpl index 3dfa094cf5..8e2387067e 100644 --- a/templates/repo/settings/webhook/settings.tmpl +++ b/templates/repo/settings/webhook/settings.tmpl @@ -263,7 +263,7 @@ {{if ne .HookType "matrix"}}{{/* Matrix doesn't make the authorization optional but it is implied by the help string, should be changed.*/}} - {{ctx.Locale.Tr "repo.settings.authorization_header_desc" "Bearer token123456, Basic YWxhZGRpbjpvcGVuc2VzYW1l" | Str2html}} + {{ctx.Locale.Tr "repo.settings.authorization_header_desc" ("Bearer token123456, Basic YWxhZGRpbjpvcGVuc2VzYW1l" | Safe)}} {{end}}
diff --git a/templates/user/settings/organization.tmpl b/templates/user/settings/organization.tmpl index 8079521984..102ff2e95b 100644 --- a/templates/user/settings/organization.tmpl +++ b/templates/user/settings/organization.tmpl @@ -47,7 +47,7 @@ {{ctx.Locale.Tr "org.members.leave"}}
-

{{ctx.Locale.Tr "org.members.leave.detail" `` | Safe}}

+

{{ctx.Locale.Tr "org.members.leave.detail" (``|Safe)}}

{{template "base/modal_actions_confirm" .}} From 81925ebb0cd2cdfc17fb1dfc0be20cfe8989f810 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 18 Feb 2024 17:52:02 +0800 Subject: [PATCH 04/18] Refactor more code in templates (#29236) Follow #29165. * Introduce JSONTemplate to help to render JSON templates * Introduce JSEscapeSafe for templates. Now only use `{{ ... | JSEscape}}` instead of `{{ ... | JSEscape | Safe}}` * Simplify "UserLocationMapURL" useage (cherry picked from commit 31bb9f3247388b993c61a10190cfd512408ce57e) --- Makefile | 4 ++-- modules/context/context_response.go | 14 ++++++++++++++ modules/templates/helper.go | 6 +++++- modules/templates/helper_test.go | 4 ++++ routers/api/v1/api.go | 2 +- routers/web/auth/oauth.go | 10 +--------- routers/web/shared/user/header.go | 4 +++- routers/web/swagger_json.go | 14 +------------- templates/shared/user/profile_big_avatar.tmpl | 5 ++--- templates/swagger/v1_json.tmpl | 4 ++-- templates/user/auth/oidc_wellknown.tmpl | 14 +++++++------- 11 files changed, 42 insertions(+), 39 deletions(-) diff --git a/Makefile b/Makefile index ffffb1faf0..f023608b1e 100644 --- a/Makefile +++ b/Makefile @@ -156,8 +156,8 @@ endif FORGEJO_API_SPEC := public/assets/forgejo/api.v1.yml SWAGGER_SPEC := templates/swagger/v1_json.tmpl -SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|g -SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|"basePath": "/api/v1"|g +SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape}}/api/v1"|g +SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape}}/api/v1"|"basePath": "/api/v1"|g SWAGGER_EXCLUDE := code.gitea.io/sdk SWAGGER_NEWLINE_COMMAND := -e '$$a\' SWAGGER_SPEC_BRANDING := s|Gitea API|Forgejo API|g diff --git a/modules/context/context_response.go b/modules/context/context_response.go index d9102b77bd..829bca1f59 100644 --- a/modules/context/context_response.go +++ b/modules/context/context_response.go @@ -90,6 +90,20 @@ func (ctx *Context) HTML(status int, name base.TplName) { } } +// JSONTemplate renders the template as JSON response +// keep in mind that the template is processed in HTML context, so JSON-things should be handled carefully, eg: by JSEscape +func (ctx *Context) JSONTemplate(tmpl base.TplName) { + t, err := ctx.Render.TemplateLookup(string(tmpl), nil) + if err != nil { + ctx.ServerError("unable to find template", err) + return + } + ctx.Resp.Header().Set("Content-Type", "application/json") + if err = t.Execute(ctx.Resp, ctx.Data); err != nil { + ctx.ServerError("unable to execute template", err) + } +} + // RenderToString renders the template content to a string func (ctx *Context) RenderToString(name base.TplName, data map[string]any) (string, error) { var buf strings.Builder diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 90371fa8fe..3bf1919b4a 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -38,7 +38,7 @@ func NewFuncMap() template.FuncMap { "Safe": Safe, "Escape": Escape, "QueryEscape": url.QueryEscape, - "JSEscape": template.JSEscapeString, + "JSEscape": JSEscapeSafe, "Str2html": Str2html, // TODO: rename it to SanitizeHTML "URLJoin": util.URLJoin, "DotEscape": DotEscape, @@ -214,6 +214,10 @@ func Escape(s any) template.HTML { panic(fmt.Sprintf("unexpected type %T", s)) } +func JSEscapeSafe(s string) template.HTML { + return template.HTML(template.JSEscapeString(s)) +} + func RenderEmojiPlain(s any) any { switch v := s.(type) { case string: diff --git a/modules/templates/helper_test.go b/modules/templates/helper_test.go index ec83e9ac33..739a92f34f 100644 --- a/modules/templates/helper_test.go +++ b/modules/templates/helper_test.go @@ -52,3 +52,7 @@ func TestSubjectBodySeparator(t *testing.T) { "", "Insuficient\n--\nSeparators") } + +func TestJSEscapeSafe(t *testing.T) { + assert.EqualValues(t, `\u0026\u003C\u003E\'\"`, JSEscapeSafe(`&<>'"`)) +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 58814d3b2e..1babccb650 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -8,7 +8,7 @@ // // Schemes: https, http // BasePath: /api/v1 -// Version: {{AppVer | JSEscape | Safe}} +// Version: {{AppVer | JSEscape}} // License: MIT http://opensource.org/licenses/MIT // // Consumes: diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go index 2adcb3aea0..e840e03bcf 100644 --- a/routers/web/auth/oauth.go +++ b/routers/web/auth/oauth.go @@ -579,16 +579,8 @@ func GrantApplicationOAuth(ctx *context.Context) { // OIDCWellKnown generates JSON so OIDC clients know Gitea's capabilities func OIDCWellKnown(ctx *context.Context) { - t, err := ctx.Render.TemplateLookup("user/auth/oidc_wellknown", nil) - if err != nil { - ctx.ServerError("unable to find template", err) - return - } - ctx.Resp.Header().Set("Content-Type", "application/json") ctx.Data["SigningKey"] = oauth2.DefaultSigningKey - if err = t.Execute(ctx.Resp, ctx.Data); err != nil { - ctx.ServerError("unable to execute template", err) - } + ctx.JSONTemplate("user/auth/oidc_wellknown") } // OIDCKeys generates the JSON Web Key Set diff --git a/routers/web/shared/user/header.go b/routers/web/shared/user/header.go index 203e5fa5a5..6830bdb8a9 100644 --- a/routers/web/shared/user/header.go +++ b/routers/web/shared/user/header.go @@ -4,6 +4,8 @@ package user import ( + "net/url" + "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" @@ -37,7 +39,7 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) { ctx.Data["IsFollowing"] = ctx.Doer != nil && user_model.IsFollowing(ctx, ctx.Doer.ID, ctx.ContextUser.ID) ctx.Data["IsBlocked"] = ctx.Doer != nil && user_model.IsBlocked(ctx, ctx.Doer.ID, ctx.ContextUser.ID) ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail && ctx.ContextUser.Email != "" && ctx.IsSigned && !ctx.ContextUser.KeepEmailPrivate - ctx.Data["UserLocationMapURL"] = setting.Service.UserLocationMapURL + ctx.Data["ContextUserLocationMapURL"] = setting.Service.UserLocationMapURL + url.QueryEscape(ctx.ContextUser.Location) // Show OpenID URIs openIDs, err := user_model.GetUserOpenIDs(ctx, ctx.ContextUser.ID) diff --git a/routers/web/swagger_json.go b/routers/web/swagger_json.go index 493c97aa67..42e9dbe967 100644 --- a/routers/web/swagger_json.go +++ b/routers/web/swagger_json.go @@ -4,22 +4,10 @@ package web import ( - "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" ) -// tplSwaggerV1Json swagger v1 json template -const tplSwaggerV1Json base.TplName = "swagger/v1_json" - // SwaggerV1Json render swagger v1 json func SwaggerV1Json(ctx *context.Context) { - t, err := ctx.Render.TemplateLookup(string(tplSwaggerV1Json), nil) - if err != nil { - ctx.ServerError("unable to find template", err) - return - } - ctx.Resp.Header().Set("Content-Type", "application/json") - if err = t.Execute(ctx.Resp, ctx.Data); err != nil { - ctx.ServerError("unable to execute template", err) - } + ctx.JSONTemplate("swagger/v1_json") } diff --git a/templates/shared/user/profile_big_avatar.tmpl b/templates/shared/user/profile_big_avatar.tmpl index fefaa9dd17..e731cfe2e0 100644 --- a/templates/shared/user/profile_big_avatar.tmpl +++ b/templates/shared/user/profile_big_avatar.tmpl @@ -31,9 +31,8 @@
  • {{svg "octicon-location"}} {{.ContextUser.Location}} - {{if .UserLocationMapURL}} - {{/* We presume that the UserLocationMapURL is safe, as it is provided by the site administrator. */}} - + {{if .ContextUserLocationMapURL}} + {{svg "octicon-link-external"}} {{end}} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 8a40cf76d4..0b330a89ee 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -19,9 +19,9 @@ "name": "MIT", "url": "http://opensource.org/licenses/MIT" }, - "version": "{{AppVer | JSEscape | Safe}}" + "version": "{{AppVer | JSEscape}}" }, - "basePath": "{{AppSubUrl | JSEscape | Safe}}/api/v1", + "basePath": "{{AppSubUrl | JSEscape}}/api/v1", "paths": { "/activitypub/user-id/{user-id}": { "get": { diff --git a/templates/user/auth/oidc_wellknown.tmpl b/templates/user/auth/oidc_wellknown.tmpl index 38e6900c38..54bb4a763d 100644 --- a/templates/user/auth/oidc_wellknown.tmpl +++ b/templates/user/auth/oidc_wellknown.tmpl @@ -1,16 +1,16 @@ { - "issuer": "{{AppUrl | JSEscape | Safe}}", - "authorization_endpoint": "{{AppUrl | JSEscape | Safe}}login/oauth/authorize", - "token_endpoint": "{{AppUrl | JSEscape | Safe}}login/oauth/access_token", - "jwks_uri": "{{AppUrl | JSEscape | Safe}}login/oauth/keys", - "userinfo_endpoint": "{{AppUrl | JSEscape | Safe}}login/oauth/userinfo", - "introspection_endpoint": "{{AppUrl | JSEscape | Safe}}login/oauth/introspect", + "issuer": "{{AppUrl | JSEscape}}", + "authorization_endpoint": "{{AppUrl | JSEscape}}login/oauth/authorize", + "token_endpoint": "{{AppUrl | JSEscape}}login/oauth/access_token", + "jwks_uri": "{{AppUrl | JSEscape}}login/oauth/keys", + "userinfo_endpoint": "{{AppUrl | JSEscape}}login/oauth/userinfo", + "introspection_endpoint": "{{AppUrl | JSEscape}}login/oauth/introspect", "response_types_supported": [ "code", "id_token" ], "id_token_signing_alg_values_supported": [ - "{{.SigningKey.SigningMethod.Alg | JSEscape | Safe}}" + "{{.SigningKey.SigningMethod.Alg | JSEscape}}" ], "subject_types_supported": [ "public" From d93d963c3f9002a5235fdc3d1c88c79fad551f6a Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Sun, 18 Feb 2024 19:58:46 +0900 Subject: [PATCH 05/18] Implement some action notifier functions (#29173) Fix #29166 Add support for the following activity types of `pull_request` - assigned - unassigned - review_requested - review_request_removed - milestoned - demilestoned (cherry picked from commit 1a6e1cbada27db1e3327b0d7d331492c95e24759) --- modules/actions/github.go | 4 +- modules/actions/workflows.go | 8 ++-- services/actions/notifier.go | 76 +++++++++++++++++++++++++++++++----- 3 files changed, 75 insertions(+), 13 deletions(-) diff --git a/modules/actions/github.go b/modules/actions/github.go index a988b2a124..d4e559408b 100644 --- a/modules/actions/github.go +++ b/modules/actions/github.go @@ -55,7 +55,9 @@ func canGithubEventMatch(eventName string, triggedEvent webhook_module.HookEvent case webhook_module.HookEventPullRequest, webhook_module.HookEventPullRequestSync, webhook_module.HookEventPullRequestAssign, - webhook_module.HookEventPullRequestLabel: + webhook_module.HookEventPullRequestLabel, + webhook_module.HookEventPullRequestReviewRequest, + webhook_module.HookEventPullRequestMilestone: return true default: diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index 00d83e06d7..81ab26bc27 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -186,7 +186,9 @@ func detectMatched(gitRepo *git.Repository, commit *git.Commit, triggedEvent web webhook_module.HookEventPullRequest, webhook_module.HookEventPullRequestSync, webhook_module.HookEventPullRequestAssign, - webhook_module.HookEventPullRequestLabel: + webhook_module.HookEventPullRequestLabel, + webhook_module.HookEventPullRequestReviewRequest, + webhook_module.HookEventPullRequestMilestone: return matchPullRequestEvent(gitRepo, commit, payload.(*api.PullRequestPayload), evt) case // pull_request_review @@ -362,13 +364,13 @@ func matchPullRequestEvent(gitRepo *git.Repository, commit *git.Commit, prPayloa } else { // See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request // Actions with the same name: - // opened, edited, closed, reopened, assigned, unassigned + // opened, edited, closed, reopened, assigned, unassigned, review_requested, review_request_removed, milestoned, demilestoned // Actions need to be converted: // synchronized -> synchronize // label_updated -> labeled // label_cleared -> unlabeled // Unsupported activity types: - // converted_to_draft, ready_for_review, locked, unlocked, review_requested, review_request_removed, auto_merge_enabled, auto_merge_disabled + // converted_to_draft, ready_for_review, locked, unlocked, auto_merge_enabled, auto_merge_disabled, enqueued, dequeued action := prPayload.Action switch action { diff --git a/services/actions/notifier.go b/services/actions/notifier.go index 0b4fed5db1..093607f05c 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -101,11 +101,40 @@ func (n *actionsNotifier) IssueChangeStatus(ctx context.Context, doer *user_mode Notify(ctx) } +// IssueChangeAssignee notifies assigned or unassigned to notifiers +func (n *actionsNotifier) IssueChangeAssignee(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { + ctx = withMethod(ctx, "IssueChangeAssignee") + + var action api.HookIssueAction + if removed { + action = api.HookIssueUnassigned + } else { + action = api.HookIssueAssigned + } + notifyIssueChange(ctx, doer, issue, webhook_module.HookEventPullRequestAssign, action) +} + +// IssueChangeMilestone notifies assignee to notifiers +func (n *actionsNotifier) IssueChangeMilestone(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) { + ctx = withMethod(ctx, "IssueChangeMilestone") + + var action api.HookIssueAction + if issue.MilestoneID > 0 { + action = api.HookIssueMilestoned + } else { + action = api.HookIssueDemilestoned + } + notifyIssueChange(ctx, doer, issue, webhook_module.HookEventPullRequestMilestone, action) +} + func (n *actionsNotifier) IssueChangeLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, _, _ []*issues_model.Label, ) { ctx = withMethod(ctx, "IssueChangeLabels") + notifyIssueChange(ctx, doer, issue, webhook_module.HookEventPullRequestLabel, api.HookIssueLabelUpdated) +} +func notifyIssueChange(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, event webhook_module.HookEventType, action api.HookIssueAction) { var err error if err = issue.LoadRepo(ctx); err != nil { log.Error("LoadRepo: %v", err) @@ -117,20 +146,15 @@ func (n *actionsNotifier) IssueChangeLabels(ctx context.Context, doer *user_mode return } - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) if issue.IsPull { if err = issue.LoadPullRequest(ctx); err != nil { log.Error("loadPullRequest: %v", err) return } - if err = issue.PullRequest.LoadIssue(ctx); err != nil { - log.Error("LoadIssue: %v", err) - return - } - newNotifyInputFromIssue(issue, webhook_module.HookEventPullRequestLabel). + newNotifyInputFromIssue(issue, event). WithDoer(doer). WithPayload(&api.PullRequestPayload{ - Action: api.HookIssueLabelUpdated, + Action: action, Index: issue.Index, PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), Repository: convert.ToRepo(ctx, issue.Repo, access_model.Permission{AccessMode: perm_model.AccessModeNone}), @@ -140,10 +164,11 @@ func (n *actionsNotifier) IssueChangeLabels(ctx context.Context, doer *user_mode Notify(ctx) return } - newNotifyInputFromIssue(issue, webhook_module.HookEventIssueLabel). + permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) + newNotifyInputFromIssue(issue, event). WithDoer(doer). WithPayload(&api.IssuePayload{ - Action: api.HookIssueLabelUpdated, + Action: action, Index: issue.Index, Issue: convert.ToAPIIssue(ctx, issue), Repository: convert.ToRepo(ctx, issue.Repo, permission), @@ -305,6 +330,39 @@ func (n *actionsNotifier) PullRequestReview(ctx context.Context, pr *issues_mode }).Notify(ctx) } +func (n *actionsNotifier) PullRequestReviewRequest(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) { + if !issue.IsPull { + log.Warn("PullRequestReviewRequest: issue is not a pull request: %v", issue.ID) + return + } + + ctx = withMethod(ctx, "PullRequestReviewRequest") + + permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) + if err := issue.LoadPullRequest(ctx); err != nil { + log.Error("LoadPullRequest failed: %v", err) + return + } + var action api.HookIssueAction + if isRequest { + action = api.HookIssueReviewRequested + } else { + action = api.HookIssueReviewRequestRemoved + } + newNotifyInputFromIssue(issue, webhook_module.HookEventPullRequestReviewRequest). + WithDoer(doer). + WithPayload(&api.PullRequestPayload{ + Action: action, + Index: issue.Index, + PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), + RequestedReviewer: convert.ToUser(ctx, reviewer, nil), + Repository: convert.ToRepo(ctx, issue.Repo, permission), + Sender: convert.ToUser(ctx, doer, nil), + }). + WithPullRequest(issue.PullRequest). + Notify(ctx) +} + func (*actionsNotifier) MergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) { ctx = withMethod(ctx, "MergePullRequest") From 559afdad731b2989737f043602e5d5b25edf4324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Nicas=20Oelschl=C3=A4ger?= <72873130+zokkis@users.noreply.github.com> Date: Sun, 18 Feb 2024 12:47:50 +0100 Subject: [PATCH 06/18] Convert visibility to number (#29226) Don't throw error while creating user (Fixes #29218) (cherry picked from commit 6093f507fe6f2d4802de8ec1ff5b04820e81571c) --- templates/admin/user/new.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/admin/user/new.tmpl b/templates/admin/user/new.tmpl index 81f70511d0..bcb53d8131 100644 --- a/templates/admin/user/new.tmpl +++ b/templates/admin/user/new.tmpl @@ -26,7 +26,7 @@
    {{if .Commit.Signature}} -
    +
    {{if .Verification.Verified}} {{if ne .Verification.SigningUser.ID 0}} diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index 05559fc9a7..9b4a9ba983 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -1,7 +1,7 @@ {{$showFileTree := (and (not .DiffNotAvailable) (gt .Diff.NumFiles 1))}}
    -
    +
    {{if $showFileTree}}
    {{end}} From bb911b2d5f709ebdf927771a141c263ff9d10e41 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Mon, 19 Feb 2024 00:24:35 +0000 Subject: [PATCH 11/18] [skip ci] Updated licenses and gitignores (cherry picked from commit f04e71f9bc05d4930e1eff0b69ceb0e890528e30) --- options/license/Brian-Gladman-2-Clause | 17 ++++++++++ options/license/CMU-Mach-nodoc | 11 +++++++ options/license/GNOME-examples-exception | 1 + options/license/Gmsh-exception | 16 +++++++++ options/license/HPND-Fenneberg-Livingston | 13 ++++++++ options/license/HPND-INRIA-IMAG | 9 +++++ options/license/Mackerras-3-Clause | 25 ++++++++++++++ .../license/Mackerras-3-Clause-acknowledgment | 25 ++++++++++++++ options/license/OpenVision | 33 +++++++++++++++++++ options/license/Sun-PPP | 13 ++++++++ options/license/UMich-Merit | 19 +++++++++++ options/license/bcrypt-Solar-Designer | 11 +++++++ options/license/gtkbook | 6 ++++ options/license/softSurfer | 6 ++++ 14 files changed, 205 insertions(+) create mode 100644 options/license/Brian-Gladman-2-Clause create mode 100644 options/license/CMU-Mach-nodoc create mode 100644 options/license/GNOME-examples-exception create mode 100644 options/license/Gmsh-exception create mode 100644 options/license/HPND-Fenneberg-Livingston create mode 100644 options/license/HPND-INRIA-IMAG create mode 100644 options/license/Mackerras-3-Clause create mode 100644 options/license/Mackerras-3-Clause-acknowledgment create mode 100644 options/license/OpenVision create mode 100644 options/license/Sun-PPP create mode 100644 options/license/UMich-Merit create mode 100644 options/license/bcrypt-Solar-Designer create mode 100644 options/license/gtkbook create mode 100644 options/license/softSurfer diff --git a/options/license/Brian-Gladman-2-Clause b/options/license/Brian-Gladman-2-Clause new file mode 100644 index 0000000000..7276f63e9e --- /dev/null +++ b/options/license/Brian-Gladman-2-Clause @@ -0,0 +1,17 @@ +Copyright (C) 1998-2013, Brian Gladman, Worcester, UK. All + rights reserved. + +The redistribution and use of this software (with or without +changes) is allowed without the payment of fees or royalties +provided that: + + source code distributions include the above copyright notice, + this list of conditions and the following disclaimer; + + binary distributions include the above copyright notice, this + list of conditions and the following disclaimer in their + documentation. + +This software is provided 'as is' with no explicit or implied +warranties in respect of its operation, including, but not limited +to, correctness and fitness for purpose. diff --git a/options/license/CMU-Mach-nodoc b/options/license/CMU-Mach-nodoc new file mode 100644 index 0000000000..c81d74fee7 --- /dev/null +++ b/options/license/CMU-Mach-nodoc @@ -0,0 +1,11 @@ +Copyright (C) 2002 Naval Research Laboratory (NRL/CCS) + +Permission to use, copy, modify and distribute this software and +its documentation is hereby granted, provided that both the +copyright notice and this permission notice appear in all copies of +the software, derivative works or modified versions, and any +portions thereof. + +NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND +DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER +RESULTING FROM THE USE OF THIS SOFTWARE. diff --git a/options/license/GNOME-examples-exception b/options/license/GNOME-examples-exception new file mode 100644 index 0000000000..0f0cd53b50 --- /dev/null +++ b/options/license/GNOME-examples-exception @@ -0,0 +1 @@ +As a special exception, the copyright holders give you permission to copy, modify, and distribute the example code contained in this document under the terms of your choosing, without restriction. diff --git a/options/license/Gmsh-exception b/options/license/Gmsh-exception new file mode 100644 index 0000000000..6d28f704e4 --- /dev/null +++ b/options/license/Gmsh-exception @@ -0,0 +1,16 @@ +The copyright holders of Gmsh give you permission to combine Gmsh + with code included in the standard release of Netgen (from Joachim + Sch"oberl), METIS (from George Karypis at the University of + Minnesota), OpenCASCADE (from Open CASCADE S.A.S) and ParaView + (from Kitware, Inc.) under their respective licenses. You may copy + and distribute such a system following the terms of the GNU GPL for + Gmsh and the licenses of the other code concerned, provided that + you include the source code of that other code when and as the GNU + GPL requires distribution of source code. + + Note that people who make modified versions of Gmsh are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU General + Public License gives permission to release a modified version + without this exception; this exception also makes it possible to + release a modified version which carries forward this exception. diff --git a/options/license/HPND-Fenneberg-Livingston b/options/license/HPND-Fenneberg-Livingston new file mode 100644 index 0000000000..aaf524f3aa --- /dev/null +++ b/options/license/HPND-Fenneberg-Livingston @@ -0,0 +1,13 @@ +Copyright (C) 1995,1996,1997,1998 Lars Fenneberg + +Permission to use, copy, modify, and distribute this software for any +purpose and without fee is hereby granted, provided that this copyright and +permission notice appear on all copies and supporting documentation, the +name of Lars Fenneberg not be used in advertising or publicity pertaining to +distribution of the program without specific prior permission, and notice be +given in supporting documentation that copying and distribution is by +permission of Lars Fenneberg. + +Lars Fenneberg makes no representations about the suitability of this +software for any purpose. It is provided "as is" without express or implied +warranty. diff --git a/options/license/HPND-INRIA-IMAG b/options/license/HPND-INRIA-IMAG new file mode 100644 index 0000000000..87d09d92cb --- /dev/null +++ b/options/license/HPND-INRIA-IMAG @@ -0,0 +1,9 @@ +This software is available with usual "research" terms with +the aim of retain credits of the software. Permission to use, +copy, modify and distribute this software for any purpose and +without fee is hereby granted, provided that the above copyright +notice and this permission notice appear in all copies, and +the name of INRIA, IMAG, or any contributor not be used in +advertising or publicity pertaining to this material without +the prior explicit permission. The software is provided "as +is" without any warranties, support or liabilities of any kind. diff --git a/options/license/Mackerras-3-Clause b/options/license/Mackerras-3-Clause new file mode 100644 index 0000000000..6467f0c98e --- /dev/null +++ b/options/license/Mackerras-3-Clause @@ -0,0 +1,25 @@ +Copyright (c) 1995 Eric Rosenquist. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + 3. The name(s) of the authors of this software must not be used to + endorse or promote products derived from this software without + prior written permission. + + THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/options/license/Mackerras-3-Clause-acknowledgment b/options/license/Mackerras-3-Clause-acknowledgment new file mode 100644 index 0000000000..5f0187add7 --- /dev/null +++ b/options/license/Mackerras-3-Clause-acknowledgment @@ -0,0 +1,25 @@ +Copyright (c) 1993-2002 Paul Mackerras. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. The name(s) of the authors of this software must not be used to + endorse or promote products derived from this software without + prior written permission. + +3. Redistributions of any form whatsoever must retain the following + acknowledgment: + "This product includes software developed by Paul Mackerras + ". + +THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN +AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING +OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/options/license/OpenVision b/options/license/OpenVision new file mode 100644 index 0000000000..983505389e --- /dev/null +++ b/options/license/OpenVision @@ -0,0 +1,33 @@ +Copyright, OpenVision Technologies, Inc., 1993-1996, All Rights +Reserved + +WARNING: Retrieving the OpenVision Kerberos Administration system +source code, as described below, indicates your acceptance of the +following terms. If you do not agree to the following terms, do +not retrieve the OpenVision Kerberos administration system. + +You may freely use and distribute the Source Code and Object Code +compiled from it, with or without modification, but this Source +Code is provided to you "AS IS" EXCLUSIVE OF ANY WARRANTY, +INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY OR +FITNESS FOR A PARTICULAR PURPOSE, OR ANY OTHER WARRANTY, WHETHER +EXPRESS OR IMPLIED. IN NO EVENT WILL OPENVISION HAVE ANY LIABILITY +FOR ANY LOST PROFITS, LOSS OF DATA OR COSTS OF PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES, OR FOR ANY SPECIAL, INDIRECT, OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, INCLUDING, +WITHOUT LIMITATION, THOSE RESULTING FROM THE USE OF THE SOURCE +CODE, OR THE FAILURE OF THE SOURCE CODE TO PERFORM, OR FOR ANY +OTHER REASON. + +OpenVision retains all copyrights in the donated Source Code. +OpenVision also retains copyright to derivative works of the Source +Code, whether created by OpenVision or by a third party. The +OpenVision copyright notice must be preserved if derivative works +are made based on the donated Source Code. + +OpenVision Technologies, Inc. has donated this Kerberos +Administration system to MIT for inclusion in the standard Kerberos +5 distribution. This donation underscores our commitment to +continuing Kerberos technology development and our gratitude for +the valuable work which has been performed by MIT and the Kerberos +community. diff --git a/options/license/Sun-PPP b/options/license/Sun-PPP new file mode 100644 index 0000000000..5f94a13437 --- /dev/null +++ b/options/license/Sun-PPP @@ -0,0 +1,13 @@ +Copyright (c) 2001 by Sun Microsystems, Inc. +All rights reserved. + +Non-exclusive rights to redistribute, modify, translate, and use +this software in source and binary forms, in whole or in part, is +hereby granted, provided that the above copyright notice is +duplicated in any source form, and that neither the name of the +copyright holder nor the author is used to endorse or promote +products derived from this software. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. diff --git a/options/license/UMich-Merit b/options/license/UMich-Merit new file mode 100644 index 0000000000..93e304b90e --- /dev/null +++ b/options/license/UMich-Merit @@ -0,0 +1,19 @@ +[C] The Regents of the University of Michigan and Merit Network, Inc. 1992, +1993, 1994, 1995 All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, provided +that the above copyright notice and this permission notice appear in all +copies of the software and derivative works or modified versions thereof, +and that both the copyright notice and this permission and disclaimer +notice appear in supporting documentation. + +THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF THE +UNIVERSITY OF MICHIGAN AND MERIT NETWORK, INC. DO NOT WARRANT THAT THE +FUNCTIONS CONTAINED IN THE SOFTWARE WILL MEET LICENSEE'S REQUIREMENTS OR +THAT OPERATION WILL BE UNINTERRUPTED OR ERROR FREE. The Regents of the +University of Michigan and Merit Network, Inc. shall not be liable for any +special, indirect, incidental or consequential damages with respect to any +claim by Licensee or any third party arising from use of the software. diff --git a/options/license/bcrypt-Solar-Designer b/options/license/bcrypt-Solar-Designer new file mode 100644 index 0000000000..8cb05017fc --- /dev/null +++ b/options/license/bcrypt-Solar-Designer @@ -0,0 +1,11 @@ +Written by Solar Designer in 1998-2014. +No copyright is claimed, and the software is hereby placed in the public +domain. In case this attempt to disclaim copyright and place the software +in the public domain is deemed null and void, then the software is +Copyright (c) 1998-2014 Solar Designer and it is hereby released to the +general public under the following terms: + +Redistribution and use in source and binary forms, with or without +modification, are permitted. + +There's ABSOLUTELY NO WARRANTY, express or implied. diff --git a/options/license/gtkbook b/options/license/gtkbook new file mode 100644 index 0000000000..91215e80d6 --- /dev/null +++ b/options/license/gtkbook @@ -0,0 +1,6 @@ +Copyright 2005 Syd Logan, All Rights Reserved + +This code is distributed without warranty. You are free to use +this code for any purpose, however, if this code is republished or +redistributed in its original form, as hardcopy or electronically, +then you must include this copyright notice along with the code. diff --git a/options/license/softSurfer b/options/license/softSurfer new file mode 100644 index 0000000000..1bbc88c34c --- /dev/null +++ b/options/license/softSurfer @@ -0,0 +1,6 @@ +Copyright 2001, softSurfer (www.softsurfer.com) +This code may be freely used and modified for any purpose +providing that this copyright notice is included with it. +SoftSurfer makes no warranty for this code, and cannot be held +liable for any real or imagined damage resulting from its use. +Users of this code must verify correctness for their application. From b3f2447bc4b6a7220da748cc6eb24bd5568bee7c Mon Sep 17 00:00:00 2001 From: silverwind Date: Mon, 19 Feb 2024 03:23:06 +0100 Subject: [PATCH 12/18] Downscale pasted PNG images based on metadata (#29123) Some images like MacOS screenshots contain [pHYs](http://www.libpng.org/pub/png/book/chapter11.html#png.ch11.div.8) data which we can use to downscale uploaded images so they render in the same dppx ratio in which they were taken. Before: image After: image (cherry picked from commit 5e72526da4e915791f03af056890e16821bde052) --- web_src/js/features/comp/ImagePaste.js | 20 +++++++++-- web_src/js/utils/image.js | 47 ++++++++++++++++++++++++++ web_src/js/utils/image.test.js | 29 ++++++++++++++++ 3 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 web_src/js/utils/image.js create mode 100644 web_src/js/utils/image.test.js diff --git a/web_src/js/features/comp/ImagePaste.js b/web_src/js/features/comp/ImagePaste.js index 27abcfe56f..444ab89150 100644 --- a/web_src/js/features/comp/ImagePaste.js +++ b/web_src/js/features/comp/ImagePaste.js @@ -1,5 +1,7 @@ import $ from 'jquery'; +import {htmlEscape} from 'escape-goat'; import {POST} from '../../modules/fetch.js'; +import {imageInfo} from '../../utils/image.js'; async function uploadFile(file, uploadUrl) { const formData = new FormData(); @@ -109,10 +111,22 @@ const uploadClipboardImage = async (editor, dropzone, e) => { const placeholder = `![${name}](uploading ...)`; editor.insertPlaceholder(placeholder); - const data = await uploadFile(img, uploadUrl); - editor.replacePlaceholder(placeholder, `![${name}](/attachments/${data.uuid})`); - const $input = $(``).attr('id', data.uuid).val(data.uuid); + const {uuid} = await uploadFile(img, uploadUrl); + const {width, dppx} = await imageInfo(img); + + const url = `/attachments/${uuid}`; + let text; + if (width > 0 && dppx > 1) { + // Scale down images from HiDPI monitors. This uses the tag because it's the only + // method to change image size in Markdown that is supported by all implementations. + text = `${htmlEscape(name)}`; + } else { + text = `![${name}](${url})`; + } + editor.replacePlaceholder(placeholder, text); + + const $input = $(``).attr('id', uuid).val(uuid); $files.append($input); } }; diff --git a/web_src/js/utils/image.js b/web_src/js/utils/image.js new file mode 100644 index 0000000000..ed5d98e35a --- /dev/null +++ b/web_src/js/utils/image.js @@ -0,0 +1,47 @@ +export async function pngChunks(blob) { + const uint8arr = new Uint8Array(await blob.arrayBuffer()); + const chunks = []; + if (uint8arr.length < 12) return chunks; + const view = new DataView(uint8arr.buffer); + if (view.getBigUint64(0) !== 9894494448401390090n) return chunks; + + const decoder = new TextDecoder(); + let index = 8; + while (index < uint8arr.length) { + const len = view.getUint32(index); + chunks.push({ + name: decoder.decode(uint8arr.slice(index + 4, index + 8)), + data: uint8arr.slice(index + 8, index + 8 + len), + }); + index += len + 12; + } + + return chunks; +} + +// decode a image and try to obtain width and dppx. If will never throw but instead +// return default values. +export async function imageInfo(blob) { + let width = 0; // 0 means no width could be determined + let dppx = 1; // 1 dot per pixel for non-HiDPI screens + + if (blob.type === 'image/png') { // only png is supported currently + try { + for (const {name, data} of await pngChunks(blob)) { + const view = new DataView(data.buffer); + if (name === 'IHDR' && data?.length) { + // extract width from mandatory IHDR chunk + width = view.getUint32(0); + } else if (name === 'pHYs' && data?.length) { + // extract dppx from optional pHYs chunk, assuming pixels are square + const unit = view.getUint8(8); + if (unit === 1) { + dppx = Math.round(view.getUint32(0) / 39.3701) / 72; // meter to inch to dppx + } + } + } + } catch {} + } + + return {width, dppx}; +} diff --git a/web_src/js/utils/image.test.js b/web_src/js/utils/image.test.js new file mode 100644 index 0000000000..ba4758250c --- /dev/null +++ b/web_src/js/utils/image.test.js @@ -0,0 +1,29 @@ +import {pngChunks, imageInfo} from './image.js'; + +const pngNoPhys = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAADUlEQVQIHQECAP3/AAAAAgABzePRKwAAAABJRU5ErkJggg=='; +const pngPhys = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAEElEQVQI12OQNZcAIgYIBQAL8gGxdzzM0A=='; +const pngEmpty = 'data:image/png;base64,'; + +async function dataUriToBlob(datauri) { + return await (await globalThis.fetch(datauri)).blob(); +} + +test('pngChunks', async () => { + expect(await pngChunks(await dataUriToBlob(pngNoPhys))).toEqual([ + {name: 'IHDR', data: new Uint8Array([0, 0, 0, 1, 0, 0, 0, 1, 8, 0, 0, 0, 0])}, + {name: 'IDAT', data: new Uint8Array([8, 29, 1, 2, 0, 253, 255, 0, 0, 0, 2, 0, 1])}, + {name: 'IEND', data: new Uint8Array([])}, + ]); + expect(await pngChunks(await dataUriToBlob(pngPhys))).toEqual([ + {name: 'IHDR', data: new Uint8Array([0, 0, 0, 2, 0, 0, 0, 2, 8, 2, 0, 0, 0])}, + {name: 'pHYs', data: new Uint8Array([0, 0, 22, 37, 0, 0, 22, 37, 1])}, + {name: 'IDAT', data: new Uint8Array([8, 215, 99, 144, 53, 151, 0, 34, 6, 8, 5, 0, 11, 242, 1, 177])}, + ]); + expect(await pngChunks(await dataUriToBlob(pngEmpty))).toEqual([]); +}); + +test('imageInfo', async () => { + expect(await imageInfo(await dataUriToBlob(pngNoPhys))).toEqual({width: 1, dppx: 1}); + expect(await imageInfo(await dataUriToBlob(pngPhys))).toEqual({width: 2, dppx: 2}); + expect(await imageInfo(await dataUriToBlob(pngEmpty))).toEqual({width: 0, dppx: 1}); +}); From e96e1bededfc04de60b2f8c730e84ecba538fc2d Mon Sep 17 00:00:00 2001 From: Jason Song Date: Mon, 19 Feb 2024 17:31:36 +0800 Subject: [PATCH 13/18] Do not use lower tag names to find releases/tags (#29261) Fix #26090, see https://github.com/go-gitea/gitea/issues/26090#issuecomment-1952013206 Since `TagName` stores the original tag name and `LowerTagName` stores the lower tag name, it doesn't make sense to use lowercase tags as `TagNames` in `FindReleasesOptions`. https://github.com/go-gitea/gitea/blob/5e72526da4e915791f03af056890e16821bde052/services/repository/push.go#L396-L397 While the only other usage looks correct: https://github.com/go-gitea/gitea/blob/5e72526da4e915791f03af056890e16821bde052/routers/web/repo/repo.go#L416 (cherry picked from commit 0ea8de2d0729e1e1d0ea9de1e59fbcb673e87fd2) --- services/repository/push.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/services/repository/push.go b/services/repository/push.go index 2ef8cac95e..5e2853b27d 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -321,14 +321,9 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo return nil } - lowerTags := make([]string, 0, len(tags)) - for _, tag := range tags { - lowerTags = append(lowerTags, strings.ToLower(tag)) - } - releases, err := db.Find[repo_model.Release](ctx, repo_model.FindReleasesOptions{ RepoID: repo.ID, - TagNames: lowerTags, + TagNames: tags, }) if err != nil { return fmt.Errorf("db.Find[repo_model.Release]: %w", err) @@ -338,6 +333,11 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo relMap[rel.LowerTagName] = rel } + lowerTags := make([]string, 0, len(tags)) + for _, tag := range tags { + lowerTags = append(lowerTags, strings.ToLower(tag)) + } + newReleases := make([]*repo_model.Release, 0, len(lowerTags)-len(relMap)) emailToUser := make(map[string]*user_model.User) From b1d66f50fbd1af1db8aa66b0c6393e57f8d08353 Mon Sep 17 00:00:00 2001 From: Markus Amshove Date: Mon, 19 Feb 2024 10:57:08 +0100 Subject: [PATCH 14/18] Disallow merge when required checked are missing (#29143) fixes #21892 This PR disallows merging a PR when not all commit status contexts configured in the branch protection are met. Previously, the PR was happy to merge when one commit status was successful and the other contexts weren't reported. Any feedback is welcome, first time Go :-) I'm also not sure if the changes in the template break something else Given the following branch protection: ![branch_protection](https://github.com/go-gitea/gitea/assets/2401875/f871b4e4-138b-435a-b496-f9ad432e3dec) This was shown before the change: ![before](https://github.com/go-gitea/gitea/assets/2401875/60424ff0-ee09-4fa0-856e-64e6e3fb0612) With the change, it is now shown as this: ![after](https://github.com/go-gitea/gitea/assets/2401875/4e464142-efb1-4889-8166-eb3be26c8f3d) --------- Co-authored-by: wxiaoguang (cherry picked from commit a11ccc9fcd61fb25ffb1c37b87a0df4ee9efd84e) --- routers/web/repo/pull.go | 30 +++++++++++++++++++++ services/pull/commit_status.go | 4 +++ templates/repo/issue/view_content/pull.tmpl | 1 + templates/repo/pulls/status.tmpl | 10 ++++++- 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index ca854a35f2..ab821f8884 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -662,6 +662,24 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C } if pb != nil && pb.EnableStatusCheck { + + var missingRequiredChecks []string + for _, requiredContext := range pb.StatusCheckContexts { + contextFound := false + matchesRequiredContext := createRequiredContextMatcher(requiredContext) + for _, presentStatus := range commitStatuses { + if matchesRequiredContext(presentStatus.Context) { + contextFound = true + break + } + } + + if !contextFound { + missingRequiredChecks = append(missingRequiredChecks, requiredContext) + } + } + ctx.Data["MissingRequiredChecks"] = missingRequiredChecks + ctx.Data["is_context_required"] = func(context string) bool { for _, c := range pb.StatusCheckContexts { if c == context { @@ -730,6 +748,18 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C return compareInfo } +func createRequiredContextMatcher(requiredContext string) func(string) bool { + if gp, err := glob.Compile(requiredContext); err == nil { + return func(contextToCheck string) bool { + return gp.Match(contextToCheck) + } + } + + return func(contextToCheck string) bool { + return requiredContext == contextToCheck + } +} + type pullCommitList struct { Commits []pull_service.CommitInfo `json:"commits"` LastReviewCommitSha string `json:"last_review_commit_sha"` diff --git a/services/pull/commit_status.go b/services/pull/commit_status.go index 06e66fad77..27ee572640 100644 --- a/services/pull/commit_status.go +++ b/services/pull/commit_status.go @@ -52,6 +52,10 @@ func MergeRequiredContextsCommitStatus(commitStatuses []*git_model.CommitStatus, } } + if matchedCount != len(requiredContexts) { + return structs.CommitStatusPending + } + if matchedCount == 0 { status := git_model.CalcCommitStatus(commitStatuses) if status != nil { diff --git a/templates/repo/issue/view_content/pull.tmpl b/templates/repo/issue/view_content/pull.tmpl index a28b849f98..e86deb8915 100644 --- a/templates/repo/issue/view_content/pull.tmpl +++ b/templates/repo/issue/view_content/pull.tmpl @@ -24,6 +24,7 @@ {{template "repo/pulls/status" (dict "CommitStatus" .LatestCommitStatus "CommitStatuses" .LatestCommitStatuses + "MissingRequiredChecks" .MissingRequiredChecks "ShowHideChecks" true "is_context_required" .is_context_required )}} diff --git a/templates/repo/pulls/status.tmpl b/templates/repo/pulls/status.tmpl index ae508b8fa4..e8636ba1b8 100644 --- a/templates/repo/pulls/status.tmpl +++ b/templates/repo/pulls/status.tmpl @@ -2,6 +2,7 @@ Template Attributes: * CommitStatus: summary of all commit status state * CommitStatuses: all commit status elements +* MissingRequiredChecks: commit check contexts that are required by branch protection but not present * ShowHideChecks: whether use a button to show/hide the checks * is_context_required: Used in pull request commit status check table */}} @@ -9,7 +10,7 @@ Template Attributes: {{if .CommitStatus}}
    - {{if eq .CommitStatus.State "pending"}} + {{if or (eq .CommitStatus.State "pending") (.MissingRequiredChecks)}} {{ctx.Locale.Tr "repo.pulls.status_checking"}} {{else if eq .CommitStatus.State "success"}} {{ctx.Locale.Tr "repo.pulls.status_checks_success"}} @@ -46,6 +47,13 @@ Template Attributes:
    {{end}} + {{range .MissingRequiredChecks}} +
    + {{svg "octicon-dot-fill" 18 "commit-status icon text yellow"}} +
    {{.}}
    +
    {{ctx.Locale.Tr "repo.pulls.status_checks_requested"}}
    +
    + {{end}}
    {{end}} From 369fe5696697cef33a188d9b985ac4b9824a4bdf Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Mon, 19 Feb 2024 11:27:05 +0100 Subject: [PATCH 15/18] Show commit status for releases (#29149) Fixes #29082 ![grafik](https://github.com/go-gitea/gitea/assets/1666336/bb2ccde1-ee99-459d-9e74-0fb8ea79e8b3) (cherry picked from commit 7e8ff709401d09467c3eee7c69cd9600d26a97a3) --- routers/web/repo/release.go | 206 ++++++++++++++-------------- services/actions/commit_status.go | 3 + templates/repo/commit_statuses.tmpl | 4 +- templates/repo/release/list.tmpl | 152 ++++++++++---------- 4 files changed, 184 insertions(+), 181 deletions(-) diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go index 4d139f2b79..33e7f739ff 100644 --- a/routers/web/repo/release.go +++ b/routers/web/repo/release.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" @@ -67,6 +68,88 @@ func calReleaseNumCommitsBehind(repoCtx *context.Repository, release *repo_model return nil } +type ReleaseInfo struct { + Release *repo_model.Release + CommitStatus *git_model.CommitStatus + CommitStatuses []*git_model.CommitStatus +} + +func getReleaseInfos(ctx *context.Context, opts *repo_model.FindReleasesOptions) ([]*ReleaseInfo, error) { + releases, err := db.Find[repo_model.Release](ctx, opts) + if err != nil { + return nil, err + } + + for _, release := range releases { + release.Repo = ctx.Repo.Repository + } + + if err = repo_model.GetReleaseAttachments(ctx, releases...); err != nil { + return nil, err + } + + // Temporary cache commits count of used branches to speed up. + countCache := make(map[string]int64) + cacheUsers := make(map[int64]*user_model.User) + if ctx.Doer != nil { + cacheUsers[ctx.Doer.ID] = ctx.Doer + } + var ok bool + + canReadActions := ctx.Repo.CanRead(unit.TypeActions) + + releaseInfos := make([]*ReleaseInfo, 0, len(releases)) + for _, r := range releases { + if r.Publisher, ok = cacheUsers[r.PublisherID]; !ok { + r.Publisher, err = user_model.GetUserByID(ctx, r.PublisherID) + if err != nil { + if user_model.IsErrUserNotExist(err) { + r.Publisher = user_model.NewGhostUser() + } else { + return nil, err + } + } + cacheUsers[r.PublisherID] = r.Publisher + } + + r.Note, err = markdown.RenderString(&markup.RenderContext{ + Links: markup.Links{ + Base: ctx.Repo.RepoLink, + }, + Metas: ctx.Repo.Repository.ComposeMetas(ctx), + GitRepo: ctx.Repo.GitRepo, + Ctx: ctx, + }, r.Note) + if err != nil { + return nil, err + } + + if !r.IsDraft { + if err := calReleaseNumCommitsBehind(ctx.Repo, r, countCache); err != nil { + return nil, err + } + } + + info := &ReleaseInfo{ + Release: r, + } + + if canReadActions { + statuses, _, err := git_model.GetLatestCommitStatus(ctx, r.Repo.ID, r.Sha1, db.ListOptions{ListAll: true}) + if err != nil { + return nil, err + } + + info.CommitStatus = git_model.CalcCommitStatus(statuses) + info.CommitStatuses = statuses + } + + releaseInfos = append(releaseInfos, info) + } + + return releaseInfos, nil +} + // Releases render releases list page func Releases(ctx *context.Context) { ctx.Data["PageIsReleaseList"] = true @@ -91,77 +174,21 @@ func Releases(ctx *context.Context) { writeAccess := ctx.Repo.CanWrite(unit.TypeReleases) ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived - opts := repo_model.FindReleasesOptions{ + releases, err := getReleaseInfos(ctx, &repo_model.FindReleasesOptions{ ListOptions: listOptions, // only show draft releases for users who can write, read-only users shouldn't see draft releases. IncludeDrafts: writeAccess, RepoID: ctx.Repo.Repository.ID, - } - - releases, err := db.Find[repo_model.Release](ctx, opts) + }) if err != nil { - ctx.ServerError("GetReleasesByRepoID", err) + ctx.ServerError("getReleaseInfos", err) return } - for _, release := range releases { - release.Repo = ctx.Repo.Repository - } - - if err = repo_model.GetReleaseAttachments(ctx, releases...); err != nil { - ctx.ServerError("GetReleaseAttachments", err) - return - } - - // Temporary cache commits count of used branches to speed up. - countCache := make(map[string]int64) - cacheUsers := make(map[int64]*user_model.User) - if ctx.Doer != nil { - cacheUsers[ctx.Doer.ID] = ctx.Doer - } - var ok bool - - for _, r := range releases { - if r.Publisher, ok = cacheUsers[r.PublisherID]; !ok { - r.Publisher, err = user_model.GetUserByID(ctx, r.PublisherID) - if err != nil { - if user_model.IsErrUserNotExist(err) { - r.Publisher = user_model.NewGhostUser() - } else { - ctx.ServerError("GetUserByID", err) - return - } - } - cacheUsers[r.PublisherID] = r.Publisher - } - - r.Note, err = markdown.RenderString(&markup.RenderContext{ - Links: markup.Links{ - Base: ctx.Repo.RepoLink, - }, - Metas: ctx.Repo.Repository.ComposeMetas(ctx), - GitRepo: ctx.Repo.GitRepo, - Ctx: ctx, - }, r.Note) - if err != nil { - ctx.ServerError("RenderString", err) - return - } - - if r.IsDraft { - continue - } - - if err := calReleaseNumCommitsBehind(ctx.Repo, r, countCache); err != nil { - ctx.ServerError("calReleaseNumCommitsBehind", err) - return - } - } - ctx.Data["Releases"] = releases numReleases := ctx.Data["NumReleases"].(int64) - pager := context.NewPagination(int(numReleases), opts.PageSize, opts.Page, 5) + pager := context.NewPagination(int(numReleases), listOptions.PageSize, listOptions.Page, 5) pager.SetDefaultParams(ctx) ctx.Data["Page"] = pager @@ -249,15 +276,24 @@ func SingleRelease(ctx *context.Context) { writeAccess := ctx.Repo.CanWrite(unit.TypeReleases) ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived - release, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, ctx.Params("*")) + releases, err := getReleaseInfos(ctx, &repo_model.FindReleasesOptions{ + ListOptions: db.ListOptions{Page: 1, PageSize: 1}, + RepoID: ctx.Repo.Repository.ID, + TagNames: []string{ctx.Params("*")}, + // only show draft releases for users who can write, read-only users shouldn't see draft releases. + IncludeDrafts: writeAccess, + }) if err != nil { - if repo_model.IsErrReleaseNotExist(err) { - ctx.NotFound("GetRelease", err) - return - } - ctx.ServerError("GetReleasesByRepoID", err) + ctx.ServerError("getReleaseInfos", err) return } + if len(releases) != 1 { + ctx.NotFound("SingleRelease", err) + return + } + + release := releases[0].Release + ctx.Data["PageIsSingleTag"] = release.IsTag if release.IsTag { ctx.Data["Title"] = release.TagName @@ -265,43 +301,7 @@ func SingleRelease(ctx *context.Context) { ctx.Data["Title"] = release.Title } - release.Repo = ctx.Repo.Repository - - err = repo_model.GetReleaseAttachments(ctx, release) - if err != nil { - ctx.ServerError("GetReleaseAttachments", err) - return - } - - release.Publisher, err = user_model.GetUserByID(ctx, release.PublisherID) - if err != nil { - if user_model.IsErrUserNotExist(err) { - release.Publisher = user_model.NewGhostUser() - } else { - ctx.ServerError("GetUserByID", err) - return - } - } - if !release.IsDraft { - if err := calReleaseNumCommitsBehind(ctx.Repo, release, make(map[string]int64)); err != nil { - ctx.ServerError("calReleaseNumCommitsBehind", err) - return - } - } - release.Note, err = markdown.RenderString(&markup.RenderContext{ - Links: markup.Links{ - Base: ctx.Repo.RepoLink, - }, - Metas: ctx.Repo.Repository.ComposeMetas(ctx), - GitRepo: ctx.Repo.GitRepo, - Ctx: ctx, - }, release.Note) - if err != nil { - ctx.ServerError("RenderString", err) - return - } - - ctx.Data["Releases"] = []*repo_model.Release{release} + ctx.Data["Releases"] = releases ctx.HTML(http.StatusOK, tplReleasesList) } diff --git a/services/actions/commit_status.go b/services/actions/commit_status.go index 72a3ab7ac6..edd1fd1568 100644 --- a/services/actions/commit_status.go +++ b/services/actions/commit_status.go @@ -64,6 +64,9 @@ func createCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er return fmt.Errorf("head of pull request is missing in event payload") } sha = payload.PullRequest.Head.Sha + case webhook_module.HookEventRelease: + event = string(run.Event) + sha = run.CommitSHA default: return nil } diff --git a/templates/repo/commit_statuses.tmpl b/templates/repo/commit_statuses.tmpl index ec2be6c38d..74c20a6a2c 100644 --- a/templates/repo/commit_statuses.tmpl +++ b/templates/repo/commit_statuses.tmpl @@ -1,10 +1,10 @@ {{if .Statuses}} {{if and (eq (len .Statuses) 1) .Status.TargetURL}} - + {{template "repo/commit_status" .Status}} {{else}} - + {{template "repo/commit_status" .Status}} {{end}} diff --git a/templates/repo/release/list.tmpl b/templates/repo/release/list.tmpl index fb2fce2950..6dbeb741db 100644 --- a/templates/repo/release/list.tmpl +++ b/templates/repo/release/list.tmpl @@ -5,90 +5,90 @@ {{template "base/alert" .}} {{template "repo/release_tag_header" .}}
      - {{range $idx, $release := .Releases}} + {{range $idx, $info := .Releases}} + {{$release := $info.Release}}
    • - {{svg "octicon-tag" 16 "gt-mr-2"}}{{.TagName}} - {{if and .Sha1 ($.Permission.CanRead $.UnitTypeCode)}} - {{svg "octicon-git-commit" 16 "gt-mr-2"}}{{ShortSha .Sha1}} - {{template "repo/branch_dropdown" dict "root" $ "release" .}} - {{end}} + {{svg "octicon-tag" 16 "gt-mr-2"}}{{$release.TagName}} + {{if and $release.Sha1 ($.Permission.CanRead $.UnitTypeCode)}} + {{svg "octicon-git-commit" 16 "gt-mr-2"}}{{ShortSha $release.Sha1}} + {{template "repo/branch_dropdown" dict "root" $ "release" $release}} + {{end}}
      -
      -

      - {{.Title}} - {{if .IsDraft}} - {{ctx.Locale.Tr "repo.release.draft"}} - {{else if .IsPrerelease}} - {{ctx.Locale.Tr "repo.release.prerelease"}} - {{else}} - {{ctx.Locale.Tr "repo.release.stable"}} - {{end}} -

      -
      - {{if $.CanCreateRelease}} - - {{svg "octicon-pencil"}} - - {{end}} -
      -
      -

      - - {{if .OriginalAuthor}} - {{svg (MigrationIcon .Repo.GetOriginalURLHostname) 20 "gt-mr-2"}}{{.OriginalAuthor}} - {{else if .Publisher}} - {{ctx.AvatarUtils.Avatar .Publisher 20 "gt-mr-2"}} - {{.Publisher.GetDisplayName}} +

      +

      + {{$release.Title}} + {{template "repo/commit_statuses" dict "Status" $info.CommitStatus "Statuses" $info.CommitStatuses "AdditionalClasses" "gt-df"}} + {{if $release.IsDraft}} + {{ctx.Locale.Tr "repo.release.draft"}} + {{else if $release.IsPrerelease}} + {{ctx.Locale.Tr "repo.release.prerelease"}} {{else}} - Ghost + {{ctx.Locale.Tr "repo.release.stable"}} {{end}} - - - {{ctx.Locale.Tr "repo.released_this"}} - - {{if .CreatedUnix}} - {{TimeSinceUnix .CreatedUnix ctx.Locale}} +

      +
      + {{if $.CanCreateRelease}} + + {{svg "octicon-pencil"}} + {{end}} - {{if and (not .IsDraft) ($.Permission.CanRead $.UnitTypeCode)}} - | {{ctx.Locale.Tr "repo.release.ahead.commits" .NumCommitsBehind | Str2html}} {{ctx.Locale.Tr "repo.release.ahead.target" .TargetBehind}} - {{end}} -

      -
      - {{Str2html .Note}}
      -
      -
      - - {{ctx.Locale.Tr "repo.release.downloads"}} - - -
      +
      +

      + + {{if $release.OriginalAuthor}} + {{svg (MigrationIcon $release.Repo.GetOriginalURLHostname) 20 "gt-mr-2"}}{{$release.OriginalAuthor}} + {{else if $release.Publisher}} + {{ctx.AvatarUtils.Avatar $release.Publisher 20 "gt-mr-2"}} + {{$release.Publisher.GetDisplayName}} + {{else}} + Ghost + {{end}} + + + {{ctx.Locale.Tr "repo.released_this"}} + + {{if $release.CreatedUnix}} + {{TimeSinceUnix $release.CreatedUnix ctx.Locale}} + {{end}} + {{if and (not $release.IsDraft) ($.Permission.CanRead $.UnitTypeCode)}} + | {{ctx.Locale.Tr "repo.release.ahead.commits" $release.NumCommitsBehind | Str2html}} {{ctx.Locale.Tr "repo.release.ahead.target" $release.TargetBehind}} + {{end}} +

      +
      + {{Str2html $release.Note}} +
      +
      +
      + + {{ctx.Locale.Tr "repo.release.downloads"}} + + +
    • From 5fffab8d9d4f1202d9fa6f6da548bf2f4808b5a9 Mon Sep 17 00:00:00 2001 From: Johan Van de Wauw Date: Mon, 19 Feb 2024 11:51:58 +0100 Subject: [PATCH 16/18] Fix c/p error in inline documentation (#29148) Fix small copy/paste error in inline documentation --------- Co-authored-by: wxiaoguang (cherry picked from commit 740c6a226c4df26432641018fbfd9186977d573f) --- services/auth/source/db/source.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/auth/source/db/source.go b/services/auth/source/db/source.go index 50eae27439..bb2270cbd6 100644 --- a/services/auth/source/db/source.go +++ b/services/auth/source/db/source.go @@ -18,7 +18,7 @@ func (source *Source) FromDB(bs []byte) error { return nil } -// ToDB exports an SMTPConfig to a serialized format. +// ToDB exports the config to a byte slice to be saved into database (this method is just dummy and does nothing for DB source) func (source *Source) ToDB() ([]byte, error) { return nil, nil } From c7c20ff5ab6dd84eed79115c00c3f230963cc105 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 19 Feb 2024 19:25:58 +0800 Subject: [PATCH 17/18] Remove DataRaceCheck (#29258) Since #26254, it started using `{{ctx.Locale.Tr ...}}` Now the `ctx` seems stable enough, so the check could be removed. (cherry picked from commit 567a68a0bf78c8d70f08c8ab948fdbb455225aa9) --- modules/context/context_template.go | 14 -------------- templates/base/footer.tmpl | 1 - templates/base/head.tmpl | 1 - 3 files changed, 16 deletions(-) diff --git a/modules/context/context_template.go b/modules/context/context_template.go index ba90fc170a..7878d409ca 100644 --- a/modules/context/context_template.go +++ b/modules/context/context_template.go @@ -5,10 +5,7 @@ package context import ( "context" - "errors" "time" - - "code.gitea.io/gitea/modules/log" ) var _ context.Context = TemplateContext(nil) @@ -36,14 +33,3 @@ func (c TemplateContext) Err() error { func (c TemplateContext) Value(key any) any { return c.parentContext().Value(key) } - -// DataRaceCheck checks whether the template context function "ctx()" returns the consistent context -// as the current template's rendering context (request context), to help to find data race issues as early as possible. -// When the code is proven to be correct and stable, this function should be removed. -func (c TemplateContext) DataRaceCheck(dataCtx context.Context) (string, error) { - if c.parentContext() != dataCtx { - log.Error("TemplateContext.DataRaceCheck: parent context mismatch\n%s", log.Stack(2)) - return "", errors.New("parent context mismatch") - } - return "", nil -} diff --git a/templates/base/footer.tmpl b/templates/base/footer.tmpl index d65a3626a4..fed426a469 100644 --- a/templates/base/footer.tmpl +++ b/templates/base/footer.tmpl @@ -16,6 +16,5 @@ {{template "custom/footer" .}} - {{ctx.DataRaceCheck $.Context}} diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl index d865d58b8e..a202ad7dd1 100644 --- a/templates/base/head.tmpl +++ b/templates/base/head.tmpl @@ -31,7 +31,6 @@ {{template "custom/header" .}} - {{ctx.DataRaceCheck $.Context}} {{template "custom/body_outer_pre" .}}
      From 8125fe063425a1a3d8c52a8ab3481af3ef1d5440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=9Eahin=20Akkaya?= Date: Mon, 19 Feb 2024 15:47:38 +0300 Subject: [PATCH 18/18] Deduplicate translations for contributors graph (#29256) I have implemented three graph pages ([contributors](https://github.com/go-gitea/gitea/pull/27882), [code frequency](https://github.com/go-gitea/gitea/pull/29191) and [recent commits](https://github.com/go-gitea/gitea/pull/29210)) and they have all same page title as the tab name so I decided to use same translations for them. This PR is for contributors graph. Other PR's have their own respective commits. (cherry picked from commit 39a77d92d9677b0a0049cb8696960d6d2ac052d6) --- options/locale/locale_en-US.ini | 3 +-- routers/web/repo/contributors.go | 2 +- templates/repo/contributors.tmpl | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 3700017330..bdae9a29ac 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2023,12 +2023,10 @@ activity.git_stats_and_deletions = and activity.git_stats_deletion_1 = %d deletion activity.git_stats_deletion_n = %d deletions -contributors = Contributors contributors.contribution_type.filter_label = Contribution type: contributors.contribution_type.commits = Commits contributors.contribution_type.additions = Additions contributors.contribution_type.deletions = Deletions -contributors.what = contributions search = Search search.search_repo = Search repository @@ -2654,6 +2652,7 @@ component_loading = Loading %s... component_loading_failed = Could not load %s component_loading_info = This might take a bit… component_failed_to_load = An unexpected error happened. +contributors.what = contributions [org] org_name_holder = Organization Name diff --git a/routers/web/repo/contributors.go b/routers/web/repo/contributors.go index f7dedc0b34..bcfef7580a 100644 --- a/routers/web/repo/contributors.go +++ b/routers/web/repo/contributors.go @@ -18,7 +18,7 @@ const ( // Contributors render the page to show repository contributors graph func Contributors(ctx *context.Context) { - ctx.Data["Title"] = ctx.Tr("repo.contributors") + ctx.Data["Title"] = ctx.Tr("repo.activity.navbar.contributors") ctx.Data["PageIsActivity"] = true ctx.Data["PageIsContributors"] = true diff --git a/templates/repo/contributors.tmpl b/templates/repo/contributors.tmpl index 3bd343197b..4a258e5b70 100644 --- a/templates/repo/contributors.tmpl +++ b/templates/repo/contributors.tmpl @@ -4,8 +4,8 @@ data-locale-contribution-type-commits="{{ctx.Locale.Tr "repo.contributors.contribution_type.commits"}}" data-locale-contribution-type-additions="{{ctx.Locale.Tr "repo.contributors.contribution_type.additions"}}" data-locale-contribution-type-deletions="{{ctx.Locale.Tr "repo.contributors.contribution_type.deletions"}}" - data-locale-loading-title="{{ctx.Locale.Tr "graphs.component_loading" (ctx.Locale.Tr "repo.contributors.what")}}" - data-locale-loading-title-failed="{{ctx.Locale.Tr "graphs.component_loading_failed" (ctx.Locale.Tr "repo.contributors.what")}}" + data-locale-loading-title="{{ctx.Locale.Tr "graphs.component_loading" (ctx.Locale.Tr "graphs.contributors.what")}}" + data-locale-loading-title-failed="{{ctx.Locale.Tr "graphs.component_loading_failed" (ctx.Locale.Tr "graphs.contributors.what")}}" data-locale-loading-info="{{ctx.Locale.Tr "graphs.component_loading_info"}}" data-locale-component-failed-to-load="{{ctx.Locale.Tr "graphs.component_failed_to_load"}}" >