From d0af8fe4dc7b294fe5409b2271468494267d5a7d Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Mon, 7 Oct 2024 23:21:07 +0200 Subject: [PATCH 1/6] Allow filtering PRs by poster in the ListPullRequests API (#32209) as title --- *Sponsored by Kithara Software GmbH* (cherry picked from commit bdd655f2bde5facada4394f36fe54e364787de7a) --- models/issues/pull_list.go | 5 ++++ routers/api/v1/repo/pull.go | 42 ++++++++++++++++++++++++++-------- templates/swagger/v1_json.tmpl | 25 +++++++++++++++----- 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/models/issues/pull_list.go b/models/issues/pull_list.go index f3970fa93b..123ff18d81 100644 --- a/models/issues/pull_list.go +++ b/models/issues/pull_list.go @@ -26,6 +26,7 @@ type PullRequestsOptions struct { SortType string Labels []int64 MilestoneID int64 + PosterID int64 } func listPullRequestStatement(ctx context.Context, baseRepoID int64, opts *PullRequestsOptions) *xorm.Session { @@ -46,6 +47,10 @@ func listPullRequestStatement(ctx context.Context, baseRepoID int64, opts *PullR sess.And("issue.milestone_id=?", opts.MilestoneID) } + if opts.PosterID > 0 { + sess.And("issue.poster_id=?", opts.PosterID) + } + return sess } diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index bcb6ef2581..748ef18802 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -52,56 +52,79 @@ func ListPullRequests(ctx *context.APIContext) { // parameters: // - name: owner // in: path - // description: owner of the repo + // description: Owner of the repo // type: string // required: true // - name: repo // in: path - // description: name of the repo + // description: Name of the repo // type: string // required: true // - name: state // in: query - // description: "State of pull request: open or closed (optional)" + // description: State of pull request // type: string - // enum: [closed, open, all] + // enum: [open, closed, all] + // default: open // - name: sort // in: query - // description: "Type of sort" + // description: Type of sort // type: string // enum: [oldest, recentupdate, leastupdate, mostcomment, leastcomment, priority] // - name: milestone // in: query - // description: "ID of the milestone" + // description: ID of the milestone // type: integer // format: int64 // - name: labels // in: query - // description: "Label IDs" + // description: Label IDs // type: array // collectionFormat: multi // items: // type: integer // format: int64 + // - name: poster + // in: query + // description: Filter by pull request author + // type: string // - name: page // in: query - // description: page number of results to return (1-based) + // description: Page number of results to return (1-based) // type: integer + // minimum: 1 + // default: 1 // - name: limit // in: query - // description: page size of results + // description: Page size of results // type: integer + // minimum: 0 // responses: // "200": // "$ref": "#/responses/PullRequestList" // "404": // "$ref": "#/responses/notFound" + // "500": + // "$ref": "#/responses/error" labelIDs, err := base.StringsToInt64s(ctx.FormStrings("labels")) if err != nil { ctx.Error(http.StatusInternalServerError, "PullRequests", err) return } + var posterID int64 + if posterStr := ctx.FormString("poster"); posterStr != "" { + poster, err := user_model.GetUserByName(ctx, posterStr) + if err != nil { + if user_model.IsErrUserNotExist(err) { + ctx.Error(http.StatusBadRequest, "Poster not found", err) + } else { + ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + } + return + } + posterID = poster.ID + } listOptions := utils.GetListOptions(ctx) prs, maxResults, err := issues_model.PullRequests(ctx, ctx.Repo.Repository.ID, &issues_model.PullRequestsOptions{ ListOptions: listOptions, @@ -109,6 +132,7 @@ func ListPullRequests(ctx *context.APIContext) { SortType: ctx.FormTrim("sort"), Labels: labelIDs, MilestoneID: ctx.FormInt64("milestone"), + PosterID: posterID, }) if err != nil { ctx.Error(http.StatusInternalServerError, "PullRequests", err) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 8c4e7eaf8b..3163481647 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -12295,26 +12295,27 @@ "parameters": [ { "type": "string", - "description": "owner of the repo", + "description": "Owner of the repo", "name": "owner", "in": "path", "required": true }, { "type": "string", - "description": "name of the repo", + "description": "Name of the repo", "name": "repo", "in": "path", "required": true }, { "enum": [ - "closed", "open", + "closed", "all" ], "type": "string", - "description": "State of pull request: open or closed (optional)", + "default": "open", + "description": "State of pull request", "name": "state", "in": "query" }, @@ -12351,14 +12352,23 @@ "in": "query" }, { + "type": "string", + "description": "Filter by pull request author", + "name": "poster", + "in": "query" + }, + { + "minimum": 1, "type": "integer", - "description": "page number of results to return (1-based)", + "default": 1, + "description": "Page number of results to return (1-based)", "name": "page", "in": "query" }, { + "minimum": 0, "type": "integer", - "description": "page size of results", + "description": "Page size of results", "name": "limit", "in": "query" } @@ -12369,6 +12379,9 @@ }, "404": { "$ref": "#/responses/notFound" + }, + "500": { + "$ref": "#/responses/error" } } }, From eff28911d32d844230bb016834fbfac055efc7a1 Mon Sep 17 00:00:00 2001 From: cloudchamb3r Date: Wed, 9 Oct 2024 02:27:05 +0900 Subject: [PATCH 2/6] Add null check for responseData.invalidTopics (#32212) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Screenshot 2024-10-08 at 10 49 10 AM `responseData.invalidTopics` can be null but it wasn't handled. (cherry picked from commit 2e12343fc4ca96a215d6820c4467b619eaa5cbe9) --- web_src/js/features/repo-home.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_src/js/features/repo-home.js b/web_src/js/features/repo-home.js index 6a5bce8268..3031432c93 100644 --- a/web_src/js/features/repo-home.js +++ b/web_src/js/features/repo-home.js @@ -60,7 +60,7 @@ export function initRepoTopicBar() { // how to test: input topic like " invalid topic " (with spaces), and select it from the list, then "Save" const responseData = await response.json(); lastErrorToast = showErrorToast(responseData.message, {duration: 5000}); - if (responseData.invalidTopics.length > 0) { + if (responseData.invalidTopics && responseData.invalidTopics.length > 0) { const {invalidTopics} = responseData; const topicLabels = queryElemChildren(topicDropdown, 'a.ui.label'); for (const [index, value] of topics.split(',').entries()) { From 7855e4bb56e2379c96e981ab179aec1b9a9ac9fc Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Sun, 13 Oct 2024 10:13:04 +0300 Subject: [PATCH 3/6] Improve the maintainblity of the reserved username list (#32229) (cherry picked from commit 6029d78ab5006e8fb4f42adb5a8c491f19fa7b0a) Conflicts: models/user/user.go services/user/user_test.go trivial context conflict tests/integration/user_test.go discarded entirely because dot may be allowed in Forgejo under some conditions --- models/user/user.go | 70 +++++++++++++++++----------------- services/user/user_test.go | 8 ++-- tests/integration/user_test.go | 7 ---- 3 files changed, 39 insertions(+), 46 deletions(-) diff --git a/models/user/user.go b/models/user/user.go index 382c6955f7..c538d56ed1 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -586,44 +586,46 @@ var ( ".", "..", ".well-known", - "admin", - "api", - "assets", - "attachments", - "avatar", - "avatars", - "captcha", - "commits", - "debug", - "devtest", - "error", - "explore", - "favicon.ico", - "ghost", - "issues", - "login", - "manifest.json", - "metrics", - "milestones", - "new", - "notifications", - "org", - "pulls", - "raw", - "repo", + + "api", // gitea api + "metrics", // prometheus metrics api + "v2", // container registry api + + "assets", // static asset files + "attachments", // issue attachments + + "avatar", // avatar by email hash + "avatars", // user avatars by file name "repo-avatars", - "robots.txt", - "search", - "serviceworker.js", - "ssh_info", + + "captcha", + "login", // oauth2 login + "org", // org create/manage, or "/org/{org}", BUT if an org is named as "invite" then it goes wrong + "repo", // repo create/migrate, etc + "user", // user login/activate/settings, etc + + "admin", + "devtest", + "explore", + "issues", + "pulls", + "milestones", + "notifications", + + "favicon.ico", + "manifest.json", // web app manifests + "robots.txt", // search engine robots + "sitemap.xml", // search engine sitemap + "ssh_info", // agit info "swagger.v1.json", - "user", - "v2", - "gitea-actions", - "forgejo-actions", + + "ghost", // reserved name for deleted users (id: -1) + "gitea-actions", // gitea builtin user (id: -2) + "forgejo-actions", // forgejo builtin user (id: -2) } - // DON'T ADD ANY NEW STUFF, WE SOLVE THIS WITH `/user/{obj}` PATHS! + // These names are reserved for user accounts: user's keys, user's rss feed, user's avatar, etc. + // DO NOT add any new stuff! The paths with these names are processed by `/{username}` handler (UsernameSubRoute) manually. reservedUserPatterns = []string{"*.keys", "*.gpg", "*.rss", "*.atom", "*.png"} ) diff --git a/services/user/user_test.go b/services/user/user_test.go index 45bf1e6993..edd8d5020c 100644 --- a/services/user/user_test.go +++ b/services/user/user_test.go @@ -114,12 +114,10 @@ func TestRenameUser(t *testing.T) { }) t.Run("Non usable username", func(t *testing.T) { - usernames := []string{"--diff", "aa.png", ".well-known", "search", "aaa.atom"} + usernames := []string{"--diff", ".well-known", "gitea-actions", "aaa.atom", "aa.png"} for _, username := range usernames { - t.Run(username, func(t *testing.T) { - require.Error(t, user_model.IsUsableUsername(username)) - require.Error(t, RenameUser(db.DefaultContext, user, username)) - }) + require.Error(t, user_model.IsUsableUsername(username), "non-usable username: %s", username) + require.Error(t, RenameUser(db.DefaultContext, user, username), "non-usable username: %s", username) } }) diff --git a/tests/integration/user_test.go b/tests/integration/user_test.go index 73976b9a35..3ea2761d11 100644 --- a/tests/integration/user_test.go +++ b/tests/integration/user_test.go @@ -114,10 +114,7 @@ func TestRenameReservedUsername(t *testing.T) { "avatar", "avatars", "captcha", - "commits", - "debug", "devtest", - "error", "explore", "favicon.ico", "ghost", @@ -126,16 +123,12 @@ func TestRenameReservedUsername(t *testing.T) { "manifest.json", "metrics", "milestones", - "new", "notifications", "org", "pulls", - "raw", "repo", "repo-avatars", "robots.txt", - "search", - "serviceworker.js", "ssh_info", "swagger.v1.json", "user", From 68aa530fb2bacdc2770c364d6cd0f7247fb8ed9c Mon Sep 17 00:00:00 2001 From: cloudchamb3r Date: Fri, 11 Oct 2024 02:12:27 +0900 Subject: [PATCH 4/6] Fix checkbox bug on private/archive filter (#32236) fix #32235 --------- Co-authored-by: wxiaoguang (cherry picked from commit cb739f533358a8cf6e1b6875b3d4f0da3bfa7c95) --- web_src/js/components/DashboardRepoList.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web_src/js/components/DashboardRepoList.vue b/web_src/js/components/DashboardRepoList.vue index e5874133b1..007891a39f 100644 --- a/web_src/js/components/DashboardRepoList.vue +++ b/web_src/js/components/DashboardRepoList.vue @@ -358,9 +358,9 @@ export default sfc; // activate the IDE's Vue plugin