diff --git a/.github/workflows/cron-lock.yml b/.github/workflows/cron-lock.yml index 746ec49bc63..665313135b6 100644 --- a/.github/workflows/cron-lock.yml +++ b/.github/workflows/cron-lock.yml @@ -19,4 +19,5 @@ jobs: steps: - uses: dessant/lock-threads@v5 with: - issue-inactive-days: 45 + issue-inactive-days: 10 + pr-inactive-days: 7 diff --git a/.gitignore b/.gitignore index 814d9103153..8f2544866a1 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,7 @@ _test # MS VSCode .vscode -__debug_bin +__debug_bin* *.cgo1.go *.cgo2.c diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f9b9a421a37..dc90c6905b9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,6 +8,7 @@ - [How to report issues](#how-to-report-issues) - [Types of issues](#types-of-issues) - [Discuss your design before the implementation](#discuss-your-design-before-the-implementation) + - [Issue locking](#issue-locking) - [Building Gitea](#building-gitea) - [Dependencies](#dependencies) - [Backend](#backend) @@ -103,6 +104,13 @@ the goals for the project and tools. Pull requests should not be the place for architecture discussions. +### Issue locking + +Commenting on closed or merged issues/PRs is strongly discouraged. +Such comments will likely be overlooked as some maintainers may not view notifications on closed issues, thinking that the item is resolved. +As such, commenting on closed/merged issues/PRs may be disabled prior to the scheduled auto-locking if a discussion starts or if unrelated comments are posted. +If further discussion is needed, we encourage you to open a new issue instead and we recommend linking to the issue/PR in question for context. + ## Building Gitea See the [development setup instructions](https://docs.gitea.com/development/hacking-on-gitea). diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 5451537d02c..dc5aa691ee3 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -956,6 +956,12 @@ LEVEL = Info ;GO_GET_CLONE_URL_PROTOCOL = https ;; ;; Close issues as long as a commit on any branch marks it as fixed +;DEFAULT_CLOSE_ISSUES_VIA_COMMITS_IN_ANY_BRANCH = false +;; +;; Allow users to push local repositories to Gitea and have them automatically created for a user or an org +;ENABLE_PUSH_CREATE_USER = false +;ENABLE_PUSH_CREATE_ORG = false +;; ;; Comma separated list of globally disabled repo units. Allowed values: repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects, repo.packages, repo.actions. ;DISABLED_REPO_UNITS = ;; @@ -1474,8 +1480,9 @@ LEVEL = Info ;; ;; Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled ;DEFAULT_EMAIL_NOTIFICATIONS = enabled -;; Disabled features for users, could be "deletion", more features can be disabled in future +;; Disabled features for users, could be "deletion","manage_gpg_keys" more features can be disabled in future ;; - deletion: a user cannot delete their own account +;; - manage_gpg_keys: a user cannot configure gpg keys ;USER_DISABLED_FEATURES = ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 643932de6c1..ea6e1eb1a4d 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -518,8 +518,9 @@ And the following unique queues: - `DEFAULT_EMAIL_NOTIFICATIONS`: **enabled**: Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled - `DISABLE_REGULAR_ORG_CREATION`: **false**: Disallow regular (non-admin) users from creating organizations. -- `USER_DISABLED_FEATURES`: **_empty_** Disabled features for users, could be `deletion` and more features can be added in future. +- `USER_DISABLED_FEATURES`: **_empty_** Disabled features for users, could be `deletion`, `manage_gpg_keys` and more features can be added in future. - `deletion`: User cannot delete their own account. + - `manage_gpg_keys`: User cannot configure gpg keys ## Security (`security`) diff --git a/docs/content/administration/config-cheat-sheet.zh-cn.md b/docs/content/administration/config-cheat-sheet.zh-cn.md index 5fe0a62215f..5cc57343590 100644 --- a/docs/content/administration/config-cheat-sheet.zh-cn.md +++ b/docs/content/administration/config-cheat-sheet.zh-cn.md @@ -497,8 +497,9 @@ Gitea 创建以下非唯一队列: - `DEFAULT_EMAIL_NOTIFICATIONS`: **enabled**:用户电子邮件通知的默认配置(用户可配置)。选项:enabled、onmention、disabled - `DISABLE_REGULAR_ORG_CREATION`: **false**:禁止普通(非管理员)用户创建组织。 -- `USER_DISABLED_FEATURES`:**_empty_** 禁用的用户特性,当前允许为空或者 `deletion`, 未来可以增加更多设置。 +- `USER_DISABLED_FEATURES`:**_empty_** 禁用的用户特性,当前允许为空或者 `deletion`,`manage_gpg_keys` 未来可以增加更多设置。 - `deletion`: 用户不能通过界面或者API删除他自己。 + - `manage_gpg_keys`: 用户不能配置 GPG 密钥 ## 安全性 (`security`) diff --git a/docs/content/administration/mail-templates.en-us.md b/docs/content/administration/mail-templates.en-us.md index b642ff4aa7f..9077f97aeac 100644 --- a/docs/content/administration/mail-templates.en-us.md +++ b/docs/content/administration/mail-templates.en-us.md @@ -224,7 +224,7 @@ Please check [Gitea's logs](administration/logging-config.md) for error messages {{if not (eq .Body "")}}

Message content


- {{.Body | Str2html}} + {{.Body | SanitizeHTML}} {{end}}


@@ -260,19 +260,19 @@ The template system contains several functions that can be used to further proce the messages. Here's a list of some of them: | Name | Parameters | Available | Usage | -| ---------------- | ----------- | --------- | --------------------------------------------------------------------------- | +| ---------------- | ----------- | --------- |-----------------------------------------------------------------------------| | `AppUrl` | - | Any | Gitea's URL | | `AppName` | - | Any | Set from `app.ini`, usually "Gitea" | | `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. | +| `SanitizeHTML` | string | Body only | Sanitizes text by removing any dangerous HTML tags from it. | | `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: ```html -Like this: {{Str2html "Escapetext"}} -Or this: {{"Escapetext" | Str2html}} +Like this: {{SanitizeHTML "Escapetext"}} +Or this: {{"Escapetext" | SanitizeHTML}} Or this: {{AppUrl}} But not like this: {{.AppUrl}} ``` diff --git a/docs/content/administration/mail-templates.zh-cn.md b/docs/content/administration/mail-templates.zh-cn.md index fd455ef3a86..d58f9dc1763 100644 --- a/docs/content/administration/mail-templates.zh-cn.md +++ b/docs/content/administration/mail-templates.zh-cn.md @@ -207,7 +207,7 @@ _主题_ 和 _邮件正文_ 由 [Golang的模板引擎](https://go.dev/pkg/text/ {{if not (eq .Body "")}}

消息内容:


- {{.Body | Str2html}} + {{.Body | SanitizeHTML}} {{end}}


@@ -242,20 +242,20 @@ _主题_ 和 _邮件正文_ 由 [Golang的模板引擎](https://go.dev/pkg/text/ 模板系统包含一些函数,可用于进一步处理和格式化消息。以下是其中一些函数的列表: -| 函数名 | 参数 | 可用于 | 用法 | -|------------------| ----------- | ------------ | --------------------------------------------------------------------------------- | -| `AppUrl` | - | 任何地方 | Gitea 的 URL | -| `AppName` | - | 任何地方 | 从 `app.ini` 中设置,通常为 "Gitea" | -| `AppDomain` | - | 任何地方 | Gitea 的主机名 | -| `EllipsisString` | string, int | 任何地方 | 将字符串截断为指定长度;根据需要添加省略号 | -| `Str2html` | string | 仅正文部分 | 通过删除其中的 HTML 标签对文本进行清理 | -| `SafeHTML` | string | 仅正文部分 | 将输入作为 HTML 处理;可用于 `.ReviewComments.RenderedContent` 等字段 | +| 函数名 | 参数 | 可用于 | 用法 | +|------------------| ----------- | ------------ |---------------------------------------------------------| +| `AppUrl` | - | 任何地方 | Gitea 的 URL | +| `AppName` | - | 任何地方 | 从 `app.ini` 中设置,通常为 "Gitea" | +| `AppDomain` | - | 任何地方 | Gitea 的主机名 | +| `EllipsisString` | string, int | 任何地方 | 将字符串截断为指定长度;根据需要添加省略号 | +| `SanitizeHTML` | string | 仅正文部分 | 通过删除其中的危险 HTML 标签对文本进行清理 | +| `SafeHTML` | string | 仅正文部分 | 将输入作为 HTML 处理;可用于 `.ReviewComments.RenderedContent` 等字段 | 这些都是 _函数_,而不是元数据,因此必须按以下方式使用: ```html -像这样使用: {{Str2html "Escapetext"}} -或者这样使用: {{"Escapetext" | Str2html}} +像这样使用: {{SanitizeHTML "Escapetext"}} +或者这样使用: {{"Escapetext" | SanitizeHTML}} 或者这样使用: {{AppUrl}} 但不要像这样使用: {{.AppUrl}} ``` diff --git a/docs/content/help/faq.en-us.md b/docs/content/help/faq.en-us.md index 5ea2c10f5ee..b3b09801256 100644 --- a/docs/content/help/faq.en-us.md +++ b/docs/content/help/faq.en-us.md @@ -221,9 +221,11 @@ Our translations are currently crowd-sourced on our [Crowdin project](https://cr Whether you want to change a translation or add a new one, it will need to be there as all translations are overwritten in our CI via the Crowdin integration. -## Push Hook / Webhook aren't running +## Push Hook / Webhook / Actions aren't running -If you can push but can't see push activities on the home dashboard, or the push doesn't trigger webhook, there are a few possibilities: +If you can push but can't see push activities on the home dashboard, or the push doesn't trigger webhook and Actions workflows, it's likely that the git hooks are not working. + +There are a few possibilities: 1. The git hooks are out of sync: run "Resynchronize pre-receive, update and post-receive hooks of all repositories" on the site admin panel 2. The git repositories (and hooks) are stored on some filesystems (ex: mounted by NAS) which don't support script execution, make sure the filesystem supports `chmod a+x any-script` diff --git a/docs/content/help/faq.zh-cn.md b/docs/content/help/faq.zh-cn.md index b8dd3cd1803..25230df70b2 100644 --- a/docs/content/help/faq.zh-cn.md +++ b/docs/content/help/faq.zh-cn.md @@ -225,9 +225,11 @@ Gitea还提供了自己的SSH服务器,用于在SSHD不可用时使用。 无论您想要更改翻译还是添加新的翻译,都需要在Crowdin集成中进行,因为所有翻译都会被CI覆盖。 -## 推送钩子/ Webhook未运行 +## 推送钩子/ Webhook / Actions 未运行 -如果您可以推送但无法在主页仪表板上看到推送活动,或者推送不触发Webhook,有几种可能性: +如果您可以推送但无法在主页仪表板上看到推送活动,或者推送不触发 Webhook 和 Actions,可能是 git 钩子不工作而导致的。 + +这可能是由于以下原因: 1. Git钩子不同步:在站点管理面板上运行“重新同步所有仓库的pre-receive、update和post-receive钩子” 2. Git仓库(和钩子)存储在一些不支持脚本执行的文件系统上(例如由NAS挂载),请确保文件系统支持`chmod a+x any-script` diff --git a/docs/content/usage/actions/faq.en-us.md b/docs/content/usage/actions/faq.en-us.md index 7ed59e02cdc..427d57c43e0 100644 --- a/docs/content/usage/actions/faq.en-us.md +++ b/docs/content/usage/actions/faq.en-us.md @@ -45,25 +45,24 @@ It is technically possible to implement, but we need to discuss whether it is ne ## Where will the runner download scripts when using actions such as `actions/checkout@v4`? -You may be aware that there are tens of thousands of [marketplace actions](https://github.com/marketplace?type=actions) in GitHub. -However, when you write `uses: actions/checkout@v4`, it actually downloads the scripts from [gitea.com/actions/checkout](http://gitea.com/actions/checkout) by default (not GitHub). -This is a mirror of [github.com/actions/checkout](http://github.com/actions/checkout), but it's impossible to mirror all of them. -That's why you may encounter failures when trying to use some actions that haven't been mirrored. +There are tens of thousands of [actions scripts](https://github.com/marketplace?type=actions) in GitHub, and when you write `uses: actions/checkout@v4`, it downloads the scripts from [github.com/actions/checkout](http://github.com/actions/checkout) by default. +But what if you want to use actions from other places such as gitea.com instead of GitHub? The good news is that you can specify the URL prefix to use actions from anywhere. This is an extra syntax in Gitea Actions. For example: -- `uses: https://github.com/xxx/xxx@xxx` - `uses: https://gitea.com/xxx/xxx@xxx` +- `uses: https://github.com/xxx/xxx@xxx` - `uses: http://your_gitea_instance.com/xxx@xxx` Be careful, the `https://` or `http://` prefix is necessary! -Alternatively, if you want your runners to download actions from GitHub or your own Gitea instance by default, you can configure it by setting `[actions].DEFAULT_ACTIONS_URL`. -See [Configuration Cheat Sheet](administration/config-cheat-sheet.md#actions-actions). +This is one of the differences from GitHub Actions which supports actions scripts only from GitHub. +But it should allow users much more flexibility in how they run Actions. -This is one of the differences from GitHub Actions, but it should allow users much more flexibility in how they run Actions. +Alternatively, if you want your runners to download actions from your own Gitea instance by default, you can configure it by setting `[actions].DEFAULT_ACTIONS_URL`. +See [Configuration Cheat Sheet](administration/config-cheat-sheet.md#actions-actions). ## How to limit the permission of the runners? diff --git a/docs/content/usage/actions/faq.zh-cn.md b/docs/content/usage/actions/faq.zh-cn.md index ba5f87bf0c4..d6e1466801b 100644 --- a/docs/content/usage/actions/faq.zh-cn.md +++ b/docs/content/usage/actions/faq.zh-cn.md @@ -45,25 +45,25 @@ DEFAULT_REPO_UNITS = ...,repo.actions ## 使用`actions/checkout@v4`等Actions时,Job容器会从何处下载脚本? -您可能知道GitHub上有成千上万个[Actions市场](https://github.com/marketplace?type=actions)。 -然而,当您编写`uses: actions/checkout@v4`时,它实际上默认从[gitea.com/actions/checkout](http://gitea.com/actions/checkout)下载脚本(而不是从GitHub下载)。 -这是[github.com/actions/checkout](http://github.com/actions/checkout)的镜像,但无法将它们全部镜像。 -这就是为什么在尝试使用尚未镜像的某些Actions时可能会遇到失败的原因。 +GitHub 上有成千上万个 [Actions 脚本](https://github.com/marketplace?type=actions)。 +当您编写 `uses: actions/checkout@v4` 时,它默认会从 [github.com/actions/checkout](https://github.com/actions/checkout) 下载脚本。 +那如果您想使用一些托管在其它平台上的脚本呢,比如在 gitea.com 上的? 好消息是,您可以指定要从任何位置使用Actions的URL前缀。 这是Gitea Actions中的额外语法。 例如: -- `uses: https://github.com/xxx/xxx@xxx` - `uses: https://gitea.com/xxx/xxx@xxx` +- `uses: https://github.com/xxx/xxx@xxx` - `uses: http://your_gitea_instance.com/xxx@xxx` 注意,`https://`或`http://`前缀是必需的! -另外,如果您希望您的Runner默认从GitHub或您自己的Gitea实例下载Actions,可以通过设置 `[actions].DEFAULT_ACTIONS_URL`进行配置。 -参见[配置速查表](administration/config-cheat-sheet.md#actions-actions)。 +这是与 GitHub Actions 的一个区别,GitHub Actions 只允许使用托管在 GitHub 上的 actions 脚本。 +但用户理应拥有权利去灵活决定如何运行 Actions。 -这是与GitHub Actions的一个区别,但它应该允许用户以更灵活的方式运行Actions。 +另外,如果您希望您的 Runner 默认从您自己的 Gitea 实例下载 Actions,可以通过设置 `[actions].DEFAULT_ACTIONS_URL`进行配置。 +参见[配置速查表](administration/config-cheat-sheet.md#actions-actions)。 ## 如何限制Runner的权限? diff --git a/docs/content/usage/badge.en-us.md b/docs/content/usage/badge.en-us.md new file mode 100644 index 00000000000..212134e01c1 --- /dev/null +++ b/docs/content/usage/badge.en-us.md @@ -0,0 +1,37 @@ +--- +date: "2023-02-25T00:00:00+00:00" +title: "Badge" +slug: "badge" +sidebar_position: 11 +toc: false +draft: false +aliases: + - /en-us/badge +menu: + sidebar: + parent: "usage" + name: "Badge" + sidebar_position: 11 + identifier: "Badge" +--- + +# Badge + +Gitea has its builtin Badge system which allows you to display the status of your repository in other places. You can use the following badges: + +## Workflow Badge + +The Gitea Actions workflow badge is a badge that shows the status of the latest workflow run. +It is designed to be compatible with [GitHub Actions workflow badge](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/adding-a-workflow-status-badge). + +You can use the following URL to get the badge: + +``` +https://your-gitea-instance.com/{owner}/{repo}/actions/workflows/{workflow_file}?branch={branch}&event={event} +``` + +- `{owner}`: The owner of the repository. +- `{repo}`: The name of the repository. +- `{workflow_file}`: The name of the workflow file. +- `{branch}`: Optional. The branch of the workflow. Default to your repository's default branch. +- `{event}`: Optional. The event of the workflow. Default to none. diff --git a/models/actions/run.go b/models/actions/run.go index fcac58d515c..7b3125949b8 100644 --- a/models/actions/run.go +++ b/models/actions/run.go @@ -339,6 +339,23 @@ func GetRunByIndex(ctx context.Context, repoID, index int64) (*ActionRun, error) return run, nil } +func GetWorkflowLatestRun(ctx context.Context, repoID int64, workflowFile, branch, event string) (*ActionRun, error) { + var run ActionRun + q := db.GetEngine(ctx).Where("repo_id=?", repoID). + And("ref = ?", branch). + And("workflow_id = ?", workflowFile) + if event != "" { + q.And("event = ?", event) + } + has, err := q.Desc("id").Get(&run) + if err != nil { + return nil, err + } else if !has { + return nil, util.NewNotExistErrorf("run with repo_id %d, ref %s, workflow_id %s", repoID, branch, workflowFile) + } + return &run, nil +} + // UpdateRun updates a run. // It requires the inputted run has Version set. // It will return error if the version is not matched (it means the run has been changed after loaded). diff --git a/models/issues/comment.go b/models/issues/comment.go index c7b22f3cca0..da91a83384e 100644 --- a/models/issues/comment.go +++ b/models/issues/comment.go @@ -8,6 +8,7 @@ package issues import ( "context" "fmt" + "html/template" "strconv" "unicode/utf8" @@ -259,8 +260,8 @@ type Comment struct { CommitID int64 Line int64 // - previous line / + proposed line TreePath string - Content string `xorm:"LONGTEXT"` - RenderedContent string `xorm:"-"` + Content string `xorm:"LONGTEXT"` + RenderedContent template.HTML `xorm:"-"` // Path represents the 4 lines of code cemented by this comment Patch string `xorm:"-"` diff --git a/models/issues/content_history.go b/models/issues/content_history.go index 8b00adda99a..31c80d2cea3 100644 --- a/models/issues/content_history.go +++ b/models/issues/content_history.go @@ -172,13 +172,9 @@ func FetchIssueContentHistoryList(dbCtx context.Context, issueID, commentID int6 // HasIssueContentHistory check if a ContentHistory entry exists func HasIssueContentHistory(dbCtx context.Context, issueID, commentID int64) (bool, error) { - exists, err := db.GetEngine(dbCtx).Cols("id").Exist(&ContentHistory{ - IssueID: issueID, - CommentID: commentID, - }) + exists, err := db.GetEngine(dbCtx).Where(builder.Eq{"issue_id": issueID, "comment_id": commentID}).Exist(&ContentHistory{}) if err != nil { - log.Error("can not fetch issue content history. err=%v", err) - return false, err + return false, fmt.Errorf("can not check issue content history. err: %w", err) } return exists, err } diff --git a/models/issues/content_history_test.go b/models/issues/content_history_test.go index 0ea1d0f7b2e..1caa73a9487 100644 --- a/models/issues/content_history_test.go +++ b/models/issues/content_history_test.go @@ -78,3 +78,22 @@ func TestContentHistory(t *testing.T) { assert.EqualValues(t, 7, list2[1].HistoryID) assert.EqualValues(t, 4, list2[2].HistoryID) } + +func TestHasIssueContentHistoryForCommentOnly(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + _ = db.TruncateBeans(db.DefaultContext, &issues_model.ContentHistory{}) + + hasHistory1, _ := issues_model.HasIssueContentHistory(db.DefaultContext, 10, 0) + assert.False(t, hasHistory1) + hasHistory2, _ := issues_model.HasIssueContentHistory(db.DefaultContext, 10, 100) + assert.False(t, hasHistory2) + + _ = issues_model.SaveIssueContentHistory(db.DefaultContext, 1, 10, 100, timeutil.TimeStampNow(), "c-a", true) + _ = issues_model.SaveIssueContentHistory(db.DefaultContext, 1, 10, 100, timeutil.TimeStampNow().Add(5), "c-b", false) + + hasHistory1, _ = issues_model.HasIssueContentHistory(db.DefaultContext, 10, 0) + assert.False(t, hasHistory1) + hasHistory2, _ = issues_model.HasIssueContentHistory(db.DefaultContext, 10, 100) + assert.True(t, hasHistory2) +} diff --git a/models/issues/issue.go b/models/issues/issue.go index 90aad10bb90..563a780dcb1 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -7,6 +7,7 @@ package issues import ( "context" "fmt" + "html/template" "regexp" "slices" @@ -105,7 +106,7 @@ type Issue struct { OriginalAuthorID int64 `xorm:"index"` Title string `xorm:"name"` Content string `xorm:"LONGTEXT"` - RenderedContent string `xorm:"-"` + RenderedContent template.HTML `xorm:"-"` Labels []*Label `xorm:"-"` MilestoneID int64 `xorm:"INDEX"` Milestone *Milestone `xorm:"-"` diff --git a/models/issues/milestone.go b/models/issues/milestone.go index f663d42fe92..ea52a64c81b 100644 --- a/models/issues/milestone.go +++ b/models/issues/milestone.go @@ -6,6 +6,7 @@ package issues import ( "context" "fmt" + "html/template" "strings" "code.gitea.io/gitea/models/db" @@ -47,8 +48,8 @@ type Milestone struct { RepoID int64 `xorm:"INDEX"` Repo *repo_model.Repository `xorm:"-"` Name string - Content string `xorm:"TEXT"` - RenderedContent string `xorm:"-"` + Content string `xorm:"TEXT"` + RenderedContent template.HTML `xorm:"-"` IsClosed bool NumIssues int NumClosedIssues int diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index beb1f3bb963..516eb53f62c 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -558,6 +558,8 @@ var migrations = []Migration{ NewMigration("Add PreviousDuration to ActionRun", v1_22.AddPreviousDurationToActionRun), // v286 -> v287 NewMigration("Add support for SHA256 git repositories", v1_22.AdjustDBForSha256), + // v287 -> v288 + NewMigration("Use Slug instead of ID for Badges", v1_22.UseSlugInsteadOfIDForBadges), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v1_22/v287.go b/models/migrations/v1_22/v287.go new file mode 100644 index 00000000000..c8b15932869 --- /dev/null +++ b/models/migrations/v1_22/v287.go @@ -0,0 +1,46 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_22 //nolint + +import ( + "xorm.io/xorm" +) + +type BadgeUnique struct { + ID int64 `xorm:"pk autoincr"` + Slug string `xorm:"UNIQUE"` +} + +func (BadgeUnique) TableName() string { + return "badge" +} + +func UseSlugInsteadOfIDForBadges(x *xorm.Engine) error { + type Badge struct { + Slug string + } + + err := x.Sync(new(Badge)) + if err != nil { + return err + } + + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + _, err = sess.Exec("UPDATE `badge` SET `slug` = `id` Where `slug` IS NULL") + if err != nil { + return err + } + + err = sess.Sync(new(BadgeUnique)) + if err != nil { + return err + } + + return sess.Commit() +} diff --git a/models/migrations/v1_22/v287_test.go b/models/migrations/v1_22/v287_test.go new file mode 100644 index 00000000000..19c7ae3b911 --- /dev/null +++ b/models/migrations/v1_22/v287_test.go @@ -0,0 +1,57 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_22 //nolint + +import ( + "fmt" + "testing" + + "code.gitea.io/gitea/models/migrations/base" + + "github.com/stretchr/testify/assert" +) + +func Test_UpdateBadgeColName(t *testing.T) { + type Badge struct { + ID int64 `xorm:"pk autoincr"` + Description string + ImageURL string + } + + // Prepare and load the testing database + x, deferable := base.PrepareTestEnv(t, 0, new(BadgeUnique), new(Badge)) + defer deferable() + if x == nil || t.Failed() { + return + } + + oldBadges := []Badge{ + {ID: 1, Description: "Test Badge 1", ImageURL: "https://example.com/badge1.png"}, + {ID: 2, Description: "Test Badge 2", ImageURL: "https://example.com/badge2.png"}, + {ID: 3, Description: "Test Badge 3", ImageURL: "https://example.com/badge3.png"}, + } + + for _, badge := range oldBadges { + _, err := x.Insert(&badge) + assert.NoError(t, err) + } + + if err := UseSlugInsteadOfIDForBadges(x); err != nil { + assert.NoError(t, err) + return + } + + got := []BadgeUnique{} + if err := x.Table("badge").Asc("id").Find(&got); !assert.NoError(t, err) { + return + } + + for i, e := range oldBadges { + got := got[i] + assert.Equal(t, e.ID, got.ID) + assert.Equal(t, fmt.Sprintf("%d", e.ID), got.Slug) + } + + // TODO: check if badges have been updated +} diff --git a/models/project/project.go b/models/project/project.go index d2fca6cdc8a..42b06e58c93 100644 --- a/models/project/project.go +++ b/models/project/project.go @@ -6,6 +6,7 @@ package project import ( "context" "fmt" + "html/template" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" @@ -100,7 +101,7 @@ type Project struct { CardType CardType Type Type - RenderedContent string `xorm:"-"` + RenderedContent template.HTML `xorm:"-"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` diff --git a/models/repo/release.go b/models/repo/release.go index 1f37f11b2e3..a9f65f6c3e8 100644 --- a/models/repo/release.go +++ b/models/repo/release.go @@ -7,6 +7,7 @@ package repo import ( "context" "fmt" + "html/template" "net/url" "sort" "strconv" @@ -15,6 +16,7 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" @@ -79,7 +81,7 @@ type Release struct { NumCommits int64 NumCommitsBehind int64 `xorm:"-"` Note string `xorm:"TEXT"` - RenderedNote string `xorm:"-"` + RenderedNote template.HTML `xorm:"-"` IsDraft bool `xorm:"NOT NULL DEFAULT false"` IsPrerelease bool `xorm:"NOT NULL DEFAULT false"` IsTag bool `xorm:"NOT NULL DEFAULT false"` // will be true only if the record is a tag and has no related releases @@ -228,10 +230,10 @@ type FindReleasesOptions struct { RepoID int64 IncludeDrafts bool IncludeTags bool - IsPreRelease util.OptionalBool - IsDraft util.OptionalBool + IsPreRelease optional.Option[bool] + IsDraft optional.Option[bool] TagNames []string - HasSha1 util.OptionalBool // useful to find draft releases which are created with existing tags + HasSha1 optional.Option[bool] // useful to find draft releases which are created with existing tags } func (opts FindReleasesOptions) ToConds() builder.Cond { @@ -246,14 +248,14 @@ func (opts FindReleasesOptions) ToConds() builder.Cond { if len(opts.TagNames) > 0 { cond = cond.And(builder.In("tag_name", opts.TagNames)) } - if !opts.IsPreRelease.IsNone() { - cond = cond.And(builder.Eq{"is_prerelease": opts.IsPreRelease.IsTrue()}) + if opts.IsPreRelease.Has() { + cond = cond.And(builder.Eq{"is_prerelease": opts.IsPreRelease.Value()}) } - if !opts.IsDraft.IsNone() { - cond = cond.And(builder.Eq{"is_draft": opts.IsDraft.IsTrue()}) + if opts.IsDraft.Has() { + cond = cond.And(builder.Eq{"is_draft": opts.IsDraft.Value()}) } - if !opts.HasSha1.IsNone() { - if opts.HasSha1.IsTrue() { + if opts.HasSha1.Has() { + if opts.HasSha1.Value() { cond = cond.And(builder.Neq{"sha1": ""}) } else { cond = cond.And(builder.Eq{"sha1": ""}) @@ -275,7 +277,7 @@ func GetTagNamesByRepoID(ctx context.Context, repoID int64) ([]string, error) { ListOptions: listOptions, IncludeDrafts: true, IncludeTags: true, - HasSha1: util.OptionalBoolTrue, + HasSha1: optional.Some(true), RepoID: repoID, } diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go index 533ca5251fe..6b452291eab 100644 --- a/models/repo/repo_list.go +++ b/models/repo/repo_list.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" @@ -125,11 +126,11 @@ type SearchRepoOptions struct { // None -> include public and private // True -> include just private // False -> include just public - IsPrivate util.OptionalBool + IsPrivate optional.Option[bool] // None -> include collaborative AND non-collaborative // True -> include just collaborative // False -> include just non-collaborative - Collaborate util.OptionalBool + Collaborate optional.Option[bool] // What type of unit the user can be collaborative in, // it is ignored if Collaborate is False. // TypeInvalid means any unit type. @@ -137,19 +138,19 @@ type SearchRepoOptions struct { // None -> include forks AND non-forks // True -> include just forks // False -> include just non-forks - Fork util.OptionalBool + Fork optional.Option[bool] // None -> include templates AND non-templates // True -> include just templates // False -> include just non-templates - Template util.OptionalBool + Template optional.Option[bool] // None -> include mirrors AND non-mirrors // True -> include just mirrors // False -> include just non-mirrors - Mirror util.OptionalBool + Mirror optional.Option[bool] // None -> include archived AND non-archived // True -> include just archived // False -> include just non-archived - Archived util.OptionalBool + Archived optional.Option[bool] // only search topic name TopicOnly bool // only search repositories with specified primary language @@ -159,7 +160,7 @@ type SearchRepoOptions struct { // None -> include has milestones AND has no milestone // True -> include just has milestones // False -> include just has no milestone - HasMilestones util.OptionalBool + HasMilestones optional.Option[bool] // LowerNames represents valid lower names to restrict to LowerNames []string // When specified true, apply some filters over the conditions: @@ -359,12 +360,12 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { ))) } - if opts.IsPrivate != util.OptionalBoolNone { - cond = cond.And(builder.Eq{"is_private": opts.IsPrivate.IsTrue()}) + if opts.IsPrivate.Has() { + cond = cond.And(builder.Eq{"is_private": opts.IsPrivate.Value()}) } - if opts.Template != util.OptionalBoolNone { - cond = cond.And(builder.Eq{"is_template": opts.Template == util.OptionalBoolTrue}) + if opts.Template.Has() { + cond = cond.And(builder.Eq{"is_template": opts.Template.Value()}) } // Restrict to starred repositories @@ -380,11 +381,11 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { // Restrict repositories to those the OwnerID owns or contributes to as per opts.Collaborate if opts.OwnerID > 0 { accessCond := builder.NewCond() - if opts.Collaborate != util.OptionalBoolTrue { + if !opts.Collaborate.Value() { accessCond = builder.Eq{"owner_id": opts.OwnerID} } - if opts.Collaborate != util.OptionalBoolFalse { + if opts.Collaborate.ValueOrDefault(true) { // A Collaboration is: collaborateCond := builder.NewCond() @@ -472,31 +473,32 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { Where(builder.Eq{"language": opts.Language}).And(builder.Eq{"is_primary": true}))) } - if opts.Fork != util.OptionalBoolNone || opts.OnlyShowRelevant { - if opts.OnlyShowRelevant && opts.Fork == util.OptionalBoolNone { + if opts.Fork.Has() || opts.OnlyShowRelevant { + if opts.OnlyShowRelevant && !opts.Fork.Has() { cond = cond.And(builder.Eq{"is_fork": false}) } else { - cond = cond.And(builder.Eq{"is_fork": opts.Fork == util.OptionalBoolTrue}) + cond = cond.And(builder.Eq{"is_fork": opts.Fork.Value()}) } } - if opts.Mirror != util.OptionalBoolNone { - cond = cond.And(builder.Eq{"is_mirror": opts.Mirror == util.OptionalBoolTrue}) + if opts.Mirror.Has() { + cond = cond.And(builder.Eq{"is_mirror": opts.Mirror.Value()}) } if opts.Actor != nil && opts.Actor.IsRestricted { cond = cond.And(AccessibleRepositoryCondition(opts.Actor, unit.TypeInvalid)) } - if opts.Archived != util.OptionalBoolNone { - cond = cond.And(builder.Eq{"is_archived": opts.Archived == util.OptionalBoolTrue}) + if opts.Archived.Has() { + cond = cond.And(builder.Eq{"is_archived": opts.Archived.Value()}) } - switch opts.HasMilestones { - case util.OptionalBoolTrue: - cond = cond.And(builder.Gt{"num_milestones": 0}) - case util.OptionalBoolFalse: - cond = cond.And(builder.Eq{"num_milestones": 0}.Or(builder.IsNull{"num_milestones"})) + if opts.HasMilestones.Has() { + if opts.HasMilestones.Value() { + cond = cond.And(builder.Gt{"num_milestones": 0}) + } else { + cond = cond.And(builder.Eq{"num_milestones": 0}.Or(builder.IsNull{"num_milestones"})) + } } if opts.OnlyShowRelevant { diff --git a/models/repo/repo_list_test.go b/models/repo/repo_list_test.go index 83e37a27fdb..88cfcde6208 100644 --- a/models/repo/repo_list_test.go +++ b/models/repo/repo_list_test.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/optional" "github.com/stretchr/testify/assert" ) @@ -27,62 +27,62 @@ func getTestCases() []struct { }{ { name: "PublicRepositoriesByName", - opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{PageSize: 10}, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{PageSize: 10}, Collaborate: optional.Some(false)}, count: 7, }, { name: "PublicAndPrivateRepositoriesByName", - opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Private: true, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Private: true, Collaborate: optional.Some(false)}, count: 14, }, { name: "PublicAndPrivateRepositoriesByNameWithPagesizeLimitFirstPage", - opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 1, PageSize: 5}, Private: true, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 1, PageSize: 5}, Private: true, Collaborate: optional.Some(false)}, count: 14, }, { name: "PublicAndPrivateRepositoriesByNameWithPagesizeLimitSecondPage", - opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 2, PageSize: 5}, Private: true, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 2, PageSize: 5}, Private: true, Collaborate: optional.Some(false)}, count: 14, }, { name: "PublicAndPrivateRepositoriesByNameWithPagesizeLimitThirdPage", - opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 3, PageSize: 5}, Private: true, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 3, PageSize: 5}, Private: true, Collaborate: optional.Some(false)}, count: 14, }, { name: "PublicAndPrivateRepositoriesByNameWithPagesizeLimitFourthPage", - opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 3, PageSize: 5}, Private: true, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 3, PageSize: 5}, Private: true, Collaborate: optional.Some(false)}, count: 14, }, { name: "PublicRepositoriesOfUser", - opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Collaborate: optional.Some(false)}, count: 2, }, { name: "PublicRepositoriesOfUser2", - opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 18, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 18, Collaborate: optional.Some(false)}, count: 0, }, { name: "PublicRepositoriesOfOrg3", - opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 20, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 20, Collaborate: optional.Some(false)}, count: 2, }, { name: "PublicAndPrivateRepositoriesOfUser", - opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Private: true, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Private: true, Collaborate: optional.Some(false)}, count: 4, }, { name: "PublicAndPrivateRepositoriesOfUser2", - opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 18, Private: true, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 18, Private: true, Collaborate: optional.Some(false)}, count: 0, }, { name: "PublicAndPrivateRepositoriesOfOrg3", - opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 20, Private: true, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 20, Private: true, Collaborate: optional.Some(false)}, count: 4, }, { @@ -117,32 +117,32 @@ func getTestCases() []struct { }, { name: "PublicRepositoriesOfOrganization", - opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, Collaborate: optional.Some(false)}, count: 1, }, { name: "PublicAndPrivateRepositoriesOfOrganization", - opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, Private: true, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, Private: true, Collaborate: optional.Some(false)}, count: 2, }, { name: "AllPublic/PublicRepositoriesByName", - opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{PageSize: 10}, AllPublic: true, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{PageSize: 10}, AllPublic: true, Collaborate: optional.Some(false)}, count: 7, }, { name: "AllPublic/PublicAndPrivateRepositoriesByName", - opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Private: true, AllPublic: true, Collaborate: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Private: true, AllPublic: true, Collaborate: optional.Some(false)}, count: 14, }, { name: "AllPublic/PublicRepositoriesOfUserIncludingCollaborative", - opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, AllPublic: true, Template: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, AllPublic: true, Template: optional.Some(false)}, count: 33, }, { name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative", - opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Private: true, AllPublic: true, AllLimited: true, Template: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Private: true, AllPublic: true, AllLimited: true, Template: optional.Some(false)}, count: 38, }, { @@ -157,12 +157,12 @@ func getTestCases() []struct { }, { name: "AllPublic/PublicRepositoriesOfOrganization", - opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, AllPublic: true, Collaborate: util.OptionalBoolFalse, Template: util.OptionalBoolFalse}, + opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, AllPublic: true, Collaborate: optional.Some(false), Template: optional.Some(false)}, count: 33, }, { name: "AllTemplates", - opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Template: util.OptionalBoolTrue}, + opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Template: optional.Some(true)}, count: 2, }, { @@ -190,7 +190,7 @@ func TestSearchRepository(t *testing.T) { PageSize: 10, }, Keyword: "repo_12", - Collaborate: util.OptionalBoolFalse, + Collaborate: optional.Some(false), }) assert.NoError(t, err) @@ -205,7 +205,7 @@ func TestSearchRepository(t *testing.T) { PageSize: 10, }, Keyword: "test_repo", - Collaborate: util.OptionalBoolFalse, + Collaborate: optional.Some(false), }) assert.NoError(t, err) @@ -220,7 +220,7 @@ func TestSearchRepository(t *testing.T) { }, Keyword: "repo_13", Private: true, - Collaborate: util.OptionalBoolFalse, + Collaborate: optional.Some(false), }) assert.NoError(t, err) @@ -236,7 +236,7 @@ func TestSearchRepository(t *testing.T) { }, Keyword: "test_repo", Private: true, - Collaborate: util.OptionalBoolFalse, + Collaborate: optional.Some(false), }) assert.NoError(t, err) @@ -257,7 +257,7 @@ func TestSearchRepository(t *testing.T) { PageSize: 10, }, Keyword: "description_14", - Collaborate: util.OptionalBoolFalse, + Collaborate: optional.Some(false), IncludeDescription: true, }) @@ -274,7 +274,7 @@ func TestSearchRepository(t *testing.T) { PageSize: 10, }, Keyword: "description_14", - Collaborate: util.OptionalBoolFalse, + Collaborate: optional.Some(false), IncludeDescription: false, }) @@ -327,30 +327,25 @@ func TestSearchRepository(t *testing.T) { assert.False(t, repo.IsPrivate) } - if testCase.opts.Fork == util.OptionalBoolTrue && testCase.opts.Mirror == util.OptionalBoolTrue { - assert.True(t, repo.IsFork || repo.IsMirror) + if testCase.opts.Fork.Value() && testCase.opts.Mirror.Value() { + assert.True(t, repo.IsFork && repo.IsMirror) } else { - switch testCase.opts.Fork { - case util.OptionalBoolFalse: - assert.False(t, repo.IsFork) - case util.OptionalBoolTrue: - assert.True(t, repo.IsFork) + if testCase.opts.Fork.Has() { + assert.Equal(t, testCase.opts.Fork.Value(), repo.IsFork) } - switch testCase.opts.Mirror { - case util.OptionalBoolFalse: - assert.False(t, repo.IsMirror) - case util.OptionalBoolTrue: - assert.True(t, repo.IsMirror) + if testCase.opts.Mirror.Has() { + assert.Equal(t, testCase.opts.Mirror.Value(), repo.IsMirror) } } if testCase.opts.OwnerID > 0 && !testCase.opts.AllPublic { - switch testCase.opts.Collaborate { - case util.OptionalBoolFalse: - assert.Equal(t, testCase.opts.OwnerID, repo.Owner.ID) - case util.OptionalBoolTrue: - assert.NotEqual(t, testCase.opts.OwnerID, repo.Owner.ID) + if testCase.opts.Collaborate.Has() { + if testCase.opts.Collaborate.Value() { + assert.NotEqual(t, testCase.opts.OwnerID, repo.Owner.ID) + } else { + assert.Equal(t, testCase.opts.OwnerID, repo.Owner.ID) + } } } } diff --git a/models/user/badge.go b/models/user/badge.go index ee52b44cf51..3ff3530a369 100644 --- a/models/user/badge.go +++ b/models/user/badge.go @@ -5,13 +5,15 @@ package user import ( "context" + "fmt" "code.gitea.io/gitea/models/db" ) // Badge represents a user badge type Badge struct { - ID int64 `xorm:"pk autoincr"` + ID int64 `xorm:"pk autoincr"` + Slug string `xorm:"UNIQUE"` Description string ImageURL string } @@ -39,3 +41,84 @@ func GetUserBadges(ctx context.Context, u *User) ([]*Badge, int64, error) { count, err := sess.FindAndCount(&badges) return badges, count, err } + +// CreateBadge creates a new badge. +func CreateBadge(ctx context.Context, badge *Badge) error { + _, err := db.GetEngine(ctx).Insert(badge) + return err +} + +// GetBadge returns a badge +func GetBadge(ctx context.Context, slug string) (*Badge, error) { + badge := new(Badge) + has, err := db.GetEngine(ctx).Where("slug=?", slug).Get(badge) + if !has { + return nil, err + } + return badge, err +} + +// UpdateBadge updates a badge based on its slug. +func UpdateBadge(ctx context.Context, badge *Badge) error { + _, err := db.GetEngine(ctx).Where("slug=?", badge.Slug).Update(badge) + return err +} + +// DeleteBadge deletes a badge. +func DeleteBadge(ctx context.Context, badge *Badge) error { + _, err := db.GetEngine(ctx).Where("slug=?", badge.Slug).Delete(badge) + return err +} + +// AddUserBadge adds a badge to a user. +func AddUserBadge(ctx context.Context, u *User, badge *Badge) error { + return AddUserBadges(ctx, u, []*Badge{badge}) +} + +// AddUserBadges adds badges to a user. +func AddUserBadges(ctx context.Context, u *User, badges []*Badge) error { + return db.WithTx(ctx, func(ctx context.Context) error { + for _, badge := range badges { + // hydrate badge and check if it exists + has, err := db.GetEngine(ctx).Where("slug=?", badge.Slug).Get(badge) + if err != nil { + return err + } else if !has { + return fmt.Errorf("badge with slug %s doesn't exist", badge.Slug) + } + if err := db.Insert(ctx, &UserBadge{ + BadgeID: badge.ID, + UserID: u.ID, + }); err != nil { + return err + } + } + return nil + }) +} + +// RemoveUserBadge removes a badge from a user. +func RemoveUserBadge(ctx context.Context, u *User, badge *Badge) error { + return RemoveUserBadges(ctx, u, []*Badge{badge}) +} + +// RemoveUserBadges removes badges from a user. +func RemoveUserBadges(ctx context.Context, u *User, badges []*Badge) error { + return db.WithTx(ctx, func(ctx context.Context) error { + for _, badge := range badges { + if _, err := db.GetEngine(ctx). + Join("INNER", "badge", "badge.id = `user_badge`.badge_id"). + Where("`user_badge`.user_id=? AND `badge`.slug=?", u.ID, badge.Slug). + Delete(&UserBadge{}); err != nil { + return err + } + } + return nil + }) +} + +// RemoveAllUserBadges removes all badges from a user. +func RemoveAllUserBadges(ctx context.Context, u *User) error { + _, err := db.GetEngine(ctx).Where("user_id=?", u.ID).Delete(&UserBadge{}) + return err +} diff --git a/models/user/email_address.go b/models/user/email_address.go index 216840916d0..5d67304691a 100644 --- a/models/user/email_address.go +++ b/models/user/email_address.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/validation" @@ -21,9 +22,6 @@ import ( "xorm.io/builder" ) -// ErrEmailNotActivated e-mail address has not been activated error -var ErrEmailNotActivated = util.NewInvalidArgumentErrorf("e-mail address has not been activated") - // ErrEmailCharIsNotSupported e-mail address contains unsupported character type ErrEmailCharIsNotSupported struct { Email string @@ -313,27 +311,27 @@ func updateActivation(ctx context.Context, email *EmailAddress, activate bool) e return UpdateUserCols(ctx, user, "rands") } -// MakeEmailPrimary sets primary email address of given user. -func MakeEmailPrimary(ctx context.Context, email *EmailAddress) error { - has, err := db.GetEngine(ctx).Get(email) - if err != nil { +func MakeActiveEmailPrimary(ctx context.Context, emailID int64) error { + return makeEmailPrimaryInternal(ctx, emailID, true) +} + +func MakeInactiveEmailPrimary(ctx context.Context, emailID int64) error { + return makeEmailPrimaryInternal(ctx, emailID, false) +} + +func makeEmailPrimaryInternal(ctx context.Context, emailID int64, isActive bool) error { + email := &EmailAddress{} + if has, err := db.GetEngine(ctx).ID(emailID).Where(builder.Eq{"is_activated": isActive}).Get(email); err != nil { return err } else if !has { - return ErrEmailAddressNotExist{Email: email.Email} - } - - if !email.IsActivated { - return ErrEmailNotActivated + return ErrEmailAddressNotExist{} } user := &User{} - has, err = db.GetEngine(ctx).ID(email.UID).Get(user) - if err != nil { + if has, err := db.GetEngine(ctx).ID(email.UID).Get(user); err != nil { return err } else if !has { - return ErrUserNotExist{ - UID: email.UID, - } + return ErrUserNotExist{UID: email.UID} } ctx, committer, err := db.TxContext(ctx) @@ -365,6 +363,21 @@ func MakeEmailPrimary(ctx context.Context, email *EmailAddress) error { return committer.Commit() } +// ChangeInactivePrimaryEmail replaces the inactive primary email of a given user +func ChangeInactivePrimaryEmail(ctx context.Context, uid int64, oldEmailAddr, newEmailAddr string) error { + return db.WithTx(ctx, func(ctx context.Context) error { + _, err := db.GetEngine(ctx).Where(builder.Eq{"uid": uid, "lower_email": strings.ToLower(oldEmailAddr)}).Delete(&EmailAddress{}) + if err != nil { + return err + } + newEmail, err := InsertEmailAddress(ctx, &EmailAddress{UID: uid, Email: newEmailAddr}) + if err != nil { + return err + } + return MakeInactiveEmailPrimary(ctx, newEmail.ID) + }) +} + // VerifyActiveEmailCode verifies active email code when active account func VerifyActiveEmailCode(ctx context.Context, code, email string) *EmailAddress { minutes := setting.Service.ActiveCodeLives @@ -404,8 +417,8 @@ type SearchEmailOptions struct { db.ListOptions Keyword string SortType SearchEmailOrderBy - IsPrimary util.OptionalBool - IsActivated util.OptionalBool + IsPrimary optional.Option[bool] + IsActivated optional.Option[bool] } // SearchEmailResult is an e-mail address found in the user or email_address table @@ -432,18 +445,12 @@ func SearchEmails(ctx context.Context, opts *SearchEmailOptions) ([]*SearchEmail )) } - switch { - case opts.IsPrimary.IsTrue(): - cond = cond.And(builder.Eq{"email_address.is_primary": true}) - case opts.IsPrimary.IsFalse(): - cond = cond.And(builder.Eq{"email_address.is_primary": false}) + if opts.IsPrimary.Has() { + cond = cond.And(builder.Eq{"email_address.is_primary": opts.IsPrimary.Value()}) } - switch { - case opts.IsActivated.IsTrue(): - cond = cond.And(builder.Eq{"email_address.is_activated": true}) - case opts.IsActivated.IsFalse(): - cond = cond.And(builder.Eq{"email_address.is_activated": false}) + if opts.IsActivated.Has() { + cond = cond.And(builder.Eq{"email_address.is_activated": opts.IsActivated.Value()}) } count, err := db.GetEngine(ctx).Join("INNER", "`user`", "`user`.ID = email_address.uid"). diff --git a/models/user/email_address_test.go b/models/user/email_address_test.go index 140443f82f9..c2e010d95b3 100644 --- a/models/user/email_address_test.go +++ b/models/user/email_address_test.go @@ -9,7 +9,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/optional" "github.com/stretchr/testify/assert" ) @@ -45,31 +45,22 @@ func TestIsEmailUsed(t *testing.T) { func TestMakeEmailPrimary(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - email := &user_model.EmailAddress{ - Email: "user567890@example.com", - } - err := user_model.MakeEmailPrimary(db.DefaultContext, email) + err := user_model.MakeActiveEmailPrimary(db.DefaultContext, 9999999) assert.Error(t, err) - assert.EqualError(t, err, user_model.ErrEmailAddressNotExist{Email: email.Email}.Error()) + assert.ErrorIs(t, err, user_model.ErrEmailAddressNotExist{}) - email = &user_model.EmailAddress{ - Email: "user11@example.com", - } - err = user_model.MakeEmailPrimary(db.DefaultContext, email) + email := unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user11@example.com"}) + err = user_model.MakeActiveEmailPrimary(db.DefaultContext, email.ID) assert.Error(t, err) - assert.EqualError(t, err, user_model.ErrEmailNotActivated.Error()) + assert.ErrorIs(t, err, user_model.ErrEmailAddressNotExist{}) // inactive email is considered as not exist for "MakeActiveEmailPrimary" - email = &user_model.EmailAddress{ - Email: "user9999999@example.com", - } - err = user_model.MakeEmailPrimary(db.DefaultContext, email) + email = unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user9999999@example.com"}) + err = user_model.MakeActiveEmailPrimary(db.DefaultContext, email.ID) assert.Error(t, err) assert.True(t, user_model.IsErrUserNotExist(err)) - email = &user_model.EmailAddress{ - Email: "user101@example.com", - } - err = user_model.MakeEmailPrimary(db.DefaultContext, email) + email = unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user101@example.com"}) + err = user_model.MakeActiveEmailPrimary(db.DefaultContext, email.ID) assert.NoError(t, err) user, _ := user_model.GetUserByID(db.DefaultContext, int64(10)) @@ -137,14 +128,14 @@ func TestListEmails(t *testing.T) { assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 27 })) // Must find only primary addresses (i.e. from the `user` table) - opts = &user_model.SearchEmailOptions{IsPrimary: util.OptionalBoolTrue} + opts = &user_model.SearchEmailOptions{IsPrimary: optional.Some(true)} emails, _, err = user_model.SearchEmails(db.DefaultContext, opts) assert.NoError(t, err) assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsPrimary })) assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsPrimary })) // Must find only inactive addresses (i.e. not validated) - opts = &user_model.SearchEmailOptions{IsActivated: util.OptionalBoolFalse} + opts = &user_model.SearchEmailOptions{IsActivated: optional.Some(false)} emails, _, err = user_model.SearchEmails(db.DefaultContext, opts) assert.NoError(t, err) assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsActivated })) diff --git a/models/user/search.go b/models/user/search.go index 0fa278c2572..45b051187ea 100644 --- a/models/user/search.go +++ b/models/user/search.go @@ -9,8 +9,9 @@ import ( "strings" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/container" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/structs" - "code.gitea.io/gitea/modules/util" "xorm.io/builder" "xorm.io/xorm" @@ -30,11 +31,13 @@ type SearchUserOptions struct { Actor *User // The user doing the search SearchByEmail bool // Search by email as well as username/full name - IsActive util.OptionalBool - IsAdmin util.OptionalBool - IsRestricted util.OptionalBool - IsTwoFactorEnabled util.OptionalBool - IsProhibitLogin util.OptionalBool + SupportedSortOrders container.Set[string] // if not nil, only allow to use the sort orders in this set + + IsActive optional.Option[bool] + IsAdmin optional.Option[bool] + IsRestricted optional.Option[bool] + IsTwoFactorEnabled optional.Option[bool] + IsProhibitLogin optional.Option[bool] IncludeReserved bool ExtraParamStrings map[string]string @@ -86,24 +89,24 @@ func (opts *SearchUserOptions) toSearchQueryBase(ctx context.Context) *xorm.Sess cond = cond.And(builder.Eq{"login_name": opts.LoginName}) } - if !opts.IsActive.IsNone() { - cond = cond.And(builder.Eq{"is_active": opts.IsActive.IsTrue()}) + if opts.IsActive.Has() { + cond = cond.And(builder.Eq{"is_active": opts.IsActive.Value()}) } - if !opts.IsAdmin.IsNone() { - cond = cond.And(builder.Eq{"is_admin": opts.IsAdmin.IsTrue()}) + if opts.IsAdmin.Has() { + cond = cond.And(builder.Eq{"is_admin": opts.IsAdmin.Value()}) } - if !opts.IsRestricted.IsNone() { - cond = cond.And(builder.Eq{"is_restricted": opts.IsRestricted.IsTrue()}) + if opts.IsRestricted.Has() { + cond = cond.And(builder.Eq{"is_restricted": opts.IsRestricted.Value()}) } - if !opts.IsProhibitLogin.IsNone() { - cond = cond.And(builder.Eq{"prohibit_login": opts.IsProhibitLogin.IsTrue()}) + if opts.IsProhibitLogin.Has() { + cond = cond.And(builder.Eq{"prohibit_login": opts.IsProhibitLogin.Value()}) } e := db.GetEngine(ctx) - if opts.IsTwoFactorEnabled.IsNone() { + if !opts.IsTwoFactorEnabled.Has() { return e.Where(cond) } @@ -111,7 +114,7 @@ func (opts *SearchUserOptions) toSearchQueryBase(ctx context.Context) *xorm.Sess // While using LEFT JOIN, sometimes the performance might not be good, but it won't be a problem now, such SQL is seldom executed. // There are some possible methods to refactor this SQL in future when we really need to optimize the performance (but not now): // (1) add a column in user table (2) add a setting value in user_setting table (3) use search engines (bleve/elasticsearch) - if opts.IsTwoFactorEnabled.IsTrue() { + if opts.IsTwoFactorEnabled.Value() { cond = cond.And(builder.Expr("two_factor.uid IS NOT NULL")) } else { cond = cond.And(builder.Expr("two_factor.uid IS NULL")) @@ -128,7 +131,7 @@ func SearchUsers(ctx context.Context, opts *SearchUserOptions) (users []*User, _ defer sessCount.Close() count, err := sessCount.Count(new(User)) if err != nil { - return nil, 0, fmt.Errorf("Count: %w", err) + return nil, 0, fmt.Errorf("count: %w", err) } if len(opts.OrderBy) == 0 { diff --git a/models/user/user_test.go b/models/user/user_test.go index 68cee9cdbd1..f522f743d59 100644 --- a/models/user/user_test.go +++ b/models/user/user_test.go @@ -16,10 +16,10 @@ import ( "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/auth/password/hash" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" - "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" ) @@ -103,29 +103,29 @@ func TestSearchUsers(t *testing.T) { testUserSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}}, []int64{1, 2, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32, 34, 37, 38, 39, 40}) - testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolFalse}, + testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsActive: optional.Some(false)}, []int64{9}) - testUserSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolTrue}, + testUserSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: optional.Some(true)}, []int64{1, 2, 4, 5, 8, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32, 34, 37, 38, 39, 40}) - testUserSuccess(&user_model.SearchUserOptions{Keyword: "user1", OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolTrue}, + testUserSuccess(&user_model.SearchUserOptions{Keyword: "user1", OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: optional.Some(true)}, []int64{1, 10, 11, 12, 13, 14, 15, 16, 18}) // order by name asc default - testUserSuccess(&user_model.SearchUserOptions{Keyword: "user1", ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolTrue}, + testUserSuccess(&user_model.SearchUserOptions{Keyword: "user1", ListOptions: db.ListOptions{Page: 1}, IsActive: optional.Some(true)}, []int64{1, 10, 11, 12, 13, 14, 15, 16, 18}) - testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsAdmin: util.OptionalBoolTrue}, + testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsAdmin: optional.Some(true)}, []int64{1}) - testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsRestricted: util.OptionalBoolTrue}, + testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsRestricted: optional.Some(true)}, []int64{29}) - testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsProhibitLogin: util.OptionalBoolTrue}, + testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsProhibitLogin: optional.Some(true)}, []int64{37}) - testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsTwoFactorEnabled: util.OptionalBoolTrue}, + testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsTwoFactorEnabled: optional.Some(true)}, []int64{24}) } diff --git a/modules/actions/task_state.go b/modules/actions/task_state.go index cbbc0b357d2..fe925bbb5d9 100644 --- a/modules/actions/task_state.go +++ b/modules/actions/task_state.go @@ -35,6 +35,9 @@ func FullSteps(task *actions_model.ActionTask) []*actions_model.ActionTaskStep { } else if task.Status.IsDone() { preStep.Stopped = task.Stopped preStep.Status = actions_model.StatusFailure + if task.Status.IsSkipped() { + preStep.Status = actions_model.StatusSkipped + } } logIndex += preStep.LogLength diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index 2db4a9296f0..595fd8bbb07 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -441,6 +441,9 @@ func matchPullRequestEvent(gitRepo *git.Repository, commit *git.Commit, prPayloa // all acts conditions should be satisfied for cond, vals := range acts { switch cond { + case "types": + // types have been checked + continue case "branches": refName := git.RefName(prPayload.PullRequest.Base.Ref) patterns, err := workflowpattern.CompilePatterns(vals...) diff --git a/modules/badge/badge.go b/modules/badge/badge.go new file mode 100644 index 00000000000..b30d0b47294 --- /dev/null +++ b/modules/badge/badge.go @@ -0,0 +1,104 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package badge + +import ( + actions_model "code.gitea.io/gitea/models/actions" +) + +// The Badge layout: |offset|label|message| +// We use 10x scale to calculate more precisely +// Then scale down to normal size in tmpl file + +type Label struct { + text string + width int +} + +func (l Label) Text() string { + return l.text +} + +func (l Label) Width() int { + return l.width +} + +func (l Label) TextLength() int { + return int(float64(l.width-defaultOffset) * 9.5) +} + +func (l Label) X() int { + return l.width*5 + 10 +} + +type Message struct { + text string + width int + x int +} + +func (m Message) Text() string { + return m.text +} + +func (m Message) Width() int { + return m.width +} + +func (m Message) X() int { + return m.x +} + +func (m Message) TextLength() int { + return int(float64(m.width-defaultOffset) * 9.5) +} + +type Badge struct { + Color string + FontSize int + Label Label + Message Message +} + +func (b Badge) Width() int { + return b.Label.width + b.Message.width +} + +const ( + defaultOffset = 9 + defaultFontSize = 11 + DefaultColor = "#9f9f9f" // Grey + defaultFontWidth = 7 // approximate speculation +) + +var StatusColorMap = map[actions_model.Status]string{ + actions_model.StatusSuccess: "#4c1", // Green + actions_model.StatusSkipped: "#dfb317", // Yellow + actions_model.StatusUnknown: "#97ca00", // Light Green + actions_model.StatusFailure: "#e05d44", // Red + actions_model.StatusCancelled: "#fe7d37", // Orange + actions_model.StatusWaiting: "#dfb317", // Yellow + actions_model.StatusRunning: "#dfb317", // Yellow + actions_model.StatusBlocked: "#dfb317", // Yellow +} + +// GenerateBadge generates badge with given template +func GenerateBadge(label, message, color string) Badge { + lw := defaultFontWidth*len(label) + defaultOffset + mw := defaultFontWidth*len(message) + defaultOffset + x := lw*10 + mw*5 - 10 + return Badge{ + Label: Label{ + text: label, + width: lw, + }, + Message: Message{ + text: message, + width: mw, + x: x, + }, + FontSize: defaultFontSize * 10, + Color: color, + } +} diff --git a/modules/indexer/issues/indexer.go b/modules/indexer/issues/indexer.go index 57037d2947c..e3bc21b49d8 100644 --- a/modules/indexer/issues/indexer.go +++ b/modules/indexer/issues/indexer.go @@ -20,10 +20,10 @@ import ( "code.gitea.io/gitea/modules/indexer/issues/internal" "code.gitea.io/gitea/modules/indexer/issues/meilisearch" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/queue" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" ) // IndexerMetadata is used to send data to the queue, so it contains only the ids. @@ -220,7 +220,7 @@ func PopulateIssueIndexer(ctx context.Context) error { ListOptions: db_model.ListOptions{Page: page, PageSize: repo_model.RepositoryListDefaultPageSize}, OrderBy: db_model.SearchOrderByID, Private: true, - Collaborate: util.OptionalBoolFalse, + Collaborate: optional.Some(false), }) if err != nil { log.Error("SearchRepositoryByName: %v", err) diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index cb29431d4be..ccb63c6baba 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -397,7 +397,7 @@ func TestRender_ShortLinks(t *testing.T) { }, }, input) assert.NoError(t, err) - assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) + assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer))) buffer, err = markdown.RenderString(&markup.RenderContext{ Ctx: git.DefaultContext, Links: markup.Links{ @@ -407,7 +407,7 @@ func TestRender_ShortLinks(t *testing.T) { IsWiki: true, }, input) assert.NoError(t, err) - assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(buffer)) + assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer))) } mediatree := util.URLJoin(markup.TestRepoURL, "media", "master") @@ -510,7 +510,7 @@ func TestRender_RelativeImages(t *testing.T) { Metas: localMetas, }, input) assert.NoError(t, err) - assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) + assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer))) buffer, err = markdown.RenderString(&markup.RenderContext{ Ctx: git.DefaultContext, Links: markup.Links{ @@ -520,7 +520,7 @@ func TestRender_RelativeImages(t *testing.T) { IsWiki: true, }, input) assert.NoError(t, err) - assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(buffer)) + assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer))) } rawwiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw") diff --git a/modules/markup/markdown/markdown.go b/modules/markup/markdown/markdown.go index 771162b9a3f..f0b1afa27e3 100644 --- a/modules/markup/markdown/markdown.go +++ b/modules/markup/markdown/markdown.go @@ -6,6 +6,7 @@ package markdown import ( "fmt" + "html/template" "io" "strings" "sync" @@ -262,12 +263,12 @@ func Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error } // RenderString renders Markdown string to HTML with all specific handling stuff and return string -func RenderString(ctx *markup.RenderContext, content string) (string, error) { +func RenderString(ctx *markup.RenderContext, content string) (template.HTML, error) { var buf strings.Builder if err := Render(ctx, strings.NewReader(content), &buf); err != nil { return "", err } - return buf.String(), nil + return template.HTML(buf.String()), nil } // RenderRaw renders Markdown to HTML without handling special links. diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go index bdf4011fa24..dbf95e5e625 100644 --- a/modules/markup/markdown/markdown_test.go +++ b/modules/markup/markdown/markdown_test.go @@ -5,6 +5,7 @@ package markdown_test import ( "context" + "html/template" "os" "strings" "testing" @@ -21,12 +22,11 @@ import ( ) const ( - AppURL = "http://localhost:3000/" - Repo = "gogits/gogs" - AppSubURL = AppURL + Repo + "/" + AppURL = "http://localhost:3000/" + FullURL = AppURL + "gogits/gogs/" ) -// these values should match the Repo const above +// these values should match the const above var localMetas = map[string]string{ "user": "gogits", "repo": "gogs", @@ -48,34 +48,33 @@ func TestMain(m *testing.M) { func TestRender_StandardLinks(t *testing.T) { setting.AppURL = AppURL - setting.AppSubURL = AppSubURL test := func(input, expected, expectedWiki string) { buffer, err := markdown.RenderString(&markup.RenderContext{ Ctx: git.DefaultContext, Links: markup.Links{ - Base: setting.AppSubURL, + Base: FullURL, }, }, input) assert.NoError(t, err) - assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) + assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer))) buffer, err = markdown.RenderString(&markup.RenderContext{ Ctx: git.DefaultContext, Links: markup.Links{ - Base: setting.AppSubURL, + Base: FullURL, }, IsWiki: true, }, input) assert.NoError(t, err) - assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(buffer)) + assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer))) } googleRendered := `

https://google.com/

` test("", googleRendered, googleRendered) - lnk := util.URLJoin(AppSubURL, "WikiPage") - lnkWiki := util.URLJoin(AppSubURL, "wiki", "WikiPage") + lnk := util.URLJoin(FullURL, "WikiPage") + lnkWiki := util.URLJoin(FullURL, "wiki", "WikiPage") test("[WikiPage](WikiPage)", `

WikiPage

`, `

WikiPage

`) @@ -83,23 +82,22 @@ func TestRender_StandardLinks(t *testing.T) { func TestRender_Images(t *testing.T) { setting.AppURL = AppURL - setting.AppSubURL = AppSubURL test := func(input, expected string) { buffer, err := markdown.RenderString(&markup.RenderContext{ Ctx: git.DefaultContext, Links: markup.Links{ - Base: setting.AppSubURL, + Base: FullURL, }, }, input) assert.NoError(t, err) - assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) + assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer))) } url := "../../.images/src/02/train.jpg" title := "Train" href := "https://gitea.io" - result := util.URLJoin(AppSubURL, url) + result := util.URLJoin(FullURL, url) // hint: With Markdown v2.5.2, there is a new syntax: [link](URL){:target="_blank"} , but we do not support it now test( @@ -289,33 +287,32 @@ This PR has been generated by [Renovate Bot](https://github.com/renovatebot/reno func TestTotal_RenderWiki(t *testing.T) { setting.AppURL = AppURL - setting.AppSubURL = AppSubURL - answers := testAnswers(util.URLJoin(AppSubURL, "wiki"), util.URLJoin(AppSubURL, "wiki", "raw")) + answers := testAnswers(util.URLJoin(FullURL, "wiki"), util.URLJoin(FullURL, "wiki", "raw")) for i := 0; i < len(sameCases); i++ { line, err := markdown.RenderString(&markup.RenderContext{ Ctx: git.DefaultContext, Links: markup.Links{ - Base: setting.AppSubURL, + Base: FullURL, }, Metas: localMetas, IsWiki: true, }, sameCases[i]) assert.NoError(t, err) - assert.Equal(t, answers[i], line) + assert.Equal(t, template.HTML(answers[i]), line) } testCases := []string{ // Guard wiki sidebar: special syntax `[[Guardfile-DSL / Configuring-Guard|Guardfile-DSL---Configuring-Guard]]`, // rendered - `

Guardfile-DSL / Configuring-Guard

+ `

Guardfile-DSL / Configuring-Guard

`, // special syntax `[[Name|Link]]`, // rendered - `

Name

+ `

Name

`, } @@ -323,32 +320,31 @@ func TestTotal_RenderWiki(t *testing.T) { line, err := markdown.RenderString(&markup.RenderContext{ Ctx: git.DefaultContext, Links: markup.Links{ - Base: setting.AppSubURL, + Base: FullURL, }, IsWiki: true, }, testCases[i]) assert.NoError(t, err) - assert.Equal(t, testCases[i+1], line) + assert.Equal(t, template.HTML(testCases[i+1]), line) } } func TestTotal_RenderString(t *testing.T) { setting.AppURL = AppURL - setting.AppSubURL = AppSubURL - answers := testAnswers(util.URLJoin(AppSubURL, "src", "master"), util.URLJoin(AppSubURL, "media", "master")) + answers := testAnswers(util.URLJoin(FullURL, "src", "master"), util.URLJoin(FullURL, "media", "master")) for i := 0; i < len(sameCases); i++ { line, err := markdown.RenderString(&markup.RenderContext{ Ctx: git.DefaultContext, Links: markup.Links{ - Base: AppSubURL, + Base: FullURL, BranchPath: "master", }, Metas: localMetas, }, sameCases[i]) assert.NoError(t, err) - assert.Equal(t, answers[i], line) + assert.Equal(t, template.HTML(answers[i]), line) } testCases := []string{} @@ -357,11 +353,11 @@ func TestTotal_RenderString(t *testing.T) { line, err := markdown.RenderString(&markup.RenderContext{ Ctx: git.DefaultContext, Links: markup.Links{ - Base: AppSubURL, + Base: FullURL, }, }, testCases[i]) assert.NoError(t, err) - assert.Equal(t, testCases[i+1], line) + assert.Equal(t, template.HTML(testCases[i+1]), line) } } @@ -428,7 +424,7 @@ func TestRenderEmojiInLinks_Issue12331(t *testing.T) { ` res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, testcase) assert.NoError(t, err) - assert.Equal(t, expected, res) + assert.Equal(t, template.HTML(expected), res) } func TestColorPreview(t *testing.T) { @@ -462,7 +458,7 @@ func TestColorPreview(t *testing.T) { for _, test := range positiveTests { res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test.testcase) assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase) - assert.Equal(t, test.expected, res, "Unexpected result in testcase %q", test.testcase) + assert.Equal(t, template.HTML(test.expected), res, "Unexpected result in testcase %q", test.testcase) } @@ -529,7 +525,7 @@ func TestMathBlock(t *testing.T) { for _, test := range testcases { res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test.testcase) assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase) - assert.Equal(t, test.expected, res, "Unexpected result in testcase %q", test.testcase) + assert.Equal(t, template.HTML(test.expected), res, "Unexpected result in testcase %q", test.testcase) } } @@ -567,12 +563,12 @@ foo: bar for _, test := range testcases { res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test.testcase) assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase) - assert.Equal(t, test.expected, res, "Unexpected result in testcase %q", test.testcase) + assert.Equal(t, template.HTML(test.expected), res, "Unexpected result in testcase %q", test.testcase) } } func TestRenderLinks(t *testing.T) { - input := ` space @mention-user + input := ` space @mention-user${SPACE}${SPACE} /just/a/path.bin https://example.com/file.bin [local link](file.bin) @@ -593,8 +589,9 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit mail@domain.com @mention-user test #123 - space + space${SPACE}${SPACE} ` + input = strings.ReplaceAll(input, "${SPACE}", " ") // replace ${SPACE} with " ", to avoid some editor's auto-trimming cases := []struct { Links markup.Links IsWiki bool @@ -957,6 +954,6 @@ space

for i, c := range cases { result, err := markdown.RenderString(&markup.RenderContext{Ctx: context.Background(), Links: c.Links, IsWiki: c.IsWiki}, input) assert.NoError(t, err, "Unexpected error in testcase: %v", i) - assert.Equal(t, c.Expected, result, "Unexpected result in testcase %v", i) + assert.Equal(t, template.HTML(c.Expected), result, "Unexpected result in testcase %v", i) } } diff --git a/modules/optional/option_test.go b/modules/optional/option_test.go index 410fd735776..4f55608004f 100644 --- a/modules/optional/option_test.go +++ b/modules/optional/option_test.go @@ -27,6 +27,16 @@ func TestOption(t *testing.T) { assert.Equal(t, int(1), some.Value()) assert.Equal(t, int(1), some.ValueOrDefault(2)) + noneBool := optional.None[bool]() + assert.False(t, noneBool.Has()) + assert.False(t, noneBool.Value()) + assert.True(t, noneBool.ValueOrDefault(true)) + + someBool := optional.Some(true) + assert.True(t, someBool.Has()) + assert.True(t, someBool.Value()) + assert.True(t, someBool.ValueOrDefault(false)) + var ptr *int assert.False(t, optional.FromPtr(ptr).Has()) diff --git a/modules/repository/init.go b/modules/repository/init.go index b90b234a73f..5f500c5233f 100644 --- a/modules/repository/init.go +++ b/modules/repository/init.go @@ -6,22 +6,18 @@ package repository import ( "context" "fmt" - "os" "path/filepath" "sort" "strings" - "time" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" - user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/label" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/options" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" - asymkey_service "code.gitea.io/gitea/services/asymkey" ) type OptionFile struct { @@ -124,70 +120,6 @@ func LoadRepoConfig() error { return nil } -// InitRepoCommit temporarily changes with work directory. -func InitRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Repository, u *user_model.User, defaultBranch string) (err error) { - commitTimeStr := time.Now().Format(time.RFC3339) - - sig := u.NewGitSig() - // Because this may call hooks we should pass in the environment - env := append(os.Environ(), - "GIT_AUTHOR_NAME="+sig.Name, - "GIT_AUTHOR_EMAIL="+sig.Email, - "GIT_AUTHOR_DATE="+commitTimeStr, - "GIT_COMMITTER_DATE="+commitTimeStr, - ) - committerName := sig.Name - committerEmail := sig.Email - - if stdout, _, err := git.NewCommand(ctx, "add", "--all"). - SetDescription(fmt.Sprintf("initRepoCommit (git add): %s", tmpPath)). - RunStdString(&git.RunOpts{Dir: tmpPath}); err != nil { - log.Error("git add --all failed: Stdout: %s\nError: %v", stdout, err) - return fmt.Errorf("git add --all: %w", err) - } - - cmd := git.NewCommand(ctx, "commit", "--message=Initial commit"). - AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email) - - sign, keyID, signer, _ := asymkey_service.SignInitialCommit(ctx, tmpPath, u) - if sign { - cmd.AddOptionFormat("-S%s", keyID) - - if repo.GetTrustModel() == repo_model.CommitterTrustModel || repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel { - // need to set the committer to the KeyID owner - committerName = signer.Name - committerEmail = signer.Email - } - } else { - cmd.AddArguments("--no-gpg-sign") - } - - env = append(env, - "GIT_COMMITTER_NAME="+committerName, - "GIT_COMMITTER_EMAIL="+committerEmail, - ) - - if stdout, _, err := cmd. - SetDescription(fmt.Sprintf("initRepoCommit (git commit): %s", tmpPath)). - RunStdString(&git.RunOpts{Dir: tmpPath, Env: env}); err != nil { - log.Error("Failed to commit: %v: Stdout: %s\nError: %v", cmd.String(), stdout, err) - return fmt.Errorf("git commit: %w", err) - } - - if len(defaultBranch) == 0 { - defaultBranch = setting.Repository.DefaultBranch - } - - if stdout, _, err := git.NewCommand(ctx, "push", "origin").AddDynamicArguments("HEAD:" + defaultBranch). - SetDescription(fmt.Sprintf("initRepoCommit (git push): %s", tmpPath)). - RunStdString(&git.RunOpts{Dir: tmpPath, Env: InternalPushingEnvironment(u, repo)}); err != nil { - log.Error("Failed to push back to HEAD: Stdout: %s\nError: %v", stdout, err) - return fmt.Errorf("git push: %w", err) - } - - return nil -} - func CheckInitRepository(ctx context.Context, owner, name, objectFormatName string) (err error) { // Somehow the directory could exist. repoPath := repo_model.RepoPath(owner, name) diff --git a/modules/repository/repo.go b/modules/repository/repo.go index 39bdc6adcf8..cb926084baa 100644 --- a/modules/repository/repo.go +++ b/modules/repository/repo.go @@ -5,16 +5,13 @@ package repository import ( "context" - "errors" "fmt" "io" - "net/http" "strings" "time" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" - "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" @@ -22,10 +19,8 @@ import ( "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/migration" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" - "code.gitea.io/gitea/modules/util" ) /* @@ -47,244 +42,6 @@ func WikiRemoteURL(ctx context.Context, remote string) string { return "" } -// MigrateRepositoryGitData starts migrating git related data after created migrating repository -func MigrateRepositoryGitData(ctx context.Context, u *user_model.User, - repo *repo_model.Repository, opts migration.MigrateOptions, - httpTransport *http.Transport, -) (*repo_model.Repository, error) { - repoPath := repo_model.RepoPath(u.Name, opts.RepoName) - - if u.IsOrganization() { - t, err := organization.OrgFromUser(u).GetOwnerTeam(ctx) - if err != nil { - return nil, err - } - repo.NumWatches = t.NumMembers - } else { - repo.NumWatches = 1 - } - - migrateTimeout := time.Duration(setting.Git.Timeout.Migrate) * time.Second - - var err error - if err = util.RemoveAll(repoPath); err != nil { - return repo, fmt.Errorf("Failed to remove %s: %w", repoPath, err) - } - - if err = git.Clone(ctx, opts.CloneAddr, repoPath, git.CloneRepoOptions{ - Mirror: true, - Quiet: true, - Timeout: migrateTimeout, - SkipTLSVerify: setting.Migrations.SkipTLSVerify, - }); err != nil { - if errors.Is(err, context.DeadlineExceeded) { - return repo, fmt.Errorf("Clone timed out. Consider increasing [git.timeout] MIGRATE in app.ini. Underlying Error: %w", err) - } - return repo, fmt.Errorf("Clone: %w", err) - } - - if err := git.WriteCommitGraph(ctx, repoPath); err != nil { - return repo, err - } - - if opts.Wiki { - wikiPath := repo_model.WikiPath(u.Name, opts.RepoName) - wikiRemotePath := WikiRemoteURL(ctx, opts.CloneAddr) - if len(wikiRemotePath) > 0 { - if err := util.RemoveAll(wikiPath); err != nil { - return repo, fmt.Errorf("Failed to remove %s: %w", wikiPath, err) - } - - if err := git.Clone(ctx, wikiRemotePath, wikiPath, git.CloneRepoOptions{ - Mirror: true, - Quiet: true, - Timeout: migrateTimeout, - Branch: "master", - SkipTLSVerify: setting.Migrations.SkipTLSVerify, - }); err != nil { - log.Warn("Clone wiki: %v", err) - if err := util.RemoveAll(wikiPath); err != nil { - return repo, fmt.Errorf("Failed to remove %s: %w", wikiPath, err) - } - } else { - if err := git.WriteCommitGraph(ctx, wikiPath); err != nil { - return repo, err - } - } - } - } - - if repo.OwnerID == u.ID { - repo.Owner = u - } - - if err = CheckDaemonExportOK(ctx, repo); err != nil { - return repo, fmt.Errorf("checkDaemonExportOK: %w", err) - } - - if stdout, _, err := git.NewCommand(ctx, "update-server-info"). - SetDescription(fmt.Sprintf("MigrateRepositoryGitData(git update-server-info): %s", repoPath)). - RunStdString(&git.RunOpts{Dir: repoPath}); err != nil { - log.Error("MigrateRepositoryGitData(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err) - return repo, fmt.Errorf("error in MigrateRepositoryGitData(git update-server-info): %w", err) - } - - gitRepo, err := git.OpenRepository(ctx, repoPath) - if err != nil { - return repo, fmt.Errorf("OpenRepository: %w", err) - } - defer gitRepo.Close() - - repo.IsEmpty, err = gitRepo.IsEmpty() - if err != nil { - return repo, fmt.Errorf("git.IsEmpty: %w", err) - } - - if !repo.IsEmpty { - if len(repo.DefaultBranch) == 0 { - // Try to get HEAD branch and set it as default branch. - headBranch, err := gitRepo.GetHEADBranch() - if err != nil { - return repo, fmt.Errorf("GetHEADBranch: %w", err) - } - if headBranch != nil { - repo.DefaultBranch = headBranch.Name - } - } - - if _, err := SyncRepoBranchesWithRepo(ctx, repo, gitRepo, u.ID); err != nil { - return repo, fmt.Errorf("SyncRepoBranchesWithRepo: %v", err) - } - - if !opts.Releases { - // note: this will greatly improve release (tag) sync - // for pull-mirrors with many tags - repo.IsMirror = opts.Mirror - if err = SyncReleasesWithTags(ctx, repo, gitRepo); err != nil { - log.Error("Failed to synchronize tags to releases for repository: %v", err) - } - } - - if opts.LFS { - endpoint := lfs.DetermineEndpoint(opts.CloneAddr, opts.LFSEndpoint) - lfsClient := lfs.NewClient(endpoint, httpTransport) - if err = StoreMissingLfsObjectsInRepository(ctx, repo, gitRepo, lfsClient); err != nil { - log.Error("Failed to store missing LFS objects for repository: %v", err) - } - } - } - - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return nil, err - } - defer committer.Close() - - if opts.Mirror { - remoteAddress, err := util.SanitizeURL(opts.CloneAddr) - if err != nil { - return repo, err - } - mirrorModel := repo_model.Mirror{ - RepoID: repo.ID, - Interval: setting.Mirror.DefaultInterval, - EnablePrune: true, - NextUpdateUnix: timeutil.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval), - LFS: opts.LFS, - RemoteAddress: remoteAddress, - } - if opts.LFS { - mirrorModel.LFSEndpoint = opts.LFSEndpoint - } - - if opts.MirrorInterval != "" { - parsedInterval, err := time.ParseDuration(opts.MirrorInterval) - if err != nil { - log.Error("Failed to set Interval: %v", err) - return repo, err - } - if parsedInterval == 0 { - mirrorModel.Interval = 0 - mirrorModel.NextUpdateUnix = 0 - } else if parsedInterval < setting.Mirror.MinInterval { - err := fmt.Errorf("interval %s is set below Minimum Interval of %s", parsedInterval, setting.Mirror.MinInterval) - log.Error("Interval: %s is too frequent", opts.MirrorInterval) - return repo, err - } else { - mirrorModel.Interval = parsedInterval - mirrorModel.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(parsedInterval) - } - } - - if err = repo_model.InsertMirror(ctx, &mirrorModel); err != nil { - return repo, fmt.Errorf("InsertOne: %w", err) - } - - repo.IsMirror = true - if err = UpdateRepository(ctx, repo, false); err != nil { - return nil, err - } - - // this is necessary for sync local tags from remote - configName := fmt.Sprintf("remote.%s.fetch", mirrorModel.GetRemoteName()) - if stdout, _, err := git.NewCommand(ctx, "config"). - AddOptionValues("--add", configName, `+refs/tags/*:refs/tags/*`). - RunStdString(&git.RunOpts{Dir: repoPath}); err != nil { - log.Error("MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*) in %v: Stdout: %s\nError: %v", repo, stdout, err) - return repo, fmt.Errorf("error in MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*): %w", err) - } - } else { - if err = UpdateRepoSize(ctx, repo); err != nil { - log.Error("Failed to update size for repository: %v", err) - } - if repo, err = CleanUpMigrateInfo(ctx, repo); err != nil { - return nil, err - } - } - - return repo, committer.Commit() -} - -// cleanUpMigrateGitConfig removes mirror info which prevents "push --all". -// This also removes possible user credentials. -func cleanUpMigrateGitConfig(ctx context.Context, repoPath string) error { - cmd := git.NewCommand(ctx, "remote", "rm", "origin") - // if the origin does not exist - _, stderr, err := cmd.RunStdString(&git.RunOpts{ - Dir: repoPath, - }) - if err != nil && !strings.HasPrefix(stderr, "fatal: No such remote") { - return err - } - return nil -} - -// CleanUpMigrateInfo finishes migrating repository and/or wiki with things that don't need to be done for mirrors. -func CleanUpMigrateInfo(ctx context.Context, repo *repo_model.Repository) (*repo_model.Repository, error) { - repoPath := repo.RepoPath() - if err := CreateDelegateHooks(repoPath); err != nil { - return repo, fmt.Errorf("createDelegateHooks: %w", err) - } - if repo.HasWiki() { - if err := CreateDelegateHooks(repo.WikiPath()); err != nil { - return repo, fmt.Errorf("createDelegateHooks.(wiki): %w", err) - } - } - - _, _, err := git.NewCommand(ctx, "remote", "rm", "origin").RunStdString(&git.RunOpts{Dir: repoPath}) - if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") { - return repo, fmt.Errorf("CleanUpMigrateInfo: %w", err) - } - - if repo.HasWiki() { - if err := cleanUpMigrateGitConfig(ctx, repo.WikiPath()); err != nil { - return repo, fmt.Errorf("cleanUpMigrateGitConfig (wiki): %w", err) - } - } - - return repo, UpdateRepository(ctx, repo, false) -} - // SyncRepoTags synchronizes releases table with repository tags func SyncRepoTags(ctx context.Context, repoID int64) error { repo, err := repo_model.GetRepositoryByID(ctx, repoID) diff --git a/modules/setting/admin.go b/modules/setting/admin.go index 48a2ea97445..29bb947bc47 100644 --- a/modules/setting/admin.go +++ b/modules/setting/admin.go @@ -20,5 +20,6 @@ func loadAdminFrom(rootCfg ConfigProvider) { } const ( - UserFeatureDeletion = "deletion" + UserFeatureDeletion = "deletion" + UserFeatureManageGPGKeys = "manage_gpg_keys" ) diff --git a/modules/structs/user.go b/modules/structs/user.go index 0df67894b03..c43558be5d2 100644 --- a/modules/structs/user.go +++ b/modules/structs/user.go @@ -1,4 +1,5 @@ // Copyright 2014 The Gogs Authors. All rights reserved. +// Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT package structs @@ -108,3 +109,33 @@ type UpdateUserAvatarOption struct { // image must be base64 encoded Image string `json:"image" binding:"Required"` } + +// Badge represents a user badge +// swagger:model +type Badge struct { + ID int64 `json:"id"` + Slug string `json:"slug"` + Description string `json:"description"` + ImageURL string `json:"image_url"` +} + +// UserBadge represents a user badge +// swagger:model +type UserBadge struct { + ID int64 `json:"id"` + BadgeID int64 `json:"badge_id"` + UserID int64 `json:"user_id"` +} + +// UserBadgeOption options for link between users and badges +type UserBadgeOption struct { + // example: ["badge1","badge2"] + BadgeSlugs []string `json:"badge_slugs" binding:"Required"` +} + +// BadgeList +// swagger:response BadgeList +type BadgeList struct { + // in:body + Body []Badge `json:"body"` +} diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 0f397675869..1487fce69dc 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -33,16 +33,16 @@ 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, - "SafeHTML": SafeHTML, - "HTMLFormat": HTMLFormat, - "HTMLEscape": HTMLEscape, - "QueryEscape": url.QueryEscape, - "JSEscape": JSEscapeSafe, - "Str2html": Str2html, // TODO: rename it to SanitizeHTML - "URLJoin": util.URLJoin, - "DotEscape": DotEscape, + "dict": dict, // it's lowercase because this name has been widely used. Our other functions should have uppercase names. + "Eval": Eval, + "SafeHTML": SafeHTML, + "HTMLFormat": HTMLFormat, + "HTMLEscape": HTMLEscape, + "QueryEscape": url.QueryEscape, + "JSEscape": JSEscapeSafe, + "SanitizeHTML": SanitizeHTML, + "URLJoin": util.URLJoin, + "DotEscape": DotEscape, "PathEscape": url.PathEscape, "PathEscapeSegments": util.PathEscapeSegments, @@ -207,8 +207,8 @@ func SafeHTML(s any) template.HTML { panic(fmt.Sprintf("unexpected type %T", s)) } -// Str2html sanitizes the input by pre-defined markdown rules -func Str2html(s any) template.HTML { +// SanitizeHTML sanitizes the input by pre-defined markdown rules +func SanitizeHTML(s any) template.HTML { switch v := s.(type) { case string: return template.HTML(markup.Sanitize(v)) diff --git a/modules/templates/helper_test.go b/modules/templates/helper_test.go index 8f5d633d4f8..3365278ac29 100644 --- a/modules/templates/helper_test.go +++ b/modules/templates/helper_test.go @@ -61,3 +61,8 @@ func TestJSEscapeSafe(t *testing.T) { func TestHTMLFormat(t *testing.T) { assert.Equal(t, template.HTML("< < 1"), HTMLFormat("%s %s %d", "<", template.HTML("<"), 1)) } + +func TestSanitizeHTML(t *testing.T) { + assert.Equal(t, template.HTML(`link xss
inline
`), SanitizeHTML(`link xss
inline
`)) + assert.Equal(t, template.HTML(`link xss
inline
`), SanitizeHTML(template.HTML(`link xss
inline
`))) +} diff --git a/modules/templates/mailer.go b/modules/templates/mailer.go index 54d857a8f6e..04032e39827 100644 --- a/modules/templates/mailer.go +++ b/modules/templates/mailer.go @@ -44,11 +44,17 @@ func buildSubjectBodyTemplate(stpl *texttmpl.Template, btpl *template.Template, } if _, err := stpl.New(name). Parse(string(subjectContent)); err != nil { - log.Warn("Failed to parse template [%s/subject]: %v", name, err) + log.Error("Failed to parse template [%s/subject]: %v", name, err) + if !setting.IsProd { + log.Fatal("Please fix the mail template error") + } } if _, err := btpl.New(name). Parse(string(bodyContent)); err != nil { - log.Warn("Failed to parse template [%s/body]: %v", name, err) + log.Error("Failed to parse template [%s/body]: %v", name, err) + if !setting.IsProd { + log.Fatal("Please fix the mail template error") + } } } diff --git a/modules/templates/util_render.go b/modules/templates/util_render.go index 1d9635410b3..cdff31698ca 100644 --- a/modules/templates/util_render.go +++ b/modules/templates/util_render.go @@ -208,7 +208,7 @@ func RenderMarkdownToHtml(ctx context.Context, input string) template.HTML { //n if err != nil { log.Error("RenderString: %v", err) } - return template.HTML(output) + return output } func RenderLabels(ctx context.Context, labels []*issues_model.Label, repoLink string) template.HTML { diff --git a/modules/templates/util_string.go b/modules/templates/util_string.go index 2771b1e223f..479b755da1c 100644 --- a/modules/templates/util_string.go +++ b/modules/templates/util_string.go @@ -4,6 +4,8 @@ package templates import ( + "fmt" + "html/template" "strings" "code.gitea.io/gitea/modules/base" @@ -17,6 +19,19 @@ func NewStringUtils() *StringUtils { return &stringUtils } +func (su *StringUtils) ToString(v any) string { + switch v := v.(type) { + case string: + return v + case template.HTML: + return string(v) + case fmt.Stringer: + return v.String() + default: + return fmt.Sprint(v) + } +} + func (su *StringUtils) HasPrefix(s, prefix string) bool { return strings.HasPrefix(s, prefix) } diff --git a/modules/util/util.go b/modules/util/util.go index 28b549f4055..615f654e475 100644 --- a/modules/util/util.go +++ b/modules/util/util.go @@ -68,13 +68,13 @@ func OptionalBoolOf(b bool) OptionalBool { return OptionalBoolFalse } -// OptionalBoolParse get the corresponding OptionalBool of a string using strconv.ParseBool -func OptionalBoolParse(s string) OptionalBool { - b, e := strconv.ParseBool(s) +// OptionalBoolParse get the corresponding optional.Option[bool] of a string using strconv.ParseBool +func OptionalBoolParse(s string) optional.Option[bool] { + v, e := strconv.ParseBool(s) if e != nil { - return OptionalBoolNone + return optional.None[bool]() } - return OptionalBoolOf(b) + return optional.Some(v) } // IsEmptyString checks if the provided string is empty diff --git a/modules/util/util_test.go b/modules/util/util_test.go index c5830ce01cb..819e12ee91f 100644 --- a/modules/util/util_test.go +++ b/modules/util/util_test.go @@ -8,6 +8,8 @@ import ( "strings" "testing" + "code.gitea.io/gitea/modules/optional" + "github.com/stretchr/testify/assert" ) @@ -173,17 +175,17 @@ func Test_RandomBytes(t *testing.T) { assert.NotEqual(t, bytes3, bytes4) } -func Test_OptionalBool(t *testing.T) { - assert.Equal(t, OptionalBoolNone, OptionalBoolParse("")) - assert.Equal(t, OptionalBoolNone, OptionalBoolParse("x")) +func TestOptionalBoolParse(t *testing.T) { + assert.Equal(t, optional.None[bool](), OptionalBoolParse("")) + assert.Equal(t, optional.None[bool](), OptionalBoolParse("x")) - assert.Equal(t, OptionalBoolFalse, OptionalBoolParse("0")) - assert.Equal(t, OptionalBoolFalse, OptionalBoolParse("f")) - assert.Equal(t, OptionalBoolFalse, OptionalBoolParse("False")) + assert.Equal(t, optional.Some(false), OptionalBoolParse("0")) + assert.Equal(t, optional.Some(false), OptionalBoolParse("f")) + assert.Equal(t, optional.Some(false), OptionalBoolParse("False")) - assert.Equal(t, OptionalBoolTrue, OptionalBoolParse("1")) - assert.Equal(t, OptionalBoolTrue, OptionalBoolParse("t")) - assert.Equal(t, OptionalBoolTrue, OptionalBoolParse("True")) + assert.Equal(t, optional.Some(true), OptionalBoolParse("1")) + assert.Equal(t, optional.Some(true), OptionalBoolParse("t")) + assert.Equal(t, optional.Some(true), OptionalBoolParse("True")) } // Test case for any function which accepts and returns a single string. diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index d30103a8eb8..2a421b11721 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -123,6 +123,7 @@ pin=Připnout unpin=Odepnout artifacts=Artefakty +confirm_delete_artifact=Jste si jisti, že chcete odstranit artefakt „%s“? archived=Archivováno @@ -423,6 +424,7 @@ authorization_failed_desc=Autorizace selhala, protože jsme detekovali neplatný sspi_auth_failed=SSPI autentizace selhala password_pwned=Heslo, které jste zvolili, je na seznamu odcizených hesel, která byla dříve odhalena při narušení veřejných dat. Zkuste to prosím znovu s jiným heslem. password_pwned_err=Nelze dokončit požadavek na HaveIBeenPwned +last_admin=Nelze odstranit posledního správce. Musí existovat alespoň jeden správce. [mail] view_it_on=Zobrazit na %s @@ -588,6 +590,7 @@ org_still_own_packages=Organizace stále vlastní jeden nebo více balíčků. N target_branch_not_exist=Cílová větev neexistuje. +admin_cannot_delete_self=Nemůžete se smazat, dokud jste správce. Nejdříve prosím odeberte svá administrátorská oprávnění. [user] change_avatar=Změnit váš avatar… @@ -967,6 +970,8 @@ issue_labels_helper=Vyberte sadu štítků úkolů. license=Licence license_helper=Vyberte licenční soubor. license_helper_desc=Licence řídí, co ostatní mohou a nemohou dělat s vaším kódem. Nejste si jisti, která je pro váš projekt správná? Podívejte se na Zvolte licenci +object_format=Formát objektu +object_format_helper=Objektový formát repozitáře. Nelze později změnit. SHA1 je nejvíce kompatibilní. readme=README readme_helper=Vyberte šablonu souboru README. readme_helper_desc=Toto je místo, kde můžete napsat úplný popis vašeho projektu. @@ -1033,6 +1038,7 @@ desc.public=Veřejný desc.template=Šablona desc.internal=Interní desc.archived=Archivováno +desc.sha256=SHA256 template.items=Položky šablony template.git_content=Obsah gitu (výchozí větev) @@ -1183,6 +1189,8 @@ audio_not_supported_in_browser=Váš prohlížeč nepodporuje značku pro HTML5 stored_lfs=Uloženo pomocí Git LFS symbolic_link=Symbolický odkaz executable_file=Spustitelný soubor +vendored=Vendorováno +generated=Generováno commit_graph=Graf commitů commit_graph.select=Vybrat větve commit_graph.hide_pr_refs=Skrýt požadavky na natažení @@ -1518,7 +1526,11 @@ issues.label_title=Název štítku issues.label_description=Popis štítku issues.label_color=Barva štítku issues.label_exclusive=Exkluzivní +issues.label_archive=Archivovat štítek issues.label_archived_filter=Zobrazit archivované popisky +issues.label_archive_tooltip=Archivované štítky jsou ve výchozím nastavení vyloučeny z návrhů při hledání podle popisku. +issues.label_exclusive_desc=Pojmenujte štítek rozsah/položka, aby se stal vzájemně exkluzivním s jinými štítky rozsah/. +issues.label_exclusive_warning=Jakékoliv protichůdné rozsahy štítků budou odstraněny při úpravě štítků u úkolů nebo u požadavku na natažení. issues.label_count=%d štítků issues.label_open_issues=%d otevřených úkolů issues.label_edit=Upravit @@ -1619,6 +1631,7 @@ issues.dependency.issue_closing_blockedby=Uzavření tohoto úkolu je blokováno issues.dependency.issue_close_blocks=Tento úkol blokuje uzavření následujících úkolů issues.dependency.pr_close_blocks=Tento požadavek na natažení blokuje uzavření následujících úkolů issues.dependency.issue_close_blocked=Musíte zavřít všechny úkoly, které blokují tento úkol, aby jej bylo možné zavřít. +issues.dependency.issue_batch_close_blocked=Nelze uzavřít úkoly, které jste vybrali, protože úkol #%d má stále otevřené závislosti issues.dependency.pr_close_blocked=Musíte zavřít všechny úkoly, které blokují tento požadavek na natažení, aby jej bylo možné sloučit. issues.dependency.blocks_short=Blokuje issues.dependency.blocked_by_short=Závisí na @@ -1700,6 +1713,7 @@ pulls.select_commit_hold_shift_for_range=Vyberte commit. Podržte klávesu shift pulls.review_only_possible_for_full_diff=Posouzení je možné pouze při zobrazení plného rozlišení pulls.filter_changes_by_commit=Filtrovat podle commitu pulls.nothing_to_compare=Tyto větve jsou stejné. Není potřeba vytvářet požadavek na natažení. +pulls.nothing_to_compare_have_tag=Vybraná větev/značka je stejná. pulls.nothing_to_compare_and_allow_empty_pr=Tyto větve jsou stejné. Tento požadavek na natažení bude prázdný. pulls.has_pull_request=`Požadavek na natažení mezi těmito větvemi již existuje: %[2]s#%[3]d` pulls.create=Vytvořit požadavek na natažení @@ -1822,6 +1836,7 @@ milestones.update_ago=Aktualizováno %s milestones.no_due_date=Bez lhůty dokončení milestones.open=Otevřít milestones.close=Zavřít +milestones.new_subheader=Milníky vám pomohou organizovat úkoly a sledovat jejich pokrok. milestones.completeness=%d%% Dokončeno milestones.create=Vytvořit milník milestones.title=Název @@ -1955,6 +1970,7 @@ activity.git_stats_and_deletions=a activity.git_stats_deletion_1=%d odebrání activity.git_stats_deletion_n=%d odebrání +contributors.contribution_type.filter_label=Typ příspěvku: contributors.contribution_type.commits=Commity search=Vyhledat @@ -2341,6 +2357,7 @@ settings.matrix.room_id=ID místnosti settings.matrix.message_type=Typ zprávy settings.archive.button=Archivovat repozitář settings.archive.header=Archivovat tento repozitář +settings.archive.text=Archivace repozitáře způsobí, že bude zcela určen pouze pro čtení. Bude skryt z ovládacího panelu. Nikdo (ani vy!) nebude moci vytvářet nové revize ani otevírat nové úkoly nebo žádosti o natažení. settings.archive.success=Repozitář byl úspěšně archivován. settings.archive.error=Nastala chyba při archivování repozitáře. Prohlédněte si záznam pro více detailů. settings.archive.error_ismirror=Nemůžete archivovat zrcadlený repozitář. @@ -2545,6 +2562,11 @@ error.csv.unexpected=Tento soubor nelze vykreslit, protože obsahuje neočekáva error.csv.invalid_field_count=Soubor nelze vykreslit, protože má nesprávný počet polí na řádku %d. [graphs] +component_loading=Načítání %s... +component_loading_failed=Nelze načíst %s +component_loading_info=Může to chvíli trvat… +component_failed_to_load=Došlo k neočekávané chybě. +contributors.what=příspěvky [org] org_name_holder=Název organizace @@ -2715,6 +2737,7 @@ dashboard.delete_repo_archives.started=Spuštěna úloha smazání všech archiv dashboard.delete_missing_repos=Smazat všechny repozitáře, které nemají Git soubory dashboard.delete_missing_repos.started=Spuštěna úloha mazání všech repozitářů, které nemají Git soubory. dashboard.delete_generated_repository_avatars=Odstranit vygenerované avatary repozitářů +dashboard.sync_repo_tags=Synchronizovat značky z git dat do databáze dashboard.update_mirrors=Aktualizovat zrcadla dashboard.repo_health_check=Kontrola stavu všech repozitářů dashboard.check_repo_stats=Zkontrolovat všechny statistiky repositáře @@ -2762,11 +2785,14 @@ dashboard.delete_old_actions=Odstranit všechny staré akce z databáze dashboard.delete_old_actions.started=Začalo odstraňování všech starých akcí z databáze. dashboard.update_checker=Kontrola aktualizací dashboard.delete_old_system_notices=Odstranit všechna stará systémová upozornění z databáze +dashboard.gc_lfs=Úklid LFS meta objektů dashboard.stop_zombie_tasks=Zastavit zombie úlohy dashboard.stop_endless_tasks=Zastavit nekonečné úlohy dashboard.cancel_abandoned_jobs=Zrušit opuštěné úlohy dashboard.start_schedule_tasks=Spustit naplánované úlohy dashboard.sync_branch.started=Synchronizace větví byla spuštěna +dashboard.sync_tag.started=Synchronizace značek spuštěna +dashboard.rebuild_issue_indexer=Znovu sestavit index úkolů users.user_manage_panel=Správa uživatelských účtů users.new_account=Vytvořit uživatelský účet @@ -3184,6 +3210,12 @@ notices.desc=Popis notices.op=Akce notices.delete_success=Systémové upozornění bylo smazáno. +self_check.no_problem_found=Zatím nebyl nalezen žádný problém. +self_check.database_collation_mismatch=Očekávejte, že databáze použije collation: %s +self_check.database_collation_case_insensitive=Databáze používá collation %s, což je collation nerozlišující velká a malá písmena. Ačkoli s ní Gitea může pracovat, mohou se vyskytnout vzácné případy, kdy nebude fungovat podle očekávání. +self_check.database_inconsistent_collation_columns=Databáze používá collation %s, ale tyto sloupce používají chybné collation. To může způsobit neočekávané problémy. +self_check.database_fix_mysql=Pro uživatele MySQL/MariaDB můžete použít příkaz "gitea doctor convert", který opraví problémy s collation, nebo můžete také problém vyřešit příkazem "ALTER ... COLLATE ..." SQL ručně. +self_check.database_fix_mssql=Uživatelé MSSQL mohou problém vyřešit pouze pomocí příkazu "ALTER ... COLLATE ..." SQL ručně. [action] create_repo=vytvořil/a repozitář %s @@ -3371,6 +3403,7 @@ rpm.distros.suse=na distribuce založené na SUSE rpm.install=Pro instalaci balíčku spusťte následující příkaz: rpm.repository=Informace o repozitáři rpm.repository.architectures=Architektury +rpm.repository.multiple_groups=Tento balíček je k dispozici ve více skupinách. rubygems.install=Pro instalaci balíčku pomocí gem spusťte následující příkaz: rubygems.install2=nebo ho přidejte do Gemfie: rubygems.dependencies.runtime=Běhové závislosti @@ -3498,6 +3531,8 @@ runs.actors_no_select=Všichni aktéři runs.status_no_select=Všechny stavy runs.no_results=Nebyly nalezeny žádné výsledky. runs.no_workflows=Zatím neexistují žádné pracovní postupy. +runs.no_workflows.quick_start=Nevíte jak začít s Gitea Actions? Podívejte se na průvodce rychlým startem. +runs.no_workflows.documentation=Další informace o Gitea Actions naleznete v dokumentaci. runs.no_runs=Pracovní postup zatím nebyl spuštěn. runs.empty_commit_message=(prázdná zpráva commitu) @@ -3515,6 +3550,7 @@ variables.none=Zatím nejsou žádné proměnné. variables.deletion=Odstranit proměnnou variables.deletion.description=Odstranění proměnné je trvalé a nelze jej vrátit zpět. Pokračovat? variables.description=Proměnné budou předány určitým akcím a nelze je přečíst jinak. +variables.id_not_exist=Proměnná s ID %d neexistuje. variables.edit=Upravit proměnnou variables.deletion.failed=Nepodařilo se odstranit proměnnou. variables.deletion.success=Proměnná byla odstraněna. diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index a0ad09f7764..6d4e109e1dc 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -368,7 +368,7 @@ forgot_password_title= Forgot Password forgot_password = Forgot password? sign_up_now = Need an account? Register now. sign_up_successful = Account was successfully created. Welcome! -confirmation_mail_sent_prompt = A new confirmation email has been sent to %s. Please check your inbox within the next %s to complete the registration process. +confirmation_mail_sent_prompt_ex = A new confirmation email has been sent to %s. Please check your inbox within the next %s to complete the registration process. If your registration email address is incorrect, you can sign in again and change it. must_change_password = Update your password allow_password_change = Require user to change password (recommended) reset_password_mail_sent_prompt = A confirmation email has been sent to %s. Please check your inbox within the next %s to complete the account recovery process. @@ -378,6 +378,7 @@ prohibit_login = Sign In Prohibited prohibit_login_desc = Your account is prohibited from signing in, please contact your site administrator. resent_limit_prompt = You have already requested an activation email recently. Please wait 3 minutes and try again. has_unconfirmed_mail = Hi %s, you have an unconfirmed email address (%s). If you haven't received a confirmation email or need to resend a new one, please click on the button below. +change_unconfirmed_mail_address = If your registration email address is incorrect, you can change it here and resend a new confirmation email. resend_mail = Click here to resend your activation email email_not_associate = The email address is not associated with any account. send_reset_mail = Send Account Recovery Email diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 7fd79446cc2..20ef954cd20 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -424,6 +424,7 @@ authorization_failed_desc=L'autorisation a échoué car nous avons détecté une sspi_auth_failed=Échec de l'authentification SSPI password_pwned=Le mot de passe que vous avez choisi se trouve sur la liste des mots de passe ayant fuité sur internet. Veuillez réessayer avec un mot de passe différent et considérer remplacer ce mot de passe si vous l'utilisez ailleurs. password_pwned_err=Impossible d'envoyer la demande à HaveIBeenPwned +last_admin=Vous ne pouvez pas supprimer ce compte car au moins un administrateur est requis. [mail] view_it_on=Voir sur %s @@ -1714,6 +1715,7 @@ pulls.select_commit_hold_shift_for_range=Maintenir Maj et cliquer sur des révis pulls.review_only_possible_for_full_diff=Une évaluation n'est possible que lorsque vous affichez le différentiel complet. pulls.filter_changes_by_commit=Filtrer par révision pulls.nothing_to_compare=Ces branches sont identiques. Il n’y a pas besoin de créer une demande d'ajout. +pulls.nothing_to_compare_have_tag=Les branches/étiquettes sélectionnées sont équivalentes. pulls.nothing_to_compare_and_allow_empty_pr=Ces branches sont égales. Cette demande d'ajout sera vide. pulls.has_pull_request='Il existe déjà une demande d'ajout entre ces deux branches : %[2]s#%[3]d' pulls.create=Créer une demande d'ajout diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 7c8153cbb13..89f237a1175 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -2119,7 +2119,7 @@ settings.trust_model.collaborator.long=协作者:信任协作者的签名 settings.trust_model.collaborator.desc=此仓库中协作者的有效签名将被标记为「可信」(无论它们是否是提交者),签名只符合提交者时将标记为「不可信」,都不匹配时标记为「不匹配」。 settings.trust_model.committer=提交者 settings.trust_model.committer.long=提交者: 信任与提交者相符的签名 (此特性类似 GitHub,这会强制采用 Gitea 作为提交者和签名者) -settings.trust_model.committer.desc=有效签名只有和提交者相匹配才会被标记为“受信任”,否则它们将被标记为“不匹配”。这强制 Gitea 成为签名提交的提交者,而实际提交者被加上 Co-authored-by: 和 Co-committed-by: 的标记。 默认的 Gitea 密钥必须撇撇数据库种的一名用户。 +settings.trust_model.committer.desc=有效签名只有和提交者相匹配才会被标记为“受信任”,否则它们将被标记为“不匹配”。这强制 Gitea 成为签名提交的提交者,而实际提交者被加上 Co-authored-by: 和 Co-committed-by: 的标记。 默认的 Gitea 密钥必须匹配数据库中的一名用户。 settings.trust_model.collaboratorcommitter=协作者+提交者 settings.trust_model.collaboratorcommitter.long=协作者+提交者:信任协作者同时是提交者的签名 settings.trust_model.collaboratorcommitter.desc=此仓库中协作者的有效签名在他同时是提交者时将被标记为「可信」,签名只匹配了提交者时将标记为「不可信」,都不匹配时标记为「不匹配」。这会强制 Gitea 成为签名者和提交者,实际的提交者将被标记于提交消息结尾处的「Co-Authored-By:」和「Co-Committed-By:」。默认的 Gitea 签名密钥必须匹配数据库中的一个用户密钥。 @@ -3250,7 +3250,9 @@ notices.delete_success=系统通知已被删除。 self_check.no_problem_found=尚未发现问题。 self_check.database_collation_mismatch=期望数据库使用的校验方式:%s self_check.database_collation_case_insensitive=数据库正在使用一个校验 %s, 这是一个不敏感的校验. 虽然Gitea可以与它合作,但可能有一些罕见的情况不如预期的那样起作用。 +self_check.database_inconsistent_collation_columns=数据库正在使用%s的排序规则,但是这些列使用了不匹配的排序规则。这可能会造成一些意外问题。 self_check.database_fix_mysql=对于MySQL/MariaDB用户,您可以使用“gitea doctor convert”命令来解决校验问题。 或者您也可以通过 "ALTER ... COLLATE ..." 这样的SQL 来手动解决这个问题。 +self_check.database_fix_mssql=对于MSSQL用户,您现在只能通过"ALTER ... COLLATE ..."SQLs手动解决这个问题。 [action] create_repo=创建了仓库 %s diff --git a/routers/api/actions/artifacts.go b/routers/api/actions/artifacts.go index 9fbd3f045d7..d530e9cee56 100644 --- a/routers/api/actions/artifacts.go +++ b/routers/api/actions/artifacts.go @@ -71,7 +71,6 @@ import ( "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -80,6 +79,7 @@ import ( "code.gitea.io/gitea/modules/web" web_types "code.gitea.io/gitea/modules/web/types" actions_service "code.gitea.io/gitea/services/actions" + "code.gitea.io/gitea/services/context" ) const artifactRouteBase = "/_apis/pipelines/workflows/{run_id}/artifacts" diff --git a/routers/api/packages/alpine/alpine.go b/routers/api/packages/alpine/alpine.go index 3fd8288c018..dae9c3dfcb2 100644 --- a/routers/api/packages/alpine/alpine.go +++ b/routers/api/packages/alpine/alpine.go @@ -14,12 +14,12 @@ import ( "strings" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" packages_module "code.gitea.io/gitea/modules/packages" alpine_module "code.gitea.io/gitea/modules/packages/alpine" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" alpine_service "code.gitea.io/gitea/services/packages/alpine" ) diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index d990ebb56a7..5e3cbac8f9c 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -10,7 +10,6 @@ import ( auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/perm" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" @@ -36,7 +35,7 @@ import ( "code.gitea.io/gitea/routers/api/packages/swift" "code.gitea.io/gitea/routers/api/packages/vagrant" "code.gitea.io/gitea/services/auth" - context_service "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context" ) func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.Context) { @@ -642,7 +641,7 @@ func CommonRoutes() *web.Route { }) }) }, reqPackageAccess(perm.AccessModeRead)) - }, context_service.UserAssignmentWeb(), context.PackageAssignment()) + }, context.UserAssignmentWeb(), context.PackageAssignment()) return r } @@ -812,7 +811,7 @@ func ContainerRoutes() *web.Route { ctx.Status(http.StatusNotFound) }) - }, container.ReqContainerAccess, context_service.UserAssignmentWeb(), context.PackageAssignment(), reqPackageAccess(perm.AccessModeRead)) + }, container.ReqContainerAccess, context.UserAssignmentWeb(), context.PackageAssignment(), reqPackageAccess(perm.AccessModeRead)) return r } diff --git a/routers/api/packages/cargo/cargo.go b/routers/api/packages/cargo/cargo.go index 8f1e965c9a3..d01a13d78f6 100644 --- a/routers/api/packages/cargo/cargo.go +++ b/routers/api/packages/cargo/cargo.go @@ -12,7 +12,6 @@ import ( "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" packages_module "code.gitea.io/gitea/modules/packages" cargo_module "code.gitea.io/gitea/modules/packages/cargo" @@ -20,6 +19,7 @@ import ( "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" packages_service "code.gitea.io/gitea/services/packages" cargo_service "code.gitea.io/gitea/services/packages/cargo" diff --git a/routers/api/packages/chef/chef.go b/routers/api/packages/chef/chef.go index f1e9ae12d81..720fce0a2a5 100644 --- a/routers/api/packages/chef/chef.go +++ b/routers/api/packages/chef/chef.go @@ -15,12 +15,12 @@ import ( "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" packages_module "code.gitea.io/gitea/modules/packages" chef_module "code.gitea.io/gitea/modules/packages/chef" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" ) diff --git a/routers/api/packages/composer/composer.go b/routers/api/packages/composer/composer.go index 0551093cd19..346408d2611 100644 --- a/routers/api/packages/composer/composer.go +++ b/routers/api/packages/composer/composer.go @@ -14,12 +14,12 @@ import ( "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" packages_module "code.gitea.io/gitea/modules/packages" composer_module "code.gitea.io/gitea/modules/packages/composer" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" packages_service "code.gitea.io/gitea/services/packages" diff --git a/routers/api/packages/conan/conan.go b/routers/api/packages/conan/conan.go index 4bf13222dc7..c45e085a4d9 100644 --- a/routers/api/packages/conan/conan.go +++ b/routers/api/packages/conan/conan.go @@ -15,13 +15,13 @@ import ( packages_model "code.gitea.io/gitea/models/packages" conan_model "code.gitea.io/gitea/models/packages/conan" "code.gitea.io/gitea/modules/container" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" packages_module "code.gitea.io/gitea/modules/packages" conan_module "code.gitea.io/gitea/modules/packages/conan" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" notify_service "code.gitea.io/gitea/services/notify" packages_service "code.gitea.io/gitea/services/packages" ) diff --git a/routers/api/packages/conan/search.go b/routers/api/packages/conan/search.go index 2bcf9df162b..7370c702cd6 100644 --- a/routers/api/packages/conan/search.go +++ b/routers/api/packages/conan/search.go @@ -9,9 +9,9 @@ import ( conan_model "code.gitea.io/gitea/models/packages/conan" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" conan_module "code.gitea.io/gitea/modules/packages/conan" + "code.gitea.io/gitea/services/context" ) // SearchResult contains the found recipe names diff --git a/routers/api/packages/conda/conda.go b/routers/api/packages/conda/conda.go index 0bee7baa96f..30c80fc15e0 100644 --- a/routers/api/packages/conda/conda.go +++ b/routers/api/packages/conda/conda.go @@ -12,13 +12,13 @@ import ( packages_model "code.gitea.io/gitea/models/packages" conda_model "code.gitea.io/gitea/models/packages/conda" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" packages_module "code.gitea.io/gitea/modules/packages" conda_module "code.gitea.io/gitea/modules/packages/conda" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" "github.com/dsnet/compress/bzip2" diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go index 8621242da4e..e5197661423 100644 --- a/routers/api/packages/container/container.go +++ b/routers/api/packages/container/container.go @@ -17,7 +17,6 @@ import ( packages_model "code.gitea.io/gitea/models/packages" container_model "code.gitea.io/gitea/models/packages/container" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" packages_module "code.gitea.io/gitea/modules/packages" @@ -25,6 +24,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" container_service "code.gitea.io/gitea/services/packages/container" diff --git a/routers/api/packages/cran/cran.go b/routers/api/packages/cran/cran.go index ae43df7c9aa..2cec75294fe 100644 --- a/routers/api/packages/cran/cran.go +++ b/routers/api/packages/cran/cran.go @@ -13,11 +13,11 @@ import ( packages_model "code.gitea.io/gitea/models/packages" cran_model "code.gitea.io/gitea/models/packages/cran" - "code.gitea.io/gitea/modules/context" packages_module "code.gitea.io/gitea/modules/packages" cran_module "code.gitea.io/gitea/modules/packages/cran" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" ) diff --git a/routers/api/packages/debian/debian.go b/routers/api/packages/debian/debian.go index 379137e87eb..241de3ac5d9 100644 --- a/routers/api/packages/debian/debian.go +++ b/routers/api/packages/debian/debian.go @@ -13,11 +13,11 @@ import ( "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" packages_module "code.gitea.io/gitea/modules/packages" debian_module "code.gitea.io/gitea/modules/packages/debian" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" notify_service "code.gitea.io/gitea/services/notify" packages_service "code.gitea.io/gitea/services/packages" debian_service "code.gitea.io/gitea/services/packages/debian" diff --git a/routers/api/packages/generic/generic.go b/routers/api/packages/generic/generic.go index 30854335c09..b65870a8d09 100644 --- a/routers/api/packages/generic/generic.go +++ b/routers/api/packages/generic/generic.go @@ -10,10 +10,10 @@ import ( "strings" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" packages_module "code.gitea.io/gitea/modules/packages" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" ) diff --git a/routers/api/packages/goproxy/goproxy.go b/routers/api/packages/goproxy/goproxy.go index 18e0074ab4d..9eb515d9a1b 100644 --- a/routers/api/packages/goproxy/goproxy.go +++ b/routers/api/packages/goproxy/goproxy.go @@ -12,11 +12,11 @@ import ( "time" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" packages_module "code.gitea.io/gitea/modules/packages" goproxy_module "code.gitea.io/gitea/modules/packages/goproxy" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" ) diff --git a/routers/api/packages/helm/helm.go b/routers/api/packages/helm/helm.go index a8daa69dc3a..e7a346d9ca7 100644 --- a/routers/api/packages/helm/helm.go +++ b/routers/api/packages/helm/helm.go @@ -13,7 +13,6 @@ import ( "time" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" packages_module "code.gitea.io/gitea/modules/packages" @@ -21,6 +20,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" "gopkg.in/yaml.v3" diff --git a/routers/api/packages/helper/helper.go b/routers/api/packages/helper/helper.go index aadb10376c8..cdb64109ade 100644 --- a/routers/api/packages/helper/helper.go +++ b/routers/api/packages/helper/helper.go @@ -10,9 +10,9 @@ import ( "net/url" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ) // LogAndProcessError logs an error and calls a custom callback with the processed error message. diff --git a/routers/api/packages/maven/maven.go b/routers/api/packages/maven/maven.go index 5106395eb1a..27f0578db70 100644 --- a/routers/api/packages/maven/maven.go +++ b/routers/api/packages/maven/maven.go @@ -20,12 +20,12 @@ import ( "strings" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" packages_module "code.gitea.io/gitea/modules/packages" maven_module "code.gitea.io/gitea/modules/packages/maven" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" ) diff --git a/routers/api/packages/npm/npm.go b/routers/api/packages/npm/npm.go index 170edfbe11c..72b43059281 100644 --- a/routers/api/packages/npm/npm.go +++ b/routers/api/packages/npm/npm.go @@ -17,12 +17,12 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" - "code.gitea.io/gitea/modules/context" packages_module "code.gitea.io/gitea/modules/packages" npm_module "code.gitea.io/gitea/modules/packages/npm" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" "github.com/hashicorp/go-version" diff --git a/routers/api/packages/nuget/nuget.go b/routers/api/packages/nuget/nuget.go index 769c4c18245..a0273aad5ad 100644 --- a/routers/api/packages/nuget/nuget.go +++ b/routers/api/packages/nuget/nuget.go @@ -17,13 +17,13 @@ import ( "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" nuget_model "code.gitea.io/gitea/models/packages/nuget" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" packages_module "code.gitea.io/gitea/modules/packages" nuget_module "code.gitea.io/gitea/modules/packages/nuget" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" ) diff --git a/routers/api/packages/pub/pub.go b/routers/api/packages/pub/pub.go index 1f605c6c9f4..f87df52a29a 100644 --- a/routers/api/packages/pub/pub.go +++ b/routers/api/packages/pub/pub.go @@ -14,7 +14,6 @@ import ( "time" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" packages_module "code.gitea.io/gitea/modules/packages" @@ -22,6 +21,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" ) diff --git a/routers/api/packages/pypi/pypi.go b/routers/api/packages/pypi/pypi.go index 5718b1203b4..7824db18235 100644 --- a/routers/api/packages/pypi/pypi.go +++ b/routers/api/packages/pypi/pypi.go @@ -12,12 +12,12 @@ import ( "strings" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" packages_module "code.gitea.io/gitea/modules/packages" pypi_module "code.gitea.io/gitea/modules/packages/pypi" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" ) diff --git a/routers/api/packages/rpm/rpm.go b/routers/api/packages/rpm/rpm.go index 5d06680552c..4de361c2142 100644 --- a/routers/api/packages/rpm/rpm.go +++ b/routers/api/packages/rpm/rpm.go @@ -13,13 +13,13 @@ import ( "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" packages_module "code.gitea.io/gitea/modules/packages" rpm_module "code.gitea.io/gitea/modules/packages/rpm" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" notify_service "code.gitea.io/gitea/services/notify" packages_service "code.gitea.io/gitea/services/packages" rpm_service "code.gitea.io/gitea/services/packages/rpm" diff --git a/routers/api/packages/rubygems/rubygems.go b/routers/api/packages/rubygems/rubygems.go index 01fd4dad669..5d05b6d524d 100644 --- a/routers/api/packages/rubygems/rubygems.go +++ b/routers/api/packages/rubygems/rubygems.go @@ -13,11 +13,11 @@ import ( "strings" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" packages_module "code.gitea.io/gitea/modules/packages" rubygems_module "code.gitea.io/gitea/modules/packages/rubygems" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" ) diff --git a/routers/api/packages/swift/swift.go b/routers/api/packages/swift/swift.go index 6ad289e51e9..1fc8baeaacd 100644 --- a/routers/api/packages/swift/swift.go +++ b/routers/api/packages/swift/swift.go @@ -13,7 +13,6 @@ import ( "strings" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" packages_module "code.gitea.io/gitea/modules/packages" @@ -21,6 +20,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" "github.com/hashicorp/go-version" diff --git a/routers/api/packages/vagrant/vagrant.go b/routers/api/packages/vagrant/vagrant.go index af9cd08a629..98a81da368e 100644 --- a/routers/api/packages/vagrant/vagrant.go +++ b/routers/api/packages/vagrant/vagrant.go @@ -12,11 +12,11 @@ import ( "strings" packages_model "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" packages_module "code.gitea.io/gitea/modules/packages" vagrant_module "code.gitea.io/gitea/modules/packages/vagrant" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" "github.com/hashicorp/go-version" diff --git a/routers/api/v1/activitypub/person.go b/routers/api/v1/activitypub/person.go index cad5032d103..995a148f0bd 100644 --- a/routers/api/v1/activitypub/person.go +++ b/routers/api/v1/activitypub/person.go @@ -9,9 +9,9 @@ import ( "strings" "code.gitea.io/gitea/modules/activitypub" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ap "github.com/go-ap/activitypub" "github.com/go-ap/jsonld" diff --git a/routers/api/v1/activitypub/reqsignature.go b/routers/api/v1/activitypub/reqsignature.go index 3f60ed7776a..59ebc74b89e 100644 --- a/routers/api/v1/activitypub/reqsignature.go +++ b/routers/api/v1/activitypub/reqsignature.go @@ -13,9 +13,9 @@ import ( "net/url" "code.gitea.io/gitea/modules/activitypub" - gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/httplib" "code.gitea.io/gitea/modules/setting" + gitea_context "code.gitea.io/gitea/services/context" ap "github.com/go-ap/activitypub" "github.com/go-fed/httpsig" diff --git a/routers/api/v1/admin/adopt.go b/routers/api/v1/admin/adopt.go index bf030eb222b..a4708fe0326 100644 --- a/routers/api/v1/admin/adopt.go +++ b/routers/api/v1/admin/adopt.go @@ -8,9 +8,9 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" repo_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/api/v1/admin/cron.go b/routers/api/v1/admin/cron.go index cc8c6c9e239..e1ca6048c93 100644 --- a/routers/api/v1/admin/cron.go +++ b/routers/api/v1/admin/cron.go @@ -6,11 +6,11 @@ package admin import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/cron" ) diff --git a/routers/api/v1/admin/email.go b/routers/api/v1/admin/email.go index 5914215bc2a..ba963e9f69d 100644 --- a/routers/api/v1/admin/email.go +++ b/routers/api/v1/admin/email.go @@ -7,9 +7,9 @@ import ( "net/http" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/admin/hooks.go b/routers/api/v1/admin/hooks.go index 8a095a7defa..2217d002a02 100644 --- a/routers/api/v1/admin/hooks.go +++ b/routers/api/v1/admin/hooks.go @@ -8,12 +8,12 @@ import ( "net/http" "code.gitea.io/gitea/models/webhook" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" webhook_service "code.gitea.io/gitea/services/webhook" ) diff --git a/routers/api/v1/admin/org.go b/routers/api/v1/admin/org.go index bf68942a9ca..a5c299bbf01 100644 --- a/routers/api/v1/admin/org.go +++ b/routers/api/v1/admin/org.go @@ -10,10 +10,10 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/admin/repo.go b/routers/api/v1/admin/repo.go index a4895f260be..c119d5390a2 100644 --- a/routers/api/v1/admin/repo.go +++ b/routers/api/v1/admin/repo.go @@ -4,10 +4,10 @@ package admin import ( - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/repo" + "code.gitea.io/gitea/services/context" ) // CreateRepo api for creating a repository diff --git a/routers/api/v1/admin/runners.go b/routers/api/v1/admin/runners.go index c0d93644350..329242d9f6e 100644 --- a/routers/api/v1/admin/runners.go +++ b/routers/api/v1/admin/runners.go @@ -4,8 +4,8 @@ package admin import ( - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/routers/api/v1/shared" + "code.gitea.io/gitea/services/context" ) // https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-a-registration-token-for-an-organization diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index 2ce7651a096..64315108b08 100644 --- a/routers/api/v1/admin/user.go +++ b/routers/api/v1/admin/user.go @@ -15,7 +15,6 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/auth/password" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" @@ -25,6 +24,7 @@ import ( "code.gitea.io/gitea/routers/api/v1/user" "code.gitea.io/gitea/routers/api/v1/utils" asymkey_service "code.gitea.io/gitea/services/asymkey" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/mailer" user_service "code.gitea.io/gitea/services/user" diff --git a/routers/api/v1/admin/user_badge.go b/routers/api/v1/admin/user_badge.go new file mode 100644 index 00000000000..bacd1f809bf --- /dev/null +++ b/routers/api/v1/admin/user_badge.go @@ -0,0 +1,124 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package admin + +import ( + "net/http" + + user_model "code.gitea.io/gitea/models/user" + api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" +) + +// ListUserBadges lists all badges belonging to a user +func ListUserBadges(ctx *context.APIContext) { + // swagger:operation GET /admin/users/{username}/badges admin adminListUserBadges + // --- + // summary: List a user's badges + // produces: + // - application/json + // parameters: + // - name: username + // in: path + // description: username of user + // type: string + // required: true + // responses: + // "200": + // "$ref": "#/responses/BadgeList" + // "404": + // "$ref": "#/responses/notFound" + + badges, maxResults, err := user_model.GetUserBadges(ctx, ctx.ContextUser) + if err != nil { + ctx.Error(http.StatusInternalServerError, "GetUserBadges", err) + return + } + + ctx.SetTotalCountHeader(maxResults) + ctx.JSON(http.StatusOK, &badges) +} + +// AddUserBadges add badges to a user +func AddUserBadges(ctx *context.APIContext) { + // swagger:operation POST /admin/users/{username}/badges admin adminAddUserBadges + // --- + // summary: Add a badge to a user + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: username + // in: path + // description: username of user + // type: string + // required: true + // - name: body + // in: body + // schema: + // "$ref": "#/definitions/UserBadgeOption" + // responses: + // "204": + // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" + + form := web.GetForm(ctx).(*api.UserBadgeOption) + badges := prepareBadgesForReplaceOrAdd(ctx, *form) + + if err := user_model.AddUserBadges(ctx, ctx.ContextUser, badges); err != nil { + ctx.Error(http.StatusInternalServerError, "ReplaceUserBadges", err) + return + } + + ctx.Status(http.StatusNoContent) +} + +// DeleteUserBadges delete a badge from a user +func DeleteUserBadges(ctx *context.APIContext) { + // swagger:operation DELETE /admin/users/{username}/badges admin adminDeleteUserBadges + // --- + // summary: Remove a badge from a user + // produces: + // - application/json + // parameters: + // - name: username + // in: path + // description: username of user + // type: string + // required: true + // - name: body + // in: body + // schema: + // "$ref": "#/definitions/UserBadgeOption" + // responses: + // "204": + // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" + // "422": + // "$ref": "#/responses/validationError" + + form := web.GetForm(ctx).(*api.UserBadgeOption) + badges := prepareBadgesForReplaceOrAdd(ctx, *form) + + if err := user_model.RemoveUserBadges(ctx, ctx.ContextUser, badges); err != nil { + ctx.Error(http.StatusInternalServerError, "ReplaceUserBadges", err) + return + } + + ctx.Status(http.StatusNoContent) +} + +func prepareBadgesForReplaceOrAdd(ctx *context.APIContext, form api.UserBadgeOption) []*user_model.Badge { + badges := make([]*user_model.Badge, len(form.BadgeSlugs)) + for i, badge := range form.BadgeSlugs { + badges[i] = &user_model.Badge{ + Slug: badge, + } + } + return badges +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index e0c72c7ac40..1587d413f55 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -79,7 +79,6 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" @@ -95,7 +94,7 @@ import ( "code.gitea.io/gitea/routers/api/v1/user" "code.gitea.io/gitea/routers/common" "code.gitea.io/gitea/services/auth" - context_service "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" _ "code.gitea.io/gitea/routers/api/v1/swagger" // for swagger generation @@ -855,11 +854,11 @@ func Routes() *web.Route { m.Group("/user/{username}", func() { m.Get("", activitypub.Person) m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.PersonInbox) - }, context_service.UserAssignmentAPI()) + }, context.UserAssignmentAPI()) m.Group("/user-id/{user-id}", func() { m.Get("", activitypub.Person) m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.PersonInbox) - }, context_service.UserIDAssignmentAPI()) + }, context.UserIDAssignmentAPI()) }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryActivityPub)) } @@ -915,7 +914,7 @@ func Routes() *web.Route { }, reqSelfOrAdmin(), reqBasicOrRevProxyAuth()) m.Get("/activities/feeds", user.ListUserActivityFeeds) - }, context_service.UserAssignmentAPI(), individualPermsChecker) + }, context.UserAssignmentAPI(), individualPermsChecker) }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser)) // Users (requires user scope) @@ -933,7 +932,7 @@ func Routes() *web.Route { m.Get("/starred", user.GetStarredRepos) m.Get("/subscriptions", user.GetWatchedRepos) - }, context_service.UserAssignmentAPI()) + }, context.UserAssignmentAPI()) }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser), reqToken()) // Users (requires user scope) @@ -968,7 +967,7 @@ func Routes() *web.Route { m.Get("", user.CheckMyFollowing) m.Put("", user.Follow) m.Delete("", user.Unfollow) - }, context_service.UserAssignmentAPI()) + }, context.UserAssignmentAPI()) }) // (admin:public_key scope) @@ -1415,14 +1414,14 @@ func Routes() *web.Route { m.Get("/files", reqToken(), packages.ListPackageFiles) }) m.Get("/", reqToken(), packages.ListPackages) - }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryPackage), context_service.UserAssignmentAPI(), context.PackageAssignmentAPI(), reqPackageAccess(perm.AccessModeRead)) + }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryPackage), context.UserAssignmentAPI(), context.PackageAssignmentAPI(), reqPackageAccess(perm.AccessModeRead)) // Organizations m.Get("/user/orgs", reqToken(), tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser, auth_model.AccessTokenScopeCategoryOrganization), org.ListMyOrgs) m.Group("/users/{username}/orgs", func() { m.Get("", reqToken(), org.ListUserOrgs) m.Get("/{org}/permissions", reqToken(), org.GetUserOrgsPermissions) - }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser, auth_model.AccessTokenScopeCategoryOrganization), context_service.UserAssignmentAPI()) + }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser, auth_model.AccessTokenScopeCategoryOrganization), context.UserAssignmentAPI()) m.Post("/orgs", tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), reqToken(), bind(api.CreateOrgOption{}), org.Create) m.Get("/orgs", org.GetAll, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization)) m.Group("/orgs/{org}", func() { @@ -1520,7 +1519,10 @@ func Routes() *web.Route { m.Post("/orgs", bind(api.CreateOrgOption{}), admin.CreateOrg) m.Post("/repos", bind(api.CreateRepoOption{}), admin.CreateRepo) m.Post("/rename", bind(api.RenameUserOption{}), admin.RenameUser) - }, context_service.UserAssignmentAPI()) + m.Get("/badges", admin.ListUserBadges) + m.Post("/badges", bind(api.UserBadgeOption{}), admin.AddUserBadges) + m.Delete("/badges", bind(api.UserBadgeOption{}), admin.DeleteUserBadges) + }, context.UserAssignmentAPI()) }) m.Group("/emails", func() { m.Get("", admin.GetAllEmails) diff --git a/routers/api/v1/misc/gitignore.go b/routers/api/v1/misc/gitignore.go index 7c7fe4b125f..dffd771752e 100644 --- a/routers/api/v1/misc/gitignore.go +++ b/routers/api/v1/misc/gitignore.go @@ -6,11 +6,11 @@ package misc import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/options" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" ) // Shows a list of all Gitignore templates diff --git a/routers/api/v1/misc/label_templates.go b/routers/api/v1/misc/label_templates.go index 0e0ca39fc5d..cc11f376262 100644 --- a/routers/api/v1/misc/label_templates.go +++ b/routers/api/v1/misc/label_templates.go @@ -6,9 +6,9 @@ package misc import ( "net/http" - "code.gitea.io/gitea/modules/context" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/misc/licenses.go b/routers/api/v1/misc/licenses.go index 65f63468cfd..2a980f5084d 100644 --- a/routers/api/v1/misc/licenses.go +++ b/routers/api/v1/misc/licenses.go @@ -8,12 +8,12 @@ import ( "net/http" "net/url" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/options" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" ) // Returns a list of all License templates diff --git a/routers/api/v1/misc/markup.go b/routers/api/v1/misc/markup.go index 7b24b353b63..9699c79368a 100644 --- a/routers/api/v1/misc/markup.go +++ b/routers/api/v1/misc/markup.go @@ -6,12 +6,12 @@ package misc import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/common" + "code.gitea.io/gitea/services/context" ) // Markup render markup document to HTML diff --git a/routers/api/v1/misc/markup_test.go b/routers/api/v1/misc/markup_test.go index ec8f8f47b70..5236fd06ae2 100644 --- a/routers/api/v1/misc/markup_test.go +++ b/routers/api/v1/misc/markup_test.go @@ -10,19 +10,19 @@ import ( "strings" "testing" - "code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/contexttest" "github.com/stretchr/testify/assert" ) const ( - AppURL = "http://localhost:3000/" - Repo = "gogits/gogs" - AppSubURL = AppURL + Repo + "/" + AppURL = "http://localhost:3000/" + Repo = "gogits/gogs" + FullURL = AppURL + Repo + "/" ) func testRenderMarkup(t *testing.T, mode, filePath, text, responseBody string, responseCode int) { @@ -74,20 +74,20 @@ func TestAPI_RenderGFM(t *testing.T) { // rendered `

Wiki! Enjoy :)

`, // Guard wiki sidebar: special syntax `[[Guardfile-DSL / Configuring-Guard|Guardfile-DSL---Configuring-Guard]]`, // rendered - `

Guardfile-DSL / Configuring-Guard

+ `

Guardfile-DSL / Configuring-Guard

`, // special syntax `[[Name|Link]]`, // rendered - `

Name

+ `

Name

`, // empty ``, @@ -111,8 +111,8 @@ Here are some links to the most important topics. You can find the full list of

Wine Staging on website wine-staging.com.

Here are some links to the most important topics. You can find the full list of pages at the sidebar.

-

Configuration -images/icon-bug.png

+

Configuration +images/icon-bug.png

`, } diff --git a/routers/api/v1/misc/nodeinfo.go b/routers/api/v1/misc/nodeinfo.go index cc754f64a21..3bd80de5c18 100644 --- a/routers/api/v1/misc/nodeinfo.go +++ b/routers/api/v1/misc/nodeinfo.go @@ -9,9 +9,9 @@ import ( issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/context" ) const cacheKeyNodeInfoUsage = "API_NodeInfoUsage" diff --git a/routers/api/v1/misc/signing.go b/routers/api/v1/misc/signing.go index 2ca9813e15c..24a46c1e704 100644 --- a/routers/api/v1/misc/signing.go +++ b/routers/api/v1/misc/signing.go @@ -7,8 +7,8 @@ import ( "fmt" "net/http" - "code.gitea.io/gitea/modules/context" asymkey_service "code.gitea.io/gitea/services/asymkey" + "code.gitea.io/gitea/services/context" ) // SigningKey returns the public key of the default signing key if it exists diff --git a/routers/api/v1/misc/version.go b/routers/api/v1/misc/version.go index 83fa35219ab..e3b43a0e6b6 100644 --- a/routers/api/v1/misc/version.go +++ b/routers/api/v1/misc/version.go @@ -6,9 +6,9 @@ package misc import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/context" ) // Version shows the version of the Gitea server diff --git a/routers/api/v1/notify/notifications.go b/routers/api/v1/notify/notifications.go index c87da9399f0..46b3c7f5e75 100644 --- a/routers/api/v1/notify/notifications.go +++ b/routers/api/v1/notify/notifications.go @@ -9,9 +9,9 @@ import ( activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" ) // NewAvailable check if unread notifications exist diff --git a/routers/api/v1/notify/repo.go b/routers/api/v1/notify/repo.go index 55ca6ad1fd5..8d97e8a3f84 100644 --- a/routers/api/v1/notify/repo.go +++ b/routers/api/v1/notify/repo.go @@ -10,9 +10,9 @@ import ( activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/notify/threads.go b/routers/api/v1/notify/threads.go index 919e52952dc..8e12d359cb3 100644 --- a/routers/api/v1/notify/threads.go +++ b/routers/api/v1/notify/threads.go @@ -10,7 +10,7 @@ import ( activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/notify/user.go b/routers/api/v1/notify/user.go index 4abdfb2e925..879f484ccee 100644 --- a/routers/api/v1/notify/user.go +++ b/routers/api/v1/notify/user.go @@ -9,8 +9,8 @@ import ( activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/org/avatar.go b/routers/api/v1/org/avatar.go index 7b621a50c31..e34c68dfc9d 100644 --- a/routers/api/v1/org/avatar.go +++ b/routers/api/v1/org/avatar.go @@ -7,9 +7,9 @@ import ( "encoding/base64" "net/http" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" user_service "code.gitea.io/gitea/services/user" ) diff --git a/routers/api/v1/org/hook.go b/routers/api/v1/org/hook.go index 3c3f058b5dd..c1dc0519ea1 100644 --- a/routers/api/v1/org/hook.go +++ b/routers/api/v1/org/hook.go @@ -6,10 +6,10 @@ package org import ( "net/http" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" webhook_service "code.gitea.io/gitea/services/webhook" ) diff --git a/routers/api/v1/org/label.go b/routers/api/v1/org/label.go index 5a03059deda..b5ec54ccf4e 100644 --- a/routers/api/v1/org/label.go +++ b/routers/api/v1/org/label.go @@ -9,11 +9,11 @@ import ( "strings" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/label" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/org/member.go b/routers/api/v1/org/member.go index 422b7cecfee..fb66d4c3f5b 100644 --- a/routers/api/v1/org/member.go +++ b/routers/api/v1/org/member.go @@ -9,11 +9,11 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/organization" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/user" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go index 255e28c7064..e848d951810 100644 --- a/routers/api/v1/org/org.go +++ b/routers/api/v1/org/org.go @@ -12,12 +12,12 @@ import ( "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/optional" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/user" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/org" user_service "code.gitea.io/gitea/services/user" diff --git a/routers/api/v1/org/runners.go b/routers/api/v1/org/runners.go index 05bce8daefb..2a52bd8778f 100644 --- a/routers/api/v1/org/runners.go +++ b/routers/api/v1/org/runners.go @@ -4,8 +4,8 @@ package org import ( - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/routers/api/v1/shared" + "code.gitea.io/gitea/services/context" ) // https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-a-registration-token-for-an-organization diff --git a/routers/api/v1/org/secrets.go b/routers/api/v1/org/secrets.go index ddc74d865b1..abb6bb26c43 100644 --- a/routers/api/v1/org/secrets.go +++ b/routers/api/v1/org/secrets.go @@ -9,11 +9,11 @@ import ( "code.gitea.io/gitea/models/db" secret_model "code.gitea.io/gitea/models/secret" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" secret_service "code.gitea.io/gitea/services/secrets" ) diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go index f129c662306..b62a386fd77 100644 --- a/routers/api/v1/org/team.go +++ b/routers/api/v1/org/team.go @@ -15,12 +15,12 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" unit_model "code.gitea.io/gitea/models/unit" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/user" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" org_service "code.gitea.io/gitea/services/org" repo_service "code.gitea.io/gitea/services/repository" diff --git a/routers/api/v1/packages/package.go b/routers/api/v1/packages/package.go index a79ba315be2..3be31b13ae1 100644 --- a/routers/api/v1/packages/package.go +++ b/routers/api/v1/packages/package.go @@ -7,10 +7,10 @@ import ( "net/http" "code.gitea.io/gitea/models/packages" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" packages_service "code.gitea.io/gitea/services/packages" ) diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go index 039cdadac9c..e0af276c715 100644 --- a/routers/api/v1/repo/action.go +++ b/routers/api/v1/repo/action.go @@ -7,10 +7,10 @@ import ( "errors" "net/http" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" secret_service "code.gitea.io/gitea/services/secrets" ) diff --git a/routers/api/v1/repo/avatar.go b/routers/api/v1/repo/avatar.go index 1b661955f05..698337ffd2f 100644 --- a/routers/api/v1/repo/avatar.go +++ b/routers/api/v1/repo/avatar.go @@ -7,9 +7,9 @@ import ( "encoding/base64" "net/http" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" repo_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/api/v1/repo/blob.go b/routers/api/v1/repo/blob.go index 26605bba03c..3b116666ead 100644 --- a/routers/api/v1/repo/blob.go +++ b/routers/api/v1/repo/blob.go @@ -6,7 +6,7 @@ package repo import ( "net/http" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" files_service "code.gitea.io/gitea/services/repository/files" ) diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 2cdbcd25a2e..5e6b6a86586 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -14,7 +14,6 @@ import ( git_model "code.gitea.io/gitea/models/git" "code.gitea.io/gitea/models/organization" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/optional" @@ -22,6 +21,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" pull_service "code.gitea.io/gitea/services/pull" repo_service "code.gitea.io/gitea/services/repository" diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go index a222e50a5e5..7d48d715169 100644 --- a/routers/api/v1/repo/collaborators.go +++ b/routers/api/v1/repo/collaborators.go @@ -13,11 +13,11 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" repo_module "code.gitea.io/gitea/modules/repository" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" repo_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index d01cf6b8bcd..d06a3b4e49a 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -12,11 +12,11 @@ import ( issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 317213c9466..4895f7b1b3f 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -19,7 +19,6 @@ import ( git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/httpcache" @@ -30,6 +29,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/common" + "code.gitea.io/gitea/services/context" archiver_service "code.gitea.io/gitea/services/repository/archiver" files_service "code.gitea.io/gitea/services/repository/files" ) @@ -655,6 +655,7 @@ func UpdateFile(ctx *context.APIContext) { apiOpts := web.GetForm(ctx).(*api.UpdateFileOptions) if ctx.Repo.Repository.IsEmpty { ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty")) + return } if apiOpts.BranchName == "" { diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go index 69433bf4cc4..212cc7a93b5 100644 --- a/routers/api/v1/repo/fork.go +++ b/routers/api/v1/repo/fork.go @@ -14,11 +14,11 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" repo_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/api/v1/repo/git_hook.go b/routers/api/v1/repo/git_hook.go index 7e471e263b6..26ae84d08d3 100644 --- a/routers/api/v1/repo/git_hook.go +++ b/routers/api/v1/repo/git_hook.go @@ -6,10 +6,10 @@ package repo import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/git_ref.go b/routers/api/v1/repo/git_ref.go index 34d2dcfcc81..0fa58425b85 100644 --- a/routers/api/v1/repo/git_ref.go +++ b/routers/api/v1/repo/git_ref.go @@ -7,10 +7,10 @@ import ( "net/http" "net/url" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" ) // GetGitAllRefs get ref or an list all the refs of a repository diff --git a/routers/api/v1/repo/hook.go b/routers/api/v1/repo/hook.go index 8859e3ae236..ffd2313591b 100644 --- a/routers/api/v1/repo/hook.go +++ b/routers/api/v1/repo/hook.go @@ -11,13 +11,13 @@ import ( "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" "code.gitea.io/gitea/models/webhook" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" webhook_module "code.gitea.io/gitea/modules/webhook" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" webhook_service "code.gitea.io/gitea/services/webhook" ) diff --git a/routers/api/v1/repo/hook_test.go b/routers/api/v1/repo/hook_test.go index 94a71e20ad7..37cf61c1edf 100644 --- a/routers/api/v1/repo/hook_test.go +++ b/routers/api/v1/repo/hook_test.go @@ -9,7 +9,7 @@ import ( "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/webhook" - "code.gitea.io/gitea/modules/contexttest" + "code.gitea.io/gitea/services/contexttest" "github.com/stretchr/testify/assert" ) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 0f76a4b4ff2..227e0e725cf 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -18,14 +18,15 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" issue_indexer "code.gitea.io/gitea/modules/indexer/issues" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" issue_service "code.gitea.io/gitea/services/issue" notify_service "code.gitea.io/gitea/services/notify" @@ -142,7 +143,7 @@ func SearchIssues(ctx *context.APIContext) { Private: false, AllPublic: true, TopicOnly: false, - Collaborate: util.OptionalBoolNone, + Collaborate: optional.None[bool](), // This needs to be a column that is not nil in fixtures or // MySQL will return different results when sorting by null in some cases OrderBy: db.SearchOrderByAlphabetically, @@ -165,7 +166,7 @@ func SearchIssues(ctx *context.APIContext) { opts.OwnerID = owner.ID opts.AllLimited = false opts.AllPublic = false - opts.Collaborate = util.OptionalBoolFalse + opts.Collaborate = optional.Some(false) } if ctx.FormString("team") != "" { if ctx.FormString("owner") == "" { diff --git a/routers/api/v1/repo/issue_attachment.go b/routers/api/v1/repo/issue_attachment.go index 11d19b21ff5..d62e23aa022 100644 --- a/routers/api/v1/repo/issue_attachment.go +++ b/routers/api/v1/repo/issue_attachment.go @@ -8,12 +8,12 @@ import ( issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/attachment" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" issue_service "code.gitea.io/gitea/services/issue" ) diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 2b7a8f7ba1c..763419b7a25 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -14,11 +14,11 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" issue_service "code.gitea.io/gitea/services/issue" ) diff --git a/routers/api/v1/repo/issue_comment_attachment.go b/routers/api/v1/repo/issue_comment_attachment.go index 21e2f4dabd6..e7436db7982 100644 --- a/routers/api/v1/repo/issue_comment_attachment.go +++ b/routers/api/v1/repo/issue_comment_attachment.go @@ -8,12 +8,12 @@ import ( issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/attachment" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" issue_service "code.gitea.io/gitea/services/issue" ) diff --git a/routers/api/v1/repo/issue_dependency.go b/routers/api/v1/repo/issue_dependency.go index 62d1057cdf9..a42920d4fd3 100644 --- a/routers/api/v1/repo/issue_dependency.go +++ b/routers/api/v1/repo/issue_dependency.go @@ -11,10 +11,10 @@ import ( issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go index c2f530956e9..7d9f85d2aa2 100644 --- a/routers/api/v1/repo/issue_label.go +++ b/routers/api/v1/repo/issue_label.go @@ -8,9 +8,9 @@ import ( "net/http" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" issue_service "code.gitea.io/gitea/services/issue" ) diff --git a/routers/api/v1/repo/issue_pin.go b/routers/api/v1/repo/issue_pin.go index 61f88de34eb..ff1135862b3 100644 --- a/routers/api/v1/repo/issue_pin.go +++ b/routers/api/v1/repo/issue_pin.go @@ -7,8 +7,8 @@ import ( "net/http" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/issue_reaction.go b/routers/api/v1/repo/issue_reaction.go index c886bd71b76..799c6878126 100644 --- a/routers/api/v1/repo/issue_reaction.go +++ b/routers/api/v1/repo/issue_reaction.go @@ -8,10 +8,10 @@ import ( "net/http" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/issue_stopwatch.go b/routers/api/v1/repo/issue_stopwatch.go index 52bf8b5c7b8..d9054e8f775 100644 --- a/routers/api/v1/repo/issue_stopwatch.go +++ b/routers/api/v1/repo/issue_stopwatch.go @@ -8,8 +8,8 @@ import ( "net/http" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go index ece880c03e1..a535172462e 100644 --- a/routers/api/v1/repo/issue_subscription.go +++ b/routers/api/v1/repo/issue_subscription.go @@ -9,9 +9,9 @@ import ( issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/issue_tracked_time.go b/routers/api/v1/repo/issue_tracked_time.go index cf03e72aa0c..c6405158819 100644 --- a/routers/api/v1/repo/issue_tracked_time.go +++ b/routers/api/v1/repo/issue_tracked_time.go @@ -12,10 +12,10 @@ import ( issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/key.go b/routers/api/v1/repo/key.go index af48c40885d..88444a26250 100644 --- a/routers/api/v1/repo/key.go +++ b/routers/api/v1/repo/key.go @@ -15,12 +15,12 @@ import ( "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" asymkey_service "code.gitea.io/gitea/services/asymkey" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go index 420d3ab5b49..b6eb51fd20a 100644 --- a/routers/api/v1/repo/label.go +++ b/routers/api/v1/repo/label.go @@ -9,11 +9,11 @@ import ( "strconv" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/label" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/language.go b/routers/api/v1/repo/language.go index 12f1761ad08..f1d5bbe45fe 100644 --- a/routers/api/v1/repo/language.go +++ b/routers/api/v1/repo/language.go @@ -9,8 +9,8 @@ import ( "strconv" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/services/context" ) type languageResponse []*repo_model.LanguageStat diff --git a/routers/api/v1/repo/migrate.go b/routers/api/v1/repo/migrate.go index 839fbfe8a1a..2caaa130e8d 100644 --- a/routers/api/v1/repo/migrate.go +++ b/routers/api/v1/repo/migrate.go @@ -17,7 +17,6 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" @@ -26,6 +25,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/migrations" diff --git a/routers/api/v1/repo/milestone.go b/routers/api/v1/repo/milestone.go index 9c2ed16d930..d4c828fe8bf 100644 --- a/routers/api/v1/repo/milestone.go +++ b/routers/api/v1/repo/milestone.go @@ -11,12 +11,12 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/mirror.go b/routers/api/v1/repo/mirror.go index 26e0be301c1..864644e1efc 100644 --- a/routers/api/v1/repo/mirror.go +++ b/routers/api/v1/repo/mirror.go @@ -13,12 +13,12 @@ import ( "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/migrations" diff --git a/routers/api/v1/repo/notes.go b/routers/api/v1/repo/notes.go index e7e00dae418..a4a1d4eab7c 100644 --- a/routers/api/v1/repo/notes.go +++ b/routers/api/v1/repo/notes.go @@ -7,9 +7,9 @@ import ( "fmt" "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/patch.go b/routers/api/v1/repo/patch.go index 9b5635d245a..0e0601b7d93 100644 --- a/routers/api/v1/repo/patch.go +++ b/routers/api/v1/repo/patch.go @@ -10,10 +10,10 @@ import ( "code.gitea.io/gitea/models" git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/repository/files" ) diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 85f8ec1de56..8f9848f71d1 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -21,7 +21,6 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" @@ -32,6 +31,7 @@ import ( "code.gitea.io/gitea/routers/api/v1/utils" asymkey_service "code.gitea.io/gitea/services/asymkey" "code.gitea.io/gitea/services/automerge" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/gitdiff" diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go index 6338651aae9..5128102e61b 100644 --- a/routers/api/v1/repo/pull_review.go +++ b/routers/api/v1/repo/pull_review.go @@ -12,11 +12,11 @@ import ( "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/gitrepo" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" issue_service "code.gitea.io/gitea/services/issue" pull_service "code.gitea.io/gitea/services/pull" diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index a41c5ba7d85..a47fc1cc598 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -11,10 +11,10 @@ import ( "code.gitea.io/gitea/models/perm" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" release_service "code.gitea.io/gitea/services/release" ) diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go index c36bf12e6d3..a29bce66a4e 100644 --- a/routers/api/v1/repo/release_attachment.go +++ b/routers/api/v1/repo/release_attachment.go @@ -7,13 +7,13 @@ import ( "net/http" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" - "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/attachment" + "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context/upload" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/release_tags.go b/routers/api/v1/repo/release_tags.go index 9f2098df066..fec91164a29 100644 --- a/routers/api/v1/repo/release_tags.go +++ b/routers/api/v1/repo/release_tags.go @@ -8,7 +8,7 @@ import ( "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" releaseservice "code.gitea.io/gitea/services/release" ) diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 40de8853d83..6fde73a4e8f 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -20,18 +20,18 @@ import ( repo_model "code.gitea.io/gitea/models/repo" unit_model "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/label" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/optional" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" - "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/issue" repo_service "code.gitea.io/gitea/services/repository" @@ -135,33 +135,33 @@ func Search(ctx *context.APIContext) { PriorityOwnerID: ctx.FormInt64("priority_owner_id"), TeamID: ctx.FormInt64("team_id"), TopicOnly: ctx.FormBool("topic"), - Collaborate: util.OptionalBoolNone, + Collaborate: optional.None[bool](), Private: ctx.IsSigned && (ctx.FormString("private") == "" || ctx.FormBool("private")), - Template: util.OptionalBoolNone, + Template: optional.None[bool](), StarredByID: ctx.FormInt64("starredBy"), IncludeDescription: ctx.FormBool("includeDesc"), } if ctx.FormString("template") != "" { - opts.Template = util.OptionalBoolOf(ctx.FormBool("template")) + opts.Template = optional.Some(ctx.FormBool("template")) } if ctx.FormBool("exclusive") { - opts.Collaborate = util.OptionalBoolFalse + opts.Collaborate = optional.Some(false) } mode := ctx.FormString("mode") switch mode { case "source": - opts.Fork = util.OptionalBoolFalse - opts.Mirror = util.OptionalBoolFalse + opts.Fork = optional.Some(false) + opts.Mirror = optional.Some(false) case "fork": - opts.Fork = util.OptionalBoolTrue + opts.Fork = optional.Some(true) case "mirror": - opts.Mirror = util.OptionalBoolTrue + opts.Mirror = optional.Some(true) case "collaborative": - opts.Mirror = util.OptionalBoolFalse - opts.Collaborate = util.OptionalBoolTrue + opts.Mirror = optional.Some(false) + opts.Collaborate = optional.Some(true) case "": default: ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("Invalid search mode: \"%s\"", mode)) @@ -169,11 +169,11 @@ func Search(ctx *context.APIContext) { } if ctx.FormString("archived") != "" { - opts.Archived = util.OptionalBoolOf(ctx.FormBool("archived")) + opts.Archived = optional.Some(ctx.FormBool("archived")) } if ctx.FormString("is_private") != "" { - opts.IsPrivate = util.OptionalBoolOf(ctx.FormBool("is_private")) + opts.IsPrivate = optional.Some(ctx.FormBool("is_private")) } sortMode := ctx.FormString("sort") @@ -358,7 +358,7 @@ func Generate(ctx *context.APIContext) { return } - opts := repo_module.GenerateRepoOptions{ + opts := repo_service.GenerateRepoOptions{ Name: form.Name, DefaultBranch: form.DefaultBranch, Description: form.Description, diff --git a/routers/api/v1/repo/repo_test.go b/routers/api/v1/repo/repo_test.go index 08ba7fabac4..8d6ca9e3b54 100644 --- a/routers/api/v1/repo/repo_test.go +++ b/routers/api/v1/repo/repo_test.go @@ -9,9 +9,9 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/contexttest" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/contexttest" "github.com/stretchr/testify/assert" ) diff --git a/routers/api/v1/repo/runners.go b/routers/api/v1/repo/runners.go index 0a2bbf81176..fe133b311d5 100644 --- a/routers/api/v1/repo/runners.go +++ b/routers/api/v1/repo/runners.go @@ -4,8 +4,8 @@ package repo import ( - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/routers/api/v1/shared" + "code.gitea.io/gitea/services/context" ) // GetRegistrationToken returns the token to register repo runners diff --git a/routers/api/v1/repo/star.go b/routers/api/v1/repo/star.go index 05227e33a0c..99676de119c 100644 --- a/routers/api/v1/repo/star.go +++ b/routers/api/v1/repo/star.go @@ -7,9 +7,9 @@ import ( "net/http" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go index b4edf0608cf..53711bedebf 100644 --- a/routers/api/v1/repo/status.go +++ b/routers/api/v1/repo/status.go @@ -9,10 +9,10 @@ import ( "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" files_service "code.gitea.io/gitea/services/repository/files" ) diff --git a/routers/api/v1/repo/subscriber.go b/routers/api/v1/repo/subscriber.go index 05509fc4435..85841828578 100644 --- a/routers/api/v1/repo/subscriber.go +++ b/routers/api/v1/repo/subscriber.go @@ -7,9 +7,9 @@ import ( "net/http" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go index 2f19f95e66d..a6908f36157 100644 --- a/routers/api/v1/repo/tag.go +++ b/routers/api/v1/repo/tag.go @@ -10,10 +10,10 @@ import ( "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" releaseservice "code.gitea.io/gitea/services/release" ) diff --git a/routers/api/v1/repo/teams.go b/routers/api/v1/repo/teams.go index 1bacc712118..0ecf3a39d8f 100644 --- a/routers/api/v1/repo/teams.go +++ b/routers/api/v1/repo/teams.go @@ -8,7 +8,7 @@ import ( "net/http" "code.gitea.io/gitea/models/organization" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" org_service "code.gitea.io/gitea/services/org" repo_service "code.gitea.io/gitea/services/repository" diff --git a/routers/api/v1/repo/topic.go b/routers/api/v1/repo/topic.go index d662b9b5832..1d8e675bde0 100644 --- a/routers/api/v1/repo/topic.go +++ b/routers/api/v1/repo/topic.go @@ -8,11 +8,11 @@ import ( "strings" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/repo/transfer.go b/routers/api/v1/repo/transfer.go index c0a40ce0620..4f05c0df518 100644 --- a/routers/api/v1/repo/transfer.go +++ b/routers/api/v1/repo/transfer.go @@ -13,10 +13,10 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" repo_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/api/v1/repo/tree.go b/routers/api/v1/repo/tree.go index f63100b6ea2..353a996d5b0 100644 --- a/routers/api/v1/repo/tree.go +++ b/routers/api/v1/repo/tree.go @@ -6,7 +6,7 @@ package repo import ( "net/http" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" files_service "code.gitea.io/gitea/services/repository/files" ) diff --git a/routers/api/v1/repo/wiki.go b/routers/api/v1/repo/wiki.go index 4f27500496c..f18ea087c4d 100644 --- a/routers/api/v1/repo/wiki.go +++ b/routers/api/v1/repo/wiki.go @@ -10,13 +10,13 @@ import ( "net/url" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" notify_service "code.gitea.io/gitea/services/notify" wiki_service "code.gitea.io/gitea/services/wiki" diff --git a/routers/api/v1/settings/settings.go b/routers/api/v1/settings/settings.go index 02bda1309d7..0ee81b96d5b 100644 --- a/routers/api/v1/settings/settings.go +++ b/routers/api/v1/settings/settings.go @@ -6,9 +6,9 @@ package settings import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/context" ) // GetGeneralUISettings returns instance's global settings for ui diff --git a/routers/api/v1/shared/runners.go b/routers/api/v1/shared/runners.go index a342bd4b637..c850ad7866a 100644 --- a/routers/api/v1/shared/runners.go +++ b/routers/api/v1/shared/runners.go @@ -8,8 +8,8 @@ import ( "net/http" actions_model "code.gitea.io/gitea/models/actions" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" ) // RegistrationToken is response related to registeration token diff --git a/routers/api/v1/swagger/options.go b/routers/api/v1/swagger/options.go index 6f7859df62e..e03862d7b9a 100644 --- a/routers/api/v1/swagger/options.go +++ b/routers/api/v1/swagger/options.go @@ -190,4 +190,10 @@ type swaggerParameterBodies struct { // in:body CreateOrUpdateSecretOption api.CreateOrUpdateSecretOption + + // in:body + UserBadgeOption api.UserBadgeOption + + // in:body + UserBadgeList api.BadgeList } diff --git a/routers/api/v1/user/action.go b/routers/api/v1/user/action.go index cbe332a7798..babb8c0cf7a 100644 --- a/routers/api/v1/user/action.go +++ b/routers/api/v1/user/action.go @@ -7,10 +7,10 @@ import ( "errors" "net/http" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" secret_service "code.gitea.io/gitea/services/secrets" ) diff --git a/routers/api/v1/user/app.go b/routers/api/v1/user/app.go index f045fb4d5d8..88e314ed31b 100644 --- a/routers/api/v1/user/app.go +++ b/routers/api/v1/user/app.go @@ -13,10 +13,10 @@ import ( auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/user/avatar.go b/routers/api/v1/user/avatar.go index 1c1bb6181aa..f912296228e 100644 --- a/routers/api/v1/user/avatar.go +++ b/routers/api/v1/user/avatar.go @@ -7,9 +7,9 @@ import ( "encoding/base64" "net/http" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" user_service "code.gitea.io/gitea/services/user" ) diff --git a/routers/api/v1/user/email.go b/routers/api/v1/user/email.go index 3dcea9083cd..33aa851a807 100644 --- a/routers/api/v1/user/email.go +++ b/routers/api/v1/user/email.go @@ -8,9 +8,9 @@ import ( "net/http" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" user_service "code.gitea.io/gitea/services/user" ) diff --git a/routers/api/v1/user/follower.go b/routers/api/v1/user/follower.go index 5815ed4f0b4..398c6b25673 100644 --- a/routers/api/v1/user/follower.go +++ b/routers/api/v1/user/follower.go @@ -8,9 +8,9 @@ import ( "net/http" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/user/gpg_key.go b/routers/api/v1/user/gpg_key.go index 234da5dfdc4..dcf5da0b2e6 100644 --- a/routers/api/v1/user/gpg_key.go +++ b/routers/api/v1/user/gpg_key.go @@ -10,10 +10,11 @@ import ( asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) @@ -132,6 +133,11 @@ func GetGPGKey(ctx *context.APIContext) { // CreateUserGPGKey creates new GPG key to given user by ID. func CreateUserGPGKey(ctx *context.APIContext, form api.CreateGPGKeyOption, uid int64) { + if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageGPGKeys) { + ctx.NotFound("Not Found", fmt.Errorf("gpg keys setting is not allowed to be visited")) + return + } + token := asymkey_model.VerificationToken(ctx.Doer, 1) lastToken := asymkey_model.VerificationToken(ctx.Doer, 0) @@ -268,6 +274,11 @@ func DeleteGPGKey(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" + if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageGPGKeys) { + ctx.NotFound("Not Found", fmt.Errorf("gpg keys setting is not allowed to be visited")) + return + } + if err := asymkey_model.DeleteGPGKey(ctx, ctx.Doer, ctx.ParamsInt64(":id")); err != nil { if asymkey_model.IsErrGPGKeyAccessDenied(err) { ctx.Error(http.StatusForbidden, "", "You do not have access to this key") diff --git a/routers/api/v1/user/helper.go b/routers/api/v1/user/helper.go index 392b266ebd8..8b5c64e2919 100644 --- a/routers/api/v1/user/helper.go +++ b/routers/api/v1/user/helper.go @@ -7,7 +7,7 @@ import ( "net/http" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" ) // GetUserByParamsName get user by name diff --git a/routers/api/v1/user/hook.go b/routers/api/v1/user/hook.go index e87385e4a26..9d9ca5bf010 100644 --- a/routers/api/v1/user/hook.go +++ b/routers/api/v1/user/hook.go @@ -6,10 +6,10 @@ package user import ( "net/http" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" webhook_service "code.gitea.io/gitea/services/webhook" ) diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go index dd185aa7d62..ada6759f8e6 100644 --- a/routers/api/v1/user/key.go +++ b/routers/api/v1/user/key.go @@ -11,13 +11,13 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/repo" "code.gitea.io/gitea/routers/api/v1/utils" asymkey_service "code.gitea.io/gitea/services/asymkey" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go index b8b2d265bf7..81f8e0f3fe9 100644 --- a/routers/api/v1/user/repo.go +++ b/routers/api/v1/user/repo.go @@ -11,9 +11,9 @@ import ( repo_model "code.gitea.io/gitea/models/repo" unit_model "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/user/runners.go b/routers/api/v1/user/runners.go index 51556ae0fb8..899218473ee 100644 --- a/routers/api/v1/user/runners.go +++ b/routers/api/v1/user/runners.go @@ -4,8 +4,8 @@ package user import ( - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/routers/api/v1/shared" + "code.gitea.io/gitea/services/context" ) // https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-a-registration-token-for-an-organization diff --git a/routers/api/v1/user/settings.go b/routers/api/v1/user/settings.go index 062df1ca43f..d0a8daaa85b 100644 --- a/routers/api/v1/user/settings.go +++ b/routers/api/v1/user/settings.go @@ -6,10 +6,10 @@ package user import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/optional" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" user_service "code.gitea.io/gitea/services/user" ) diff --git a/routers/api/v1/user/star.go b/routers/api/v1/user/star.go index 2659789ddd9..e624884db36 100644 --- a/routers/api/v1/user/star.go +++ b/routers/api/v1/user/star.go @@ -12,9 +12,9 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/user/user.go b/routers/api/v1/user/user.go index fb8f67d0722..09147cd2ae0 100644 --- a/routers/api/v1/user/user.go +++ b/routers/api/v1/user/user.go @@ -9,8 +9,8 @@ import ( activities_model "code.gitea.io/gitea/models/activities" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/user/watch.go b/routers/api/v1/user/watch.go index 7f531eafaa6..706f4cc66bc 100644 --- a/routers/api/v1/user/watch.go +++ b/routers/api/v1/user/watch.go @@ -11,9 +11,9 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/api/v1/utils/git.go b/routers/api/v1/utils/git.go index 5e801900173..4e25137817e 100644 --- a/routers/api/v1/utils/git.go +++ b/routers/api/v1/utils/git.go @@ -8,10 +8,10 @@ import ( "fmt" "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/services/context" ) // ResolveRefOrSha resolve ref to sha if exist diff --git a/routers/api/v1/utils/hook.go b/routers/api/v1/utils/hook.go index 28b21ab8db6..f1abd49a7d6 100644 --- a/routers/api/v1/utils/hook.go +++ b/routers/api/v1/utils/hook.go @@ -12,12 +12,12 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/models/webhook" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" webhook_module "code.gitea.io/gitea/modules/webhook" + "code.gitea.io/gitea/services/context" webhook_service "code.gitea.io/gitea/services/webhook" ) diff --git a/routers/api/v1/utils/page.go b/routers/api/v1/utils/page.go index 6910b829319..024ba7b8d92 100644 --- a/routers/api/v1/utils/page.go +++ b/routers/api/v1/utils/page.go @@ -5,7 +5,7 @@ package utils import ( "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/common/auth.go b/routers/common/auth.go index 8904785d51f..115d65ed104 100644 --- a/routers/common/auth.go +++ b/routers/common/auth.go @@ -5,9 +5,9 @@ package common import ( user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/web/middleware" auth_service "code.gitea.io/gitea/services/auth" + "code.gitea.io/gitea/services/context" ) type AuthResult struct { diff --git a/routers/common/errpage.go b/routers/common/errpage.go index 923421a29c8..402ca44c12d 100644 --- a/routers/common/errpage.go +++ b/routers/common/errpage.go @@ -9,13 +9,13 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/modules/web/routing" + "code.gitea.io/gitea/services/context" ) const tplStatus500 base.TplName = "status/500" diff --git a/routers/common/markup.go b/routers/common/markup.go index a1c2c37ac07..7819ee72276 100644 --- a/routers/common/markup.go +++ b/routers/common/markup.go @@ -9,11 +9,11 @@ import ( "net/http" "strings" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" "mvdan.cc/xurls/v2" ) diff --git a/routers/common/middleware.go b/routers/common/middleware.go index 8a39dda1798..1ee4c629adb 100644 --- a/routers/common/middleware.go +++ b/routers/common/middleware.go @@ -9,11 +9,11 @@ import ( "strings" "code.gitea.io/gitea/modules/cache" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/modules/web/routing" + "code.gitea.io/gitea/services/context" "gitea.com/go-chi/session" "github.com/chi-middleware/proxy" diff --git a/routers/common/serve.go b/routers/common/serve.go index 8a7f8b33321..446908db75d 100644 --- a/routers/common/serve.go +++ b/routers/common/serve.go @@ -7,11 +7,11 @@ import ( "io" "time" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/httplib" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/services/context" ) // ServeBlob download a git.Blob diff --git a/routers/install/install.go b/routers/install/install.go index decf74cecb6..9c6a8849b63 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -22,7 +22,6 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/auth/password/hash" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/generate" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" @@ -36,6 +35,7 @@ import ( "code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/routers/common" auth_service "code.gitea.io/gitea/services/auth" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" "gitea.com/go-chi/session" diff --git a/routers/private/actions.go b/routers/private/actions.go index 886f23b1c24..53c2412308f 100644 --- a/routers/private/actions.go +++ b/routers/private/actions.go @@ -12,11 +12,11 @@ import ( actions_model "code.gitea.io/gitea/models/actions" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" ) // GenerateActionsRunnerToken generates a new runner token for a given scope diff --git a/routers/private/default_branch.go b/routers/private/default_branch.go index a23e101e9d1..2e323129ef0 100644 --- a/routers/private/default_branch.go +++ b/routers/private/default_branch.go @@ -8,9 +8,9 @@ import ( "net/http" repo_model "code.gitea.io/gitea/models/repo" - gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/private" + gitea_context "code.gitea.io/gitea/services/context" ) // SetDefaultBranch updates the default branch diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go index 8b954a8130c..4eafe3923df 100644 --- a/routers/private/hook_post_receive.go +++ b/routers/private/hook_post_receive.go @@ -10,7 +10,6 @@ import ( issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" - gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" @@ -18,6 +17,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + gitea_context "code.gitea.io/gitea/services/context" repo_service "code.gitea.io/gitea/services/repository" ) @@ -159,7 +159,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { } // If we've pushed a branch (and not deleted it) - if git.IsEmptyCommitID(newCommitID) && refFullName.IsBranch() { + if !git.IsEmptyCommitID(newCommitID) && refFullName.IsBranch() { // First ensure we have the repository loaded, we're allowed pulls requests and we can get the base repo if repo == nil { repo = loadRepository(ctx, ownerName, repoName) diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go index ad52f350845..32ec3003e26 100644 --- a/routers/private/hook_pre_receive.go +++ b/routers/private/hook_pre_receive.go @@ -16,11 +16,11 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" - gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/web" + gitea_context "code.gitea.io/gitea/services/context" pull_service "code.gitea.io/gitea/services/pull" ) diff --git a/routers/private/hook_proc_receive.go b/routers/private/hook_proc_receive.go index 5805202bb57..cee3bbdd121 100644 --- a/routers/private/hook_proc_receive.go +++ b/routers/private/hook_proc_receive.go @@ -7,12 +7,12 @@ import ( "net/http" repo_model "code.gitea.io/gitea/models/repo" - gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/agit" + gitea_context "code.gitea.io/gitea/services/context" ) // HookProcReceive proc-receive hook - only handles agit Proc-Receive requests at present diff --git a/routers/private/internal.go b/routers/private/internal.go index 407edebeede..ede310113ca 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -8,11 +8,11 @@ import ( "net/http" "strings" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "gitea.com/go-chi/binding" chi_middleware "github.com/go-chi/chi/v5/middleware" diff --git a/routers/private/internal_repo.go b/routers/private/internal_repo.go index 615239d479d..e8ee8ba8ac3 100644 --- a/routers/private/internal_repo.go +++ b/routers/private/internal_repo.go @@ -9,10 +9,10 @@ import ( "net/http" repo_model "code.gitea.io/gitea/models/repo" - gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" + gitea_context "code.gitea.io/gitea/services/context" ) // This file contains common functions relating to setting the Repository for the internal routes diff --git a/routers/private/key.go b/routers/private/key.go index 0096480d6a6..5b8f238a83e 100644 --- a/routers/private/key.go +++ b/routers/private/key.go @@ -7,9 +7,9 @@ import ( "net/http" asymkey_model "code.gitea.io/gitea/models/asymkey" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/services/context" ) // UpdatePublicKeyInRepo update public key and deploy key updates diff --git a/routers/private/mail.go b/routers/private/mail.go index e5e162c8809..c19ee67896a 100644 --- a/routers/private/mail.go +++ b/routers/private/mail.go @@ -11,11 +11,11 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/mailer" ) diff --git a/routers/private/manager.go b/routers/private/manager.go index 397e6fac7bf..a6aa03e4ec9 100644 --- a/routers/private/manager.go +++ b/routers/private/manager.go @@ -8,7 +8,6 @@ import ( "net/http" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful/releasereopen" "code.gitea.io/gitea/modules/log" @@ -17,6 +16,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" ) // ReloadTemplates reloads all the templates diff --git a/routers/private/manager_process.go b/routers/private/manager_process.go index 68e4a21805b..9a0298a37c6 100644 --- a/routers/private/manager_process.go +++ b/routers/private/manager_process.go @@ -11,10 +11,10 @@ import ( "runtime" "time" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" process_module "code.gitea.io/gitea/modules/process" + "code.gitea.io/gitea/services/context" ) // Processes prints out the processes diff --git a/routers/private/manager_unix.go b/routers/private/manager_unix.go index 09ced33b8d7..0c63ebc918f 100644 --- a/routers/private/manager_unix.go +++ b/routers/private/manager_unix.go @@ -8,8 +8,8 @@ package private import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/graceful" + "code.gitea.io/gitea/services/context" ) // Restart causes the server to perform a graceful restart diff --git a/routers/private/manager_windows.go b/routers/private/manager_windows.go index bd3c3c30d06..f1b9365f528 100644 --- a/routers/private/manager_windows.go +++ b/routers/private/manager_windows.go @@ -8,9 +8,9 @@ package private import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/private" + "code.gitea.io/gitea/services/context" ) // Restart is not implemented for Windows based servers as they can't fork diff --git a/routers/private/restore_repo.go b/routers/private/restore_repo.go index 7efc22a3d9b..4e95d3071db 100644 --- a/routers/private/restore_repo.go +++ b/routers/private/restore_repo.go @@ -7,9 +7,9 @@ import ( "io" "net/http" - myCtx "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/private" + myCtx "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/migrations" ) diff --git a/routers/private/serv.go b/routers/private/serv.go index 3812ccb52b5..85368a0aed4 100644 --- a/routers/private/serv.go +++ b/routers/private/serv.go @@ -14,11 +14,11 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" repo_service "code.gitea.io/gitea/services/repository" wiki_service "code.gitea.io/gitea/services/wiki" ) diff --git a/routers/private/ssh_log.go b/routers/private/ssh_log.go index eacfa18f058..5bec632ead9 100644 --- a/routers/private/ssh_log.go +++ b/routers/private/ssh_log.go @@ -6,11 +6,11 @@ package private import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" ) // SSHLog hook to response ssh log diff --git a/routers/web/admin/admin.go b/routers/web/admin/admin.go index 9fbd429f743..f3f10fd1b82 100644 --- a/routers/web/admin/admin.go +++ b/routers/web/admin/admin.go @@ -14,13 +14,13 @@ import ( activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/updatechecker" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/cron" "code.gitea.io/gitea/services/forms" release_service "code.gitea.io/gitea/services/release" diff --git a/routers/web/admin/applications.go b/routers/web/admin/applications.go index b6f7bcd2a5b..85833980746 100644 --- a/routers/web/admin/applications.go +++ b/routers/web/admin/applications.go @@ -10,9 +10,9 @@ import ( "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" user_setting "code.gitea.io/gitea/routers/web/user/setting" + "code.gitea.io/gitea/services/context" ) var ( diff --git a/routers/web/admin/auths.go b/routers/web/admin/auths.go index 7fdd18dfae9..ba487d10457 100644 --- a/routers/web/admin/auths.go +++ b/routers/web/admin/auths.go @@ -16,7 +16,6 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/auth/pam" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" @@ -27,6 +26,7 @@ import ( pam_service "code.gitea.io/gitea/services/auth/source/pam" "code.gitea.io/gitea/services/auth/source/smtp" "code.gitea.io/gitea/services/auth/source/sspi" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" "xorm.io/xorm/convert" diff --git a/routers/web/admin/config.go b/routers/web/admin/config.go index 47f92015046..2f5f17e2013 100644 --- a/routers/web/admin/config.go +++ b/routers/web/admin/config.go @@ -12,13 +12,13 @@ import ( system_model "code.gitea.io/gitea/models/system" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting/config" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/mailer" "gitea.com/go-chi/session" diff --git a/routers/web/admin/diagnosis.go b/routers/web/admin/diagnosis.go index 2d550125d55..020554a35a4 100644 --- a/routers/web/admin/diagnosis.go +++ b/routers/web/admin/diagnosis.go @@ -9,8 +9,8 @@ import ( "runtime/pprof" "time" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/httplib" + "code.gitea.io/gitea/services/context" ) func MonitorDiagnosis(ctx *context.Context) { diff --git a/routers/web/admin/emails.go b/routers/web/admin/emails.go index 59f80035d89..2cf4035c6a8 100644 --- a/routers/web/admin/emails.go +++ b/routers/web/admin/emails.go @@ -11,10 +11,10 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" ) const ( @@ -68,10 +68,10 @@ func Emails(ctx *context.Context) { opts.Keyword = ctx.FormTrim("q") opts.SortType = orderBy if len(ctx.FormString("is_activated")) != 0 { - opts.IsActivated = util.OptionalBoolOf(ctx.FormBool("activated")) + opts.IsActivated = optional.Some(ctx.FormBool("activated")) } if len(ctx.FormString("is_primary")) != 0 { - opts.IsPrimary = util.OptionalBoolOf(ctx.FormBool("primary")) + opts.IsPrimary = optional.Some(ctx.FormBool("primary")) } if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) { diff --git a/routers/web/admin/hooks.go b/routers/web/admin/hooks.go index cd8cc29cdfb..8d4c66fdb2b 100644 --- a/routers/web/admin/hooks.go +++ b/routers/web/admin/hooks.go @@ -8,9 +8,9 @@ import ( "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/admin/notice.go b/routers/web/admin/notice.go index e1cb578d052..36303cbc06e 100644 --- a/routers/web/admin/notice.go +++ b/routers/web/admin/notice.go @@ -11,9 +11,9 @@ import ( "code.gitea.io/gitea/models/db" system_model "code.gitea.io/gitea/models/system" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/admin/orgs.go b/routers/web/admin/orgs.go index 00131c9e2f7..c5454db71e3 100644 --- a/routers/web/admin/orgs.go +++ b/routers/web/admin/orgs.go @@ -8,10 +8,10 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/web/explore" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/admin/packages.go b/routers/web/admin/packages.go index 35ce215be48..7c16b69a85c 100644 --- a/routers/web/admin/packages.go +++ b/routers/web/admin/packages.go @@ -11,9 +11,9 @@ import ( "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" packages_service "code.gitea.io/gitea/services/packages" packages_cleanup_service "code.gitea.io/gitea/services/packages/cleanup" ) diff --git a/routers/web/admin/queue.go b/routers/web/admin/queue.go index 18a8d7d3e68..d8c50730b14 100644 --- a/routers/web/admin/queue.go +++ b/routers/web/admin/queue.go @@ -7,9 +7,9 @@ import ( "net/http" "strconv" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/queue" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ) func Queues(ctx *context.Context) { diff --git a/routers/web/admin/repos.go b/routers/web/admin/repos.go index 45c280ef731..ddf44401676 100644 --- a/routers/web/admin/repos.go +++ b/routers/web/admin/repos.go @@ -12,11 +12,11 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/web/explore" + "code.gitea.io/gitea/services/context" repo_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/web/admin/runners.go b/routers/web/admin/runners.go index eaa268b4f14..d73290a8dba 100644 --- a/routers/web/admin/runners.go +++ b/routers/web/admin/runners.go @@ -4,8 +4,8 @@ package admin import ( - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ) func RedirectToDefaultSetting(ctx *context.Context) { diff --git a/routers/web/admin/stacktrace.go b/routers/web/admin/stacktrace.go index b603fb59a26..d6def94bb49 100644 --- a/routers/web/admin/stacktrace.go +++ b/routers/web/admin/stacktrace.go @@ -7,9 +7,9 @@ import ( "net/http" "runtime" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ) // Stacktrace show admin monitor goroutines page diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go index adb9799c016..bbdbc820d78 100644 --- a/routers/web/admin/users.go +++ b/routers/web/admin/users.go @@ -19,7 +19,6 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/auth/password" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" @@ -27,6 +26,7 @@ import ( "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/web/explore" user_setting "code.gitea.io/gitea/routers/web/user/setting" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/mailer" user_service "code.gitea.io/gitea/services/user" @@ -276,7 +276,7 @@ func ViewUser(ctx *context.Context) { OwnerID: u.ID, OrderBy: db.SearchOrderByAlphabetically, Private: true, - Collaborate: util.OptionalBoolFalse, + Collaborate: optional.Some(false), }) if err != nil { ctx.ServerError("SearchRepository", err) diff --git a/routers/web/admin/users_test.go b/routers/web/admin/users_test.go index 560ee70ea04..f6f92378581 100644 --- a/routers/web/admin/users_test.go +++ b/routers/web/admin/users_test.go @@ -8,10 +8,10 @@ import ( "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/contexttest" "code.gitea.io/gitea/services/forms" "github.com/stretchr/testify/assert" diff --git a/routers/web/auth/2fa.go b/routers/web/auth/2fa.go index dc0062ebaa5..f93177bf96b 100644 --- a/routers/web/auth/2fa.go +++ b/routers/web/auth/2fa.go @@ -10,9 +10,9 @@ import ( "code.gitea.io/gitea/models/auth" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/externalaccount" "code.gitea.io/gitea/services/forms" ) diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index a30ee0ce542..7704a110a67 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -16,7 +16,6 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/auth/password" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/eventsource" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" @@ -29,6 +28,7 @@ import ( "code.gitea.io/gitea/routers/utils" auth_service "code.gitea.io/gitea/services/auth" "code.gitea.io/gitea/services/auth/source/oauth2" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/externalaccount" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/mailer" @@ -646,7 +646,7 @@ func sendActivateEmail(ctx *context.Context, u *user_model.User) { mailer.SendActivateAccountMail(ctx.Locale, u) activeCodeLives := timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale) - msgHTML := ctx.Locale.Tr("auth.confirmation_mail_sent_prompt", u.Email, activeCodeLives) + msgHTML := ctx.Locale.Tr("auth.confirmation_mail_sent_prompt_ex", u.Email, activeCodeLives) renderActivationPromptMessage(ctx, msgHTML) } @@ -656,6 +656,10 @@ func renderActivationVerifyPassword(ctx *context.Context, code string) { ctx.HTML(http.StatusOK, TplActivate) } +func renderActivationChangeEmail(ctx *context.Context) { + ctx.HTML(http.StatusOK, TplActivate) +} + // Activate render activate user page func Activate(ctx *context.Context) { code := ctx.FormString("code") @@ -674,7 +678,7 @@ func Activate(ctx *context.Context) { return } - // Resend confirmation email. + // Resend confirmation email. FIXME: ideally this should be in a POST request sendActivateEmail(ctx, ctx.Doer) return } @@ -698,7 +702,28 @@ func Activate(ctx *context.Context) { // ActivatePost handles account activation with password check func ActivatePost(ctx *context.Context) { code := ctx.FormString("code") - if code == "" || (ctx.Doer != nil && ctx.Doer.IsActive) { + if ctx.Doer != nil && ctx.Doer.IsActive { + ctx.Redirect(setting.AppSubURL + "/user/activate") // it will redirect again to the correct page + return + } + + if code == "" { + newEmail := strings.TrimSpace(ctx.FormString("change_email")) + if ctx.Doer != nil && newEmail != "" && !strings.EqualFold(ctx.Doer.Email, newEmail) { + if user_model.ValidateEmail(newEmail) != nil { + ctx.Flash.Error(ctx.Locale.Tr("form.email_invalid"), true) + renderActivationChangeEmail(ctx) + return + } + err := user_model.ChangeInactivePrimaryEmail(ctx, ctx.Doer.ID, ctx.Doer.Email, newEmail) + if err != nil { + ctx.Flash.Error(ctx.Locale.Tr("admin.emails.not_updated", newEmail), true) + renderActivationChangeEmail(ctx) + return + } + ctx.Doer.Email = newEmail + } + // FIXME: at the moment, GET request handles the "send confirmation email" action. But the old code does this redirect and then send a confirmation email. ctx.Redirect(setting.AppSubURL + "/user/activate") return } diff --git a/routers/web/auth/linkaccount.go b/routers/web/auth/linkaccount.go index 1d94e52fe3e..f744a57a43f 100644 --- a/routers/web/auth/linkaccount.go +++ b/routers/web/auth/linkaccount.go @@ -12,13 +12,13 @@ import ( "code.gitea.io/gitea/models/auth" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" auth_service "code.gitea.io/gitea/services/auth" "code.gitea.io/gitea/services/auth/source/oauth2" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/externalaccount" "code.gitea.io/gitea/services/forms" diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go index 33a4ae91927..d5ca7397f06 100644 --- a/routers/web/auth/oauth.go +++ b/routers/web/auth/oauth.go @@ -22,7 +22,6 @@ import ( auth_module "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/container" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" @@ -34,6 +33,7 @@ import ( auth_service "code.gitea.io/gitea/services/auth" source_service "code.gitea.io/gitea/services/auth/source" "code.gitea.io/gitea/services/auth/source/oauth2" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/externalaccount" "code.gitea.io/gitea/services/forms" user_service "code.gitea.io/gitea/services/user" diff --git a/routers/web/auth/openid.go b/routers/web/auth/openid.go index 29ef772b1c6..2143b8096a0 100644 --- a/routers/web/auth/openid.go +++ b/routers/web/auth/openid.go @@ -11,12 +11,12 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/auth/openid" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/auth" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" ) diff --git a/routers/web/auth/password.go b/routers/web/auth/password.go index 1f2d1332820..c9e03860412 100644 --- a/routers/web/auth/password.go +++ b/routers/web/auth/password.go @@ -12,7 +12,6 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/auth/password" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" @@ -20,6 +19,7 @@ import ( "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/routers/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/mailer" user_service "code.gitea.io/gitea/services/user" diff --git a/routers/web/auth/webauthn.go b/routers/web/auth/webauthn.go index 95c8d262a53..1079f44a085 100644 --- a/routers/web/auth/webauthn.go +++ b/routers/web/auth/webauthn.go @@ -11,9 +11,9 @@ import ( user_model "code.gitea.io/gitea/models/user" wa "code.gitea.io/gitea/modules/auth/webauthn" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/externalaccount" "github.com/go-webauthn/webauthn/protocol" diff --git a/routers/web/devtest/devtest.go b/routers/web/devtest/devtest.go index 525ca9be53c..dd20663f94b 100644 --- a/routers/web/devtest/devtest.go +++ b/routers/web/devtest/devtest.go @@ -10,8 +10,8 @@ import ( "time" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/templates" + "code.gitea.io/gitea/services/context" ) // List all devtest templates, they will be used for e2e tests for the UI components diff --git a/routers/web/events/events.go b/routers/web/events/events.go index 1a5a162c1a2..52f20e07dc3 100644 --- a/routers/web/events/events.go +++ b/routers/web/events/events.go @@ -7,11 +7,11 @@ import ( "net/http" "time" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/eventsource" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/routers/web/auth" + "code.gitea.io/gitea/services/context" ) // Events listens for events diff --git a/routers/web/explore/code.go b/routers/web/explore/code.go index d81884ec62d..2cde8b655ee 100644 --- a/routers/web/explore/code.go +++ b/routers/web/explore/code.go @@ -8,9 +8,9 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" code_indexer "code.gitea.io/gitea/modules/indexer/code" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/explore/org.go b/routers/web/explore/org.go index dc1318beefe..f8fd6ec38ef 100644 --- a/routers/web/explore/org.go +++ b/routers/web/explore/org.go @@ -6,9 +6,10 @@ package explore import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/context" ) // Organizations render explore organizations page @@ -24,8 +25,16 @@ func Organizations(ctx *context.Context) { visibleTypes = append(visibleTypes, structs.VisibleTypeLimited, structs.VisibleTypePrivate) } - if ctx.FormString("sort") == "" { - ctx.SetFormString("sort", setting.UI.ExploreDefaultSort) + supportedSortOrders := container.SetOf( + "newest", + "oldest", + "alphabetically", + "reversealphabetically", + ) + sortOrder := ctx.FormString("sort") + if sortOrder == "" { + sortOrder = "newest" + ctx.SetFormString("sort", sortOrder) } RenderUserSearch(ctx, &user_model.SearchUserOptions{ @@ -33,5 +42,7 @@ func Organizations(ctx *context.Context) { Type: user_model.UserTypeOrganization, ListOptions: db.ListOptions{PageSize: setting.UI.ExplorePagingNum}, Visible: visibleTypes, + + SupportedSortOrders: supportedSortOrders, }, tplExploreUsers) } diff --git a/routers/web/explore/repo.go b/routers/web/explore/repo.go index 0446edebe69..d5a46f6883b 100644 --- a/routers/web/explore/repo.go +++ b/routers/web/explore/repo.go @@ -10,10 +10,10 @@ import ( "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/sitemap" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/explore/topic.go b/routers/web/explore/topic.go index bb1be310de7..95fecfe2b81 100644 --- a/routers/web/explore/topic.go +++ b/routers/web/explore/topic.go @@ -8,8 +8,8 @@ import ( "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/web/explore/user.go b/routers/web/explore/user.go index 09d31f95ef4..b79a79fb2c8 100644 --- a/routers/web/explore/user.go +++ b/routers/web/explore/user.go @@ -10,12 +10,13 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/sitemap" "code.gitea.io/gitea/modules/structs" - "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" ) const ( @@ -79,10 +80,16 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions, fallthrough default: // in case the sortType is not valid, we set it to recentupdate + sortOrder = "recentupdate" ctx.Data["SortType"] = "recentupdate" orderBy = "`user`.updated_unix DESC" } + if opts.SupportedSortOrders != nil && !opts.SupportedSortOrders.Contains(sortOrder) { + ctx.NotFound("unsupported sort order", nil) + return + } + opts.Keyword = ctx.FormTrim("q") opts.OrderBy = orderBy if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) { @@ -132,15 +139,25 @@ func Users(ctx *context.Context) { ctx.Data["PageIsExploreUsers"] = true ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled - if ctx.FormString("sort") == "" { - ctx.SetFormString("sort", setting.UI.ExploreDefaultSort) + supportedSortOrders := container.SetOf( + "newest", + "oldest", + "alphabetically", + "reversealphabetically", + ) + sortOrder := ctx.FormString("sort") + if sortOrder == "" { + sortOrder = "newest" + ctx.SetFormString("sort", sortOrder) } RenderUserSearch(ctx, &user_model.SearchUserOptions{ Actor: ctx.Doer, Type: user_model.UserTypeIndividual, ListOptions: db.ListOptions{PageSize: setting.UI.ExplorePagingNum}, - IsActive: util.OptionalBoolTrue, + IsActive: optional.Some(true), Visible: []structs.VisibleType{structs.VisibleTypePublic, structs.VisibleTypeLimited, structs.VisibleTypePrivate}, + + SupportedSortOrders: supportedSortOrders, }, tplExploreUsers) } diff --git a/routers/web/feed/branch.go b/routers/web/feed/branch.go index f13038ff9b4..80ce2ad198b 100644 --- a/routers/web/feed/branch.go +++ b/routers/web/feed/branch.go @@ -9,7 +9,7 @@ import ( "time" "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" "github.com/gorilla/feeds" ) diff --git a/routers/web/feed/convert.go b/routers/web/feed/convert.go index 1e040ed819e..3defa436a70 100644 --- a/routers/web/feed/convert.go +++ b/routers/web/feed/convert.go @@ -14,12 +14,12 @@ import ( activities_model "code.gitea.io/gitea/models/activities" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" "github.com/gorilla/feeds" ) @@ -50,7 +50,7 @@ func toReleaseLink(ctx *context.Context, act *activities_model.Action) string { // renderMarkdown creates a minimal markdown render context from an action. // If rendering fails, the original markdown text is returned -func renderMarkdown(ctx *context.Context, act *activities_model.Action, content string) string { +func renderMarkdown(ctx *context.Context, act *activities_model.Action, content string) template.HTML { markdownCtx := &markup.RenderContext{ Ctx: ctx, Links: markup.Links{ @@ -64,7 +64,7 @@ func renderMarkdown(ctx *context.Context, act *activities_model.Action, content } markdown, err := markdown.RenderString(markdownCtx, content) if err != nil { - return content + return templates.SanitizeHTML(content) // old code did so: use SanitizeHTML to render in tmpl } return markdown } @@ -74,7 +74,11 @@ func feedActionsToFeedItems(ctx *context.Context, actions activities_model.Actio for _, act := range actions { act.LoadActUser(ctx) - var content, desc, title string + // TODO: the code seems quite strange (maybe not right) + // sometimes it uses text content but sometimes it uses HTML content + // it should clearly defines which kind of content it should use for the feed items: plan text or rich HTML + var title, desc string + var content template.HTML link := &feeds.Link{Href: act.GetCommentHTMLURL(ctx)} @@ -228,7 +232,7 @@ func feedActionsToFeedItems(ctx *context.Context, actions activities_model.Actio desc = act.GetIssueTitle(ctx) comment := act.GetIssueInfos()[1] if len(comment) != 0 { - desc += "\n\n" + renderMarkdown(ctx, act, comment) + desc += "\n\n" + string(renderMarkdown(ctx, act, comment)) } case activities_model.ActionMergePullRequest, activities_model.ActionAutoMergePullRequest: desc = act.GetIssueInfos()[1] @@ -239,7 +243,7 @@ func feedActionsToFeedItems(ctx *context.Context, actions activities_model.Actio } } if len(content) == 0 { - content = desc + content = templates.SanitizeHTML(desc) } items = append(items, &feeds.Item{ @@ -253,7 +257,7 @@ func feedActionsToFeedItems(ctx *context.Context, actions activities_model.Actio }, Id: fmt.Sprintf("%v: %v", strconv.FormatInt(act.ID, 10), link.Href), Created: act.CreatedUnix.AsTime(), - Content: content, + Content: string(content), }) } return items, err @@ -282,7 +286,8 @@ func releasesToFeedItems(ctx *context.Context, releases []*repo_model.Release, i return nil, err } - var title, content string + var title string + var content template.HTML if rel.IsTag { title = rel.TagName @@ -311,7 +316,7 @@ func releasesToFeedItems(ctx *context.Context, releases []*repo_model.Release, i Email: rel.Publisher.GetEmail(), }, Id: fmt.Sprintf("%v: %v", strconv.FormatInt(rel.ID, 10), link.Href), - Content: content, + Content: string(content), }) } diff --git a/routers/web/feed/file.go b/routers/web/feed/file.go index 56a9c54ddcb..1ab768ff27f 100644 --- a/routers/web/feed/file.go +++ b/routers/web/feed/file.go @@ -9,9 +9,9 @@ import ( "time" "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" "github.com/gorilla/feeds" ) diff --git a/routers/web/feed/profile.go b/routers/web/feed/profile.go index 3feca68d61a..08cbcd9e12b 100644 --- a/routers/web/feed/profile.go +++ b/routers/web/feed/profile.go @@ -7,9 +7,9 @@ import ( "time" activities_model "code.gitea.io/gitea/models/activities" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" + "code.gitea.io/gitea/services/context" "github.com/gorilla/feeds" ) @@ -58,7 +58,7 @@ func showUserFeed(ctx *context.Context, formatType string) { feed := &feeds.Feed{ Title: ctx.Locale.TrString("home.feed_of", ctx.ContextUser.DisplayName()), Link: &feeds.Link{Href: ctx.ContextUser.HTMLURL()}, - Description: ctxUserDescription, + Description: string(ctxUserDescription), Created: time.Now(), } diff --git a/routers/web/feed/release.go b/routers/web/feed/release.go index 558c03dba74..273f47e3b46 100644 --- a/routers/web/feed/release.go +++ b/routers/web/feed/release.go @@ -8,7 +8,7 @@ import ( "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" "github.com/gorilla/feeds" ) diff --git a/routers/web/feed/render.go b/routers/web/feed/render.go index 8931dae8cce..a41808c24ac 100644 --- a/routers/web/feed/render.go +++ b/routers/web/feed/render.go @@ -4,7 +4,7 @@ package feed import ( - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" ) // RenderBranchFeed render format for branch or file diff --git a/routers/web/feed/repo.go b/routers/web/feed/repo.go index 51c24510c7e..bfcc3a37d6a 100644 --- a/routers/web/feed/repo.go +++ b/routers/web/feed/repo.go @@ -8,7 +8,7 @@ import ( activities_model "code.gitea.io/gitea/models/activities" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" "github.com/gorilla/feeds" ) diff --git a/routers/web/githttp.go b/routers/web/githttp.go index ab74e9a333b..5f1dedce763 100644 --- a/routers/web/githttp.go +++ b/routers/web/githttp.go @@ -6,11 +6,10 @@ package web import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/web/repo" - context_service "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context" ) func requireSignIn(ctx *context.Context) { @@ -39,5 +38,5 @@ func gitHTTPRouters(m *web.Route) { m.Methods("GET,OPTIONS", "/objects/{head:[0-9a-f]{2}}/{hash:[0-9a-f]{38,62}}", repo.GetLooseObject) m.Methods("GET,OPTIONS", "/objects/pack/pack-{file:[0-9a-f]{40,64}}.pack", repo.GetPackFile) m.Methods("GET,OPTIONS", "/objects/pack/pack-{file:[0-9a-f]{40,64}}.idx", repo.GetIdxFile) - }, ignSignInAndCsrf, requireSignIn, repo.HTTPGitEnabledHandler, repo.CorsHandler(), context_service.UserAssignmentWeb()) + }, ignSignInAndCsrf, requireSignIn, repo.HTTPGitEnabledHandler, repo.CorsHandler(), context.UserAssignmentWeb()) } diff --git a/routers/web/goget.go b/routers/web/goget.go index c5b8b6cbc01..8d5612ebfe9 100644 --- a/routers/web/goget.go +++ b/routers/web/goget.go @@ -12,9 +12,9 @@ import ( "strings" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" ) func goGet(ctx *context.Context) { diff --git a/routers/web/home.go b/routers/web/home.go index 2321b00efe7..d4be0931e85 100644 --- a/routers/web/home.go +++ b/routers/web/home.go @@ -12,15 +12,15 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/sitemap" "code.gitea.io/gitea/modules/structs" - "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/routers/web/auth" "code.gitea.io/gitea/routers/web/user" + "code.gitea.io/gitea/services/context" ) const ( @@ -71,7 +71,7 @@ func HomeSitemap(ctx *context.Context) { _, cnt, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{ Type: user_model.UserTypeIndividual, ListOptions: db.ListOptions{PageSize: 1}, - IsActive: util.OptionalBoolTrue, + IsActive: optional.Some(true), Visible: []structs.VisibleType{structs.VisibleTypePublic}, }) if err != nil { diff --git a/routers/web/misc/markup.go b/routers/web/misc/markup.go index c91da9a7f10..2dbbd6fc097 100644 --- a/routers/web/misc/markup.go +++ b/routers/web/misc/markup.go @@ -5,10 +5,10 @@ package misc import ( - "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/common" + "code.gitea.io/gitea/services/context" ) // Markup render markup document to HTML diff --git a/routers/web/misc/swagger.go b/routers/web/misc/swagger.go index 72c09a37801..5fddfa8885f 100644 --- a/routers/web/misc/swagger.go +++ b/routers/web/misc/swagger.go @@ -7,7 +7,7 @@ import ( "net/http" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" ) // tplSwagger swagger page template diff --git a/routers/web/nodeinfo.go b/routers/web/nodeinfo.go index 01b71e7086b..f1cc7bf530f 100644 --- a/routers/web/nodeinfo.go +++ b/routers/web/nodeinfo.go @@ -7,8 +7,8 @@ import ( "fmt" "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ) type nodeInfoLinks struct { diff --git a/routers/web/org/home.go b/routers/web/org/home.go index 36f543dc45f..4a7378689ad 100644 --- a/routers/web/org/home.go +++ b/routers/web/org/home.go @@ -12,7 +12,6 @@ import ( "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" @@ -20,6 +19,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" shared_user "code.gitea.io/gitea/routers/web/shared/user" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/org/members.go b/routers/web/org/members.go index 15a615c706f..9a3d60e122b 100644 --- a/routers/web/org/members.go +++ b/routers/web/org/members.go @@ -10,10 +10,10 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" shared_user "code.gitea.io/gitea/routers/web/shared/user" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/org/org.go b/routers/web/org/org.go index 1e4544730e1..f94dd16eaef 100644 --- a/routers/web/org/org.go +++ b/routers/web/org/org.go @@ -12,10 +12,10 @@ import ( "code.gitea.io/gitea/models/organization" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" ) diff --git a/routers/web/org/org_labels.go b/routers/web/org/org_labels.go index f78bd002742..02eae8052ea 100644 --- a/routers/web/org/org_labels.go +++ b/routers/web/org/org_labels.go @@ -8,10 +8,10 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/label" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" ) diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go index f062127d24f..82cd91997a5 100644 --- a/routers/web/org/projects.go +++ b/routers/web/org/projects.go @@ -17,12 +17,13 @@ import ( attachment_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" shared_user "code.gitea.io/gitea/routers/web/shared/user" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" ) @@ -104,7 +105,7 @@ func Projects(ctx *context.Context) { } for _, project := range projects { - project.RenderedContent = project.Description + project.RenderedContent = templates.SanitizeHTML(project.Description) // FIXME: is it right? why not render? } err = shared_user.LoadHeaderCount(ctx) @@ -395,7 +396,7 @@ func ViewProject(ctx *context.Context) { } } - project.RenderedContent = project.Description + project.RenderedContent = templates.SanitizeHTML(project.Description) // FIXME: is it right? why not render? ctx.Data["LinkedPRs"] = linkedPrsMap ctx.Data["PageIsViewProjects"] = true ctx.Data["CanWriteProjects"] = canWriteProjects(ctx) diff --git a/routers/web/org/projects_test.go b/routers/web/org/projects_test.go index 8053ab4cf93..f4ccfe1c066 100644 --- a/routers/web/org/projects_test.go +++ b/routers/web/org/projects_test.go @@ -7,8 +7,8 @@ import ( "testing" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/routers/web/org" + "code.gitea.io/gitea/services/contexttest" "github.com/stretchr/testify/assert" ) diff --git a/routers/web/org/setting.go b/routers/web/org/setting.go index 47d0063f767..494ada4323a 100644 --- a/routers/web/org/setting.go +++ b/routers/web/org/setting.go @@ -14,7 +14,6 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" repo_module "code.gitea.io/gitea/modules/repository" @@ -22,6 +21,7 @@ import ( "code.gitea.io/gitea/modules/web" shared_user "code.gitea.io/gitea/routers/web/shared/user" user_setting "code.gitea.io/gitea/routers/web/user/setting" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" org_service "code.gitea.io/gitea/services/org" repo_service "code.gitea.io/gitea/services/repository" diff --git a/routers/web/org/setting/runners.go b/routers/web/org/setting/runners.go index c3c771036aa..fe05709237d 100644 --- a/routers/web/org/setting/runners.go +++ b/routers/web/org/setting/runners.go @@ -4,7 +4,7 @@ package setting import ( - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" ) func RedirectToDefaultSetting(ctx *context.Context) { diff --git a/routers/web/org/setting_oauth2.go b/routers/web/org/setting_oauth2.go index ca4fe09f380..7f855795d36 100644 --- a/routers/web/org/setting_oauth2.go +++ b/routers/web/org/setting_oauth2.go @@ -10,10 +10,10 @@ import ( "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" shared_user "code.gitea.io/gitea/routers/web/shared/user" user_setting "code.gitea.io/gitea/routers/web/user/setting" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/org/setting_packages.go b/routers/web/org/setting_packages.go index 796829d34ef..af9836e42c2 100644 --- a/routers/web/org/setting_packages.go +++ b/routers/web/org/setting_packages.go @@ -8,10 +8,10 @@ import ( "net/http" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" shared "code.gitea.io/gitea/routers/web/shared/packages" shared_user "code.gitea.io/gitea/routers/web/shared/user" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go index 71fe99c97c7..fd7486cacdb 100644 --- a/routers/web/org/teams.go +++ b/routers/web/org/teams.go @@ -20,11 +20,11 @@ import ( unit_model "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" shared_user "code.gitea.io/gitea/routers/web/shared/user" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/forms" org_service "code.gitea.io/gitea/services/org" diff --git a/routers/web/passkey.go b/routers/web/passkey.go index 95874dfc48d..0d10a69dfe6 100644 --- a/routers/web/passkey.go +++ b/routers/web/passkey.go @@ -6,8 +6,8 @@ package web import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ) type passkeyEndpointsType struct { diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index 19aca267117..e7849123779 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -15,11 +15,11 @@ import ( "code.gitea.io/gitea/modules/actions" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/container" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/web/repo" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" "github.com/nektos/act/pkg/model" diff --git a/routers/web/repo/actions/badge.go b/routers/web/repo/actions/badge.go new file mode 100644 index 00000000000..6fa951826c3 --- /dev/null +++ b/routers/web/repo/actions/badge.go @@ -0,0 +1,56 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package actions + +import ( + "errors" + "fmt" + "net/http" + "path/filepath" + "strings" + + actions_model "code.gitea.io/gitea/models/actions" + "code.gitea.io/gitea/modules/badge" + "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" +) + +func GetWorkflowBadge(ctx *context.Context) { + workflowFile := ctx.Params("workflow_name") + branch := ctx.Req.URL.Query().Get("branch") + if branch == "" { + branch = ctx.Repo.Repository.DefaultBranch + } + branchRef := fmt.Sprintf("refs/heads/%s", branch) + event := ctx.Req.URL.Query().Get("event") + + badge, err := getWorkflowBadge(ctx, workflowFile, branchRef, event) + if err != nil { + ctx.ServerError("GetWorkflowBadge", err) + return + } + + ctx.Data["Badge"] = badge + ctx.RespHeader().Set("Content-Type", "image/svg+xml") + ctx.HTML(http.StatusOK, "shared/actions/runner_badge") +} + +func getWorkflowBadge(ctx *context.Context, workflowFile, branchName, event string) (badge.Badge, error) { + extension := filepath.Ext(workflowFile) + workflowName := strings.TrimSuffix(workflowFile, extension) + + run, err := actions_model.GetWorkflowLatestRun(ctx, ctx.Repo.Repository.ID, workflowFile, branchName, event) + if err != nil { + if errors.Is(err, util.ErrNotExist) { + return badge.GenerateBadge(workflowName, "no status", badge.DefaultColor), nil + } + return badge.Badge{}, err + } + + color, ok := badge.StatusColorMap[run.Status] + if !ok { + return badge.GenerateBadge(workflowName, "unknown status", badge.DefaultColor), nil + } + return badge.GenerateBadge(workflowName, run.Status.String(), color), nil +} diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index 49387362b35..52c3cf1d07c 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -12,6 +12,7 @@ import ( "io" "net/http" "net/url" + "strconv" "strings" "time" @@ -21,12 +22,12 @@ import ( "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/actions" "code.gitea.io/gitea/modules/base" - context_module "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" actions_service "code.gitea.io/gitea/services/actions" + context_module "code.gitea.io/gitea/services/context" "xorm.io/builder" ) @@ -262,10 +263,14 @@ func ViewPost(ctx *context_module.Context) { } // Rerun will rerun jobs in the given run -// jobIndex = 0 means rerun all jobs +// If jobIndexStr is a blank string, it means rerun all jobs func Rerun(ctx *context_module.Context) { runIndex := ctx.ParamsInt64("run") - jobIndex := ctx.ParamsInt64("job") + jobIndexStr := ctx.Params("job") + var jobIndex int64 + if jobIndexStr != "" { + jobIndex, _ = strconv.ParseInt(jobIndexStr, 10, 64) + } run, err := actions_model.GetRunByIndex(ctx, ctx.Repo.Repository.ID, runIndex) if err != nil { @@ -297,7 +302,7 @@ func Rerun(ctx *context_module.Context) { return } - if jobIndex != 0 { + if jobIndexStr != "" { jobs = []*actions_model.ActionRunJob{job} } diff --git a/routers/web/repo/activity.go b/routers/web/repo/activity.go index af99c4ed986..6f6641cc65e 100644 --- a/routers/web/repo/activity.go +++ b/routers/web/repo/activity.go @@ -10,7 +10,7 @@ import ( activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/repo/attachment.go b/routers/web/repo/attachment.go index 8c322b45e5e..f0c5622aec7 100644 --- a/routers/web/repo/attachment.go +++ b/routers/web/repo/attachment.go @@ -9,15 +9,15 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" - "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/common" "code.gitea.io/gitea/services/attachment" + "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context/upload" repo_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go index 7602b30d2b1..b088b8387e7 100644 --- a/routers/web/repo/blame.go +++ b/routers/web/repo/blame.go @@ -13,13 +13,13 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/charset" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/highlight" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" files_service "code.gitea.io/gitea/services/repository/files" ) diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index c543160f420..05f06a3ceb7 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -16,7 +16,6 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" @@ -24,6 +23,7 @@ import ( "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/utils" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" release_service "code.gitea.io/gitea/services/release" repo_service "code.gitea.io/gitea/services/repository" diff --git a/routers/web/repo/cherry_pick.go b/routers/web/repo/cherry_pick.go index 8de54d569fd..088f8d889d4 100644 --- a/routers/web/repo/cherry_pick.go +++ b/routers/web/repo/cherry_pick.go @@ -12,11 +12,11 @@ import ( git_model "code.gitea.io/gitea/models/git" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/repository/files" ) diff --git a/routers/web/repo/code_frequency.go b/routers/web/repo/code_frequency.go index 48ade655b7b..c76f492da07 100644 --- a/routers/web/repo/code_frequency.go +++ b/routers/web/repo/code_frequency.go @@ -8,7 +8,7 @@ import ( "net/http" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" contributors_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index 32fa973ef61..16da917d222 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -19,7 +19,6 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitgraph" "code.gitea.io/gitea/modules/gitrepo" @@ -27,6 +26,7 @@ import ( "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/gitdiff" git_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 535487d5fdb..b0570f97c3b 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -25,7 +25,6 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" - "code.gitea.io/gitea/modules/context" csv_module "code.gitea.io/gitea/modules/csv" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" @@ -35,8 +34,9 @@ import ( "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/typesniffer" - "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context/upload" "code.gitea.io/gitea/services/gitdiff" ) diff --git a/routers/web/repo/contributors.go b/routers/web/repo/contributors.go index bcfef7580a6..5fda17469e9 100644 --- a/routers/web/repo/contributors.go +++ b/routers/web/repo/contributors.go @@ -8,7 +8,7 @@ import ( "net/http" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" contributors_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/web/repo/download.go b/routers/web/repo/download.go index a9e2e2b2fad..c4a8baecca3 100644 --- a/routers/web/repo/download.go +++ b/routers/web/repo/download.go @@ -9,7 +9,6 @@ import ( "time" git_model "code.gitea.io/gitea/models/git" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/lfs" @@ -17,6 +16,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/routers/common" + "code.gitea.io/gitea/services/context" ) // ServeBlobOrLFS download a git.Blob redirecting to LFS if necessary diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index 28644fbe3d5..8f3d9612eca 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -16,17 +16,17 @@ import ( "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/typesniffer" - "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/utils" + "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context/upload" "code.gitea.io/gitea/services/forms" files_service "code.gitea.io/gitea/services/repository/files" ) diff --git a/routers/web/repo/editor_test.go b/routers/web/repo/editor_test.go index c28c3ef1d63..313fcfe33a2 100644 --- a/routers/web/repo/editor_test.go +++ b/routers/web/repo/editor_test.go @@ -7,9 +7,9 @@ import ( "testing" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" + "code.gitea.io/gitea/services/contexttest" "github.com/stretchr/testify/assert" ) diff --git a/routers/web/repo/find.go b/routers/web/repo/find.go index daefe59c8f2..07b37227988 100644 --- a/routers/web/repo/find.go +++ b/routers/web/repo/find.go @@ -7,7 +7,7 @@ import ( "net/http" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/repo/githttp.go b/routers/web/repo/githttp.go index 27c7f4961d2..8fb6d930688 100644 --- a/routers/web/repo/githttp.go +++ b/routers/web/repo/githttp.go @@ -24,13 +24,13 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" repo_service "code.gitea.io/gitea/services/repository" "github.com/go-chi/cors" diff --git a/routers/web/repo/helper.go b/routers/web/repo/helper.go index a98abe566f8..5e1e116018e 100644 --- a/routers/web/repo/helper.go +++ b/routers/web/repo/helper.go @@ -8,8 +8,8 @@ import ( "sort" "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/services/context" ) func MakeSelfOnTop(doer *user.User, users []*user.User) []*user.User { diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 46d48c46381..ebaa955ac80 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -31,7 +31,6 @@ import ( user_model "code.gitea.io/gitea/models/user" "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" @@ -39,16 +38,19 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" + "code.gitea.io/gitea/modules/optional" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/templates/vars" "code.gitea.io/gitea/modules/timeutil" - "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/utils" asymkey_service "code.gitea.io/gitea/services/asymkey" + "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context/upload" "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/forms" issue_service "code.gitea.io/gitea/services/issue" @@ -1759,7 +1761,7 @@ func ViewIssue(ctx *context.Context) { // so "|" is used as delimeter to mark the new format if comment.Content[0] != '|' { // handle old time comments that have formatted text stored - comment.RenderedContent = comment.Content + comment.RenderedContent = templates.SanitizeHTML(comment.Content) comment.Content = "" } else { // else it's just a duration in seconds to pass on to the frontend @@ -2519,7 +2521,7 @@ func SearchIssues(ctx *context.Context) { Private: false, AllPublic: true, TopicOnly: false, - Collaborate: util.OptionalBoolNone, + Collaborate: optional.None[bool](), // This needs to be a column that is not nil in fixtures or // MySQL will return different results when sorting by null in some cases OrderBy: db.SearchOrderByAlphabetically, @@ -2542,7 +2544,7 @@ func SearchIssues(ctx *context.Context) { opts.OwnerID = owner.ID opts.AllLimited = false opts.AllPublic = false - opts.Collaborate = util.OptionalBoolFalse + opts.Collaborate = optional.Some(false) } if ctx.FormString("team") != "" { if ctx.FormString("owner") == "" { diff --git a/routers/web/repo/issue_content_history.go b/routers/web/repo/issue_content_history.go index 0939af487c1..1ec497658f9 100644 --- a/routers/web/repo/issue_content_history.go +++ b/routers/web/repo/issue_content_history.go @@ -11,11 +11,11 @@ import ( "code.gitea.io/gitea/models/avatars" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/services/context" "github.com/sergi/go-diff/diffmatchpatch" ) @@ -94,7 +94,7 @@ func canSoftDeleteContentHistory(ctx *context.Context, issue *issues_model.Issue // CanWrite means the doer can manage the issue/PR list if ctx.Repo.IsOwner() || ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) { canSoftDelete = true - } else { + } else if ctx.Doer != nil { // for read-only users, they could still post issues or comments, // they should be able to delete the history related to their own issue/comment, a case is: // 1. the user posts some sensitive data @@ -186,6 +186,10 @@ func SoftDeleteContentHistory(ctx *context.Context) { if ctx.Written() { return } + if ctx.Doer == nil { + ctx.NotFound("Require SignIn", nil) + return + } commentID := ctx.FormInt64("comment_id") historyID := ctx.FormInt64("history_id") diff --git a/routers/web/repo/issue_dependency.go b/routers/web/repo/issue_dependency.go index 022ec3ae3e2..e3b85ee638e 100644 --- a/routers/web/repo/issue_dependency.go +++ b/routers/web/repo/issue_dependency.go @@ -8,8 +8,8 @@ import ( issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ) // AddDependency adds new dependencies diff --git a/routers/web/repo/issue_label.go b/routers/web/repo/issue_label.go index dd3e2803b4e..9dedaefa4be 100644 --- a/routers/web/repo/issue_label.go +++ b/routers/web/repo/issue_label.go @@ -10,12 +10,12 @@ import ( issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/label" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" issue_service "code.gitea.io/gitea/services/issue" ) diff --git a/routers/web/repo/issue_label_test.go b/routers/web/repo/issue_label_test.go index 742f12114d5..93fc72300b3 100644 --- a/routers/web/repo/issue_label_test.go +++ b/routers/web/repo/issue_label_test.go @@ -10,10 +10,10 @@ import ( issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/contexttest" "code.gitea.io/gitea/services/forms" "github.com/stretchr/testify/assert" diff --git a/routers/web/repo/issue_lock.go b/routers/web/repo/issue_lock.go index f83109d9b3f..1d5fc8a5f39 100644 --- a/routers/web/repo/issue_lock.go +++ b/routers/web/repo/issue_lock.go @@ -5,8 +5,8 @@ package repo import ( issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" ) diff --git a/routers/web/repo/issue_pin.go b/routers/web/repo/issue_pin.go index 9f334129f94..365c812681a 100644 --- a/routers/web/repo/issue_pin.go +++ b/routers/web/repo/issue_pin.go @@ -7,9 +7,9 @@ import ( "net/http" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/services/context" ) // IssuePinOrUnpin pin or unpin a Issue diff --git a/routers/web/repo/issue_stopwatch.go b/routers/web/repo/issue_stopwatch.go index ab9fe3e69d9..70d42b27c0a 100644 --- a/routers/web/repo/issue_stopwatch.go +++ b/routers/web/repo/issue_stopwatch.go @@ -9,8 +9,8 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/eventsource" + "code.gitea.io/gitea/services/context" ) // IssueStopwatch creates or stops a stopwatch for the given issue. diff --git a/routers/web/repo/issue_timetrack.go b/routers/web/repo/issue_timetrack.go index c9bf861b844..241e4340499 100644 --- a/routers/web/repo/issue_timetrack.go +++ b/routers/web/repo/issue_timetrack.go @@ -9,9 +9,9 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" ) diff --git a/routers/web/repo/issue_watch.go b/routers/web/repo/issue_watch.go index 1f51ceba5e4..8b033f3b17a 100644 --- a/routers/web/repo/issue_watch.go +++ b/routers/web/repo/issue_watch.go @@ -9,8 +9,8 @@ import ( issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/repo/middlewares.go b/routers/web/repo/middlewares.go index d70a53030e6..420931c5fb7 100644 --- a/routers/web/repo/middlewares.go +++ b/routers/web/repo/middlewares.go @@ -9,9 +9,9 @@ import ( system_model "code.gitea.io/gitea/models/system" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/optional" + "code.gitea.io/gitea/services/context" user_service "code.gitea.io/gitea/services/user" ) diff --git a/routers/web/repo/migrate.go b/routers/web/repo/migrate.go index b70901d5f28..97b0c425ea3 100644 --- a/routers/web/repo/migrate.go +++ b/routers/web/repo/migrate.go @@ -15,13 +15,13 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/migrations" "code.gitea.io/gitea/services/task" diff --git a/routers/web/repo/milestone.go b/routers/web/repo/milestone.go index 400748b963d..49ac94aaf15 100644 --- a/routers/web/repo/milestone.go +++ b/routers/web/repo/milestone.go @@ -12,13 +12,13 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/issue" diff --git a/routers/web/repo/packages.go b/routers/web/repo/packages.go index ac9e64d774e..6ed5909dcf6 100644 --- a/routers/web/repo/packages.go +++ b/routers/web/repo/packages.go @@ -10,9 +10,9 @@ import ( "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/repo/patch.go b/routers/web/repo/patch.go index 00bd45aaec1..0dee02dd9ca 100644 --- a/routers/web/repo/patch.go +++ b/routers/web/repo/patch.go @@ -10,10 +10,10 @@ import ( git_model "code.gitea.io/gitea/models/git" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/repository/files" ) diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go index cc0127e7e17..1f9ee727c36 100644 --- a/routers/web/repo/projects.go +++ b/routers/web/repo/projects.go @@ -17,13 +17,13 @@ import ( attachment_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" ) diff --git a/routers/web/repo/projects_test.go b/routers/web/repo/projects_test.go index 6698d47028b..479f8c55a22 100644 --- a/routers/web/repo/projects_test.go +++ b/routers/web/repo/projects_test.go @@ -7,7 +7,7 @@ import ( "testing" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/contexttest" + "code.gitea.io/gitea/services/contexttest" "github.com/stretchr/testify/assert" ) diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index af626dad303..c97edd8720e 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -27,7 +27,6 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/emoji" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" @@ -36,12 +35,13 @@ import ( "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" - "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/utils" asymkey_service "code.gitea.io/gitea/services/asymkey" "code.gitea.io/gitea/services/automerge" + "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context/upload" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/gitdiff" notify_service "code.gitea.io/gitea/services/notify" @@ -112,7 +112,7 @@ func getRepository(ctx *context.Context, repoID int64) *repo_model.Repository { } func getForkRepository(ctx *context.Context) *repo_model.Repository { - forkRepo := getRepository(ctx, ctx.ParamsInt64(":repoid")) + forkRepo := ctx.Repo.Repository if ctx.Written() { return nil } diff --git a/routers/web/repo/pull_review.go b/routers/web/repo/pull_review.go index 92665af7e78..64212291e16 100644 --- a/routers/web/repo/pull_review.go +++ b/routers/web/repo/pull_review.go @@ -11,12 +11,12 @@ import ( issues_model "code.gitea.io/gitea/models/issues" pull_model "code.gitea.io/gitea/models/pull" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context/upload" "code.gitea.io/gitea/services/forms" pull_service "code.gitea.io/gitea/services/pull" ) diff --git a/routers/web/repo/pull_review_test.go b/routers/web/repo/pull_review_test.go index 8fc9cecaf35..5f035f1eb04 100644 --- a/routers/web/repo/pull_review_test.go +++ b/routers/web/repo/pull_review_test.go @@ -10,9 +10,9 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/templates" + "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/contexttest" "code.gitea.io/gitea/services/pull" "github.com/stretchr/testify/assert" diff --git a/routers/web/repo/recent_commits.go b/routers/web/repo/recent_commits.go index 3507cb87521..c158fb30b64 100644 --- a/routers/web/repo/recent_commits.go +++ b/routers/web/repo/recent_commits.go @@ -8,7 +8,7 @@ import ( "net/http" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" contributors_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go index b920ffb6dd0..c6d8c45af10 100644 --- a/routers/web/repo/release.go +++ b/routers/web/repo/release.go @@ -17,16 +17,17 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/web/feed" + "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context/upload" "code.gitea.io/gitea/services/forms" releaseservice "code.gitea.io/gitea/services/release" ) @@ -112,7 +113,7 @@ func getReleaseInfos(ctx *context.Context, opts *repo_model.FindReleasesOptions) cacheUsers[r.PublisherID] = r.Publisher } - r.Note, err = markdown.RenderString(&markup.RenderContext{ + r.RenderedNote, err = markdown.RenderString(&markup.RenderContext{ Links: markup.Links{ Base: ctx.Repo.RepoLink, }, @@ -223,7 +224,7 @@ func TagsList(ctx *context.Context) { // the drafts should also be included because a real tag might be used as a draft. IncludeDrafts: true, IncludeTags: true, - HasSha1: util.OptionalBoolTrue, + HasSha1: optional.Some(true), RepoID: ctx.Repo.Repository.ID, } diff --git a/routers/web/repo/release_test.go b/routers/web/repo/release_test.go index c4a2c1904e3..7ebea4c3fbe 100644 --- a/routers/web/repo/release_test.go +++ b/routers/web/repo/release_test.go @@ -10,8 +10,8 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/contexttest" "code.gitea.io/gitea/services/forms" "github.com/stretchr/testify/assert" diff --git a/routers/web/repo/render.go b/routers/web/repo/render.go index 7eb5a42aa43..10fa21c60e2 100644 --- a/routers/web/repo/render.go +++ b/routers/web/repo/render.go @@ -10,11 +10,11 @@ import ( "path" "code.gitea.io/gitea/modules/charset" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/typesniffer" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" ) // RenderFile renders a file by repos path diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 323413d9766..49779efa375 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -21,7 +21,6 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/cache" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" @@ -31,6 +30,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/forms" repo_service "code.gitea.io/gitea/services/repository" @@ -244,7 +244,7 @@ func CreatePost(ctx *context.Context) { var repo *repo_model.Repository var err error if form.RepoTemplate > 0 { - opts := repo_module.GenerateRepoOptions{ + opts := repo_service.GenerateRepoOptions{ Name: form.RepoName, Description: form.Description, Private: form.Private, @@ -553,33 +553,33 @@ func SearchRepo(ctx *context.Context) { PriorityOwnerID: ctx.FormInt64("priority_owner_id"), TeamID: ctx.FormInt64("team_id"), TopicOnly: ctx.FormBool("topic"), - Collaborate: util.OptionalBoolNone, + Collaborate: optional.None[bool](), Private: ctx.IsSigned && (ctx.FormString("private") == "" || ctx.FormBool("private")), - Template: util.OptionalBoolNone, + Template: optional.None[bool](), StarredByID: ctx.FormInt64("starredBy"), IncludeDescription: ctx.FormBool("includeDesc"), } if ctx.FormString("template") != "" { - opts.Template = util.OptionalBoolOf(ctx.FormBool("template")) + opts.Template = optional.Some(ctx.FormBool("template")) } if ctx.FormBool("exclusive") { - opts.Collaborate = util.OptionalBoolFalse + opts.Collaborate = optional.Some(false) } mode := ctx.FormString("mode") switch mode { case "source": - opts.Fork = util.OptionalBoolFalse - opts.Mirror = util.OptionalBoolFalse + opts.Fork = optional.Some(false) + opts.Mirror = optional.Some(false) case "fork": - opts.Fork = util.OptionalBoolTrue + opts.Fork = optional.Some(true) case "mirror": - opts.Mirror = util.OptionalBoolTrue + opts.Mirror = optional.Some(true) case "collaborative": - opts.Mirror = util.OptionalBoolFalse - opts.Collaborate = util.OptionalBoolTrue + opts.Mirror = optional.Some(false) + opts.Collaborate = optional.Some(true) case "": default: ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid search mode: \"%s\"", mode)) @@ -587,11 +587,11 @@ func SearchRepo(ctx *context.Context) { } if ctx.FormString("archived") != "" { - opts.Archived = util.OptionalBoolOf(ctx.FormBool("archived")) + opts.Archived = optional.Some(ctx.FormBool("archived")) } if ctx.FormString("is_private") != "" { - opts.IsPrivate = util.OptionalBoolOf(ctx.FormBool("is_private")) + opts.IsPrivate = optional.Some(ctx.FormBool("is_private")) } sortMode := ctx.FormString("sort") diff --git a/routers/web/repo/search.go b/routers/web/repo/search.go index 3c0fa4bc00e..c53d8fd918a 100644 --- a/routers/web/repo/search.go +++ b/routers/web/repo/search.go @@ -7,9 +7,9 @@ import ( "net/http" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" code_indexer "code.gitea.io/gitea/modules/indexer/code" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ) const tplSearch base.TplName = "repo/search" diff --git a/routers/web/repo/setting/avatar.go b/routers/web/repo/setting/avatar.go index 44468d2666c..504f57cfc2b 100644 --- a/routers/web/repo/setting/avatar.go +++ b/routers/web/repo/setting/avatar.go @@ -8,11 +8,11 @@ import ( "fmt" "io" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/typesniffer" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" repo_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/web/repo/setting/collaboration.go b/routers/web/repo/setting/collaboration.go index c5c2a88c49c..6bfd4855667 100644 --- a/routers/web/repo/setting/collaboration.go +++ b/routers/web/repo/setting/collaboration.go @@ -13,10 +13,10 @@ import ( repo_model "code.gitea.io/gitea/models/repo" unit_model "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/mailer" org_service "code.gitea.io/gitea/services/org" repo_service "code.gitea.io/gitea/services/repository" diff --git a/routers/web/repo/setting/default_branch.go b/routers/web/repo/setting/default_branch.go index c8a576e5766..881d148afc4 100644 --- a/routers/web/repo/setting/default_branch.go +++ b/routers/web/repo/setting/default_branch.go @@ -7,10 +7,10 @@ import ( "net/http" git_model "code.gitea.io/gitea/models/git" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/routers/web/repo" + "code.gitea.io/gitea/services/context" repo_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/web/repo/setting/deploy_key.go b/routers/web/repo/setting/deploy_key.go index 3d4420006c4..abc3eb4af18 100644 --- a/routers/web/repo/setting/deploy_key.go +++ b/routers/web/repo/setting/deploy_key.go @@ -8,11 +8,11 @@ import ( asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" asymkey_service "code.gitea.io/gitea/services/asymkey" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" ) diff --git a/routers/web/repo/setting/git_hooks.go b/routers/web/repo/setting/git_hooks.go index 551327d44b4..217a01c90c1 100644 --- a/routers/web/repo/setting/git_hooks.go +++ b/routers/web/repo/setting/git_hooks.go @@ -6,8 +6,8 @@ package setting import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/services/context" ) // GitHooks hooks of a repository diff --git a/routers/web/repo/setting/lfs.go b/routers/web/repo/setting/lfs.go index 76a90a4ac58..32049cf0a42 100644 --- a/routers/web/repo/setting/lfs.go +++ b/routers/web/repo/setting/lfs.go @@ -18,7 +18,6 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/container" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git/pipeline" "code.gitea.io/gitea/modules/lfs" @@ -28,6 +27,7 @@ import ( "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/typesniffer" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/repo/setting/protected_branch.go b/routers/web/repo/setting/protected_branch.go index 85068f0ab2a..b30dc3b0614 100644 --- a/routers/web/repo/setting/protected_branch.go +++ b/routers/web/repo/setting/protected_branch.go @@ -15,9 +15,9 @@ import ( "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/web/repo" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" pull_service "code.gitea.io/gitea/services/pull" "code.gitea.io/gitea/services/repository" diff --git a/routers/web/repo/setting/protected_tag.go b/routers/web/repo/setting/protected_tag.go index 46addb3f0ac..2c25b650b97 100644 --- a/routers/web/repo/setting/protected_tag.go +++ b/routers/web/repo/setting/protected_tag.go @@ -13,9 +13,9 @@ import ( "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" ) diff --git a/routers/web/repo/setting/runners.go b/routers/web/repo/setting/runners.go index 8d4112c157b..a47d3b45e2c 100644 --- a/routers/web/repo/setting/runners.go +++ b/routers/web/repo/setting/runners.go @@ -11,10 +11,10 @@ import ( actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" actions_shared "code.gitea.io/gitea/routers/web/shared/actions" shared_user "code.gitea.io/gitea/routers/web/shared/user" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/repo/setting/secrets.go b/routers/web/repo/setting/secrets.go index cf427b2c44b..d4d56bfc57e 100644 --- a/routers/web/repo/setting/secrets.go +++ b/routers/web/repo/setting/secrets.go @@ -8,10 +8,10 @@ import ( "net/http" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" shared "code.gitea.io/gitea/routers/web/shared/secrets" shared_user "code.gitea.io/gitea/routers/web/shared/user" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go index 3b11638a920..0f649acba31 100644 --- a/routers/web/repo/setting/setting.go +++ b/routers/web/repo/setting/setting.go @@ -18,19 +18,18 @@ import ( unit_model "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/indexer/code" "code.gitea.io/gitea/modules/indexer/stats" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" - repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web" asymkey_service "code.gitea.io/gitea/services/asymkey" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/migrations" mirror_service "code.gitea.io/gitea/services/mirror" @@ -693,7 +692,7 @@ func SettingsPost(ctx *context.Context) { } repo.IsMirror = false - if _, err := repo_module.CleanUpMigrateInfo(ctx, repo); err != nil { + if _, err := repo_service.CleanUpMigrateInfo(ctx, repo); err != nil { ctx.ServerError("CleanUpMigrateInfo", err) return } else if err = repo_model.DeleteMirrorByRepoID(ctx, ctx.Repo.Repository.ID); err != nil { diff --git a/routers/web/repo/setting/settings_test.go b/routers/web/repo/setting/settings_test.go index 066d2ef2a9f..09586cc68d6 100644 --- a/routers/web/repo/setting/settings_test.go +++ b/routers/web/repo/setting/settings_test.go @@ -14,10 +14,10 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/contexttest" "code.gitea.io/gitea/services/forms" repo_service "code.gitea.io/gitea/services/repository" diff --git a/routers/web/repo/setting/variables.go b/routers/web/repo/setting/variables.go index 428aa0bd5c4..45b6c0f39a6 100644 --- a/routers/web/repo/setting/variables.go +++ b/routers/web/repo/setting/variables.go @@ -8,10 +8,10 @@ import ( "net/http" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" shared "code.gitea.io/gitea/routers/web/shared/actions" shared_user "code.gitea.io/gitea/routers/web/shared/user" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index c12d7e82a66..bba4d4df51e 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -18,7 +18,6 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/setting" @@ -26,6 +25,7 @@ import ( "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" webhook_module "code.gitea.io/gitea/modules/webhook" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/forms" webhook_service "code.gitea.io/gitea/services/webhook" diff --git a/routers/web/repo/topic.go b/routers/web/repo/topic.go index d0e706c5bd7..d81a695df97 100644 --- a/routers/web/repo/topic.go +++ b/routers/web/repo/topic.go @@ -8,8 +8,8 @@ import ( "strings" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/services/context" ) // TopicsPost response for creating repository diff --git a/routers/web/repo/treelist.go b/routers/web/repo/treelist.go index c364e7090f7..d11af4669f9 100644 --- a/routers/web/repo/treelist.go +++ b/routers/web/repo/treelist.go @@ -7,8 +7,8 @@ import ( "net/http" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/services/context" "github.com/go-enry/go-enry/v2" ) diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 48a35dd0605..e89739e2fb6 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -36,7 +36,6 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/container" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/highlight" "code.gitea.io/gitea/modules/lfs" @@ -49,6 +48,7 @@ import ( "code.gitea.io/gitea/modules/typesniffer" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/web/feed" + "code.gitea.io/gitea/services/context" issue_service "code.gitea.io/gitea/services/issue" files_service "code.gitea.io/gitea/services/repository/files" diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index 49e95faaba2..91cf727e2c5 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -18,7 +18,6 @@ import ( "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" @@ -29,6 +28,7 @@ import ( "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/common" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" notify_service "code.gitea.io/gitea/services/notify" wiki_service "code.gitea.io/gitea/services/wiki" diff --git a/routers/web/repo/wiki_test.go b/routers/web/repo/wiki_test.go index d3decdae2de..49c83cfef59 100644 --- a/routers/web/repo/wiki_test.go +++ b/routers/web/repo/wiki_test.go @@ -11,10 +11,10 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/contexttest" "code.gitea.io/gitea/services/forms" wiki_service "code.gitea.io/gitea/services/wiki" diff --git a/routers/web/shared/actions/runners.go b/routers/web/shared/actions/runners.go index ae9a3767241..34b79694427 100644 --- a/routers/web/shared/actions/runners.go +++ b/routers/web/shared/actions/runners.go @@ -8,10 +8,10 @@ import ( actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" ) diff --git a/routers/web/shared/actions/variables.go b/routers/web/shared/actions/variables.go index 07a05752078..0f705399c97 100644 --- a/routers/web/shared/actions/variables.go +++ b/routers/web/shared/actions/variables.go @@ -10,9 +10,9 @@ import ( actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" secret_service "code.gitea.io/gitea/services/secrets" ) diff --git a/routers/web/shared/packages/packages.go b/routers/web/shared/packages/packages.go index 30c25374d1b..1454396f041 100644 --- a/routers/web/shared/packages/packages.go +++ b/routers/web/shared/packages/packages.go @@ -12,10 +12,10 @@ import ( packages_model "code.gitea.io/gitea/models/packages" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" cargo_service "code.gitea.io/gitea/services/packages/cargo" container_service "code.gitea.io/gitea/services/packages/container" diff --git a/routers/web/shared/secrets/secrets.go b/routers/web/shared/secrets/secrets.go index c805da734ac..73505ec372d 100644 --- a/routers/web/shared/secrets/secrets.go +++ b/routers/web/shared/secrets/secrets.go @@ -6,10 +6,10 @@ package secrets import ( "code.gitea.io/gitea/models/db" secret_model "code.gitea.io/gitea/models/secret" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/web/shared/actions" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" secret_service "code.gitea.io/gitea/services/secrets" ) diff --git a/routers/web/shared/user/header.go b/routers/web/shared/user/header.go index 99b701b4392..51b04e0613a 100644 --- a/routers/web/shared/user/header.go +++ b/routers/web/shared/user/header.go @@ -13,12 +13,13 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" ) // prepareContextForCommonProfile store some common data into context data for user's profile related pages (including the nav menu) @@ -35,8 +36,9 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) { prepareContextForCommonProfile(ctx) ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail && ctx.ContextUser.Email != "" && ctx.IsSigned && !ctx.ContextUser.KeepEmailPrivate - ctx.Data["ContextUserLocationMapURL"] = setting.Service.UserLocationMapURL + url.QueryEscape(ctx.ContextUser.Location) - + if 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) if err != nil { @@ -113,7 +115,7 @@ func LoadHeaderCount(ctx *context.Context) error { Actor: ctx.Doer, OwnerID: ctx.ContextUser.ID, Private: ctx.IsSigned, - Collaborate: util.OptionalBoolFalse, + Collaborate: optional.Some(false), IncludeDescription: setting.UI.SearchRepoDescription, }) if err != nil { diff --git a/routers/web/swagger_json.go b/routers/web/swagger_json.go index 42e9dbe9670..fc39b504a92 100644 --- a/routers/web/swagger_json.go +++ b/routers/web/swagger_json.go @@ -4,7 +4,7 @@ package web import ( - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" ) // SwaggerV1Json render swagger v1 json diff --git a/routers/web/user/avatar.go b/routers/web/user/avatar.go index 772cc38bea0..04f510161db 100644 --- a/routers/web/user/avatar.go +++ b/routers/web/user/avatar.go @@ -9,8 +9,8 @@ import ( "code.gitea.io/gitea/models/avatars" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/httpcache" + "code.gitea.io/gitea/services/context" ) func cacheableRedirect(ctx *context.Context, location string) { diff --git a/routers/web/user/code.go b/routers/web/user/code.go index ee514a7cfe5..eb711b76ebb 100644 --- a/routers/web/user/code.go +++ b/routers/web/user/code.go @@ -8,10 +8,10 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" code_indexer "code.gitea.io/gitea/modules/indexer/code" "code.gitea.io/gitea/modules/setting" shared_user "code.gitea.io/gitea/routers/web/shared/user" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/user/home.go b/routers/web/user/home.go index b7abbcbc002..6f36806ff75 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -24,15 +24,15 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/container" - "code.gitea.io/gitea/modules/context" issue_indexer "code.gitea.io/gitea/modules/indexer/issues" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/web/feed" - context_service "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context" issue_service "code.gitea.io/gitea/services/issue" pull_service "code.gitea.io/gitea/services/pull" @@ -162,8 +162,8 @@ func Milestones(ctx *context.Context) { Private: true, AllPublic: false, // Include also all public repositories of users and public organisations AllLimited: false, // Include also all public repositories of limited organisations - Archived: util.OptionalBoolFalse, - HasMilestones: util.OptionalBoolTrue, // Just needs display repos has milestones + Archived: optional.Some(false), + HasMilestones: optional.Some(true), // Just needs display repos has milestones } if ctxUser.IsOrganization() && ctx.Org.Team != nil { @@ -466,9 +466,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { Private: true, AllPublic: false, AllLimited: false, - Collaborate: util.OptionalBoolNone, + Collaborate: optional.None[bool](), UnitType: unitType, - Archived: util.OptionalBoolFalse, + Archived: optional.Some(false), } if team != nil { repoOpts.TeamID = team.ID @@ -714,7 +714,7 @@ func UsernameSubRoute(ctx *context.Context) { username := ctx.Params("username") reloadParam := func(suffix string) (success bool) { ctx.SetParams("username", strings.TrimSuffix(username, suffix)) - context_service.UserAssignmentWeb()(ctx) + context.UserAssignmentWeb()(ctx) // check view permissions if !user_model.IsUserVisibleToViewer(ctx, ctx.ContextUser, ctx.Doer) { ctx.NotFound("user", fmt.Errorf(ctx.ContextUser.Name)) @@ -741,7 +741,7 @@ func UsernameSubRoute(ctx *context.Context) { return } if reloadParam(".rss") { - context_service.UserAssignmentWeb()(ctx) + context.UserAssignmentWeb()(ctx) feed.ShowUserFeedRSS(ctx) } case strings.HasSuffix(username, ".atom"): @@ -753,7 +753,7 @@ func UsernameSubRoute(ctx *context.Context) { feed.ShowUserFeedAtom(ctx) } default: - context_service.UserAssignmentWeb()(ctx) + context.UserAssignmentWeb()(ctx) if !ctx.Written() { ctx.Data["EnableFeed"] = setting.Other.EnableFeed OwnerProfile(ctx) diff --git a/routers/web/user/home_test.go b/routers/web/user/home_test.go index a32b015cd1d..3f5fd266895 100644 --- a/routers/web/user/home_test.go +++ b/routers/web/user/home_test.go @@ -10,8 +10,8 @@ import ( "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/contexttest" "github.com/stretchr/testify/assert" ) diff --git a/routers/web/user/notification.go b/routers/web/user/notification.go index 26f77cfc3a3..801e1cf95ea 100644 --- a/routers/web/user/notification.go +++ b/routers/web/user/notification.go @@ -16,11 +16,12 @@ import ( issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" issue_service "code.gitea.io/gitea/services/issue" pull_service "code.gitea.io/gitea/services/pull" ) @@ -399,7 +400,7 @@ func NotificationWatching(ctx *context.Context) { OrderBy: orderBy, Private: ctx.IsSigned, WatchedByID: ctx.Doer.ID, - Collaborate: util.OptionalBoolFalse, + Collaborate: optional.Some(false), TopicOnly: ctx.FormBool("topic"), IncludeDescription: setting.UI.SearchRepoDescription, }) diff --git a/routers/web/user/package.go b/routers/web/user/package.go index 708af3e43c9..d03b28309fd 100644 --- a/routers/web/user/package.go +++ b/routers/web/user/package.go @@ -15,7 +15,6 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/container" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" alpine_module "code.gitea.io/gitea/modules/packages/alpine" debian_module "code.gitea.io/gitea/modules/packages/debian" @@ -25,6 +24,7 @@ import ( "code.gitea.io/gitea/modules/web" packages_helper "code.gitea.io/gitea/routers/api/packages/helper" shared_user "code.gitea.io/gitea/routers/web/shared/user" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" packages_service "code.gitea.io/gitea/services/packages" ) diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go index 4d0ad06cbad..b9b069b0d4c 100644 --- a/routers/web/user/profile.go +++ b/routers/web/user/profile.go @@ -15,16 +15,17 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/web/feed" "code.gitea.io/gitea/routers/web/org" shared_user "code.gitea.io/gitea/routers/web/shared/user" + "code.gitea.io/gitea/services/context" ) const ( @@ -203,7 +204,7 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb OrderBy: orderBy, Private: ctx.IsSigned, StarredByID: ctx.ContextUser.ID, - Collaborate: util.OptionalBoolFalse, + Collaborate: optional.Some(false), TopicOnly: topicOnly, Language: language, IncludeDescription: setting.UI.SearchRepoDescription, @@ -225,7 +226,7 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb OrderBy: orderBy, Private: ctx.IsSigned, WatchedByID: ctx.ContextUser.ID, - Collaborate: util.OptionalBoolFalse, + Collaborate: optional.Some(false), TopicOnly: topicOnly, Language: language, IncludeDescription: setting.UI.SearchRepoDescription, @@ -270,7 +271,7 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb OwnerID: ctx.ContextUser.ID, OrderBy: orderBy, Private: ctx.IsSigned, - Collaborate: util.OptionalBoolFalse, + Collaborate: optional.Some(false), TopicOnly: topicOnly, Language: language, IncludeDescription: setting.UI.SearchRepoDescription, diff --git a/routers/web/user/search.go b/routers/web/user/search.go index 4d090a3784c..fb7729bbe14 100644 --- a/routers/web/user/search.go +++ b/routers/web/user/search.go @@ -8,7 +8,7 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go index 659c3e29c1e..abb5873e98a 100644 --- a/routers/web/user/setting/account.go +++ b/routers/web/user/setting/account.go @@ -13,13 +13,13 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/auth/password" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/auth" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/mailer" "code.gitea.io/gitea/services/user" @@ -92,9 +92,9 @@ func EmailPost(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true - // Make emailaddress primary. + // Make email address primary. if ctx.FormString("_method") == "PRIMARY" { - if err := user_model.MakeEmailPrimary(ctx, &user_model.EmailAddress{ID: ctx.FormInt64("id")}); err != nil { + if err := user_model.MakeActiveEmailPrimary(ctx, ctx.FormInt64("id")); err != nil { ctx.ServerError("MakeEmailPrimary", err) return } diff --git a/routers/web/user/setting/account_test.go b/routers/web/user/setting/account_test.go index 6742c382e97..9fdc5e4d532 100644 --- a/routers/web/user/setting/account_test.go +++ b/routers/web/user/setting/account_test.go @@ -8,9 +8,9 @@ import ( "testing" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/contexttest" "code.gitea.io/gitea/services/forms" "github.com/stretchr/testify/assert" diff --git a/routers/web/user/setting/adopt.go b/routers/web/user/setting/adopt.go index decb35c1e17..171c1933d4f 100644 --- a/routers/web/user/setting/adopt.go +++ b/routers/web/user/setting/adopt.go @@ -8,9 +8,9 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" repo_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/web/user/setting/applications.go b/routers/web/user/setting/applications.go index a7e31fd5051..e3822ca988c 100644 --- a/routers/web/user/setting/applications.go +++ b/routers/web/user/setting/applications.go @@ -10,9 +10,9 @@ import ( auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" ) diff --git a/routers/web/user/setting/keys.go b/routers/web/user/setting/keys.go index 16410d06ff0..cb01913bdaf 100644 --- a/routers/web/user/setting/keys.go +++ b/routers/web/user/setting/keys.go @@ -5,15 +5,16 @@ package setting import ( + "fmt" "net/http" asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" asymkey_service "code.gitea.io/gitea/services/asymkey" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" ) @@ -77,6 +78,11 @@ func KeysPost(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("settings.add_principal_success", form.Content)) ctx.Redirect(setting.AppSubURL + "/user/settings/keys") case "gpg": + if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageGPGKeys) { + ctx.NotFound("Not Found", fmt.Errorf("gpg keys setting is not allowed to be visited")) + return + } + token := asymkey_model.VerificationToken(ctx.Doer, 1) lastToken := asymkey_model.VerificationToken(ctx.Doer, 0) @@ -224,6 +230,10 @@ func KeysPost(ctx *context.Context) { func DeleteKey(ctx *context.Context) { switch ctx.FormString("type") { case "gpg": + if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageGPGKeys) { + ctx.NotFound("Not Found", fmt.Errorf("gpg keys setting is not allowed to be visited")) + return + } if err := asymkey_model.DeleteGPGKey(ctx, ctx.Doer, ctx.FormInt64("id")); err != nil { ctx.Flash.Error("DeleteGPGKey: " + err.Error()) } else { diff --git a/routers/web/user/setting/oauth2.go b/routers/web/user/setting/oauth2.go index 93142c21fcf..1f485e06c81 100644 --- a/routers/web/user/setting/oauth2.go +++ b/routers/web/user/setting/oauth2.go @@ -5,8 +5,8 @@ package setting import ( "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/user/setting/oauth2_common.go b/routers/web/user/setting/oauth2_common.go index fecaa4b873e..85d1e820a51 100644 --- a/routers/web/user/setting/oauth2_common.go +++ b/routers/web/user/setting/oauth2_common.go @@ -9,10 +9,10 @@ import ( "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" shared_user "code.gitea.io/gitea/routers/web/shared/user" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" ) diff --git a/routers/web/user/setting/packages.go b/routers/web/user/setting/packages.go index 34d18f999e2..41326594953 100644 --- a/routers/web/user/setting/packages.go +++ b/routers/web/user/setting/packages.go @@ -9,11 +9,11 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" chef_module "code.gitea.io/gitea/modules/packages/chef" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" shared "code.gitea.io/gitea/routers/web/shared/packages" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go index 24a807d518f..49eb050dcb6 100644 --- a/routers/web/user/setting/profile.go +++ b/routers/web/user/setting/profile.go @@ -20,7 +20,6 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" @@ -29,6 +28,7 @@ import ( "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web/middleware" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" user_service "code.gitea.io/gitea/services/user" ) diff --git a/routers/web/user/setting/runner.go b/routers/web/user/setting/runner.go index 451fd0ca97a..2bb10cceb95 100644 --- a/routers/web/user/setting/runner.go +++ b/routers/web/user/setting/runner.go @@ -4,8 +4,8 @@ package setting import ( - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ) func RedirectToDefaultSetting(ctx *context.Context) { diff --git a/routers/web/user/setting/security/2fa.go b/routers/web/user/setting/security/2fa.go index 7858b634ce3..cd091023698 100644 --- a/routers/web/user/setting/security/2fa.go +++ b/routers/web/user/setting/security/2fa.go @@ -13,10 +13,10 @@ import ( "strings" "code.gitea.io/gitea/models/auth" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" "github.com/pquerna/otp" diff --git a/routers/web/user/setting/security/openid.go b/routers/web/user/setting/security/openid.go index 9a207e149d1..8f788e17356 100644 --- a/routers/web/user/setting/security/openid.go +++ b/routers/web/user/setting/security/openid.go @@ -8,10 +8,10 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/auth/openid" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" ) diff --git a/routers/web/user/setting/security/security.go b/routers/web/user/setting/security/security.go index 3647d606eef..30611dd9f19 100644 --- a/routers/web/user/setting/security/security.go +++ b/routers/web/user/setting/security/security.go @@ -12,10 +12,10 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/services/auth/source/oauth2" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/user/setting/security/webauthn.go b/routers/web/user/setting/security/webauthn.go index ce103528c57..e382c8b9af4 100644 --- a/routers/web/user/setting/security/webauthn.go +++ b/routers/web/user/setting/security/webauthn.go @@ -11,10 +11,10 @@ import ( "code.gitea.io/gitea/models/auth" wa "code.gitea.io/gitea/modules/auth/webauthn" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" "github.com/go-webauthn/webauthn/protocol" diff --git a/routers/web/user/setting/webhooks.go b/routers/web/user/setting/webhooks.go index 679b72e5011..4423b627814 100644 --- a/routers/web/user/setting/webhooks.go +++ b/routers/web/user/setting/webhooks.go @@ -9,8 +9,8 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ) const ( diff --git a/routers/web/user/stop_watch.go b/routers/web/user/stop_watch.go index 86f66e64a69..38f74ea4554 100644 --- a/routers/web/user/stop_watch.go +++ b/routers/web/user/stop_watch.go @@ -8,7 +8,7 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/routers/web/user/task.go b/routers/web/user/task.go index bec68c5f209..8476767e9e0 100644 --- a/routers/web/user/task.go +++ b/routers/web/user/task.go @@ -8,8 +8,8 @@ import ( "strconv" admin_model "code.gitea.io/gitea/models/admin" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" + "code.gitea.io/gitea/services/context" ) // TaskStatus returns task's status diff --git a/routers/web/web.go b/routers/web/web.go index b1fa5cf3550..9de652fba53 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -12,7 +12,6 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/metrics" "code.gitea.io/gitea/modules/public" @@ -42,7 +41,7 @@ import ( user_setting "code.gitea.io/gitea/routers/web/user/setting" "code.gitea.io/gitea/routers/web/user/setting/security" auth_service "code.gitea.io/gitea/services/auth" - context_service "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/lfs" @@ -790,7 +789,7 @@ func registerRoutes(m *web.Route) { m.Methods("GET, OPTIONS", "/attachments/{uuid}", optionsCorsHandler(), repo.GetAttachment) }, ignSignIn) - m.Post("/{username}", reqSignIn, context_service.UserAssignmentWeb(), user.Action) + m.Post("/{username}", reqSignIn, context.UserAssignmentWeb(), user.Action) reqRepoAdmin := context.RequireRepoAdmin() reqRepoCodeWriter := context.RequireRepoWriter(unit.TypeCode) @@ -957,10 +956,6 @@ func registerRoutes(m *web.Route) { m.Post("/create", web.Bind(forms.CreateRepoForm{}), repo.CreatePost) m.Get("/migrate", repo.Migrate) m.Post("/migrate", web.Bind(forms.MigrateRepoForm{}), repo.MigratePost) - m.Group("/fork", func() { - m.Combo("/{repoid}").Get(repo.Fork). - Post(web.Bind(forms.CreateRepoForm{}), repo.ForkPost) - }, context.RepoIDAssignment(), context.UnitTypes(), reqRepoCodeReader) m.Get("/search", repo.SearchRepo) }, reqSignIn) @@ -1019,7 +1014,7 @@ func registerRoutes(m *web.Route) { m.Group("", func() { m.Get("/code", user.CodeSearch) }, reqUnitAccess(unit.TypeCode, perm.AccessModeRead, false), individualPermsChecker) - }, ignSignIn, context_service.UserAssignmentWeb(), context.OrgAssignment()) // for "/{username}/-" (packages, projects, code) + }, ignSignIn, context.UserAssignmentWeb(), context.OrgAssignment()) // for "/{username}/-" (packages, projects, code) m.Group("/{username}/{reponame}", func() { m.Group("/settings", func() { @@ -1256,6 +1251,8 @@ func registerRoutes(m *web.Route) { m.Post("/delete", repo.DeleteBranchPost) m.Post("/restore", repo.RestoreBranchPost) }, context.RepoMustNotBeArchived(), reqRepoCodeWriter, repo.MustBeNotEmpty) + + m.Combo("/fork", reqRepoCodeReader).Get(repo.Fork).Post(web.Bind(forms.CreateRepoForm{}), repo.ForkPost) }, reqSignIn, context.RepoAssignment, context.UnitTypes()) // Tags @@ -1372,6 +1369,9 @@ func registerRoutes(m *web.Route) { m.Delete("/artifacts/{artifact_name}", actions.ArtifactsDeleteView) m.Post("/rerun", reqRepoActionsWriter, actions.Rerun) }) + m.Group("/workflows/{workflow_name}", func() { + m.Get("/badge.svg", actions.GetWorkflowBadge) + }) }, reqRepoActionsReader, actions.MustEnableActions) m.Group("/wiki", func() { diff --git a/routers/web/webfinger.go b/routers/web/webfinger.go index faa35b8d2f5..a87c426b3ba 100644 --- a/routers/web/webfinger.go +++ b/routers/web/webfinger.go @@ -10,9 +10,9 @@ import ( "strings" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ) // https://datatracker.ietf.org/doc/html/draft-ietf-appsawg-webfinger-14#section-4.4 diff --git a/services/actions/job_emitter.go b/services/actions/job_emitter.go index fe39312386d..d2bbbd9a7ca 100644 --- a/services/actions/job_emitter.go +++ b/services/actions/job_emitter.go @@ -7,12 +7,14 @@ import ( "context" "errors" "fmt" + "strings" actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/queue" + "github.com/nektos/act/pkg/jobparser" "xorm.io/builder" ) @@ -76,12 +78,15 @@ func checkJobsOfRun(ctx context.Context, runID int64) error { type jobStatusResolver struct { statuses map[int64]actions_model.Status needs map[int64][]int64 + jobMap map[int64]*actions_model.ActionRunJob } func newJobStatusResolver(jobs actions_model.ActionJobList) *jobStatusResolver { idToJobs := make(map[string][]*actions_model.ActionRunJob, len(jobs)) + jobMap := make(map[int64]*actions_model.ActionRunJob) for _, job := range jobs { idToJobs[job.JobID] = append(idToJobs[job.JobID], job) + jobMap[job.ID] = job } statuses := make(map[int64]actions_model.Status, len(jobs)) @@ -97,6 +102,7 @@ func newJobStatusResolver(jobs actions_model.ActionJobList) *jobStatusResolver { return &jobStatusResolver{ statuses: statuses, needs: needs, + jobMap: jobMap, } } @@ -135,7 +141,20 @@ func (r *jobStatusResolver) resolve() map[int64]actions_model.Status { if allSucceed { ret[id] = actions_model.StatusWaiting } else { - ret[id] = actions_model.StatusSkipped + // If a job's "if" condition is "always()", the job should always run even if some of its dependencies did not succeed. + // See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idneeds + always := false + if wfJobs, _ := jobparser.Parse(r.jobMap[id].WorkflowPayload); len(wfJobs) == 1 { + _, wfJob := wfJobs[0].Job() + expr := strings.TrimSpace(strings.TrimSuffix(strings.TrimPrefix(wfJob.If.Value, "${{"), "}}")) + always = expr == "always()" + } + + if always { + ret[id] = actions_model.StatusWaiting + } else { + ret[id] = actions_model.StatusSkipped + } } } } diff --git a/services/actions/job_emitter_test.go b/services/actions/job_emitter_test.go index e81aa61d807..038df7d4f86 100644 --- a/services/actions/job_emitter_test.go +++ b/services/actions/job_emitter_test.go @@ -70,6 +70,62 @@ func Test_jobStatusResolver_Resolve(t *testing.T) { }, want: map[int64]actions_model.Status{}, }, + { + name: "with ${{ always() }} condition", + jobs: actions_model.ActionJobList{ + {ID: 1, JobID: "job1", Status: actions_model.StatusFailure, Needs: []string{}}, + {ID: 2, JobID: "job2", Status: actions_model.StatusBlocked, Needs: []string{"job1"}, WorkflowPayload: []byte( + ` +name: test +on: push +jobs: + job2: + runs-on: ubuntu-latest + needs: job1 + if: ${{ always() }} + steps: + - run: echo "always run" +`)}, + }, + want: map[int64]actions_model.Status{2: actions_model.StatusWaiting}, + }, + { + name: "with always() condition", + jobs: actions_model.ActionJobList{ + {ID: 1, JobID: "job1", Status: actions_model.StatusFailure, Needs: []string{}}, + {ID: 2, JobID: "job2", Status: actions_model.StatusBlocked, Needs: []string{"job1"}, WorkflowPayload: []byte( + ` +name: test +on: push +jobs: + job2: + runs-on: ubuntu-latest + needs: job1 + if: always() + steps: + - run: echo "always run" +`)}, + }, + want: map[int64]actions_model.Status{2: actions_model.StatusWaiting}, + }, + { + name: "without always() condition", + jobs: actions_model.ActionJobList{ + {ID: 1, JobID: "job1", Status: actions_model.StatusFailure, Needs: []string{}}, + {ID: 2, JobID: "job2", Status: actions_model.StatusBlocked, Needs: []string{"job1"}, WorkflowPayload: []byte( + ` +name: test +on: push +jobs: + job2: + runs-on: ubuntu-latest + needs: job1 + steps: + - run: echo "not always run" +`)}, + }, + want: map[int64]actions_model.Status{2: actions_model.StatusSkipped}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/services/actions/notifier.go b/services/actions/notifier.go index e144484dabd..1e99c51a8b0 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -152,7 +152,13 @@ func (n *actionsNotifier) IssueChangeAssignee(ctx context.Context, doer *user_mo } else { action = api.HookIssueAssigned } - notifyIssueChange(ctx, doer, issue, webhook_module.HookEventPullRequestAssign, action) + + hookEvent := webhook_module.HookEventIssueAssign + if issue.IsPull { + hookEvent = webhook_module.HookEventPullRequestAssign + } + + notifyIssueChange(ctx, doer, issue, hookEvent, action) } // IssueChangeMilestone notifies assignee to notifiers diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index c20335af6f3..b248af1d018 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -117,6 +117,9 @@ func notify(ctx context.Context, input *notifyInput) error { log.Debug("ignore executing %v for event %v whose doer is %v", getMethod(ctx), input.Event, input.Doer.Name) return nil } + if input.Repo.IsEmpty { + return nil + } if unit_model.TypeActions.UnitGlobalDisabled() { if err := actions_model.CleanRepoScheduleTasks(ctx, input.Repo); err != nil { log.Error("CleanRepoScheduleTasks: %v", err) diff --git a/services/attachment/attachment.go b/services/attachment/attachment.go index 967332fd982..eab3d0b142a 100644 --- a/services/attachment/attachment.go +++ b/services/attachment/attachment.go @@ -12,8 +12,8 @@ import ( "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/storage" - "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context/upload" "github.com/google/uuid" ) diff --git a/services/auth/auth.go b/services/auth/auth.go index 7c07dc438e4..a2523a2452e 100644 --- a/services/auth/auth.go +++ b/services/auth/auth.go @@ -12,12 +12,12 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/auth/webauthn" - gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/session" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web/middleware" + gitea_context "code.gitea.io/gitea/services/context" user_service "code.gitea.io/gitea/services/user" ) diff --git a/services/auth/sspi.go b/services/auth/sspi.go index 8c0fc77a96f..9108a0a668a 100644 --- a/services/auth/sspi.go +++ b/services/auth/sspi.go @@ -14,13 +14,13 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" - gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/services/auth/source/sspi" + gitea_context "code.gitea.io/gitea/services/context" gouuid "github.com/google/uuid" ) diff --git a/modules/context/access_log.go b/services/context/access_log.go similarity index 100% rename from modules/context/access_log.go rename to services/context/access_log.go diff --git a/modules/context/api.go b/services/context/api.go similarity index 100% rename from modules/context/api.go rename to services/context/api.go diff --git a/modules/context/api_org.go b/services/context/api_org.go similarity index 100% rename from modules/context/api_org.go rename to services/context/api_org.go diff --git a/modules/context/api_test.go b/services/context/api_test.go similarity index 100% rename from modules/context/api_test.go rename to services/context/api_test.go diff --git a/modules/context/base.go b/services/context/base.go similarity index 92% rename from modules/context/base.go rename to services/context/base.go index fa05850a166..c4aa467ff42 100644 --- a/modules/context/base.go +++ b/services/context/base.go @@ -17,8 +17,8 @@ import ( "code.gitea.io/gitea/modules/httplib" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/translation" - "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web/middleware" "github.com/go-chi/chi/v5" @@ -207,17 +207,17 @@ func (b *Base) FormBool(key string) bool { return v } -// FormOptionalBool returns an OptionalBoolTrue or OptionalBoolFalse if the value -// for the provided key exists in the form else it returns OptionalBoolNone -func (b *Base) FormOptionalBool(key string) util.OptionalBool { +// FormOptionalBool returns an optional.Some(true) or optional.Some(false) if the value +// for the provided key exists in the form else it returns optional.None[bool]() +func (b *Base) FormOptionalBool(key string) optional.Option[bool] { value := b.Req.FormValue(key) if len(value) == 0 { - return util.OptionalBoolNone + return optional.None[bool]() } s := b.Req.FormValue(key) v, _ := strconv.ParseBool(s) v = v || strings.EqualFold(s, "on") - return util.OptionalBoolOf(v) + return optional.Some(v) } func (b *Base) SetFormString(key, value string) { @@ -265,6 +265,14 @@ func (b *Base) Redirect(location string, status ...int) { // So in this case, we should remove the session cookie from the response header removeSessionCookieHeader(b.Resp) } + // in case the request is made by htmx, have it redirect the browser instead of trying to follow the redirect inside htmx + if b.Req.Header.Get("HX-Request") == "true" { + b.Resp.Header().Set("HX-Redirect", location) + // we have to return a non-redirect status code so XMLHTTPRequest will not immediately follow the redirect + // so as to give htmx redirect logic a chance to run + b.Status(http.StatusNoContent) + return + } http.Redirect(b.Resp, b.Req, location, code) } diff --git a/modules/context/captcha.go b/services/context/captcha.go similarity index 100% rename from modules/context/captcha.go rename to services/context/captcha.go diff --git a/modules/context/context.go b/services/context/context.go similarity index 100% rename from modules/context/context.go rename to services/context/context.go diff --git a/modules/context/context_cookie.go b/services/context/context_cookie.go similarity index 100% rename from modules/context/context_cookie.go rename to services/context/context_cookie.go diff --git a/modules/context/context_model.go b/services/context/context_model.go similarity index 100% rename from modules/context/context_model.go rename to services/context/context_model.go diff --git a/modules/context/context_request.go b/services/context/context_request.go similarity index 100% rename from modules/context/context_request.go rename to services/context/context_request.go diff --git a/modules/context/context_response.go b/services/context/context_response.go similarity index 100% rename from modules/context/context_response.go rename to services/context/context_response.go diff --git a/modules/context/context_template.go b/services/context/context_template.go similarity index 100% rename from modules/context/context_template.go rename to services/context/context_template.go diff --git a/modules/context/context_test.go b/services/context/context_test.go similarity index 100% rename from modules/context/context_test.go rename to services/context/context_test.go diff --git a/modules/context/csrf.go b/services/context/csrf.go similarity index 100% rename from modules/context/csrf.go rename to services/context/csrf.go diff --git a/modules/context/org.go b/services/context/org.go similarity index 100% rename from modules/context/org.go rename to services/context/org.go diff --git a/modules/context/package.go b/services/context/package.go similarity index 100% rename from modules/context/package.go rename to services/context/package.go diff --git a/modules/context/pagination.go b/services/context/pagination.go similarity index 100% rename from modules/context/pagination.go rename to services/context/pagination.go diff --git a/modules/context/permission.go b/services/context/permission.go similarity index 100% rename from modules/context/permission.go rename to services/context/permission.go diff --git a/modules/context/private.go b/services/context/private.go similarity index 100% rename from modules/context/private.go rename to services/context/private.go diff --git a/modules/context/repo.go b/services/context/repo.go similarity index 98% rename from modules/context/repo.go rename to services/context/repo.go index a73d09ee21b..0b15c95e59f 100644 --- a/modules/context/repo.go +++ b/services/context/repo.go @@ -408,26 +408,6 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) { ctx.Data["IsEmptyRepo"] = ctx.Repo.Repository.IsEmpty } -// RepoIDAssignment returns a handler which assigns the repo to the context. -func RepoIDAssignment() func(ctx *Context) { - return func(ctx *Context) { - repoID := ctx.ParamsInt64(":repoid") - - // Get repository. - repo, err := repo_model.GetRepositoryByID(ctx, repoID) - if err != nil { - if repo_model.IsErrRepoNotExist(err) { - ctx.NotFound("GetRepositoryByID", nil) - } else { - ctx.ServerError("GetRepositoryByID", err) - } - return - } - - repoAssignment(ctx, repo) - } -} - // RepoAssignment returns a middleware to handle repository assignment func RepoAssignment(ctx *Context) context.CancelFunc { if _, repoAssignmentOnce := ctx.Data["repoAssignmentExecuted"]; repoAssignmentOnce { @@ -546,7 +526,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc { ctx.Data["NumTags"], err = db.Count[repo_model.Release](ctx, repo_model.FindReleasesOptions{ IncludeDrafts: true, IncludeTags: true, - HasSha1: util.OptionalBoolTrue, // only draft releases which are created with existing tags + HasSha1: optional.Some(true), // only draft releases which are created with existing tags RepoID: ctx.Repo.Repository.ID, }) if err != nil { diff --git a/modules/context/response.go b/services/context/response.go similarity index 100% rename from modules/context/response.go rename to services/context/response.go diff --git a/modules/upload/upload.go b/services/context/upload/upload.go similarity index 98% rename from modules/upload/upload.go rename to services/context/upload/upload.go index cd107158644..77a7eb93773 100644 --- a/modules/upload/upload.go +++ b/services/context/upload/upload.go @@ -11,9 +11,9 @@ import ( "regexp" "strings" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" ) // ErrFileTypeForbidden not allowed file type error diff --git a/modules/upload/upload_test.go b/services/context/upload/upload_test.go similarity index 100% rename from modules/upload/upload_test.go rename to services/context/upload/upload_test.go diff --git a/services/context/user.go b/services/context/user.go index 8b2faf33691..4c9cd2928b9 100644 --- a/services/context/user.go +++ b/services/context/user.go @@ -9,12 +9,11 @@ import ( "strings" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" ) // UserAssignmentWeb returns a middleware to handle context-user assignment for web routes -func UserAssignmentWeb() func(ctx *context.Context) { - return func(ctx *context.Context) { +func UserAssignmentWeb() func(ctx *Context) { + return func(ctx *Context) { errorFn := func(status int, title string, obj any) { err, ok := obj.(error) if !ok { @@ -32,8 +31,8 @@ func UserAssignmentWeb() func(ctx *context.Context) { } // UserIDAssignmentAPI returns a middleware to handle context-user assignment for api routes -func UserIDAssignmentAPI() func(ctx *context.APIContext) { - return func(ctx *context.APIContext) { +func UserIDAssignmentAPI() func(ctx *APIContext) { + return func(ctx *APIContext) { userID := ctx.ParamsInt64(":user-id") if ctx.IsSigned && ctx.Doer.ID == userID { @@ -53,13 +52,13 @@ func UserIDAssignmentAPI() func(ctx *context.APIContext) { } // UserAssignmentAPI returns a middleware to handle context-user assignment for api routes -func UserAssignmentAPI() func(ctx *context.APIContext) { - return func(ctx *context.APIContext) { +func UserAssignmentAPI() func(ctx *APIContext) { + return func(ctx *APIContext) { ctx.ContextUser = userAssignment(ctx.Base, ctx.Doer, ctx.Error) } } -func userAssignment(ctx *context.Base, doer *user_model.User, errCb func(int, string, any)) (contextUser *user_model.User) { +func userAssignment(ctx *Base, doer *user_model.User, errCb func(int, string, any)) (contextUser *user_model.User) { username := ctx.Params(":username") if doer != nil && doer.LowerName == strings.ToLower(username) { @@ -70,7 +69,7 @@ func userAssignment(ctx *context.Base, doer *user_model.User, errCb func(int, st if err != nil { if user_model.IsErrUserNotExist(err) { if redirectUserID, err := user_model.LookupUserRedirect(ctx, username); err == nil { - context.RedirectToUser(ctx, username, redirectUserID) + RedirectToUser(ctx, username, redirectUserID) } else if user_model.IsErrUserRedirectNotExist(err) { errCb(http.StatusNotFound, "GetUserByName", err) } else { diff --git a/modules/context/utils.go b/services/context/utils.go similarity index 100% rename from modules/context/utils.go rename to services/context/utils.go diff --git a/modules/context/xsrf.go b/services/context/xsrf.go similarity index 100% rename from modules/context/xsrf.go rename to services/context/xsrf.go diff --git a/modules/context/xsrf_test.go b/services/context/xsrf_test.go similarity index 100% rename from modules/context/xsrf_test.go rename to services/context/xsrf_test.go diff --git a/modules/contexttest/context_tests.go b/services/contexttest/context_tests.go similarity index 99% rename from modules/contexttest/context_tests.go rename to services/contexttest/context_tests.go index c9bacf259f5..8a7dd69a0f0 100644 --- a/modules/contexttest/context_tests.go +++ b/services/contexttest/context_tests.go @@ -17,11 +17,11 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/modules/web/middleware" + "code.gitea.io/gitea/services/context" "github.com/go-chi/chi/v5" "github.com/stretchr/testify/assert" diff --git a/services/convert/git_commit.go b/services/convert/git_commit.go index ed08691c8b1..e0efcddbcb0 100644 --- a/services/convert/git_commit.go +++ b/services/convert/git_commit.go @@ -10,11 +10,11 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" - ctx "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" + ctx "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/gitdiff" ) diff --git a/services/forms/admin.go b/services/forms/admin.go index 4b3cacc606f..f1120130607 100644 --- a/services/forms/admin.go +++ b/services/forms/admin.go @@ -6,9 +6,9 @@ package forms import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web/middleware" + "code.gitea.io/gitea/services/context" "gitea.com/go-chi/binding" ) diff --git a/services/forms/auth_form.go b/services/forms/auth_form.go index 25acbbb99e8..c9f3182b3a0 100644 --- a/services/forms/auth_form.go +++ b/services/forms/auth_form.go @@ -6,8 +6,8 @@ package forms import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/web/middleware" + "code.gitea.io/gitea/services/context" "gitea.com/go-chi/binding" ) diff --git a/services/forms/org.go b/services/forms/org.go index 6e2d787516d..3677fcf429b 100644 --- a/services/forms/org.go +++ b/services/forms/org.go @@ -7,9 +7,9 @@ package forms import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web/middleware" + "code.gitea.io/gitea/services/context" "gitea.com/go-chi/binding" ) diff --git a/services/forms/package_form.go b/services/forms/package_form.go index 2f08dfe9f48..cc940d42d34 100644 --- a/services/forms/package_form.go +++ b/services/forms/package_form.go @@ -6,8 +6,8 @@ package forms import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/web/middleware" + "code.gitea.io/gitea/services/context" "gitea.com/go-chi/binding" ) diff --git a/services/forms/repo_branch_form.go b/services/forms/repo_branch_form.go index 5deb0ae463a..42e6c85c371 100644 --- a/services/forms/repo_branch_form.go +++ b/services/forms/repo_branch_form.go @@ -6,8 +6,8 @@ package forms import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/web/middleware" + "code.gitea.io/gitea/services/context" "gitea.com/go-chi/binding" ) diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 98b8d610d0a..e40bcf4eea8 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -12,10 +12,10 @@ import ( "code.gitea.io/gitea/models" issues_model "code.gitea.io/gitea/models/issues" project_model "code.gitea.io/gitea/models/project" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web/middleware" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/webhook" "gitea.com/go-chi/binding" diff --git a/services/forms/repo_tag_form.go b/services/forms/repo_tag_form.go index 4dd99f9e32f..0135684737c 100644 --- a/services/forms/repo_tag_form.go +++ b/services/forms/repo_tag_form.go @@ -6,8 +6,8 @@ package forms import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/web/middleware" + "code.gitea.io/gitea/services/context" "gitea.com/go-chi/binding" ) diff --git a/services/forms/runner.go b/services/forms/runner.go index 6d16cfce49b..6abfc66fc27 100644 --- a/services/forms/runner.go +++ b/services/forms/runner.go @@ -6,8 +6,8 @@ package forms import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/web/middleware" + "code.gitea.io/gitea/services/context" "gitea.com/go-chi/binding" ) diff --git a/services/forms/user_form.go b/services/forms/user_form.go index cbab2742388..186aa4a8782 100644 --- a/services/forms/user_form.go +++ b/services/forms/user_form.go @@ -10,11 +10,11 @@ import ( "strings" auth_model "code.gitea.io/gitea/models/auth" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web/middleware" + "code.gitea.io/gitea/services/context" "gitea.com/go-chi/binding" ) diff --git a/services/forms/user_form_auth_openid.go b/services/forms/user_form_auth_openid.go index d8137a8d134..ca1c77e3208 100644 --- a/services/forms/user_form_auth_openid.go +++ b/services/forms/user_form_auth_openid.go @@ -6,8 +6,8 @@ package forms import ( "net/http" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/web/middleware" + "code.gitea.io/gitea/services/context" "gitea.com/go-chi/binding" ) diff --git a/services/forms/user_form_hidden_comments.go b/services/forms/user_form_hidden_comments.go index 03e629a553a..c21fddf4786 100644 --- a/services/forms/user_form_hidden_comments.go +++ b/services/forms/user_form_hidden_comments.go @@ -7,8 +7,8 @@ import ( "math/big" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/services/context" ) type hiddenCommentTypeGroupsType map[string][]issues_model.CommentType diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 740c748347d..b05c210a0cf 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -154,7 +154,7 @@ func (d *DiffLine) GetBlobExcerptQuery() string { // GetExpandDirection gets DiffLineExpandDirection func (d *DiffLine) GetExpandDirection() DiffLineExpandDirection { - if d.Type != DiffLineSection || d.SectionInfo == nil || d.SectionInfo.RightIdx-d.SectionInfo.LastRightIdx <= 1 { + if d.Type != DiffLineSection || d.SectionInfo == nil || d.SectionInfo.LeftIdx-d.SectionInfo.LastLeftIdx <= 1 || d.SectionInfo.RightIdx-d.SectionInfo.LastRightIdx <= 1 { return DiffLineExpandNone } if d.SectionInfo.LastLeftIdx <= 0 && d.SectionInfo.LastRightIdx <= 0 { diff --git a/services/lfs/locks.go b/services/lfs/locks.go index 08d74326567..2a362b1c0d4 100644 --- a/services/lfs/locks.go +++ b/services/lfs/locks.go @@ -11,12 +11,12 @@ import ( auth_model "code.gitea.io/gitea/models/auth" git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" lfs_module "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" ) diff --git a/services/lfs/server.go b/services/lfs/server.go index 56714120ad0..706be0d080e 100644 --- a/services/lfs/server.go +++ b/services/lfs/server.go @@ -26,12 +26,12 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" lfs_module "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" + "code.gitea.io/gitea/services/context" "github.com/golang-jwt/jwt/v5" ) diff --git a/services/mailer/incoming/incoming_handler.go b/services/mailer/incoming/incoming_handler.go index 5ce2cd5fd57..dc0b5398221 100644 --- a/services/mailer/incoming/incoming_handler.go +++ b/services/mailer/incoming/incoming_handler.go @@ -14,9 +14,9 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/util" attachment_service "code.gitea.io/gitea/services/attachment" + "code.gitea.io/gitea/services/context/upload" issue_service "code.gitea.io/gitea/services/issue" incoming_payload "code.gitea.io/gitea/services/mailer/incoming/payload" "code.gitea.io/gitea/services/mailer/token" diff --git a/services/markup/processorhelper.go b/services/markup/processorhelper.go index 3551f85c466..a4378678a08 100644 --- a/services/markup/processorhelper.go +++ b/services/markup/processorhelper.go @@ -7,8 +7,8 @@ import ( "context" "code.gitea.io/gitea/models/user" - gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/markup" + gitea_context "code.gitea.io/gitea/services/context" ) func ProcessorHelper() *markup.ProcessorHelper { diff --git a/services/markup/processorhelper_test.go b/services/markup/processorhelper_test.go index ef8f5622451..170edae0e0b 100644 --- a/services/markup/processorhelper_test.go +++ b/services/markup/processorhelper_test.go @@ -12,8 +12,8 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/user" - gitea_context "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/contexttest" + gitea_context "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/contexttest" "github.com/stretchr/testify/assert" ) diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go index 1c9824fe3a1..87691bf7296 100644 --- a/services/migrations/gitea_uploader.go +++ b/services/migrations/gitea_uploader.go @@ -120,7 +120,7 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate r.DefaultBranch = repo.DefaultBranch r.Description = repo.Description - r, err = repo_module.MigrateRepositoryGitData(g.ctx, owner, r, base.MigrateOptions{ + r, err = repo_service.MigrateRepositoryGitData(g.ctx, owner, r, base.MigrateOptions{ RepoName: g.repoName, Description: repo.Description, OriginalURL: repo.OriginalURL, diff --git a/services/pull/pull.go b/services/pull/pull.go index e1ea4357fc5..42363f886d7 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -21,7 +21,6 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/container" - gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/graceful" @@ -31,6 +30,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/sync" "code.gitea.io/gitea/modules/util" + gitea_context "code.gitea.io/gitea/services/context" issue_service "code.gitea.io/gitea/services/issue" notify_service "code.gitea.io/gitea/services/notify" ) diff --git a/services/repository/archiver/archiver_test.go b/services/repository/archiver/archiver_test.go index 5deec259da5..ec6e9dfac3c 100644 --- a/services/repository/archiver/archiver_test.go +++ b/services/repository/archiver/archiver_test.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/contexttest" + "code.gitea.io/gitea/services/contexttest" _ "code.gitea.io/gitea/models/actions" diff --git a/services/repository/commit.go b/services/repository/commit.go index 2497910a838..e8c0262ef41 100644 --- a/services/repository/commit.go +++ b/services/repository/commit.go @@ -7,8 +7,8 @@ import ( "context" "fmt" - gitea_ctx "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/util" + gitea_ctx "code.gitea.io/gitea/services/context" ) type ContainedLinks struct { // TODO: better name? diff --git a/services/repository/create.go b/services/repository/create.go index a648c0d8167..c47ce9c4136 100644 --- a/services/repository/create.go +++ b/services/repository/create.go @@ -157,7 +157,7 @@ func initRepository(ctx context.Context, repoPath string, u *user_model.User, re } // Apply changes and commit. - if err = repo_module.InitRepoCommit(ctx, tmpDir, repo, u, opts.DefaultBranch); err != nil { + if err = initRepoCommit(ctx, tmpDir, repo, u, opts.DefaultBranch); err != nil { return fmt.Errorf("initRepoCommit: %w", err) } } diff --git a/services/repository/files/content_test.go b/services/repository/files/content_test.go index d50847789ac..4811f9d327a 100644 --- a/services/repository/files/content_test.go +++ b/services/repository/files/content_test.go @@ -7,9 +7,9 @@ import ( "testing" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/gitrepo" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/contexttest" _ "code.gitea.io/gitea/models/actions" diff --git a/services/repository/files/diff_test.go b/services/repository/files/diff_test.go index 91c878e5053..63aff9b0e30 100644 --- a/services/repository/files/diff_test.go +++ b/services/repository/files/diff_test.go @@ -8,8 +8,8 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/json" + "code.gitea.io/gitea/services/contexttest" "code.gitea.io/gitea/services/gitdiff" "github.com/stretchr/testify/assert" diff --git a/services/repository/files/file_test.go b/services/repository/files/file_test.go index 675ddbddb3e..a5b3aad91e3 100644 --- a/services/repository/files/file_test.go +++ b/services/repository/files/file_test.go @@ -7,10 +7,10 @@ import ( "testing" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/contexttest" "github.com/stretchr/testify/assert" ) diff --git a/services/repository/files/tree_test.go b/services/repository/files/tree_test.go index 528ef500df2..508f20090dd 100644 --- a/services/repository/files/tree_test.go +++ b/services/repository/files/tree_test.go @@ -7,8 +7,8 @@ import ( "testing" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/contexttest" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/contexttest" "github.com/stretchr/testify/assert" ) diff --git a/modules/repository/generate.go b/services/repository/generate.go similarity index 94% rename from modules/repository/generate.go rename to services/repository/generate.go index f622383bb52..c444b60b2c5 100644 --- a/modules/repository/generate.go +++ b/services/repository/generate.go @@ -21,6 +21,7 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" + repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/util" "github.com/gobwas/glob" @@ -242,7 +243,7 @@ func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *r defaultBranch = templateRepo.DefaultBranch } - return InitRepoCommit(ctx, tmpDir, repo, repo.Owner, defaultBranch) + return initRepoCommit(ctx, tmpDir, repo, repo.Owner, defaultBranch) } func generateGitContent(ctx context.Context, repo, templateRepo, generateRepo *repo_model.Repository) (err error) { @@ -292,7 +293,7 @@ func GenerateGitContent(ctx context.Context, templateRepo, generateRepo *repo_mo return err } - if err := UpdateRepoSize(ctx, generateRepo); err != nil { + if err := repo_module.UpdateRepoSize(ctx, generateRepo); err != nil { return fmt.Errorf("failed to update size for repository: %w", err) } @@ -323,8 +324,8 @@ func (gro GenerateRepoOptions) IsValid() bool { gro.IssueLabels || gro.ProtectedBranch // or other items as they are added } -// GenerateRepository generates a repository from a template -func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templateRepo *repo_model.Repository, opts GenerateRepoOptions) (_ *repo_model.Repository, err error) { +// generateRepository generates a repository from a template +func generateRepository(ctx context.Context, doer, owner *user_model.User, templateRepo *repo_model.Repository, opts GenerateRepoOptions) (_ *repo_model.Repository, err error) { generateRepo := &repo_model.Repository{ OwnerID: owner.ID, Owner: owner, @@ -341,7 +342,7 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templ ObjectFormatName: templateRepo.ObjectFormatName, } - if err = CreateRepositoryByExample(ctx, doer, owner, generateRepo, false, false); err != nil { + if err = repo_module.CreateRepositoryByExample(ctx, doer, owner, generateRepo, false, false); err != nil { return nil, err } @@ -358,11 +359,11 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templ } } - if err = CheckInitRepository(ctx, owner.Name, generateRepo.Name, generateRepo.ObjectFormatName); err != nil { + if err = repo_module.CheckInitRepository(ctx, owner.Name, generateRepo.Name, generateRepo.ObjectFormatName); err != nil { return generateRepo, err } - if err = CheckDaemonExportOK(ctx, generateRepo); err != nil { + if err = repo_module.CheckDaemonExportOK(ctx, generateRepo); err != nil { return generateRepo, fmt.Errorf("checkDaemonExportOK: %w", err) } diff --git a/modules/repository/generate_test.go b/services/repository/generate_test.go similarity index 100% rename from modules/repository/generate_test.go rename to services/repository/generate_test.go diff --git a/services/repository/init.go b/services/repository/init.go new file mode 100644 index 00000000000..817fa4abd77 --- /dev/null +++ b/services/repository/init.go @@ -0,0 +1,83 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package repository + +import ( + "context" + "fmt" + "os" + "time" + + repo_model "code.gitea.io/gitea/models/repo" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" + repo_module "code.gitea.io/gitea/modules/repository" + "code.gitea.io/gitea/modules/setting" + asymkey_service "code.gitea.io/gitea/services/asymkey" +) + +// initRepoCommit temporarily changes with work directory. +func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Repository, u *user_model.User, defaultBranch string) (err error) { + commitTimeStr := time.Now().Format(time.RFC3339) + + sig := u.NewGitSig() + // Because this may call hooks we should pass in the environment + env := append(os.Environ(), + "GIT_AUTHOR_NAME="+sig.Name, + "GIT_AUTHOR_EMAIL="+sig.Email, + "GIT_AUTHOR_DATE="+commitTimeStr, + "GIT_COMMITTER_DATE="+commitTimeStr, + ) + committerName := sig.Name + committerEmail := sig.Email + + if stdout, _, err := git.NewCommand(ctx, "add", "--all"). + SetDescription(fmt.Sprintf("initRepoCommit (git add): %s", tmpPath)). + RunStdString(&git.RunOpts{Dir: tmpPath}); err != nil { + log.Error("git add --all failed: Stdout: %s\nError: %v", stdout, err) + return fmt.Errorf("git add --all: %w", err) + } + + cmd := git.NewCommand(ctx, "commit", "--message=Initial commit"). + AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email) + + sign, keyID, signer, _ := asymkey_service.SignInitialCommit(ctx, tmpPath, u) + if sign { + cmd.AddOptionFormat("-S%s", keyID) + + if repo.GetTrustModel() == repo_model.CommitterTrustModel || repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel { + // need to set the committer to the KeyID owner + committerName = signer.Name + committerEmail = signer.Email + } + } else { + cmd.AddArguments("--no-gpg-sign") + } + + env = append(env, + "GIT_COMMITTER_NAME="+committerName, + "GIT_COMMITTER_EMAIL="+committerEmail, + ) + + if stdout, _, err := cmd. + SetDescription(fmt.Sprintf("initRepoCommit (git commit): %s", tmpPath)). + RunStdString(&git.RunOpts{Dir: tmpPath, Env: env}); err != nil { + log.Error("Failed to commit: %v: Stdout: %s\nError: %v", cmd.String(), stdout, err) + return fmt.Errorf("git commit: %w", err) + } + + if len(defaultBranch) == 0 { + defaultBranch = setting.Repository.DefaultBranch + } + + if stdout, _, err := git.NewCommand(ctx, "push", "origin").AddDynamicArguments("HEAD:" + defaultBranch). + SetDescription(fmt.Sprintf("initRepoCommit (git push): %s", tmpPath)). + RunStdString(&git.RunOpts{Dir: tmpPath, Env: repo_module.InternalPushingEnvironment(u, repo)}); err != nil { + log.Error("Failed to push back to HEAD: Stdout: %s\nError: %v", stdout, err) + return fmt.Errorf("git push: %w", err) + } + + return nil +} diff --git a/services/repository/migrate.go b/services/repository/migrate.go new file mode 100644 index 00000000000..51fdd90f540 --- /dev/null +++ b/services/repository/migrate.go @@ -0,0 +1,264 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package repository + +import ( + "context" + "errors" + "fmt" + "net/http" + "strings" + "time" + + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/organization" + repo_model "code.gitea.io/gitea/models/repo" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/lfs" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/migration" + repo_module "code.gitea.io/gitea/modules/repository" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" +) + +// MigrateRepositoryGitData starts migrating git related data after created migrating repository +func MigrateRepositoryGitData(ctx context.Context, u *user_model.User, + repo *repo_model.Repository, opts migration.MigrateOptions, + httpTransport *http.Transport, +) (*repo_model.Repository, error) { + repoPath := repo_model.RepoPath(u.Name, opts.RepoName) + + if u.IsOrganization() { + t, err := organization.OrgFromUser(u).GetOwnerTeam(ctx) + if err != nil { + return nil, err + } + repo.NumWatches = t.NumMembers + } else { + repo.NumWatches = 1 + } + + migrateTimeout := time.Duration(setting.Git.Timeout.Migrate) * time.Second + + var err error + if err = util.RemoveAll(repoPath); err != nil { + return repo, fmt.Errorf("Failed to remove %s: %w", repoPath, err) + } + + if err = git.Clone(ctx, opts.CloneAddr, repoPath, git.CloneRepoOptions{ + Mirror: true, + Quiet: true, + Timeout: migrateTimeout, + SkipTLSVerify: setting.Migrations.SkipTLSVerify, + }); err != nil { + if errors.Is(err, context.DeadlineExceeded) { + return repo, fmt.Errorf("Clone timed out. Consider increasing [git.timeout] MIGRATE in app.ini. Underlying Error: %w", err) + } + return repo, fmt.Errorf("Clone: %w", err) + } + + if err := git.WriteCommitGraph(ctx, repoPath); err != nil { + return repo, err + } + + if opts.Wiki { + wikiPath := repo_model.WikiPath(u.Name, opts.RepoName) + wikiRemotePath := repo_module.WikiRemoteURL(ctx, opts.CloneAddr) + if len(wikiRemotePath) > 0 { + if err := util.RemoveAll(wikiPath); err != nil { + return repo, fmt.Errorf("Failed to remove %s: %w", wikiPath, err) + } + + if err := git.Clone(ctx, wikiRemotePath, wikiPath, git.CloneRepoOptions{ + Mirror: true, + Quiet: true, + Timeout: migrateTimeout, + Branch: "master", + SkipTLSVerify: setting.Migrations.SkipTLSVerify, + }); err != nil { + log.Warn("Clone wiki: %v", err) + if err := util.RemoveAll(wikiPath); err != nil { + return repo, fmt.Errorf("Failed to remove %s: %w", wikiPath, err) + } + } else { + if err := git.WriteCommitGraph(ctx, wikiPath); err != nil { + return repo, err + } + } + } + } + + if repo.OwnerID == u.ID { + repo.Owner = u + } + + if err = repo_module.CheckDaemonExportOK(ctx, repo); err != nil { + return repo, fmt.Errorf("checkDaemonExportOK: %w", err) + } + + if stdout, _, err := git.NewCommand(ctx, "update-server-info"). + SetDescription(fmt.Sprintf("MigrateRepositoryGitData(git update-server-info): %s", repoPath)). + RunStdString(&git.RunOpts{Dir: repoPath}); err != nil { + log.Error("MigrateRepositoryGitData(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err) + return repo, fmt.Errorf("error in MigrateRepositoryGitData(git update-server-info): %w", err) + } + + gitRepo, err := git.OpenRepository(ctx, repoPath) + if err != nil { + return repo, fmt.Errorf("OpenRepository: %w", err) + } + defer gitRepo.Close() + + repo.IsEmpty, err = gitRepo.IsEmpty() + if err != nil { + return repo, fmt.Errorf("git.IsEmpty: %w", err) + } + + if !repo.IsEmpty { + if len(repo.DefaultBranch) == 0 { + // Try to get HEAD branch and set it as default branch. + headBranch, err := gitRepo.GetHEADBranch() + if err != nil { + return repo, fmt.Errorf("GetHEADBranch: %w", err) + } + if headBranch != nil { + repo.DefaultBranch = headBranch.Name + } + } + + if _, err := repo_module.SyncRepoBranchesWithRepo(ctx, repo, gitRepo, u.ID); err != nil { + return repo, fmt.Errorf("SyncRepoBranchesWithRepo: %v", err) + } + + if !opts.Releases { + // note: this will greatly improve release (tag) sync + // for pull-mirrors with many tags + repo.IsMirror = opts.Mirror + if err = repo_module.SyncReleasesWithTags(ctx, repo, gitRepo); err != nil { + log.Error("Failed to synchronize tags to releases for repository: %v", err) + } + } + + if opts.LFS { + endpoint := lfs.DetermineEndpoint(opts.CloneAddr, opts.LFSEndpoint) + lfsClient := lfs.NewClient(endpoint, httpTransport) + if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, repo, gitRepo, lfsClient); err != nil { + log.Error("Failed to store missing LFS objects for repository: %v", err) + } + } + } + + ctx, committer, err := db.TxContext(ctx) + if err != nil { + return nil, err + } + defer committer.Close() + + if opts.Mirror { + remoteAddress, err := util.SanitizeURL(opts.CloneAddr) + if err != nil { + return repo, err + } + mirrorModel := repo_model.Mirror{ + RepoID: repo.ID, + Interval: setting.Mirror.DefaultInterval, + EnablePrune: true, + NextUpdateUnix: timeutil.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval), + LFS: opts.LFS, + RemoteAddress: remoteAddress, + } + if opts.LFS { + mirrorModel.LFSEndpoint = opts.LFSEndpoint + } + + if opts.MirrorInterval != "" { + parsedInterval, err := time.ParseDuration(opts.MirrorInterval) + if err != nil { + log.Error("Failed to set Interval: %v", err) + return repo, err + } + if parsedInterval == 0 { + mirrorModel.Interval = 0 + mirrorModel.NextUpdateUnix = 0 + } else if parsedInterval < setting.Mirror.MinInterval { + err := fmt.Errorf("interval %s is set below Minimum Interval of %s", parsedInterval, setting.Mirror.MinInterval) + log.Error("Interval: %s is too frequent", opts.MirrorInterval) + return repo, err + } else { + mirrorModel.Interval = parsedInterval + mirrorModel.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(parsedInterval) + } + } + + if err = repo_model.InsertMirror(ctx, &mirrorModel); err != nil { + return repo, fmt.Errorf("InsertOne: %w", err) + } + + repo.IsMirror = true + if err = UpdateRepository(ctx, repo, false); err != nil { + return nil, err + } + + // this is necessary for sync local tags from remote + configName := fmt.Sprintf("remote.%s.fetch", mirrorModel.GetRemoteName()) + if stdout, _, err := git.NewCommand(ctx, "config"). + AddOptionValues("--add", configName, `+refs/tags/*:refs/tags/*`). + RunStdString(&git.RunOpts{Dir: repoPath}); err != nil { + log.Error("MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*) in %v: Stdout: %s\nError: %v", repo, stdout, err) + return repo, fmt.Errorf("error in MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*): %w", err) + } + } else { + if err = repo_module.UpdateRepoSize(ctx, repo); err != nil { + log.Error("Failed to update size for repository: %v", err) + } + if repo, err = CleanUpMigrateInfo(ctx, repo); err != nil { + return nil, err + } + } + + return repo, committer.Commit() +} + +// cleanUpMigrateGitConfig removes mirror info which prevents "push --all". +// This also removes possible user credentials. +func cleanUpMigrateGitConfig(ctx context.Context, repoPath string) error { + cmd := git.NewCommand(ctx, "remote", "rm", "origin") + // if the origin does not exist + _, stderr, err := cmd.RunStdString(&git.RunOpts{ + Dir: repoPath, + }) + if err != nil && !strings.HasPrefix(stderr, "fatal: No such remote") { + return err + } + return nil +} + +// CleanUpMigrateInfo finishes migrating repository and/or wiki with things that don't need to be done for mirrors. +func CleanUpMigrateInfo(ctx context.Context, repo *repo_model.Repository) (*repo_model.Repository, error) { + repoPath := repo.RepoPath() + if err := repo_module.CreateDelegateHooks(repoPath); err != nil { + return repo, fmt.Errorf("createDelegateHooks: %w", err) + } + if repo.HasWiki() { + if err := repo_module.CreateDelegateHooks(repo.WikiPath()); err != nil { + return repo, fmt.Errorf("createDelegateHooks.(wiki): %w", err) + } + } + + _, _, err := git.NewCommand(ctx, "remote", "rm", "origin").RunStdString(&git.RunOpts{Dir: repoPath}) + if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") { + return repo, fmt.Errorf("CleanUpMigrateInfo: %w", err) + } + + if repo.HasWiki() { + if err := cleanUpMigrateGitConfig(ctx, repo.WikiPath()); err != nil { + return repo, fmt.Errorf("cleanUpMigrateGitConfig (wiki): %w", err) + } + } + + return repo, UpdateRepository(ctx, repo, false) +} diff --git a/services/repository/template.go b/services/repository/template.go index 06cf05026ff..36a680c8e20 100644 --- a/services/repository/template.go +++ b/services/repository/template.go @@ -11,7 +11,6 @@ import ( issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" - repo_module "code.gitea.io/gitea/modules/repository" notify_service "code.gitea.io/gitea/services/notify" ) @@ -63,7 +62,7 @@ func GenerateProtectedBranch(ctx context.Context, templateRepo, generateRepo *re } // GenerateRepository generates a repository from a template -func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templateRepo *repo_model.Repository, opts repo_module.GenerateRepoOptions) (_ *repo_model.Repository, err error) { +func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templateRepo *repo_model.Repository, opts GenerateRepoOptions) (_ *repo_model.Repository, err error) { if !doer.IsAdmin && !owner.CanCreateRepo() { return nil, repo_model.ErrReachLimitOfRepo{ Limit: owner.MaxRepoCreation, @@ -72,14 +71,14 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templ var generateRepo *repo_model.Repository if err = db.WithTx(ctx, func(ctx context.Context) error { - generateRepo, err = repo_module.GenerateRepository(ctx, doer, owner, templateRepo, opts) + generateRepo, err = generateRepository(ctx, doer, owner, templateRepo, opts) if err != nil { return err } // Git Content if opts.GitContent && !templateRepo.IsEmpty { - if err = repo_module.GenerateGitContent(ctx, templateRepo, generateRepo); err != nil { + if err = GenerateGitContent(ctx, templateRepo, generateRepo); err != nil { return err } } diff --git a/tailwind.config.js b/tailwind.config.js index 8c474c33a8e..7f36822001b 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -6,6 +6,7 @@ const isProduction = env.NODE_ENV !== 'development'; export default { prefix: 'tw-', + important: true, // the frameworks are mixed together, so tailwind needs to override other framework's styles content: [ isProduction && '!./templates/devtest/**/*', isProduction && '!./web_src/js/standalone/devtest.js', diff --git a/templates/admin/self_check.tmpl b/templates/admin/self_check.tmpl index 6bca01ec655..fafaf9242d3 100644 --- a/templates/admin/self_check.tmpl +++ b/templates/admin/self_check.tmpl @@ -20,7 +20,7 @@ {{if .DatabaseCheckInconsistentCollationColumns}}
{{ctx.Locale.Tr "admin.self_check.database_inconsistent_collation_columns" .DatabaseCheckResult.DatabaseCollation}} -
    +
      {{range .DatabaseCheckInconsistentCollationColumns}}
    • {{.}}
    • {{end}} diff --git a/templates/base/alert.tmpl b/templates/base/alert.tmpl index 160584f769b..760d3bfa2cc 100644 --- a/templates/base/alert.tmpl +++ b/templates/base/alert.tmpl @@ -1,20 +1,20 @@ {{if .Flash.ErrorMsg}}
      -

      {{.Flash.ErrorMsg | Str2html}}

      +

      {{.Flash.ErrorMsg | SanitizeHTML}}

      {{end}} {{if .Flash.SuccessMsg}}
      -

      {{.Flash.SuccessMsg | Str2html}}

      +

      {{.Flash.SuccessMsg | SanitizeHTML}}

      {{end}} {{if .Flash.InfoMsg}}
      -

      {{.Flash.InfoMsg | Str2html}}

      +

      {{.Flash.InfoMsg | SanitizeHTML}}

      {{end}} {{if .Flash.WarningMsg}}
      -

      {{.Flash.WarningMsg | Str2html}}

      +

      {{.Flash.WarningMsg | SanitizeHTML}}

      {{end}} diff --git a/templates/base/alert_details.tmpl b/templates/base/alert_details.tmpl index 1d7ec15dc0d..6801c8240fd 100644 --- a/templates/base/alert_details.tmpl +++ b/templates/base/alert_details.tmpl @@ -2,6 +2,6 @@
      {{.Summary}} - {{.Details | Str2html}} + {{.Details | SanitizeHTML}}
      diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index effe4dcea9f..3797de0a0f8 100644 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -13,14 +13,14 @@ diff --git a/templates/devtest/fomantic-modal.tmpl b/templates/devtest/fomantic-modal.tmpl index eda169a043c..0b4199a197f 100644 --- a/templates/devtest/fomantic-modal.tmpl +++ b/templates/devtest/fomantic-modal.tmpl @@ -5,7 +5,7 @@ @@ -14,7 +14,7 @@
      Form dialog (layout 2)
      -
      +
      {{template "base/modal_actions_confirm" (dict "ModalButtonTypes" "confirm")}}
      @@ -24,7 +24,7 @@
      Form dialog (layout 3)
      -
      +
      {{template "base/modal_actions_confirm" (dict "ModalButtonTypes" "confirm")}}
      @@ -33,7 +33,7 @@
diff --git a/templates/mail/issue/default.tmpl b/templates/mail/issue/default.tmpl index 79dbe897cc8..10fa0f1ffce 100644 --- a/templates/mail/issue/default.tmpl +++ b/templates/mail/issue/default.tmpl @@ -58,7 +58,7 @@ {{.locale.Tr "mail.issue.action.new" .Doer.Name .Issue.Index}} {{end}} {{else}} - {{.Body | Str2html}} + {{.Body | SanitizeHTML}} {{end -}} {{- range .ReviewComments}}
diff --git a/templates/mail/notify/repo_transfer.tmpl b/templates/mail/notify/repo_transfer.tmpl index 597048ddf49..8c8b276484e 100644 --- a/templates/mail/notify/repo_transfer.tmpl +++ b/templates/mail/notify/repo_transfer.tmpl @@ -5,7 +5,7 @@ {{.Subject}} -{{$url := HTMLFormat "%[2]s" .Link .Repo)}} +{{$url := HTMLFormat "%[2]s" .Link .Repo}}

{{.Subject}}. {{.locale.Tr "mail.repo.transfer.body" $url}} diff --git a/templates/mail/release.tmpl b/templates/mail/release.tmpl index 62a16573c6b..90a3caa4c53 100644 --- a/templates/mail/release.tmpl +++ b/templates/mail/release.tmpl @@ -22,7 +22,7 @@ {{.locale.Tr "mail.release.note"}}
{{- if eq .Release.RenderedNote ""}} {{else}} - {{.Release.RenderedNote | Str2html}} + {{.Release.RenderedNote}} {{end -}}



diff --git a/templates/org/header.tmpl b/templates/org/header.tmpl index 8423fd7d3b5..efbbc43b1d0 100644 --- a/templates/org/header.tmpl +++ b/templates/org/header.tmpl @@ -18,7 +18,7 @@ {{end}} - {{if .RenderedDescription}}
{{.RenderedDescription | Str2html}}
{{end}} + {{if .RenderedDescription}}
{{.RenderedDescription}}
{{end}}
{{if .Org.Location}}
{{svg "octicon-location"}} {{.Org.Location}}
{{end}} {{if .Org.Website}}
{{svg "octicon-link"}} {{.Org.Website}}
{{end}} diff --git a/templates/org/home.tmpl b/templates/org/home.tmpl index 4e33b1af729..892ba0da5b6 100644 --- a/templates/org/home.tmpl +++ b/templates/org/home.tmpl @@ -6,7 +6,7 @@
{{if .ProfileReadme}} -
{{.ProfileReadme | Str2html}}
+
{{.ProfileReadme}}
{{end}} {{template "explore/repo_search" .}} {{template "explore/repo_list" .}} diff --git a/templates/package/content/nuget.tmpl b/templates/package/content/nuget.tmpl index f84288629d2..2008cf4cc87 100644 --- a/templates/package/content/nuget.tmpl +++ b/templates/package/content/nuget.tmpl @@ -20,7 +20,7 @@

{{ctx.Locale.Tr "packages.about"}}

{{if .PackageDescriptor.Metadata.Description}}{{.PackageDescriptor.Metadata.Description}}{{end}} - {{if .PackageDescriptor.Metadata.ReleaseNotes}}{{Str2html .PackageDescriptor.Metadata.ReleaseNotes}}{{end}} + {{if .PackageDescriptor.Metadata.ReleaseNotes}}{{.PackageDescriptor.Metadata.ReleaseNotes}}{{end}}
{{end}} diff --git a/templates/projects/list.tmpl b/templates/projects/list.tmpl index cbff82dd702..30fbd498a4e 100644 --- a/templates/projects/list.tmpl +++ b/templates/projects/list.tmpl @@ -75,7 +75,7 @@
{{if .Description}}
- {{.RenderedContent|Str2html}} + {{.RenderedContent}}
{{end}} diff --git a/templates/projects/view.tmpl b/templates/projects/view.tmpl index b3ad03c3549..3792ccca0e1 100644 --- a/templates/projects/view.tmpl +++ b/templates/projects/view.tmpl @@ -58,7 +58,7 @@ {{end}}
-
{{$.Project.RenderedContent|Str2html}}
+
{{$.Project.RenderedContent}}
diff --git a/templates/repo/clone_script.tmpl b/templates/repo/clone_script.tmpl index 0376da4a713..40dae76dc71 100644 --- a/templates/repo/clone_script.tmpl +++ b/templates/repo/clone_script.tmpl @@ -24,14 +24,22 @@ const btn = isSSH ? sshBtn : httpsBtn; if (!btn) return; - let link = btn.getAttribute('data-link'); - if (link.startsWith('http://') || link.startsWith('https://')) { - // use current protocol/host as the clone link - const url = new URL(link); - url.protocol = window.location.protocol; - url.host = window.location.host; - link = url.toString(); + // NOTE: Keep this function in sync with the one in the js folder + function toOriginUrl(urlStr) { + try { + if (urlStr.startsWith('http://') || urlStr.startsWith('https://') || urlStr.startsWith('/')) { + const {origin, protocol, hostname, port} = window.location; + const url = new URL(urlStr, origin); + url.protocol = protocol; + url.hostname = hostname; + url.port = port || (protocol === 'https:' ? '443' : '80'); + return url.toString(); + } + } catch {} + return urlStr; } + const link = toOriginUrl(btn.getAttribute('data-link')); + for (const el of document.getElementsByClassName('js-clone-url')) { el[el.nodeName === 'INPUT' ? 'value' : 'textContent'] = link; } diff --git a/templates/repo/commit_page.tmpl b/templates/repo/commit_page.tmpl index 115ee929551..7892a571632 100644 --- a/templates/repo/commit_page.tmpl +++ b/templates/repo/commit_page.tmpl @@ -276,7 +276,7 @@ {{TimeSince .NoteCommit.Author.When ctx.Locale}}
-
{{.NoteRendered | Str2html}}
+
{{.NoteRendered | SanitizeHTML}}
{{end}} {{template "repo/diff/box" .}} diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index b9a43a06127..c24500a149f 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -203,7 +203,7 @@ {{if $showFileViewToggle}} {{/* for image or CSV, it can have a horizontal scroll bar, there won't be review comment context menu (position absolute) which would be clipped by "overflow" */}}
- +
{{if $isImage}} {{template "repo/diff/image_diff" dict "file" . "root" $ "blobBase" $blobBase "blobHead" $blobHead "sniffedTypeBase" $sniffedTypeBase "sniffedTypeHead" $sniffedTypeHead}} {{else}} diff --git a/templates/repo/diff/comments.tmpl b/templates/repo/diff/comments.tmpl index e567417fa62..0bb577deba7 100644 --- a/templates/repo/diff/comments.tmpl +++ b/templates/repo/diff/comments.tmpl @@ -55,7 +55,7 @@
{{if .RenderedContent}} - {{.RenderedContent|Str2html}} + {{.RenderedContent}} {{else}} {{ctx.Locale.Tr "repo.issues.no_content"}} {{end}} @@ -63,7 +63,7 @@
{{.Content}}
{{if .Attachments}} - {{template "repo/issue/view_content/attachments" dict "ctxData" $ "Attachments" .Attachments "Content" .RenderedContent}} + {{template "repo/issue/view_content/attachments" dict "ctxData" $ "Attachments" .Attachments "RenderedContent" .RenderedContent}} {{end}}
{{$reactions := .Reactions.GroupByType}} diff --git a/templates/repo/editor/patch.tmpl b/templates/repo/editor/patch.tmpl index c9a78cc35fd..8df87589889 100644 --- a/templates/repo/editor/patch.tmpl +++ b/templates/repo/editor/patch.tmpl @@ -14,8 +14,8 @@ {{.BranchName}} {{ctx.Locale.Tr "repo.editor.or"}} {{ctx.Locale.Tr "repo.editor.cancel_lower"}} - - + +
diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index 3e27d963bb6..ee46af42362 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -82,7 +82,7 @@ {{/*else is not required here, because the button shouldn't link to any site if you can't create a fork*/}} {{end}} {{else if not $.UserAndOrgForks}} - href="{{AppSubUrl}}/repo/fork/{{.ID}}" + href="{{$.RepoLink}}/fork" {{else}} data-modal="#fork-repo-modal" {{end}} @@ -103,7 +103,7 @@
{{if $.CanSignedUserFork}}
- {{ctx.Locale.Tr "repo.fork_to_different_account"}} + {{ctx.Locale.Tr "repo.fork_to_different_account"}} {{end}} diff --git a/templates/repo/issue/card.tmpl b/templates/repo/issue/card.tmpl index 7fb3d828273..5e524079c8c 100644 --- a/templates/repo/issue/card.tmpl +++ b/templates/repo/issue/card.tmpl @@ -6,7 +6,7 @@ {{end}} {{end}} -
+
{{template "shared/issueicon" .}} diff --git a/templates/repo/issue/milestone_issues.tmpl b/templates/repo/issue/milestone_issues.tmpl index d9495d9b77a..35a8a77680b 100644 --- a/templates/repo/issue/milestone_issues.tmpl +++ b/templates/repo/issue/milestone_issues.tmpl @@ -22,7 +22,7 @@
{{if .Milestone.RenderedContent}}
- {{.Milestone.RenderedContent|Str2html}} + {{.Milestone.RenderedContent}}
{{end}}
diff --git a/templates/repo/issue/milestones.tmpl b/templates/repo/issue/milestones.tmpl index 698e3fffba4..363ba7e3a2b 100644 --- a/templates/repo/issue/milestones.tmpl +++ b/templates/repo/issue/milestones.tmpl @@ -82,7 +82,7 @@
{{if .Content}}
- {{.RenderedContent|Str2html}} + {{.RenderedContent}}
{{end}} diff --git a/templates/repo/issue/view_content.tmpl b/templates/repo/issue/view_content.tmpl index b5441872a33..aa91764be46 100644 --- a/templates/repo/issue/view_content.tmpl +++ b/templates/repo/issue/view_content.tmpl @@ -54,7 +54,7 @@
{{if .Issue.RenderedContent}} - {{.Issue.RenderedContent|Str2html}} + {{.Issue.RenderedContent}} {{else}} {{ctx.Locale.Tr "repo.issues.no_content"}} {{end}} @@ -62,7 +62,7 @@
{{.Issue.Content}}
{{if .Issue.Attachments}} - {{template "repo/issue/view_content/attachments" dict "ctxData" $ "Attachments" .Issue.Attachments "Content" .Issue.RenderedContent}} + {{template "repo/issue/view_content/attachments" dict "ctxData" $ "Attachments" .Issue.Attachments "RenderedContent" .Issue.RenderedContent}} {{end}}
{{$reactions := .Issue.Reactions.GroupByType}} diff --git a/templates/repo/issue/view_content/attachments.tmpl b/templates/repo/issue/view_content/attachments.tmpl index 1fb6f2f2c29..2c3a47d6703 100644 --- a/templates/repo/issue/view_content/attachments.tmpl +++ b/templates/repo/issue/view_content/attachments.tmpl @@ -8,7 +8,7 @@
{{if FilenameIsImage .Name}} - {{if not (StringUtils.Contains $.Content .UUID)}} + {{if not (StringUtils.Contains (StringUtils.ToString $.RenderedContent) .UUID)}} {{$hasThumbnails = true}} {{end}} {{svg "octicon-file"}} @@ -29,7 +29,7 @@
{{- range .Attachments -}} {{if FilenameIsImage .Name}} - {{if not (StringUtils.Contains $.Content .UUID)}} + {{if not (StringUtils.Contains (StringUtils.ToString $.RenderedContent) .UUID)}} {{.Name}} diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index 562e44c791c..b500cec91cf 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -61,7 +61,7 @@
{{if .RenderedContent}} - {{.RenderedContent|Str2html}} + {{.RenderedContent}} {{else}} {{ctx.Locale.Tr "repo.issues.no_content"}} {{end}} @@ -69,7 +69,7 @@
{{.Content}}
{{if .Attachments}} - {{template "repo/issue/view_content/attachments" dict "ctxData" $ "Attachments" .Attachments "Content" .RenderedContent}} + {{template "repo/issue/view_content/attachments" dict "ctxData" $ "Attachments" .Attachments "RenderedContent" .RenderedContent}} {{end}}
{{$reactions := .Reactions.GroupByType}} @@ -162,7 +162,7 @@
{{svg "octicon-git-commit"}} - {{.Content | Str2html}} + {{.Content | SanitizeHTML}}
{{else if eq .Type 7}} @@ -432,7 +432,7 @@
{{if .RenderedContent}} - {{.RenderedContent|Str2html}} + {{.RenderedContent}} {{else}} {{ctx.Locale.Tr "repo.issues.no_content"}} {{end}} @@ -440,7 +440,7 @@
{{.Content}}
{{if .Attachments}} - {{template "repo/issue/view_content/attachments" dict "ctxData" $ "Attachments" .Attachments "Content" .RenderedContent}} + {{template "repo/issue/view_content/attachments" dict "ctxData" $ "Attachments" .Attachments "RenderedContent" .RenderedContent}} {{end}}
{{$reactions := .Reactions.GroupByType}} @@ -631,7 +631,7 @@
{{if .RenderedContent}} - {{.RenderedContent|Str2html}} + {{.RenderedContent}} {{else}} {{ctx.Locale.Tr "repo.issues.no_content"}} {{end}} diff --git a/templates/repo/issue/view_content/conversation.tmpl b/templates/repo/issue/view_content/conversation.tmpl index 1bad0e9b55d..5bb99d1db6a 100644 --- a/templates/repo/issue/view_content/conversation.tmpl +++ b/templates/repo/issue/view_content/conversation.tmpl @@ -87,7 +87,7 @@
{{if .RenderedContent}} - {{.RenderedContent|Str2html}} + {{.RenderedContent}} {{else}} {{ctx.Locale.Tr "repo.issues.no_content"}} {{end}} @@ -95,7 +95,7 @@
{{.Content}}
{{if .Attachments}} - {{template "repo/issue/view_content/attachments" dict "ctxData" $ "Attachments" .Attachments "Content" .RenderedContent}} + {{template "repo/issue/view_content/attachments" dict "ctxData" $ "Attachments" .Attachments "RenderedContent" .RenderedContent}} {{end}}
{{$reactions := .Reactions.GroupByType}} diff --git a/templates/repo/release/list.tmpl b/templates/repo/release/list.tmpl index 5b747c2bf9a..7f38fa3ff05 100644 --- a/templates/repo/release/list.tmpl +++ b/templates/repo/release/list.tmpl @@ -58,7 +58,7 @@ {{end}}

- {{Str2html $release.Note}} + {{$release.RenderedNote}}
diff --git a/templates/repo/release_tag_header.tmpl b/templates/repo/release_tag_header.tmpl index f474fb89ead..31c151da08f 100644 --- a/templates/repo/release_tag_header.tmpl +++ b/templates/repo/release_tag_header.tmpl @@ -13,7 +13,7 @@
{{if .EnableFeed}} - {{svg "octicon-rss" 18}} {{ctx.Locale.Tr "rss_feed"}} + {{svg "octicon-rss" 16}} {{ctx.Locale.Tr "rss_feed"}} {{end}} {{if and (not .PageIsTagList) .CanCreateRelease}} diff --git a/templates/repo/settings/webhook/base_list.tmpl b/templates/repo/settings/webhook/base_list.tmpl index 5a3fc0e7b88..00f9a48ba77 100644 --- a/templates/repo/settings/webhook/base_list.tmpl +++ b/templates/repo/settings/webhook/base_list.tmpl @@ -10,7 +10,7 @@
- {{.Description | Str2html}} + {{.Description | SanitizeHTML}}
{{range .Webhooks}}
diff --git a/templates/shared/actions/runner_badge.tmpl b/templates/shared/actions/runner_badge.tmpl new file mode 100644 index 00000000000..816e87e177a --- /dev/null +++ b/templates/shared/actions/runner_badge.tmpl @@ -0,0 +1,25 @@ + + {{.Badge.Label.Text}}: {{.Badge.Message.Text}} + + + + + + + + + + + + + + + {{.Badge.Label.Text}}{{.Badge.Message.Text}} + diff --git a/templates/shared/user/profile_big_avatar.tmpl b/templates/shared/user/profile_big_avatar.tmpl index 19a3b25cc5a..88d3b9a6e56 100644 --- a/templates/shared/user/profile_big_avatar.tmpl +++ b/templates/shared/user/profile_big_avatar.tmpl @@ -70,7 +70,7 @@ {{end}} {{if $.RenderedDescription}}
  • -
    {{$.RenderedDescription|Str2html}}
    +
    {{$.RenderedDescription}}
  • {{end}} {{range .OpenIDs}} diff --git a/templates/status/404.tmpl b/templates/status/404.tmpl index a8cd3d32901..f1f11996656 100644 --- a/templates/status/404.tmpl +++ b/templates/status/404.tmpl @@ -1,5 +1,5 @@ {{template "base/head" .}} -
    +
    {{if .IsRepo}}{{template "repo/header" .}}{{end}}

    404

    diff --git a/templates/status/500.tmpl b/templates/status/500.tmpl index d6cff281748..a92933c153d 100644 --- a/templates/status/500.tmpl +++ b/templates/status/500.tmpl @@ -1,5 +1,5 @@ {{/* This page should only depend the minimal template functions/variables, to avoid triggering new panics. -* base template functions: AppName, AssetUrlPrefix, AssetVersion, AppSubUrl, ThemeName, Str2html +* base template functions: AppName, AssetUrlPrefix, AssetVersion, AppSubUrl, ThemeName, SanitizeHTML * ctx.Locale * .Flash * .ErrorMsg diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index b2bd1bf1744..d4c5d9a7ee6 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -689,6 +689,109 @@ } } }, + "/admin/users/{username}/badges": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "List a user's badges", + "operationId": "adminListUserBadges", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/BadgeList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "Add a badge to a user", + "operationId": "adminAddUserBadges", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/UserBadgeOption" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + }, + "delete": { + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "Remove a badge from a user", + "operationId": "adminDeleteUserBadges", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/UserBadgeOption" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, "/admin/users/{username}/keys": { "post": { "consumes": [ @@ -17003,6 +17106,45 @@ }, "x-go-package": "code.gitea.io/gitea/modules/structs" }, + "Badge": { + "description": "Badge represents a user badge", + "type": "object", + "properties": { + "description": { + "type": "string", + "x-go-name": "Description" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "image_url": { + "type": "string", + "x-go-name": "ImageURL" + }, + "slug": { + "type": "string", + "x-go-name": "Slug" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "BadgeList": { + "description": "BadgeList", + "type": "object", + "properties": { + "body": { + "description": "in:body", + "type": "array", + "items": { + "$ref": "#/definitions/Badge" + }, + "x-go-name": "Body" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, "Branch": { "description": "Branch represents a repository branch", "type": "object", @@ -23047,6 +23189,24 @@ }, "x-go-package": "code.gitea.io/gitea/modules/structs" }, + "UserBadgeOption": { + "description": "UserBadgeOption options for link between users and badges", + "type": "object", + "properties": { + "badge_slugs": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "BadgeSlugs", + "example": [ + "badge1", + "badge2" + ] + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, "UserHeatmapData": { "description": "UserHeatmapData represents the data needed to create a heatmap", "type": "object", @@ -23336,6 +23496,15 @@ } } }, + "BadgeList": { + "description": "BadgeList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Badge" + } + } + }, "Branch": { "description": "Branch", "schema": { @@ -24249,7 +24418,7 @@ "parameterBodies": { "description": "parameterBodies", "schema": { - "$ref": "#/definitions/CreateOrUpdateSecretOption" + "$ref": "#/definitions/BadgeList" } }, "redirect": { diff --git a/templates/user/auth/activate.tmpl b/templates/user/auth/activate.tmpl index 51dc1eb6a6b..e32a5d87073 100644 --- a/templates/user/auth/activate.tmpl +++ b/templates/user/auth/activate.tmpl @@ -21,6 +21,13 @@ {{else}}

    {{ctx.Locale.Tr "auth.has_unconfirmed_mail" .SignedUser.Name .SignedUser.Email}}

    +
    + {{ctx.Locale.Tr "auth.change_unconfirmed_mail_address"}} +
    + + +
    +
    diff --git a/templates/user/dashboard/milestones.tmpl b/templates/user/dashboard/milestones.tmpl index 1829021ff41..737a0f7e2b4 100644 --- a/templates/user/dashboard/milestones.tmpl +++ b/templates/user/dashboard/milestones.tmpl @@ -141,7 +141,7 @@
    {{if .Content}}
    - {{.RenderedContent|Str2html}} + {{.RenderedContent}}
    {{end}} diff --git a/templates/user/profile.tmpl b/templates/user/profile.tmpl index 426b5f042a5..37590fc2fa7 100644 --- a/templates/user/profile.tmpl +++ b/templates/user/profile.tmpl @@ -29,7 +29,7 @@ {{else if eq .TabName "followers"}} {{template "repo/user_cards" .}} {{else if eq .TabName "overview"}} -
    {{.ProfileReadme | Str2html}}
    +
    {{.ProfileReadme}}
    {{else}} {{template "explore/repo_search" .}} {{template "explore/repo_list" .}} diff --git a/templates/user/settings/keys.tmpl b/templates/user/settings/keys.tmpl index 93037e7e282..a44bf500482 100644 --- a/templates/user/settings/keys.tmpl +++ b/templates/user/settings/keys.tmpl @@ -2,6 +2,8 @@
    {{template "user/settings/keys_ssh" .}} {{template "user/settings/keys_principal" .}} + {{if not ($.UserDisabledFeatures.Contains "manage_gpg_keys")}} {{template "user/settings/keys_gpg" .}} + {{end}}
    {{template "user/settings/layout_footer" .}} diff --git a/tests/integration/api_repo_file_create_test.go b/tests/integration/api_repo_file_create_test.go index 0d192a1fe84..41ad7211ff8 100644 --- a/tests/integration/api_repo_file_create_test.go +++ b/tests/integration/api_repo_file_create_test.go @@ -17,10 +17,10 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/context" "github.com/stretchr/testify/assert" ) diff --git a/tests/integration/api_repo_file_update_test.go b/tests/integration/api_repo_file_update_test.go index 195a1090c7c..ac28e0c0a26 100644 --- a/tests/integration/api_repo_file_update_test.go +++ b/tests/integration/api_repo_file_update_test.go @@ -16,10 +16,10 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/context" "github.com/stretchr/testify/assert" ) diff --git a/tests/integration/api_repo_files_change_test.go b/tests/integration/api_repo_files_change_test.go index ab5cf19a9c8..fb3ae5e4ddb 100644 --- a/tests/integration/api_repo_files_change_test.go +++ b/tests/integration/api_repo_files_change_test.go @@ -15,10 +15,10 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/context" "github.com/stretchr/testify/assert" ) diff --git a/tests/integration/editor_test.go b/tests/integration/editor_test.go index de2a9d7d23b..045567ce77c 100644 --- a/tests/integration/editor_test.go +++ b/tests/integration/editor_test.go @@ -10,8 +10,8 @@ import ( "path" "testing" - gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" + gitea_context "code.gitea.io/gitea/services/context" "github.com/stretchr/testify/assert" ) diff --git a/tests/integration/explore_user_test.go b/tests/integration/explore_user_test.go new file mode 100644 index 00000000000..046caf378ef --- /dev/null +++ b/tests/integration/explore_user_test.go @@ -0,0 +1,44 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package integration + +import ( + "net/http" + "testing" + + "code.gitea.io/gitea/tests" + + "github.com/stretchr/testify/assert" +) + +func TestExploreUser(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + cases := []struct{ sortOrder, expected string }{ + {"", "/explore/users?sort=newest&q="}, + {"newest", "/explore/users?sort=newest&q="}, + {"oldest", "/explore/users?sort=oldest&q="}, + {"alphabetically", "/explore/users?sort=alphabetically&q="}, + {"reversealphabetically", "/explore/users?sort=reversealphabetically&q="}, + } + for _, c := range cases { + req := NewRequest(t, "GET", "/explore/users?sort="+c.sortOrder) + resp := MakeRequest(t, req, http.StatusOK) + h := NewHTMLParser(t, resp.Body) + href, _ := h.Find(`.ui.dropdown .menu a.active.item[href^="/explore/users"]`).Attr("href") + assert.Equal(t, c.expected, href) + } + + // these sort orders shouldn't be supported, to avoid leaking user activity + cases404 := []string{ + "/explore/users?sort=lastlogin", + "/explore/users?sort=reverselastlogin", + "/explore/users?sort=leastupdate", + "/explore/users?sort=reverseleastupdate", + } + for _, c := range cases404 { + req := NewRequest(t, "GET", c).SetHeader("Accept", "text/html") + MakeRequest(t, req, http.StatusNotFound) + } +} diff --git a/tests/integration/git_test.go b/tests/integration/git_test.go index 95350d79caa..818e1fa6535 100644 --- a/tests/integration/git_test.go +++ b/tests/integration/git_test.go @@ -24,12 +24,12 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + gitea_context "code.gitea.io/gitea/services/context" files_service "code.gitea.io/gitea/services/repository/files" "code.gitea.io/gitea/tests" diff --git a/tests/integration/integration_test.go b/tests/integration/integration_test.go index 1127de1afcd..f9bd352b622 100644 --- a/tests/integration/integration_test.go +++ b/tests/integration/integration_test.go @@ -24,7 +24,6 @@ import ( "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/unittest" - gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" @@ -33,6 +32,7 @@ import ( "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers" + gitea_context "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/tests" "github.com/PuerkitoBio/goquery" diff --git a/tests/integration/mirror_pull_test.go b/tests/integration/mirror_pull_test.go index 2e71b80fbb5..77050c4bbc1 100644 --- a/tests/integration/mirror_pull_test.go +++ b/tests/integration/mirror_pull_test.go @@ -14,7 +14,6 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/migration" - "code.gitea.io/gitea/modules/repository" mirror_service "code.gitea.io/gitea/services/mirror" release_service "code.gitea.io/gitea/services/release" repo_service "code.gitea.io/gitea/services/repository" @@ -52,7 +51,7 @@ func TestMirrorPull(t *testing.T) { ctx := context.Background() - mirror, err := repository.MigrateRepositoryGitData(ctx, user, mirrorRepo, opts, nil) + mirror, err := repo_service.MigrateRepositoryGitData(ctx, user, mirrorRepo, opts, nil) assert.NoError(t, err) gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo) diff --git a/tests/integration/mirror_push_test.go b/tests/integration/mirror_push_test.go index 3dc719593c3..1c262b33496 100644 --- a/tests/integration/mirror_push_test.go +++ b/tests/integration/mirror_push_test.go @@ -15,10 +15,10 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/setting" + gitea_context "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/migrations" mirror_service "code.gitea.io/gitea/services/mirror" repo_service "code.gitea.io/gitea/services/repository" diff --git a/tests/integration/repo_fork_test.go b/tests/integration/repo_fork_test.go index 594fba67965..ca5d61ecc2a 100644 --- a/tests/integration/repo_fork_test.go +++ b/tests/integration/repo_fork_test.go @@ -29,14 +29,14 @@ func testRepoFork(t *testing.T, session *TestSession, ownerName, repoName, forkO // Step2: click the fork button htmlDoc := NewHTMLParser(t, resp.Body) - link, exists := htmlDoc.doc.Find("a.ui.button[href^=\"/repo/fork/\"]").Attr("href") + link, exists := htmlDoc.doc.Find(`a.ui.button[href*="/fork"]`).Attr("href") assert.True(t, exists, "The template has changed") req = NewRequest(t, "GET", link) resp = session.MakeRequest(t, req, http.StatusOK) // Step3: fill the form of the forking htmlDoc = NewHTMLParser(t, resp.Body) - link, exists = htmlDoc.doc.Find("form.ui.form[action^=\"/repo/fork/\"]").Attr("action") + link, exists = htmlDoc.doc.Find(`form.ui.form[action*="/fork"]`).Attr("action") assert.True(t, exists, "The template has changed") _, exists = htmlDoc.doc.Find(fmt.Sprintf(".owner.dropdown .item[data-value=\"%d\"]", forkOwner.ID)).Attr("data-value") assert.True(t, exists, fmt.Sprintf("Fork owner '%s' is not present in select box", forkOwnerName)) @@ -70,6 +70,6 @@ func TestRepoForkToOrg(t *testing.T) { req := NewRequest(t, "GET", "/user2/repo1") resp := session.MakeRequest(t, req, http.StatusOK) htmlDoc := NewHTMLParser(t, resp.Body) - _, exists := htmlDoc.doc.Find("a.ui.button[href^=\"/repo/fork/\"]").Attr("href") + _, exists := htmlDoc.doc.Find(`a.ui.button[href*="/fork"]`).Attr("href") assert.False(t, exists, "Forking should not be allowed anymore") } diff --git a/tests/integration/repofiles_change_test.go b/tests/integration/repofiles_change_test.go index 19fbd1754cc..49abeb83fb1 100644 --- a/tests/integration/repofiles_change_test.go +++ b/tests/integration/repofiles_change_test.go @@ -12,11 +12,11 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/contexttest" files_service "code.gitea.io/gitea/services/repository/files" "github.com/stretchr/testify/assert" diff --git a/tests/integration/signup_test.go b/tests/integration/signup_test.go index fbf586f6964..e9a05201eef 100644 --- a/tests/integration/signup_test.go +++ b/tests/integration/signup_test.go @@ -107,13 +107,25 @@ func TestSignupEmailActive(t *testing.T) { resp := MakeRequest(t, req, http.StatusOK) assert.Contains(t, resp.Body.String(), `A new confirmation email has been sent to email-1@example.com.`) - // access "user/active" means trying to re-send the activation email + // access "user/activate" means trying to re-send the activation email session := loginUserWithPassword(t, "test-user-1", "password1") resp = session.MakeRequest(t, NewRequest(t, "GET", "/user/activate"), http.StatusOK) assert.Contains(t, resp.Body.String(), "You have already requested an activation email recently") - // access "user/active" with a valid activation code, then get the "verify password" page + // access anywhere else will see a "Activate Your Account" prompt, and there is a chance to change email + resp = session.MakeRequest(t, NewRequest(t, "GET", "/user/issues"), http.StatusOK) + assert.Contains(t, resp.Body.String(), ` .button, .ui.basic.buttons .button, .ui.basic.button, diff --git a/web_src/css/themes/theme-gitea-dark.css b/web_src/css/themes/theme-gitea-dark.css index bac002e3db5..ac77b7bbd94 100644 --- a/web_src/css/themes/theme-gitea-dark.css +++ b/web_src/css/themes/theme-gitea-dark.css @@ -3,72 +3,72 @@ :root { --is-dark-theme: true; - --color-primary: #87ab63; + --color-primary: #4183c4; --color-primary-contrast: #ffffff; - --color-primary-dark-1: #93b373; - --color-primary-dark-2: #9fbc82; - --color-primary-dark-3: #abc492; - --color-primary-dark-4: #b7cda1; - --color-primary-dark-5: #cfddc1; - --color-primary-dark-6: #e7eee0; - --color-primary-dark-7: #f8faf6; - --color-primary-light-1: #7a9e55; - --color-primary-light-2: #6c8c4c; - --color-primary-light-3: #5f7b42; - --color-primary-light-4: #516939; - --color-primary-light-5: #364626; - --color-primary-light-6: #1b2313; - --color-primary-light-7: #080b06; - --color-primary-alpha-10: #87ab6319; - --color-primary-alpha-20: #87ab6333; - --color-primary-alpha-30: #87ab634b; - --color-primary-alpha-40: #87ab6366; - --color-primary-alpha-50: #87ab6380; - --color-primary-alpha-60: #87ab6399; - --color-primary-alpha-70: #87ab63b3; - --color-primary-alpha-80: #87ab63cc; - --color-primary-alpha-90: #87ab63e1; + --color-primary-dark-1: #548fca; + --color-primary-dark-2: #679cd0; + --color-primary-dark-3: #7aa8d6; + --color-primary-dark-4: #8db5dc; + --color-primary-dark-5: #b3cde7; + --color-primary-dark-6: #d9e6f3; + --color-primary-dark-7: #f4f8fb; + --color-primary-light-1: #3876b3; + --color-primary-light-2: #31699f; + --color-primary-light-3: #2b5c8b; + --color-primary-light-4: #254f77; + --color-primary-light-5: #193450; + --color-primary-light-6: #0c1a28; + --color-primary-light-7: #04080c; + --color-primary-alpha-10: #4183c419; + --color-primary-alpha-20: #4183c433; + --color-primary-alpha-30: #4183c44b; + --color-primary-alpha-40: #4183c466; + --color-primary-alpha-50: #4183c480; + --color-primary-alpha-60: #4183c499; + --color-primary-alpha-70: #4183c4b3; + --color-primary-alpha-80: #4183c4cc; + --color-primary-alpha-90: #4183c4e1; --color-primary-hover: var(--color-primary-light-1); --color-primary-active: var(--color-primary-light-2); - --color-secondary: #525767; - --color-secondary-dark-1: #5c6374; - --color-secondary-dark-2: #666e81; - --color-secondary-dark-3: #7c8497; - --color-secondary-dark-4: #8990a1; - --color-secondary-dark-5: #959cab; - --color-secondary-dark-6: #a2a8b5; - --color-secondary-dark-7: #afb4c0; - --color-secondary-dark-8: #bcc0ca; - --color-secondary-dark-9: #c9cbd4; - --color-secondary-dark-10: #d6d7de; - --color-secondary-dark-11: #e2e3e8; - --color-secondary-dark-12: #eeeff2; - --color-secondary-dark-13: #fbfbfc; - --color-secondary-light-1: #454a57; - --color-secondary-light-2: #383c47; - --color-secondary-light-3: #2c2f37; - --color-secondary-light-4: #1f2226; - --color-secondary-alpha-10: #52576719; - --color-secondary-alpha-20: #52576733; - --color-secondary-alpha-30: #5257674b; - --color-secondary-alpha-40: #52576766; - --color-secondary-alpha-50: #52576780; - --color-secondary-alpha-60: #52576799; - --color-secondary-alpha-70: #525767b3; - --color-secondary-alpha-80: #525767cc; - --color-secondary-alpha-90: #525767e1; + --color-secondary: #3f4346; + --color-secondary-dark-1: #464a4d; + --color-secondary-dark-2: #4f5356; + --color-secondary-dark-3: #5f6366; + --color-secondary-dark-4: #72767a; + --color-secondary-dark-5: #7f8488; + --color-secondary-dark-6: #8d9297; + --color-secondary-dark-7: #999ea3; + --color-secondary-dark-8: #a6abaf; + --color-secondary-dark-9: #aeb3b8; + --color-secondary-dark-10: #babfc4; + --color-secondary-dark-11: #c5cbd0; + --color-secondary-dark-12: #ced4da; + --color-secondary-dark-13: #d1d7dd; + --color-secondary-light-1: #313538; + --color-secondary-light-2: #272b2e; + --color-secondary-light-3: #1e2225; + --color-secondary-light-4: #171b1e; + --color-secondary-alpha-10: #3f434619; + --color-secondary-alpha-20: #3f434633; + --color-secondary-alpha-30: #3f43464b; + --color-secondary-alpha-40: #3f434666; + --color-secondary-alpha-50: #3f434680; + --color-secondary-alpha-60: #3f434699; + --color-secondary-alpha-70: #3f4346b3; + --color-secondary-alpha-80: #3f4346cc; + --color-secondary-alpha-90: #3f4346e1; --color-secondary-button: var(--color-secondary-dark-4); --color-secondary-hover: var(--color-secondary-dark-3); --color-secondary-active: var(--color-secondary-dark-2); /* console colors - used for actions console and console files */ - --color-console-fg: #eeeff2; - --color-console-fg-subtle: #959cab; - --color-console-bg: #262936; - --color-console-border: #383c47; + --color-console-fg: #d9dde2; + --color-console-fg-subtle: #95989c; + --color-console-bg: #1c2023; + --color-console-border: #272b2e; --color-console-hover-bg: #ffffff16; - --color-console-active-bg: #454a57; - --color-console-menu-bg: #383c47; - --color-console-menu-border: #5c6374; + --color-console-active-bg: #313538; + --color-console-menu-bg: #272b2e; + --color-console-menu-border: #464a4d; /* named colors */ --color-red: #cc4848; --color-orange: #cc580c; @@ -81,7 +81,7 @@ --color-purple: #b259d0; --color-pink: #d22e8b; --color-brown: #a47252; - --color-black: #2e323e; + --color-black: #1f2326; /* light variants - produced via Sass scale-color(color, $lightness: +10%) */ --color-red-light: #d15a5a; --color-orange-light: #f6a066; @@ -94,7 +94,7 @@ --color-purple-light: #ba6ad5; --color-pink-light: #d74397; --color-brown-light: #b08061; - --color-black-light: #3f4555; + --color-black-light: #46494d; /* dark 1 variants - produced via Sass scale-color(color, $lightness: -10%) */ --color-red-dark-1: #c23636; --color-orange-dark-1: #f38236; @@ -107,7 +107,7 @@ --color-purple-dark-1: #a742c9; --color-pink-dark-1: #be297d; --color-brown-dark-1: #94674a; - --color-black-dark-1: #292d38; + --color-black-dark-1: #2c2f35; /* dark 2 variants - produced via Sass scale-color(color, $lightness: -20%) */ --color-red-dark-2: #ad3030; --color-orange-dark-2: #f16e17; @@ -120,7 +120,7 @@ --color-purple-dark-2: #9834b9; --color-pink-dark-2: #a9246f; --color-brown-dark-2: #835b42; - --color-black-dark-2: #252832; + --color-black-dark-2: #292a2e; /* ansi colors used for actions console and console files */ --color-ansi-black: var(--color-black); --color-ansi-red: var(--color-red); @@ -139,8 +139,8 @@ --color-ansi-bright-cyan: var(--color-teal-light); --color-ansi-bright-white: var(--color-console-fg); /* other colors */ - --color-grey: #505665; - --color-grey-light: #a1a6b7; + --color-grey: #3c4043; + --color-grey-light: #898e92; --color-gold: #b1983b; --color-white: #ffffff; --color-diff-removed-word-bg: #6f3333; @@ -151,7 +151,7 @@ --color-diff-removed-row-border: #634343; --color-diff-moved-row-border: #bcca6f; --color-diff-added-row-border: #314a37; - --color-diff-inactive: #353846; + --color-diff-inactive: #24282b; --color-error-border: #a04141; --color-error-bg: #522; --color-error-bg-active: #744; @@ -180,40 +180,40 @@ --color-orange-badge-hover-bg: #f2711c4d; --color-git: #f05133; /* target-based colors */ - --color-body: #2e323e; - --color-box-header: #303340; - --color-box-body: #222733; - --color-box-body-highlight: #262b36; - --color-text-dark: #dbe0ea; - --color-text: #cbd0da; - --color-text-light: #bbbfca; - --color-text-light-1: #aaafb9; - --color-text-light-2: #9a9ea9; - --color-text-light-3: #8a8e99; - --color-footer: #232834; - --color-timeline: #4c525e; - --color-input-text: #dfe3ec; - --color-input-background: #1e252e; - --color-input-toggle-background: #454a57; + --color-body: #1f2326; + --color-box-header: #202427; + --color-box-body: #191d20; + --color-box-body-highlight: #1d2124; + --color-text-dark: #f8f8f9; + --color-text: #ced2d5; + --color-text-light: #bec4c8; + --color-text-light-1: #acb3b8; + --color-text-light-2: #8d969c; + --color-text-light-3: #747f87; + --color-footer: var(--color-nav-bg); + --color-timeline: #383c3f; + --color-input-text: var(--color-text-dark); + --color-input-background: #161a1d; + --color-input-toggle-background: #313538; --color-input-border: var(--color-secondary); --color-input-border-hover: var(--color-secondary-dark-1); - --color-header-wrapper: #202430; + --color-header-wrapper: #191d20; --color-light: #00000028; --color-light-mimic-enabled: rgba(0, 0, 0, calc(40 / 255 * 222 / 255 / var(--opacity-disabled))); --color-light-border: #ffffff28; --color-hover: #ffffff19; --color-active: #ffffff24; - --color-menu: #1e252e; - --color-card: #1e252e; + --color-menu: #161a1d; + --color-card: #161a1d; --color-markup-table-row: #ffffff06; --color-markup-code-block: #ffffff16; - --color-button: #1e252e; - --color-code-bg: #222733; - --color-code-sidebar-bg: #232834; + --color-button: #161a1d; + --color-code-bg: #191d20; + --color-code-sidebar-bg: #1b1f22; --color-shadow: #00000058; - --color-secondary-bg: #2a2e3a; - --color-expand-button: #3c404d; - --color-placeholder-text: #8a8e99; + --color-secondary-bg: #2f3135; + --color-expand-button: #414348; + --color-placeholder-text: var(--color-text-light-3); --color-editor-line-highlight: var(--color-primary-light-5); --color-project-board-bg: var(--color-secondary-light-2); --color-project-board-dark-label: #111111; @@ -224,13 +224,13 @@ --color-reaction-active-bg: var(--color-primary-light-5); --color-tooltip-text: #ffffff; --color-tooltip-bg: #000000f0; - --color-nav-bg: #232834; - --color-nav-hover-bg: #383c47; + --color-nav-bg: #1b1f22; + --color-nav-hover-bg: #272b2e; --color-nav-text: var(--color-text); - --color-label-text: #dfe3ec; - --color-label-bg: #7c84974b; - --color-label-hover-bg: #7c8497a0; - --color-label-active-bg: #7c8497ff; + --color-label-text: var(--color-text); + --color-label-bg: #7a7f834b; + --color-label-hover-bg: #7a7f83a0; + --color-label-active-bg: #7a7f83ff; --color-accent: var(--color-primary-light-1); --color-small-accent: var(--color-primary-light-5); --color-active-line: #534d1b; diff --git a/web_src/css/themes/theme-gitea-light.css b/web_src/css/themes/theme-gitea-light.css index ca5d15cd25b..5c375712d84 100644 --- a/web_src/css/themes/theme-gitea-light.css +++ b/web_src/css/themes/theme-gitea-light.css @@ -190,9 +190,9 @@ --color-text-light-1: #6a6a6a; --color-text-light-2: #808080; --color-text-light-3: #a0a0a0; - --color-footer: #ffffff; + --color-footer: var(--color-nav-bg); --color-timeline: #ececec; - --color-input-text: #212121; + --color-input-text: var(--color-text-dark); --color-input-background: #fafafa; --color-input-toggle-background: #dedede; --color-input-border: var(--color-secondary); @@ -213,7 +213,7 @@ --color-shadow: #00000026; --color-secondary-bg: #f4f4f4; --color-expand-button: #d8efff; - --color-placeholder-text: #aaa; + --color-placeholder-text: var(--color-text-light-3); --color-editor-line-highlight: var(--color-primary-light-6); --color-project-board-bg: var(--color-secondary-light-4); --color-project-board-dark-label: #111111; @@ -227,7 +227,7 @@ --color-nav-bg: #ffffff; --color-nav-hover-bg: #ebebeb; --color-nav-text: var(--color-text); - --color-label-text: #232323; + --color-label-text: var(--color-text); --color-label-bg: #cacaca5b; --color-label-hover-bg: #cacacaa0; --color-label-active-bg: #cacacaff; diff --git a/web_src/js/bootstrap.js b/web_src/js/bootstrap.js index e46c91e5e6d..c0047b0ac24 100644 --- a/web_src/js/bootstrap.js +++ b/web_src/js/bootstrap.js @@ -1,5 +1,6 @@ // DO NOT IMPORT window.config HERE! -// to make sure the error handler always works, we should never import `window.config`, because some user's custom template breaks it. +// to make sure the error handler always works, we should never import `window.config`, because +// some user's custom template breaks it. // This sets up the URL prefix used in webpack's chunk loading. // This file must be imported before any lazy-loading is being attempted. @@ -26,29 +27,42 @@ export function showGlobalErrorMessage(msg) { } /** - * @param {ErrorEvent} e + * @param {ErrorEvent|PromiseRejectionEvent} event - Event + * @param {string} event.message - Only present on ErrorEvent + * @param {string} event.error - Only present on ErrorEvent + * @param {string} event.type - Only present on ErrorEvent + * @param {string} event.filename - Only present on ErrorEvent + * @param {number} event.lineno - Only present on ErrorEvent + * @param {number} event.colno - Only present on ErrorEvent + * @param {string} event.reason - Only present on PromiseRejectionEvent + * @param {number} event.promise - Only present on PromiseRejectionEvent */ -function processWindowErrorEvent(e) { - const err = e.error ?? e.reason; +function processWindowErrorEvent({error, reason, message, type, filename, lineno, colno}) { + const err = error ?? reason; const assetBaseUrl = String(new URL(__webpack_public_path__, window.location.origin)); + const {runModeIsProd} = window.config ?? {}; - // error is likely from browser extension or inline script. Do not show these in production builds. - if (!err.stack?.includes(assetBaseUrl) && window.config?.runModeIsProd) return; - - let message; - if (e.type === 'unhandledrejection') { - message = `JavaScript promise rejection: ${err.message}.`; - } else { - message = `JavaScript error: ${e.message} (${e.filename} @ ${e.lineno}:${e.colno}).`; + // `error` and `reason` are not guaranteed to be errors. If the value is falsy, it is likly a + // non-critical event from the browser. We log them but don't show them to users. Examples: + // - https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver#observation_errors + // - https://github.com/mozilla-mobile/firefox-ios/issues/10817 + // - https://github.com/go-gitea/gitea/issues/20240 + if (!err) { + if (message) console.error(new Error(message)); + if (runModeIsProd) return; } - if (!e.error && e.lineno === 0 && e.colno === 0 && e.filename === '' && window.navigator.userAgent.includes('FxiOS/')) { - // At the moment, Firefox (iOS) (10x) has an engine bug. See https://github.com/go-gitea/gitea/issues/20240 - // If a script inserts a newly created (and content changed) element into DOM, there will be a nonsense error event reporting: Script error: line 0, col 0. - return; // ignore such nonsense error event + // If the error stack trace does not include the base URL of our script assets, it likely came + // from a browser extension or inline script. Do not show such errors in production. + if (err instanceof Error && !err.stack?.includes(assetBaseUrl) && runModeIsProd) { + return; } - showGlobalErrorMessage(`${message} Open browser console to see more details.`); + let msg = err?.message ?? message; + if (lineno) msg += ` (${filename} @ ${lineno}:${colno})`; + const dot = msg.endsWith('.') ? '' : '.'; + const renderedType = type === 'unhandledrejection' ? 'promise rejection' : type; + showGlobalErrorMessage(`JavaScript ${renderedType}: ${msg}${dot} Open browser console to see more details.`); } function initGlobalErrorHandler() { @@ -59,13 +73,14 @@ function initGlobalErrorHandler() { if (!window.config) { showGlobalErrorMessage(`Gitea JavaScript code couldn't run correctly, please check your custom templates`); } - // we added an event handler for window error at the very beginning of