From 0da7318cf3b4933ec76ba7730daa1deacfcb0e78 Mon Sep 17 00:00:00 2001 From: Andreas Svanberg Date: Fri, 21 Mar 2025 05:25:36 +0100 Subject: [PATCH 1/9] Allow filtering issues by any assignee (#33343) This is the opposite of the "No assignee" filter, it will match all issues that have at least one assignee. Before ![Before change](https://github.com/user-attachments/assets/4aea194b-9add-4a84-8d6b-61bfd8d9e58e) After ![After change with any filter](https://github.com/user-attachments/assets/99f1205d-ba9f-4a0a-a60b-cc1a0c0823fe) --------- Co-authored-by: wxiaoguang --- models/db/search.go | 4 --- models/issues/issue_search.go | 31 +++++++++---------- models/issues/issue_test.go | 3 +- modules/indexer/issues/bleve/bleve.go | 18 ++++++++--- modules/indexer/issues/db/options.go | 2 +- modules/indexer/issues/dboptions.go | 6 +--- .../issues/elasticsearch/elasticsearch.go | 18 ++++++++--- modules/indexer/issues/indexer_test.go | 31 ++++++++++++++++--- modules/indexer/issues/internal/model.go | 5 ++- .../indexer/issues/internal/tests/tests.go | 21 +++++++++++-- .../indexer/issues/meilisearch/meilisearch.go | 16 +++++++--- options/locale/locale_en-US.ini | 4 +-- routers/api/v1/repo/issue.go | 8 ++--- routers/web/org/projects.go | 4 +-- routers/web/repo/issue_list.go | 18 +++++------ routers/web/repo/projects.go | 4 +-- routers/web/shared/user/helper.go | 19 ++++++------ routers/web/user/home.go | 16 +++++----- templates/projects/view.tmpl | 4 +-- .../repo/issue/filter_item_user_assign.tmpl | 26 ++++++++++------ templates/repo/issue/filter_list.tmpl | 4 +-- web_src/fomantic/build/components/dropdown.js | 6 +++- 22 files changed, 167 insertions(+), 101 deletions(-) diff --git a/models/db/search.go b/models/db/search.go index e0a1b6bde9..44d54f21fc 100644 --- a/models/db/search.go +++ b/models/db/search.go @@ -29,7 +29,3 @@ const ( // NoConditionID means a condition to filter the records which don't match any id. // eg: "milestone_id=-1" means "find the items without any milestone. const NoConditionID int64 = -1 - -// NonExistingID means a condition to match no result (eg: a non-existing user) -// It doesn't use -1 or -2 because they are used as builtin users. -const NonExistingID int64 = -1000000 diff --git a/models/issues/issue_search.go b/models/issues/issue_search.go index 694b918755..737b69f154 100644 --- a/models/issues/issue_search.go +++ b/models/issues/issue_search.go @@ -27,8 +27,8 @@ type IssuesOptions struct { //nolint RepoIDs []int64 // overwrites RepoCond if the length is not 0 AllPublic bool // include also all public repositories RepoCond builder.Cond - AssigneeID optional.Option[int64] - PosterID optional.Option[int64] + AssigneeID string // "(none)" or "(any)" or a user ID + PosterID string // "(none)" or "(any)" or a user ID MentionedID int64 ReviewRequestedID int64 ReviewedID int64 @@ -356,26 +356,25 @@ func issuePullAccessibleRepoCond(repoIDstr string, userID int64, owner *user_mod return cond } -func applyAssigneeCondition(sess *xorm.Session, assigneeID optional.Option[int64]) { +func applyAssigneeCondition(sess *xorm.Session, assigneeID string) { // old logic: 0 is also treated as "not filtering assignee", because the "assignee" was read as FormInt64 - if !assigneeID.Has() || assigneeID.Value() == 0 { - return - } - if assigneeID.Value() == db.NoConditionID { + if assigneeID == "(none)" { sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_assignees)") - } else { + } else if assigneeID == "(any)" { + sess.Where("issue.id IN (SELECT issue_id FROM issue_assignees)") + } else if assigneeIDInt64, _ := strconv.ParseInt(assigneeID, 10, 64); assigneeIDInt64 > 0 { sess.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). - And("issue_assignees.assignee_id = ?", assigneeID.Value()) + And("issue_assignees.assignee_id = ?", assigneeIDInt64) } } -func applyPosterCondition(sess *xorm.Session, posterID optional.Option[int64]) { - if !posterID.Has() { - return - } - // poster doesn't need to support db.NoConditionID(-1), so just use the value as-is - if posterID.Has() { - sess.And("issue.poster_id=?", posterID.Value()) +func applyPosterCondition(sess *xorm.Session, posterID string) { + // Actually every issue has a poster. + // The "(none)" is for internal usage only: when doer tries to search non-existing user as poster, use "(none)" to return empty result. + if posterID == "(none)" { + sess.And("issue.poster_id=0") + } else if posterIDInt64, _ := strconv.ParseInt(posterID, 10, 64); posterIDInt64 > 0 { + sess.And("issue.poster_id=?", posterIDInt64) } } diff --git a/models/issues/issue_test.go b/models/issues/issue_test.go index 3f76a81bb6..c32aa26b2b 100644 --- a/models/issues/issue_test.go +++ b/models/issues/issue_test.go @@ -15,7 +15,6 @@ 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/optional" "code.gitea.io/gitea/modules/setting" "github.com/stretchr/testify/assert" @@ -155,7 +154,7 @@ func TestIssues(t *testing.T) { }{ { issues_model.IssuesOptions{ - AssigneeID: optional.Some(int64(1)), + AssigneeID: "1", SortType: "oldest", }, []int64{1, 6}, diff --git a/modules/indexer/issues/bleve/bleve.go b/modules/indexer/issues/bleve/bleve.go index 9534b0b750..39d96cab98 100644 --- a/modules/indexer/issues/bleve/bleve.go +++ b/modules/indexer/issues/bleve/bleve.go @@ -5,11 +5,13 @@ package bleve import ( "context" + "strconv" "code.gitea.io/gitea/modules/indexer" indexer_internal "code.gitea.io/gitea/modules/indexer/internal" inner_bleve "code.gitea.io/gitea/modules/indexer/internal/bleve" "code.gitea.io/gitea/modules/indexer/issues/internal" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/util" "github.com/blevesearch/bleve/v2" @@ -246,12 +248,20 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( queries = append(queries, inner_bleve.NumericEqualityQuery(options.ProjectColumnID.Value(), "project_board_id")) } - if options.PosterID.Has() { - queries = append(queries, inner_bleve.NumericEqualityQuery(options.PosterID.Value(), "poster_id")) + if options.PosterID != "" { + // "(none)" becomes 0, it means no poster + posterIDInt64, _ := strconv.ParseInt(options.PosterID, 10, 64) + queries = append(queries, inner_bleve.NumericEqualityQuery(posterIDInt64, "poster_id")) } - if options.AssigneeID.Has() { - queries = append(queries, inner_bleve.NumericEqualityQuery(options.AssigneeID.Value(), "assignee_id")) + if options.AssigneeID != "" { + if options.AssigneeID == "(any)" { + queries = append(queries, inner_bleve.NumericRangeInclusiveQuery(optional.Some[int64](1), optional.None[int64](), "assignee_id")) + } else { + // "(none)" becomes 0, it means no assignee + assigneeIDInt64, _ := strconv.ParseInt(options.AssigneeID, 10, 64) + queries = append(queries, inner_bleve.NumericEqualityQuery(assigneeIDInt64, "assignee_id")) + } } if options.MentionID.Has() { diff --git a/modules/indexer/issues/db/options.go b/modules/indexer/issues/db/options.go index 87ce398a20..3b19d742ba 100644 --- a/modules/indexer/issues/db/options.go +++ b/modules/indexer/issues/db/options.go @@ -54,7 +54,7 @@ func ToDBOptions(ctx context.Context, options *internal.SearchOptions) (*issue_m RepoIDs: options.RepoIDs, AllPublic: options.AllPublic, RepoCond: nil, - AssigneeID: optional.Some(convertID(options.AssigneeID)), + AssigneeID: options.AssigneeID, PosterID: options.PosterID, MentionedID: convertID(options.MentionID), ReviewRequestedID: convertID(options.ReviewRequestedID), diff --git a/modules/indexer/issues/dboptions.go b/modules/indexer/issues/dboptions.go index 4f6ad96d22..4e2dff572a 100644 --- a/modules/indexer/issues/dboptions.go +++ b/modules/indexer/issues/dboptions.go @@ -45,11 +45,7 @@ func ToSearchOptions(keyword string, opts *issues_model.IssuesOptions) *SearchOp searchOpt.ProjectID = optional.Some[int64](0) // Those issues with no project(projectid==0) } - if opts.AssigneeID.Value() == db.NoConditionID { - searchOpt.AssigneeID = optional.Some[int64](0) // FIXME: this is inconsistent from other places, 0 means "no assignee" - } else if opts.AssigneeID.Value() != 0 { - searchOpt.AssigneeID = opts.AssigneeID - } + searchOpt.AssigneeID = opts.AssigneeID // See the comment of issues_model.SearchOptions for the reason why we need to convert convertID := func(id int64) optional.Option[int64] { diff --git a/modules/indexer/issues/elasticsearch/elasticsearch.go b/modules/indexer/issues/elasticsearch/elasticsearch.go index 464c0028f2..e3b1b17059 100644 --- a/modules/indexer/issues/elasticsearch/elasticsearch.go +++ b/modules/indexer/issues/elasticsearch/elasticsearch.go @@ -212,12 +212,22 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( query.Must(elastic.NewTermQuery("project_board_id", options.ProjectColumnID.Value())) } - if options.PosterID.Has() { - query.Must(elastic.NewTermQuery("poster_id", options.PosterID.Value())) + if options.PosterID != "" { + // "(none)" becomes 0, it means no poster + posterIDInt64, _ := strconv.ParseInt(options.PosterID, 10, 64) + query.Must(elastic.NewTermQuery("poster_id", posterIDInt64)) } - if options.AssigneeID.Has() { - query.Must(elastic.NewTermQuery("assignee_id", options.AssigneeID.Value())) + if options.AssigneeID != "" { + if options.AssigneeID == "(any)" { + q := elastic.NewRangeQuery("assignee_id") + q.Gte(1) + query.Must(q) + } else { + // "(none)" becomes 0, it means no assignee + assigneeIDInt64, _ := strconv.ParseInt(options.AssigneeID, 10, 64) + query.Must(elastic.NewTermQuery("assignee_id", assigneeIDInt64)) + } } if options.MentionID.Has() { diff --git a/modules/indexer/issues/indexer_test.go b/modules/indexer/issues/indexer_test.go index 14dd6ba101..3e38ac49b7 100644 --- a/modules/indexer/issues/indexer_test.go +++ b/modules/indexer/issues/indexer_test.go @@ -44,6 +44,7 @@ func TestDBSearchIssues(t *testing.T) { t.Run("search issues with order", searchIssueWithOrder) t.Run("search issues in project", searchIssueInProject) t.Run("search issues with paginator", searchIssueWithPaginator) + t.Run("search issues with any assignee", searchIssueWithAnyAssignee) } func searchIssueWithKeyword(t *testing.T) { @@ -176,19 +177,19 @@ func searchIssueByID(t *testing.T) { }{ { opts: SearchOptions{ - PosterID: optional.Some(int64(1)), + PosterID: "1", }, expectedIDs: []int64{11, 6, 3, 2, 1}, }, { opts: SearchOptions{ - AssigneeID: optional.Some(int64(1)), + AssigneeID: "1", }, expectedIDs: []int64{6, 1}, }, { - // NOTE: This tests no assignees filtering and also ToSearchOptions() to ensure it will set AssigneeID to 0 when it is passed as -1. - opts: *ToSearchOptions("", &issues.IssuesOptions{AssigneeID: optional.Some(db.NoConditionID)}), + // NOTE: This tests no assignees filtering and also ToSearchOptions() to ensure it handles the filter correctly + opts: *ToSearchOptions("", &issues.IssuesOptions{AssigneeID: "(none)"}), expectedIDs: []int64{22, 21, 16, 15, 14, 13, 12, 11, 20, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2}, }, { @@ -462,3 +463,25 @@ func searchIssueWithPaginator(t *testing.T) { assert.Equal(t, test.expectedTotal, total) } } + +func searchIssueWithAnyAssignee(t *testing.T) { + tests := []struct { + opts SearchOptions + expectedIDs []int64 + expectedTotal int64 + }{ + { + SearchOptions{ + AssigneeID: "(any)", + }, + []int64{17, 6, 1}, + 3, + }, + } + for _, test := range tests { + issueIDs, total, err := SearchIssues(t.Context(), &test.opts) + require.NoError(t, err) + assert.Equal(t, test.expectedIDs, issueIDs) + assert.Equal(t, test.expectedTotal, total) + } +} diff --git a/modules/indexer/issues/internal/model.go b/modules/indexer/issues/internal/model.go index 976e2d696b..0d4f0f727d 100644 --- a/modules/indexer/issues/internal/model.go +++ b/modules/indexer/issues/internal/model.go @@ -97,9 +97,8 @@ type SearchOptions struct { ProjectID optional.Option[int64] // project the issues belong to ProjectColumnID optional.Option[int64] // project column the issues belong to - PosterID optional.Option[int64] // poster of the issues - - AssigneeID optional.Option[int64] // assignee of the issues, zero means no assignee + PosterID string // poster of the issues, "(none)" or "(any)" or a user ID + AssigneeID string // assignee of the issues, "(none)" or "(any)" or a user ID MentionID optional.Option[int64] // mentioned user of the issues diff --git a/modules/indexer/issues/internal/tests/tests.go b/modules/indexer/issues/internal/tests/tests.go index 0483853dfd..6e92c7885c 100644 --- a/modules/indexer/issues/internal/tests/tests.go +++ b/modules/indexer/issues/internal/tests/tests.go @@ -379,7 +379,7 @@ var cases = []*testIndexerCase{ Paginator: &db.ListOptions{ PageSize: 5, }, - PosterID: optional.Some(int64(1)), + PosterID: "1", }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { assert.Len(t, result.Hits, 5) @@ -397,7 +397,7 @@ var cases = []*testIndexerCase{ Paginator: &db.ListOptions{ PageSize: 5, }, - AssigneeID: optional.Some(int64(1)), + AssigneeID: "1", }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { assert.Len(t, result.Hits, 5) @@ -415,7 +415,7 @@ var cases = []*testIndexerCase{ Paginator: &db.ListOptions{ PageSize: 5, }, - AssigneeID: optional.Some(int64(0)), + AssigneeID: "(none)", }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { assert.Len(t, result.Hits, 5) @@ -647,6 +647,21 @@ var cases = []*testIndexerCase{ } }, }, + { + Name: "SearchAnyAssignee", + SearchOptions: &internal.SearchOptions{ + AssigneeID: "(any)", + }, + Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { + assert.Len(t, result.Hits, 180) + for _, v := range result.Hits { + assert.GreaterOrEqual(t, data[v.ID].AssigneeID, int64(1)) + } + assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool { + return v.AssigneeID >= 1 + }), result.Total) + }, + }, } type testIndexerCase struct { diff --git a/modules/indexer/issues/meilisearch/meilisearch.go b/modules/indexer/issues/meilisearch/meilisearch.go index a1746f5954..759a98473f 100644 --- a/modules/indexer/issues/meilisearch/meilisearch.go +++ b/modules/indexer/issues/meilisearch/meilisearch.go @@ -187,12 +187,20 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( query.And(inner_meilisearch.NewFilterEq("project_board_id", options.ProjectColumnID.Value())) } - if options.PosterID.Has() { - query.And(inner_meilisearch.NewFilterEq("poster_id", options.PosterID.Value())) + if options.PosterID != "" { + // "(none)" becomes 0, it means no poster + posterIDInt64, _ := strconv.ParseInt(options.PosterID, 10, 64) + query.And(inner_meilisearch.NewFilterEq("poster_id", posterIDInt64)) } - if options.AssigneeID.Has() { - query.And(inner_meilisearch.NewFilterEq("assignee_id", options.AssigneeID.Value())) + if options.AssigneeID != "" { + if options.AssigneeID == "(any)" { + query.And(inner_meilisearch.NewFilterGte("assignee_id", 1)) + } else { + // "(none)" becomes 0, it means no assignee + assigneeIDInt64, _ := strconv.ParseInt(options.AssigneeID, 10, 64) + query.And(inner_meilisearch.NewFilterEq("assignee_id", assigneeIDInt64)) + } } if options.MentionID.Has() { diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 876e135b22..573c00eee6 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1547,8 +1547,8 @@ issues.filter_project = Project issues.filter_project_all = All projects issues.filter_project_none = No project issues.filter_assignee = Assignee -issues.filter_assginee_no_select = All assignees -issues.filter_assginee_no_assignee = No assignee +issues.filter_assginee_no_assignee = Assigned to nobody +issues.filter_assignee_any_assignee = Assigned to anybody issues.filter_poster = Author issues.filter_user_placeholder = Search users issues.filter_user_no_select = All users diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index c9575ff98a..e678db5262 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -290,10 +290,10 @@ func SearchIssues(ctx *context.APIContext) { if ctx.IsSigned { ctxUserID := ctx.Doer.ID if ctx.FormBool("created") { - searchOpt.PosterID = optional.Some(ctxUserID) + searchOpt.PosterID = strconv.FormatInt(ctxUserID, 10) } if ctx.FormBool("assigned") { - searchOpt.AssigneeID = optional.Some(ctxUserID) + searchOpt.AssigneeID = strconv.FormatInt(ctxUserID, 10) } if ctx.FormBool("mentioned") { searchOpt.MentionID = optional.Some(ctxUserID) @@ -538,10 +538,10 @@ func ListIssues(ctx *context.APIContext) { } if createdByID > 0 { - searchOpt.PosterID = optional.Some(createdByID) + searchOpt.PosterID = strconv.FormatInt(createdByID, 10) } if assignedByID > 0 { - searchOpt.AssigneeID = optional.Some(assignedByID) + searchOpt.AssigneeID = strconv.FormatInt(assignedByID, 10) } if mentionedByID > 0 { searchOpt.MentionID = optional.Some(mentionedByID) diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go index 985fd2ca45..49f4792772 100644 --- a/routers/web/org/projects.go +++ b/routers/web/org/projects.go @@ -347,11 +347,11 @@ func ViewProject(ctx *context.Context) { if ctx.Written() { return } - assigneeID := ctx.FormInt64("assignee") // TODO: use "optional" but not 0 in the future + assigneeID := ctx.FormString("assignee") opts := issues_model.IssuesOptions{ LabelIDs: labelIDs, - AssigneeID: optional.Some(assigneeID), + AssigneeID: assigneeID, Owner: project.Owner, Doer: ctx.Doer, } diff --git a/routers/web/repo/issue_list.go b/routers/web/repo/issue_list.go index a65ae77795..69b38c81ec 100644 --- a/routers/web/repo/issue_list.go +++ b/routers/web/repo/issue_list.go @@ -208,10 +208,10 @@ func SearchIssues(ctx *context.Context) { if ctx.IsSigned { ctxUserID := ctx.Doer.ID if ctx.FormBool("created") { - searchOpt.PosterID = optional.Some(ctxUserID) + searchOpt.PosterID = strconv.FormatInt(ctxUserID, 10) } if ctx.FormBool("assigned") { - searchOpt.AssigneeID = optional.Some(ctxUserID) + searchOpt.AssigneeID = strconv.FormatInt(ctxUserID, 10) } if ctx.FormBool("mentioned") { searchOpt.MentionID = optional.Some(ctxUserID) @@ -373,10 +373,10 @@ func SearchRepoIssuesJSON(ctx *context.Context) { } if createdByID > 0 { - searchOpt.PosterID = optional.Some(createdByID) + searchOpt.PosterID = strconv.FormatInt(createdByID, 10) } if assignedByID > 0 { - searchOpt.AssigneeID = optional.Some(assignedByID) + searchOpt.AssigneeID = strconv.FormatInt(assignedByID, 10) } if mentionedByID > 0 { searchOpt.MentionID = optional.Some(mentionedByID) @@ -490,7 +490,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt viewType = "all" } - assigneeID := ctx.FormInt64("assignee") // TODO: use "optional" but not 0 in the future + assigneeID := ctx.FormString("assignee") posterUsername := ctx.FormString("poster") posterUserID := shared_user.GetFilterUserIDByName(ctx, posterUsername) var mentionedID, reviewRequestedID, reviewedID int64 @@ -498,11 +498,11 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt if ctx.IsSigned { switch viewType { case "created_by": - posterUserID = optional.Some(ctx.Doer.ID) + posterUserID = strconv.FormatInt(ctx.Doer.ID, 10) case "mentioned": mentionedID = ctx.Doer.ID case "assigned": - assigneeID = ctx.Doer.ID + assigneeID = fmt.Sprint(ctx.Doer.ID) case "review_requested": reviewRequestedID = ctx.Doer.ID case "reviewed_by": @@ -532,7 +532,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt LabelIDs: labelIDs, MilestoneIDs: mileIDs, ProjectID: projectID, - AssigneeID: optional.Some(assigneeID), + AssigneeID: assigneeID, MentionedID: mentionedID, PosterID: posterUserID, ReviewRequestedID: reviewRequestedID, @@ -613,7 +613,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt PageSize: setting.UI.IssuePagingNum, }, RepoIDs: []int64{repo.ID}, - AssigneeID: optional.Some(assigneeID), + AssigneeID: assigneeID, PosterID: posterUserID, MentionedID: mentionedID, ReviewRequestedID: reviewRequestedID, diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go index 5b81a5e4d1..6810025c6f 100644 --- a/routers/web/repo/projects.go +++ b/routers/web/repo/projects.go @@ -315,12 +315,12 @@ func ViewProject(ctx *context.Context) { labelIDs := issue.PrepareFilterIssueLabels(ctx, ctx.Repo.Repository.ID, ctx.Repo.Owner) - assigneeID := ctx.FormInt64("assignee") // TODO: use "optional" but not 0 in the future + assigneeID := ctx.FormString("assignee") issuesMap, err := project_service.LoadIssuesFromProject(ctx, project, &issues_model.IssuesOptions{ RepoIDs: []int64{ctx.Repo.Repository.ID}, LabelIDs: labelIDs, - AssigneeID: optional.Some(assigneeID), + AssigneeID: assigneeID, }) if err != nil { ctx.ServerError("LoadIssuesOfColumns", err) diff --git a/routers/web/shared/user/helper.go b/routers/web/shared/user/helper.go index b82181a1df..3fc39fd3ab 100644 --- a/routers/web/shared/user/helper.go +++ b/routers/web/shared/user/helper.go @@ -8,9 +8,7 @@ import ( "slices" "strconv" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/optional" ) func MakeSelfOnTop(doer *user.User, users []*user.User) []*user.User { @@ -34,19 +32,20 @@ func MakeSelfOnTop(doer *user.User, users []*user.User) []*user.User { // So it's better to make it work like GitHub: users could input username directly. // Since it only converts the username to ID directly and is only used internally (to search issues), so no permission check is needed. // Return values: -// * nil: no filter -// * some(id): match the id, the id could be -1 to match the issues without assignee -// * some(NonExistingID): match no issue (due to the user doesn't exist) -func GetFilterUserIDByName(ctx context.Context, name string) optional.Option[int64] { +// * "": no filter +// * "{the-id}": match the id +// * "(none)": match no issue (due to the user doesn't exist) +func GetFilterUserIDByName(ctx context.Context, name string) string { if name == "" { - return optional.None[int64]() + return "" } u, err := user.GetUserByName(ctx, name) if err != nil { if id, err := strconv.ParseInt(name, 10, 64); err == nil { - return optional.Some(id) + return strconv.FormatInt(id, 10) } - return optional.Some(db.NonExistingID) + // The "(none)" is for internal usage only: when doer tries to search non-existing user, use "(none)" to return empty result. + return "(none)" } - return optional.Some(u.ID) + return strconv.FormatInt(u.ID, 10) } diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 3973aea742..864a2831d1 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -501,9 +501,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { case issues_model.FilterModeAll: case issues_model.FilterModeYourRepositories: case issues_model.FilterModeAssign: - opts.AssigneeID = optional.Some(ctx.Doer.ID) + opts.AssigneeID = strconv.FormatInt(ctx.Doer.ID, 10) case issues_model.FilterModeCreate: - opts.PosterID = optional.Some(ctx.Doer.ID) + opts.PosterID = strconv.FormatInt(ctx.Doer.ID, 10) case issues_model.FilterModeMention: opts.MentionedID = ctx.Doer.ID case issues_model.FilterModeReviewRequested: @@ -792,9 +792,9 @@ func getUserIssueStats(ctx *context.Context, ctxUser *user_model.User, filterMod case issues_model.FilterModeYourRepositories: openClosedOpts.AllPublic = false case issues_model.FilterModeAssign: - openClosedOpts.AssigneeID = optional.Some(doerID) + openClosedOpts.AssigneeID = strconv.FormatInt(doerID, 10) case issues_model.FilterModeCreate: - openClosedOpts.PosterID = optional.Some(doerID) + openClosedOpts.PosterID = strconv.FormatInt(doerID, 10) case issues_model.FilterModeMention: openClosedOpts.MentionID = optional.Some(doerID) case issues_model.FilterModeReviewRequested: @@ -816,8 +816,8 @@ func getUserIssueStats(ctx *context.Context, ctxUser *user_model.User, filterMod // Below stats are for the left sidebar opts = opts.Copy(func(o *issue_indexer.SearchOptions) { - o.AssigneeID = nil - o.PosterID = nil + o.AssigneeID = "" + o.PosterID = "" o.MentionID = nil o.ReviewRequestedID = nil o.ReviewedID = nil @@ -827,11 +827,11 @@ func getUserIssueStats(ctx *context.Context, ctxUser *user_model.User, filterMod if err != nil { return nil, err } - ret.AssignCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.AssigneeID = optional.Some(doerID) })) + ret.AssignCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.AssigneeID = strconv.FormatInt(doerID, 10) })) if err != nil { return nil, err } - ret.CreateCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.PosterID = optional.Some(doerID) })) + ret.CreateCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.PosterID = strconv.FormatInt(doerID, 10) })) if err != nil { return nil, err } diff --git a/templates/projects/view.tmpl b/templates/projects/view.tmpl index 3cbd651059..f4478d544a 100644 --- a/templates/projects/view.tmpl +++ b/templates/projects/view.tmpl @@ -15,8 +15,8 @@ "UserSearchList" $.Assignees "SelectedUserId" $.AssigneeID "TextFilterTitle" (ctx.Locale.Tr "repo.issues.filter_assignee") - "TextZeroValue" (ctx.Locale.Tr "repo.issues.filter_assginee_no_select") - "TextNegativeOne" (ctx.Locale.Tr "repo.issues.filter_assginee_no_assignee") + "TextFilterMatchNone" (ctx.Locale.Tr "repo.issues.filter_assginee_no_assignee") + "TextFilterMatchAny" (ctx.Locale.Tr "repo.issues.filter_assignee_any_assignee") }} diff --git a/templates/repo/issue/filter_item_user_assign.tmpl b/templates/repo/issue/filter_item_user_assign.tmpl index 4f1db71d57..42886edaa0 100644 --- a/templates/repo/issue/filter_item_user_assign.tmpl +++ b/templates/repo/issue/filter_item_user_assign.tmpl @@ -4,8 +4,8 @@ * UserSearchList * SelectedUserId: 0 or empty means default, -1 means "no user is set" * TextFilterTitle -* TextZeroValue: the text for "all issues" -* TextNegativeOne: the text for "issues with no assignee" +* TextFilterMatchNone: the text for "issues with no assignee" +* TextFilterMatchAny: the text for "issues with any assignee" */}} {{$queryLink := .QueryLink}} - {{if $.TextZeroValue}} - {{$.TextZeroValue}} + {{if $.TextFilterMatchNone}} + {{$isSelected := eq .SelectedUserId "(none)"}} + + {{svg "octicon-check" 14 (Iif $isSelected "" "tw-invisible")}} {{$.TextFilterMatchNone}} + {{end}} - {{if $.TextNegativeOne}} - {{$.TextNegativeOne}} + {{if $.TextFilterMatchAny}} + {{$isSelected := eq .SelectedUserId "(any)"}} + + {{svg "octicon-check" 14 (Iif $isSelected "" "tw-invisible")}} {{$.TextFilterMatchAny}} + {{end}}
- {{range .UserSearchList}} - - {{ctx.AvatarUtils.Avatar . 20}}{{template "repo/search_name" .}} + {{range $user := .UserSearchList}} + {{$isSelected := eq $.SelectedUserId (print $user.ID)}} + + {{svg "octicon-check" 14 (Iif $isSelected "" "tw-invisible")}} + {{ctx.AvatarUtils.Avatar $user 20}}{{template "repo/search_name" .}} {{end}} diff --git a/templates/repo/issue/filter_list.tmpl b/templates/repo/issue/filter_list.tmpl index 7612d93b21..58ca4a7c00 100644 --- a/templates/repo/issue/filter_list.tmpl +++ b/templates/repo/issue/filter_list.tmpl @@ -94,8 +94,8 @@ "UserSearchList" $.Assignees "SelectedUserId" $.AssigneeID "TextFilterTitle" (ctx.Locale.Tr "repo.issues.filter_assignee") - "TextZeroValue" (ctx.Locale.Tr "repo.issues.filter_assginee_no_select") - "TextNegativeOne" (ctx.Locale.Tr "repo.issues.filter_assginee_no_assignee") + "TextFilterMatchNone" (ctx.Locale.Tr "repo.issues.filter_assginee_no_assignee") + "TextFilterMatchAny" (ctx.Locale.Tr "repo.issues.filter_assignee_any_assignee") }} {{if .IsSigned}} diff --git a/web_src/fomantic/build/components/dropdown.js b/web_src/fomantic/build/components/dropdown.js index d3a1f7dc24..009b51d8b1 100644 --- a/web_src/fomantic/build/components/dropdown.js +++ b/web_src/fomantic/build/components/dropdown.js @@ -1130,7 +1130,11 @@ $.fn.dropdown = function(parameters) { icon: { click: function(event) { iconClicked=true; - if(module.has.search()) { + // GITEA-PATCH: official dropdown doesn't support the search input in menu + // so we need to make the menu could be shown when the search input is in menu and user clicks the icon + const searchInputInMenu = Boolean($menu.find('.search > input').length); + if(module.has.search() && !searchInputInMenu) { + // the search input is in the dropdown element (but not in the popup menu), try to focus it if(!module.is.active()) { if(settings.showOnFocus){ module.focusSearch(); From 279473f467f6af558293c2147a08241f8b934eea Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 21 Mar 2025 20:50:39 +0800 Subject: [PATCH 2/9] Fix oauth2 auth and UI (#33961) --- routers/web/auth/oauth2_provider.go | 2 +- templates/user/auth/grant.tmpl | 60 ++++++++++++++-------------- templates/user/auth/grant_error.tmpl | 19 ++++----- 3 files changed, 38 insertions(+), 43 deletions(-) diff --git a/routers/web/auth/oauth2_provider.go b/routers/web/auth/oauth2_provider.go index 00b5b2db52..ff571fbf2c 100644 --- a/routers/web/auth/oauth2_provider.go +++ b/routers/web/auth/oauth2_provider.go @@ -249,7 +249,7 @@ func AuthorizeOAuth(ctx *context.Context) { }, form.RedirectURI) return } - if err := ctx.Session.Set("CodeChallengeMethod", form.CodeChallenge); err != nil { + if err := ctx.Session.Set("CodeChallenge", form.CodeChallenge); err != nil { handleAuthorizeError(ctx, AuthorizeError{ ErrorCode: ErrorCodeServerError, ErrorDescription: "cannot set code challenge", diff --git a/templates/user/auth/grant.tmpl b/templates/user/auth/grant.tmpl index 7a6f156e36..e56241b0f8 100644 --- a/templates/user/auth/grant.tmpl +++ b/templates/user/auth/grant.tmpl @@ -1,35 +1,33 @@ {{template "base/head" .}} -
-
-
-

- {{ctx.Locale.Tr "auth.authorize_title" .Application.Name}} -

-
- {{template "base/alert" .}} -

- {{if not .AdditionalScopes}} - {{ctx.Locale.Tr "auth.authorize_application_description"}}
- {{end}} - {{ctx.Locale.Tr "auth.authorize_application_created_by" .ApplicationCreatorLinkHTML}}
- {{ctx.Locale.Tr "auth.authorize_application_with_scopes" (HTMLFormat "%s" .Scope)}} -

-
-
-

{{ctx.Locale.Tr "auth.authorize_redirect_notice" .ApplicationRedirectDomainHTML}}

-
-
-
- {{.CsrfTokenHtml}} - - - - - - - -
-
+
+
+

+ {{ctx.Locale.Tr "auth.authorize_title" .Application.Name}} +

+
+ {{template "base/alert" .}} +

+ {{if not .AdditionalScopes}} + {{ctx.Locale.Tr "auth.authorize_application_description"}}
+ {{end}} + {{ctx.Locale.Tr "auth.authorize_application_created_by" .ApplicationCreatorLinkHTML}}
+ {{ctx.Locale.Tr "auth.authorize_application_with_scopes" (HTMLFormat "%s" .Scope)}} +

+
+
+

{{ctx.Locale.Tr "auth.authorize_redirect_notice" .ApplicationRedirectDomainHTML}}

+
+
+
+ {{.CsrfTokenHtml}} + + + + + + + +
diff --git a/templates/user/auth/grant_error.tmpl b/templates/user/auth/grant_error.tmpl index e37c4f6544..7a4521d331 100644 --- a/templates/user/auth/grant_error.tmpl +++ b/templates/user/auth/grant_error.tmpl @@ -1,15 +1,12 @@ {{template "base/head" .}} -
- {{if .IsRepo}}{{template "repo/header" .}}{{end}} -
-
-

- {{ctx.Locale.Tr "auth.authorization_failed"}} -

-

{{.Error.ErrorDescription}}

-
-

{{ctx.Locale.Tr "auth.authorization_failed_desc"}}

-
+
+
+

+ {{ctx.Locale.Tr "auth.authorization_failed"}} +

+

{{.Error.ErrorDescription}}

+
+

{{ctx.Locale.Tr "auth.authorization_failed_desc"}}

From b956cee06f462c4f34a7911351b7c878ce890725 Mon Sep 17 00:00:00 2001 From: charles <30816317+charles7668@users.noreply.github.com> Date: Sat, 22 Mar 2025 03:00:02 +0800 Subject: [PATCH 3/9] Fix file name could not be searched if the file was not a text file when using the Bleve indexer (#33959) Close #33828 --------- Co-authored-by: wxiaoguang --- modules/indexer/code/bleve/bleve.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/indexer/code/bleve/bleve.go b/modules/indexer/code/bleve/bleve.go index e1a381f992..130ee78a4b 100644 --- a/modules/indexer/code/bleve/bleve.go +++ b/modules/indexer/code/bleve/bleve.go @@ -191,7 +191,8 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro return err } else if !typesniffer.DetectContentType(fileContents).IsText() { // FIXME: UTF-16 files will probably fail here - return nil + // Even if the file is not recognized as a "text file", we could still put its name into the indexers to make the filename become searchable, while leave the content to empty. + fileContents = nil } if _, err = batchReader.Discard(1); err != nil { From b5d2e31d6d7d96e1884f1aaed43ca7b74cc591db Mon Sep 17 00:00:00 2001 From: Kai Leonhardt <8343141+Mik4sa@users.noreply.github.com> Date: Fri, 21 Mar 2025 20:52:14 +0100 Subject: [PATCH 4/9] Drop timeout for requests made to the internal hook api (#33947) This change targets https://github.com/go-gitea/gitea/issues/32663 We drop the hardcoded timeout of 60 seconds for requests to the internal hook api. With this change the timeout is completly removed. --------- Co-authored-by: wxiaoguang --- modules/private/hook.go | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/modules/private/hook.go b/modules/private/hook.go index 87d6549f9c..215996b9b9 100644 --- a/modules/private/hook.go +++ b/modules/private/hook.go @@ -7,9 +7,9 @@ import ( "context" "fmt" "net/url" - "time" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/httplib" "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" ) @@ -82,29 +82,32 @@ type HookProcReceiveRefResult struct { HeadBranch string } +func newInternalRequestAPIForHooks(ctx context.Context, hookName, ownerName, repoName string, opts HookOptions) *httplib.Request { + reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/%s/%s/%s", hookName, url.PathEscape(ownerName), url.PathEscape(repoName)) + req := newInternalRequestAPI(ctx, reqURL, "POST", opts) + // This "timeout" applies to http.Client's timeout: A Timeout of zero means no timeout. + // This "timeout" was previously set to `time.Duration(60+len(opts.OldCommitIDs))` seconds, but it caused unnecessary timeout failures. + // It should be good enough to remove the client side timeout, only respect the "ctx" and server side timeout. + req.SetReadWriteTimeout(0) + return req +} + // HookPreReceive check whether the provided commits are allowed func HookPreReceive(ctx context.Context, ownerName, repoName string, opts HookOptions) ResponseExtra { - reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/pre-receive/%s/%s", url.PathEscape(ownerName), url.PathEscape(repoName)) - req := newInternalRequestAPI(ctx, reqURL, "POST", opts) - req.SetReadWriteTimeout(time.Duration(60+len(opts.OldCommitIDs)) * time.Second) + req := newInternalRequestAPIForHooks(ctx, "pre-receive", ownerName, repoName, opts) _, extra := requestJSONResp(req, &ResponseText{}) return extra } // HookPostReceive updates services and users func HookPostReceive(ctx context.Context, ownerName, repoName string, opts HookOptions) (*HookPostReceiveResult, ResponseExtra) { - reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/post-receive/%s/%s", url.PathEscape(ownerName), url.PathEscape(repoName)) - req := newInternalRequestAPI(ctx, reqURL, "POST", opts) - req.SetReadWriteTimeout(time.Duration(60+len(opts.OldCommitIDs)) * time.Second) + req := newInternalRequestAPIForHooks(ctx, "post-receive", ownerName, repoName, opts) return requestJSONResp(req, &HookPostReceiveResult{}) } // HookProcReceive proc-receive hook func HookProcReceive(ctx context.Context, ownerName, repoName string, opts HookOptions) (*HookProcReceiveResult, ResponseExtra) { - reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/proc-receive/%s/%s", url.PathEscape(ownerName), url.PathEscape(repoName)) - - req := newInternalRequestAPI(ctx, reqURL, "POST", opts) - req.SetReadWriteTimeout(time.Duration(60+len(opts.OldCommitIDs)) * time.Second) + req := newInternalRequestAPIForHooks(ctx, "proc-receive", ownerName, repoName, opts) return requestJSONResp(req, &HookProcReceiveResult{}) } From d1a755e5b7c676750f3dfad2254e047e2d23c4ac Mon Sep 17 00:00:00 2001 From: silverwind Date: Fri, 21 Mar 2025 21:48:06 +0100 Subject: [PATCH 5/9] Cover `go.mod` and `go.sum` in `.editorconfig` (#33960) These files were previously set to use spaces for indendation but they are supposed to use tabs, so set this in editorconfig. --- .editorconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.editorconfig b/.editorconfig index e23e4cd649..13aa8d50f0 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,6 +12,9 @@ insert_final_newline = true [*.{go,tmpl,html}] indent_style = tab +[go.*] +indent_style = tab + [templates/custom/*.tmpl] insert_final_newline = false From 1c5c13a442dcd9eae157926c371925e9a8177556 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Sat, 22 Mar 2025 00:33:13 +0000 Subject: [PATCH 6/9] [skip ci] Updated translations via Crowdin --- options/locale/locale_cs-CZ.ini | 1 - options/locale/locale_de-DE.ini | 1 - options/locale/locale_el-GR.ini | 1 - options/locale/locale_es-ES.ini | 1 - options/locale/locale_fa-IR.ini | 1 - options/locale/locale_fr-FR.ini | 9 +++++++-- options/locale/locale_ga-IE.ini | 2 -- options/locale/locale_hu-HU.ini | 2 -- options/locale/locale_id-ID.ini | 1 - options/locale/locale_it-IT.ini | 1 - options/locale/locale_ja-JP.ini | 1 - options/locale/locale_ko-KR.ini | 1 - options/locale/locale_lv-LV.ini | 1 - options/locale/locale_nl-NL.ini | 1 - options/locale/locale_pl-PL.ini | 1 - options/locale/locale_pt-BR.ini | 2 -- options/locale/locale_pt-PT.ini | 1 - options/locale/locale_ru-RU.ini | 1 - options/locale/locale_si-LK.ini | 1 - options/locale/locale_sv-SE.ini | 1 - options/locale/locale_tr-TR.ini | 1 - options/locale/locale_uk-UA.ini | 1 - options/locale/locale_zh-CN.ini | 2 -- options/locale/locale_zh-TW.ini | 2 -- 24 files changed, 7 insertions(+), 30 deletions(-) diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 41c770452f..42baa83a9c 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -1530,7 +1530,6 @@ issues.filter_project=Projekt issues.filter_project_all=Všechny projekty issues.filter_project_none=Žádný projekt issues.filter_assignee=Zpracovatel -issues.filter_assginee_no_select=Všichni zpracovatelé issues.filter_assginee_no_assignee=Bez zpracovatele issues.filter_poster=Autor issues.filter_user_placeholder=Hledat uživatele diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index c9e7f5edab..e8e5ce3867 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -1531,7 +1531,6 @@ issues.filter_project=Projekt issues.filter_project_all=Alle Projekte issues.filter_project_none=Kein Projekt issues.filter_assignee=Zuständig -issues.filter_assginee_no_select=Alle Zuständigen issues.filter_assginee_no_assignee=Niemand zuständig issues.filter_poster=Autor issues.filter_user_placeholder=Benutzer suchen diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index 09ae6f5a87..bb8e92f60e 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -1378,7 +1378,6 @@ issues.filter_project=Έργο issues.filter_project_all=Όλα τα έργα issues.filter_project_none=Χωρίς έργα issues.filter_assignee=Αποδέκτης -issues.filter_assginee_no_select=Όλοι οι αποδέκτες issues.filter_assginee_no_assignee=Κανένας Αποδέκτης issues.filter_poster=Συγγραφέας issues.filter_type=Τύπος diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index 1a0ee9be8e..74dff40fac 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -1368,7 +1368,6 @@ issues.filter_project=Proyecto issues.filter_project_all=Todos los proyectos issues.filter_project_none=Ningún proyecto issues.filter_assignee=Asignada a -issues.filter_assginee_no_select=Todos los asignados issues.filter_assginee_no_assignee=Sin asignado issues.filter_poster=Autor issues.filter_type=Tipo diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index 147c570ca0..5c96cea8f6 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -1059,7 +1059,6 @@ issues.filter_label_no_select=تمامی برچسب‎ها issues.filter_milestone=نقطه عطف issues.filter_project_none=هیچ پروژه ثبت نشده issues.filter_assignee=مسئول رسیدگی -issues.filter_assginee_no_select=تمامی مسئولان رسیدگی issues.filter_assginee_no_assignee=بدون مسئول رسیدگی issues.filter_type=نوع issues.filter_type.all_issues=همه مسائل diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 9964bcc077..8df99312b4 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -113,6 +113,7 @@ copy_type_unsupported=Ce type de fichier ne peut pas être copié write=Écrire preview=Aperçu loading=Chargement… +files=Fichiers error=Erreur error404=La page que vous essayez d'atteindre n'existe pas ou vous n'êtes pas autorisé à la voir. @@ -169,6 +170,10 @@ search=Rechercher… type_tooltip=Type de recherche fuzzy=Approximative fuzzy_tooltip=Inclure également les résultats proches de la recherche +words=Mots +words_tooltip=Inclure uniquement les résultats qui correspondent exactement aux mots recherchés +regexp=Regexp +regexp_tooltip=Inclure uniquement les résultats qui correspondent à l’expression régulière recherchée exact=Exact exact_tooltip=Inclure uniquement les résultats qui correspondent exactement au terme de recherche repo_kind=Chercher des dépôts… @@ -1403,6 +1408,7 @@ commits.signed_by_untrusted_user_unmatched=Signature discordante de l'auteur de commits.gpg_key_id=ID de la clé GPG commits.ssh_key_fingerprint=Empreinte numérique de la clé SSH commits.view_path=Voir à ce point de l'historique +commits.view_file_diff=Voir les modifications du fichier dans cette révision commit.operations=Opérations commit.revert=Rétablir @@ -1540,8 +1546,6 @@ issues.filter_project=Projet issues.filter_project_all=Tous les projets issues.filter_project_none=Aucun projet issues.filter_assignee=Assigné -issues.filter_assginee_no_select=Tous les assignés -issues.filter_assginee_no_assignee=Aucun assigné issues.filter_poster=Auteur issues.filter_user_placeholder=Rechercher des utilisateurs issues.filter_user_no_select=Tous les utilisateurs @@ -3708,6 +3712,7 @@ creation=Ajouter un secret creation.description=Description creation.name_placeholder=Caractères alphanumériques ou tirets bas uniquement, insensibles à la casse, ne peut commencer par GITEA_ ou GITHUB_. creation.value_placeholder=Entrez n’importe quoi. Les blancs cernant seront taillés. +creation.description_placeholder=Décrire brièvement votre dépôt (optionnel). creation.success=Le secret "%s" a été ajouté. creation.failed=Impossible d'ajouter le secret. deletion=Supprimer le secret diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini index aa79a03a3a..00d2364ace 100644 --- a/options/locale/locale_ga-IE.ini +++ b/options/locale/locale_ga-IE.ini @@ -1540,8 +1540,6 @@ issues.filter_project=Tionscadal issues.filter_project_all=Gach tionscadal issues.filter_project_none=Gan aon tionscadal issues.filter_assignee=Sannaitheoir -issues.filter_assginee_no_select=Gach sannaithe -issues.filter_assginee_no_assignee=Gan sannaitheoir issues.filter_poster=Údar issues.filter_user_placeholder=Cuardaigh úsáideoirí issues.filter_user_no_select=Gach úsáideoir diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini index f4f0bed24c..a57d6960dd 100644 --- a/options/locale/locale_hu-HU.ini +++ b/options/locale/locale_hu-HU.ini @@ -774,8 +774,6 @@ issues.filter_label=Címke issues.filter_label_no_select=Minden címke issues.filter_milestone=Mérföldkő issues.filter_assignee=Megbízott -issues.filter_assginee_no_select=Minden megbízott -issues.filter_assginee_no_assignee=Nincs megbízott issues.filter_type=Típus issues.filter_type.all_issues=Minden hibajegy issues.filter_type.assigned_to_you=Hozzám rendelt diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini index 10d8c43c5b..c54bfbb924 100644 --- a/options/locale/locale_id-ID.ini +++ b/options/locale/locale_id-ID.ini @@ -763,7 +763,6 @@ issues.delete_branch_at=`telah dihapus cabang %s %s` issues.filter_label=Label issues.filter_milestone=Tonggak issues.filter_assignee=Menerima -issues.filter_assginee_no_assignee=Tidak ada yang menerima issues.filter_type=Tipe issues.filter_type.all_issues=Semua masalah issues.filter_type.assigned_to_you=Ditugaskan kepada anda diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index b3564eb8f7..6a6c59f537 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -1144,7 +1144,6 @@ issues.filter_milestone=Traguardo issues.filter_project=Progetto issues.filter_project_none=Nessun progetto issues.filter_assignee=Assegnatario -issues.filter_assginee_no_select=Tutte le assegnazioni issues.filter_assginee_no_assignee=Nessun assegnatario issues.filter_poster=Autore issues.filter_type=Tipo diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index dd88f3eeaa..bf6c5515e3 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -1538,7 +1538,6 @@ issues.filter_project=プロジェクト issues.filter_project_all=すべてのプロジェクト issues.filter_project_none=プロジェクトなし issues.filter_assignee=担当者 -issues.filter_assginee_no_select=すべての担当者 issues.filter_assginee_no_assignee=担当者なし issues.filter_poster=作成者 issues.filter_user_placeholder=ユーザーを検索 diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini index 601c203aba..697371c2c9 100644 --- a/options/locale/locale_ko-KR.ini +++ b/options/locale/locale_ko-KR.ini @@ -707,7 +707,6 @@ issues.filter_label=레이블 issues.filter_label_no_select=모든 레이블 issues.filter_milestone=마일스톤 issues.filter_assignee=담당자 -issues.filter_assginee_no_select=모든 담당자 issues.filter_assginee_no_assignee=담당자 없음 issues.filter_type=유형 issues.filter_type.all_issues=모든 이슈 diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index 975943ec91..3fff777dc7 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -1384,7 +1384,6 @@ issues.filter_project=Projekts issues.filter_project_all=Visi projekti issues.filter_project_none=Nav projekta issues.filter_assignee=Atbildīgais -issues.filter_assginee_no_select=Visi atbildīgie issues.filter_assginee_no_assignee=Nav atbildīgā issues.filter_poster=Autors issues.filter_type=Veids diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index efea6b82df..f499685916 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -1142,7 +1142,6 @@ issues.filter_milestone=Mijlpaal issues.filter_project=Project issues.filter_project_none=Geen project issues.filter_assignee=Aangewezene -issues.filter_assginee_no_select=Alle toegewezen personen issues.filter_assginee_no_assignee=Geen verantwoordelijke issues.filter_poster=Auteur issues.filter_type=Type diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index 1e6268e2be..f64b8771ac 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -1054,7 +1054,6 @@ issues.filter_label_no_select=Wszystkie etykiety issues.filter_milestone=Kamień milowy issues.filter_project_none=Brak projektu issues.filter_assignee=Przypisany -issues.filter_assginee_no_select=Wszyscy przypisani issues.filter_assginee_no_assignee=Brak przypisania issues.filter_type=Typ issues.filter_type.all_issues=Wszystkie zgłoszenia diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index b23e45088d..b76a6e548d 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -1379,8 +1379,6 @@ issues.filter_project=Projeto issues.filter_project_all=Todos os projetos issues.filter_project_none=Sem projeto issues.filter_assignee=Atribuído -issues.filter_assginee_no_select=Todos os responsáveis -issues.filter_assginee_no_assignee=Sem responsável issues.filter_poster=Autor issues.filter_type=Tipo issues.filter_type.all_issues=Todas as issues diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 5b6672c266..12a7e146c2 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -1546,7 +1546,6 @@ issues.filter_project=Planeamento issues.filter_project_all=Todos os planeamentos issues.filter_project_none=Nenhum planeamento issues.filter_assignee=Encarregado -issues.filter_assginee_no_select=Todos os encarregados issues.filter_assginee_no_assignee=Sem encarregado issues.filter_poster=Autor(a) issues.filter_user_placeholder=Procurar utilizadores diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index 6b08ec9e5c..e53d483f2c 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -1356,7 +1356,6 @@ issues.filter_project=Проект issues.filter_project_all=Все проекты issues.filter_project_none=Нет проекта issues.filter_assignee=Назначено -issues.filter_assginee_no_select=Все назначения issues.filter_assginee_no_assignee=Нет ответственного issues.filter_poster=Автор issues.filter_type=Тип diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini index 0f5ae91e40..2cd7fb29b9 100644 --- a/options/locale/locale_si-LK.ini +++ b/options/locale/locale_si-LK.ini @@ -1025,7 +1025,6 @@ issues.filter_label_no_select=සියලු ලේබල issues.filter_milestone=සන්ධිස්ථානය issues.filter_project_none=ව්‍යාපෘති නැත issues.filter_assignee=අස්ගිනී -issues.filter_assginee_no_select=සියලුම ඇග්රි issues.filter_assginee_no_assignee=කිසිදු අස්වැද්දුමක් issues.filter_type=වර්ගය issues.filter_type.all_issues=සියලු ගැටළු diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini index d79d751ea3..dbe53aaadf 100644 --- a/options/locale/locale_sv-SE.ini +++ b/options/locale/locale_sv-SE.ini @@ -873,7 +873,6 @@ issues.filter_label_no_select=Alla etiketter issues.filter_milestone=Milsten issues.filter_project_none=Inget projekt issues.filter_assignee=Förvärvare -issues.filter_assginee_no_select=Alla tilldelade issues.filter_assginee_no_assignee=Ingen tilldelad issues.filter_type=Typ issues.filter_type.all_issues=Alla ärenden diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index d00cce5006..d639c05c2f 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -1485,7 +1485,6 @@ issues.filter_project=Proje issues.filter_project_all=Tüm projeler issues.filter_project_none=Proje yok issues.filter_assignee=Atanan -issues.filter_assginee_no_select=Tüm atananlar issues.filter_assginee_no_assignee=Atanan yok issues.filter_poster=Yazar issues.filter_type=Tür diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index 3b3017a127..8c8911ceb6 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -1071,7 +1071,6 @@ issues.filter_milestone=Етап issues.filter_project=Проєкт issues.filter_project_none=Проєкт відсутній issues.filter_assignee=Виконавець -issues.filter_assginee_no_select=Всі виконавці issues.filter_assginee_no_assignee=Немає виконавця issues.filter_type=Тип issues.filter_type.all_issues=Всі задачі diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index d6ef36dede..5f9a07dbf6 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -1525,8 +1525,6 @@ issues.filter_project=项目 issues.filter_project_all=所有项目 issues.filter_project_none=暂无项目 issues.filter_assignee=指派人筛选 -issues.filter_assginee_no_select=所有指派成员 -issues.filter_assginee_no_assignee=未指派 issues.filter_poster=作者 issues.filter_user_placeholder=搜索用户 issues.filter_user_no_select=所有用户 diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 8b6dc3afcb..a4af247ea0 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -1518,8 +1518,6 @@ issues.filter_project=專案 issues.filter_project_all=所有專案 issues.filter_project_none=未選擇專案 issues.filter_assignee=負責人 -issues.filter_assginee_no_select=所有負責人 -issues.filter_assginee_no_assignee=沒有負責人 issues.filter_poster=作者 issues.filter_user_placeholder=搜尋使用者 issues.filter_user_no_select=所有使用者 From e1bba9c1a24f1aca86a5925d6e5017414ac5ec5b Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 22 Mar 2025 10:15:45 +0800 Subject: [PATCH 7/9] Improve oauth2 error handling (#33969) Show the callback error to end users, it should be safe. Fix #33967 --- options/locale/locale_en-US.ini | 2 +- routers/web/auth/auth_test.go | 40 +++++++++++++++++++++------------ routers/web/auth/oauth.go | 6 +++-- tests/integration/oauth_test.go | 2 +- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 573c00eee6..b2e079c696 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -457,7 +457,7 @@ oauth_signup_submit = Complete Account oauth_signin_tab = Link to Existing Account oauth_signin_title = Sign In to Authorize Linked Account oauth_signin_submit = Link Account -oauth.signin.error = There was an error processing the authorization request. If this error persists, please contact the site administrator. +oauth.signin.error.general = There was an error processing the authorization request: %s. If this error persists, please contact the site administrator. oauth.signin.error.access_denied = The authorization request was denied. oauth.signin.error.temporarily_unavailable = Authorization failed because the authentication server is temporarily unavailable. Please try again later. oauth_callback_unable_auto_reg = Auto Registration is enabled, but OAuth2 Provider %[1]s returned missing fields: %[2]s, unable to create an account automatically, please create or link to an account, or contact the site administrator. diff --git a/routers/web/auth/auth_test.go b/routers/web/auth/auth_test.go index cbcb2a5222..e238125407 100644 --- a/routers/web/auth/auth_test.go +++ b/routers/web/auth/auth_test.go @@ -61,23 +61,35 @@ func TestUserLogin(t *testing.T) { assert.Equal(t, "/", test.RedirectURL(resp)) } -func TestSignUpOAuth2ButMissingFields(t *testing.T) { +func TestSignUpOAuth2Login(t *testing.T) { defer test.MockVariableValue(&setting.OAuth2Client.EnableAutoRegistration, true)() - defer test.MockVariableValue(&gothic.CompleteUserAuth, func(res http.ResponseWriter, req *http.Request) (goth.User, error) { - return goth.User{Provider: "dummy-auth-source", UserID: "dummy-user"}, nil - })() addOAuth2Source(t, "dummy-auth-source", oauth2.Source{}) - mockOpt := contexttest.MockContextOption{SessionStore: session.NewMockStore("dummy-sid")} - ctx, resp := contexttest.MockContext(t, "/user/oauth2/dummy-auth-source/callback?code=dummy-code", mockOpt) - ctx.SetPathParam("provider", "dummy-auth-source") - SignInOAuthCallback(ctx) - assert.Equal(t, http.StatusSeeOther, resp.Code) - assert.Equal(t, "/user/link_account", test.RedirectURL(resp)) + t.Run("OAuth2MissingField", func(t *testing.T) { + defer test.MockVariableValue(&gothic.CompleteUserAuth, func(res http.ResponseWriter, req *http.Request) (goth.User, error) { + return goth.User{Provider: "dummy-auth-source", UserID: "dummy-user"}, nil + })() + mockOpt := contexttest.MockContextOption{SessionStore: session.NewMockStore("dummy-sid")} + ctx, resp := contexttest.MockContext(t, "/user/oauth2/dummy-auth-source/callback?code=dummy-code", mockOpt) + ctx.SetPathParam("provider", "dummy-auth-source") + SignInOAuthCallback(ctx) + assert.Equal(t, http.StatusSeeOther, resp.Code) + assert.Equal(t, "/user/link_account", test.RedirectURL(resp)) - // then the user will be redirected to the link account page, and see a message about the missing fields - ctx, _ = contexttest.MockContext(t, "/user/link_account", mockOpt) - LinkAccount(ctx) - assert.EqualValues(t, "auth.oauth_callback_unable_auto_reg:dummy-auth-source,email", ctx.Data["AutoRegistrationFailedPrompt"]) + // then the user will be redirected to the link account page, and see a message about the missing fields + ctx, _ = contexttest.MockContext(t, "/user/link_account", mockOpt) + LinkAccount(ctx) + assert.EqualValues(t, "auth.oauth_callback_unable_auto_reg:dummy-auth-source,email", ctx.Data["AutoRegistrationFailedPrompt"]) + }) + + t.Run("OAuth2CallbackError", func(t *testing.T) { + mockOpt := contexttest.MockContextOption{SessionStore: session.NewMockStore("dummy-sid")} + ctx, resp := contexttest.MockContext(t, "/user/oauth2/dummy-auth-source/callback", mockOpt) + ctx.SetPathParam("provider", "dummy-auth-source") + SignInOAuthCallback(ctx) + assert.Equal(t, http.StatusSeeOther, resp.Code) + assert.Equal(t, "/user/login", test.RedirectURL(resp)) + assert.Contains(t, ctx.Flash.ErrorMsg, "auth.oauth.signin.error.general") + }) } diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go index 7a9721cf56..277f8bed31 100644 --- a/routers/web/auth/oauth.go +++ b/routers/web/auth/oauth.go @@ -115,7 +115,7 @@ func SignInOAuthCallback(ctx *context.Context) { case "temporarily_unavailable": ctx.Flash.Error(ctx.Tr("auth.oauth.signin.error.temporarily_unavailable")) default: - ctx.Flash.Error(ctx.Tr("auth.oauth.signin.error")) + ctx.Flash.Error(ctx.Tr("auth.oauth.signin.error.general", callbackErr.Description)) } ctx.Redirect(setting.AppSubURL + "/user/login") return @@ -431,8 +431,10 @@ func oAuth2UserLoginCallback(ctx *context.Context, authSource *auth.Source, requ gothUser, err := oauth2Source.Callback(request, response) if err != nil { if err.Error() == "securecookie: the value is too long" || strings.Contains(err.Error(), "Data too long") { - log.Error("OAuth2 Provider %s returned too long a token. Current max: %d. Either increase the [OAuth2] MAX_TOKEN_LENGTH or reduce the information returned from the OAuth2 provider", authSource.Name, setting.OAuth2.MaxTokenLength) err = fmt.Errorf("OAuth2 Provider %s returned too long a token. Current max: %d. Either increase the [OAuth2] MAX_TOKEN_LENGTH or reduce the information returned from the OAuth2 provider", authSource.Name, setting.OAuth2.MaxTokenLength) + log.Error("oauth2Source.Callback failed: %v", err) + } else { + err = errCallback{Code: "internal", Description: err.Error()} } return nil, goth.User{}, err } diff --git a/tests/integration/oauth_test.go b/tests/integration/oauth_test.go index d7ef103506..d2228bae79 100644 --- a/tests/integration/oauth_test.go +++ b/tests/integration/oauth_test.go @@ -19,7 +19,7 @@ import ( "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" - oauth2_provider "code.gitea.io/gitea/services/oauth2_provider" + "code.gitea.io/gitea/services/oauth2_provider" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" From 0fee4f1392268f2c37db8df7a54ba7d32ed65f29 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Sun, 23 Mar 2025 00:37:07 +0000 Subject: [PATCH 8/9] [skip ci] Updated translations via Crowdin --- options/locale/locale_cs-CZ.ini | 1 - options/locale/locale_de-DE.ini | 1 - options/locale/locale_el-GR.ini | 1 - options/locale/locale_es-ES.ini | 1 - options/locale/locale_fr-FR.ini | 1 - options/locale/locale_ga-IE.ini | 10 +++++++++- options/locale/locale_it-IT.ini | 1 - options/locale/locale_ja-JP.ini | 1 - options/locale/locale_lv-LV.ini | 1 - options/locale/locale_nl-NL.ini | 1 - options/locale/locale_pt-BR.ini | 1 - options/locale/locale_pt-PT.ini | 2 +- options/locale/locale_ru-RU.ini | 1 - options/locale/locale_sk-SK.ini | 1 - options/locale/locale_tr-TR.ini | 1 - options/locale/locale_zh-CN.ini | 1 - options/locale/locale_zh-TW.ini | 1 - 17 files changed, 10 insertions(+), 17 deletions(-) diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 42baa83a9c..57d7e8e076 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -446,7 +446,6 @@ oauth_signup_submit=Dokončit účet oauth_signin_tab=Propojit s existujícím účtem oauth_signin_title=Přihlaste se pro ověření propojeného účtu oauth_signin_submit=Propojit účet -oauth.signin.error=Došlo k chybě při zpracování žádosti o autorizaci. Pokud tato chyba přetrvává, obraťte se na správce webu. oauth.signin.error.access_denied=Žádost o autorizaci byla zamítnuta. oauth.signin.error.temporarily_unavailable=Autorizace se nezdařila, protože ověřovací server je dočasně nedostupný. Opakujte akci později. oauth_callback_unable_auto_reg=Automatická registrace je povolena, ale OAuth2 poskytovatel %[1]s vrátil chybějící pole: %[2]s, nelze vytvořit účet automaticky, vytvořte účet nebo se připojte k účtu, nebo kontaktujte správce webu. diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index e8e5ce3867..0b0544b89c 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -452,7 +452,6 @@ oauth_signup_submit=Konto vervollständigen oauth_signin_tab=Mit existierendem Konto verbinden oauth_signin_title=Anmelden um verbundenes Konto zu autorisieren oauth_signin_submit=Konto verbinden -oauth.signin.error=Beim Verarbeiten der Autorisierungsanfrage ist ein Fehler aufgetreten. Wenn dieser Fehler weiterhin besteht, wende dich bitte an deinen Administrator. oauth.signin.error.access_denied=Die Autorisierungsanfrage wurde abgelehnt. oauth.signin.error.temporarily_unavailable=Autorisierung fehlgeschlagen, da der Authentifizierungsserver vorübergehend nicht verfügbar ist. Bitte versuch es später erneut. oauth_callback_unable_auto_reg=Automatische Registrierung ist aktiviert, aber der OAuth2-Provider %[1]s hat fehlende Felder zurückgegeben: %[2]s, kann den Account nicht automatisch erstellen. Bitte erstelle oder verbinde einen Account oder kontaktieren den Administrator. diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index bb8e92f60e..f430c0506c 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -390,7 +390,6 @@ oauth_signup_submit=Ολοκληρωμένος Λογαριασμός oauth_signin_tab=Σύνδεση με υπάρχων λογαριασμό oauth_signin_title=Συνδεθείτε για να εγκρίνετε τον Συνδεδεμένο Λογαριασμό oauth_signin_submit=Σύνδεση Λογαριασμού -oauth.signin.error=Παρουσιάστηκε σφάλμα κατά την επεξεργασία του αιτήματος εξουσιοδότησης. Εάν αυτό το σφάλμα επιμένει, παρακαλούμε επικοινωνήστε με το διαχειριστή του ιστοτόπου. oauth.signin.error.access_denied=Η αίτηση εξουσιοδότησης απορρίφθηκε. oauth.signin.error.temporarily_unavailable=Η εξουσιοδότηση απέτυχε επειδή ο διακομιστής ταυτοποίησης δεν είναι διαθέσιμος προσωρινά. Παρακαλώ προσπαθήστε ξανά αργότερα. openid_connect_submit=Σύνδεση diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index 74dff40fac..debf9a6f5d 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -387,7 +387,6 @@ oauth_signup_submit=Completar Cuenta oauth_signin_tab=Vincular a una Cuenta Existente oauth_signin_title=Regístrese para autorizar cuenta vinculada oauth_signin_submit=Vincular Cuenta -oauth.signin.error=Hubo un error al procesar la solicitud de autorización. Si este error persiste, póngase en contacto con el administrador del sitio. oauth.signin.error.access_denied=La solicitud de autorización fue denegada. oauth.signin.error.temporarily_unavailable=La autorización falló porque el servidor de autenticación no está disponible temporalmente. Inténtalo de nuevo más tarde. openid_connect_submit=Conectar diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 8df99312b4..c9b3345382 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -457,7 +457,6 @@ oauth_signup_submit=Finaliser la création du compte oauth_signin_tab=Lier à un compte existant oauth_signin_title=Connectez-vous pour autoriser le compte lié oauth_signin_submit=Lier un compte -oauth.signin.error=Une erreur s'est produite lors du traitement de la demande d'autorisation. Si cette erreur persiste, veuillez contacter l'administrateur du site. oauth.signin.error.access_denied=La demande d'autorisation a été refusée. oauth.signin.error.temporarily_unavailable=L'autorisation a échoué car le serveur d'authentification est temporairement indisponible. Veuillez réessayer plus tard. oauth_callback_unable_auto_reg=L’inscription automatique est activée, mais le fournisseur OAuth2 %[1]s a signalé des champs manquants : %[2]s, impossible de créer un compte automatiquement, veuillez créer ou lier un compte, ou bien contacter l’administrateur du site. diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini index 00d2364ace..1245a8beed 100644 --- a/options/locale/locale_ga-IE.ini +++ b/options/locale/locale_ga-IE.ini @@ -113,6 +113,7 @@ copy_type_unsupported=Ní féidir an cineál comhaid seo a chóipeáil write=Scríobh preview=Réamhamharc loading=Á lódáil... +files=Comhaid error=Earráid error404=Níl an leathanach atá tú ag iarraidh a bhaint amach annníl tú údaraithe chun é a fheiceáil. @@ -169,6 +170,10 @@ search=Cuardaigh... type_tooltip=Cineál cuardaigh fuzzy=Doiléir fuzzy_tooltip=Cuir san áireamh torthaí a mheaitseálann an téarma cuardaigh go dlúth freisin +words=Focail +words_tooltip=Ná cuir san áireamh ach torthaí a mheaitseálann na focail téarma cuardaigh +regexp=Nathanna Rialta +regexp_tooltip=Ná cuir ach torthaí a mheaitseálann an téarma cuardaigh nathanna rialta san áireamh exact=Beacht exact_tooltip=Ní chuir san áireamh ach torthaí a mheaitseálann leis an téarma repo_kind=Cuardaigh stórtha... @@ -452,7 +457,6 @@ oauth_signup_submit=Cuntas Comhlánaigh oauth_signin_tab=Nasc leis an gCuntas Reatha oauth_signin_title=Sínigh isteach chun Cuntas Nasctha a Údarú oauth_signin_submit=Cuntas Nasc -oauth.signin.error=Bhí earráid ann ag próiseáil an t-iarratas ar údarú. Má leanann an earráid seo, déan teagmháil le riarthóir an láithreáin. oauth.signin.error.access_denied=Diúltaíodh an t-iarratas ar údarú. oauth.signin.error.temporarily_unavailable=Theip ar údarú toisc nach bhfuil an fhreastalaí fíordheimhnithe ar fáil Bain triail as arís níos déanaí. oauth_callback_unable_auto_reg=Tá Clárú Uathoibríoch cumasaithe, ach sheol Soláthraí OAuth2 %[1]s réimsí in easnamh ar ais: %[2]s, ní raibh sé in ann cuntas a chruthú go huathoibríoch, cruthaigh nó nasc le cuntas, nó déan teagmháil le riarthóir an tsuímh. @@ -1403,6 +1407,7 @@ commits.signed_by_untrusted_user_unmatched=Sínithe ag úsáideoir neamhiontaofa commits.gpg_key_id=GPG Eochair ID commits.ssh_key_fingerprint=Méarloirg Eochair SSH commits.view_path=Féach ag an bpointe seo sa stair +commits.view_file_diff=Féach ar athruithe ar an gcomhad seo sa tiomantas seo commit.operations=Oibríochtaí commit.revert=Téigh ar ais @@ -1540,6 +1545,8 @@ issues.filter_project=Tionscadal issues.filter_project_all=Gach tionscadal issues.filter_project_none=Gan aon tionscadal issues.filter_assignee=Sannaitheoir +issues.filter_assginee_no_assignee=Sannta do dhuine ar bith +issues.filter_assignee_any_assignee=Sannta do dhuine ar bith issues.filter_poster=Údar issues.filter_user_placeholder=Cuardaigh úsáideoirí issues.filter_user_no_select=Gach úsáideoir @@ -3706,6 +3713,7 @@ creation=Cuir Rúnda leis creation.description=Cur síos creation.name_placeholder=carachtair alfanumair nó íoslaghda amháin nach féidir a thosú le GITEA_ nó GITHUB_ creation.value_placeholder=Ionchur ábhar ar bith. Fágfar spás bán ag tús agus ag deireadh ar lár. +creation.description_placeholder=Cuir isteach cur síos gairid (roghnach). creation.success=Tá an rún "%s" curtha leis. creation.failed=Theip ar an rún a chur leis. deletion=Bain rún diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index 6a6c59f537..3ce5a6770f 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -323,7 +323,6 @@ oauth_signup_submit=Completa l'Account oauth_signin_tab=Collegamento ad un Account Esistente oauth_signin_title=Accedi per autorizzare l' Account collegato oauth_signin_submit=Collega Account -oauth.signin.error=Si è verificato un errore nell'elaborazione della richiesta di autorizzazione. Se questo errore persiste, si prega di contattare l'amministratore del sito. oauth.signin.error.access_denied=La richiesta di autorizzazione è stata negata. oauth.signin.error.temporarily_unavailable=Autorizzazione non riuscita perché il server di autenticazione non è temporaneamente disponibile. Riprova più tardi. openid_connect_submit=Connetti diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index bf6c5515e3..26909cdb63 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -452,7 +452,6 @@ oauth_signup_submit=アカウント登録完了 oauth_signin_tab=既存アカウントにリンク oauth_signin_title=リンク先アカウント認可のためサインイン oauth_signin_submit=アカウントにリンク -oauth.signin.error=認可リクエストの処理中にエラーが発生しました。このエラーが解決しない場合は、サイト管理者に問い合わせてください。 oauth.signin.error.access_denied=認可リクエストが拒否されました。 oauth.signin.error.temporarily_unavailable=認証サーバーが一時的に利用できないため、認可に失敗しました。後でもう一度やり直してください。 oauth_callback_unable_auto_reg=自動登録が有効になっていますが、OAuth2プロバイダー %[1]s の応答はフィールド %[2]s が不足しており、自動でアカウントを作成することができません。 アカウントを作成またはリンクするか、サイト管理者に問い合わせてください。 diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index 3fff777dc7..4439537fd7 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -393,7 +393,6 @@ oauth_signup_submit=Pabeigt reģistrāciju oauth_signin_tab=Sasaistīt ar esošu kontu oauth_signin_title=Pieteikties, lai autorizētu saistīto kontu oauth_signin_submit=Sasaistīt kontu -oauth.signin.error=Radās kļūda apstrādājot pieteikšanās pieprasījumu. Ja šī kļūda atkārtojas, sazinieties ar lapas administratoru. oauth.signin.error.access_denied=Autorizācijas pieprasījums tika noraidīts. oauth.signin.error.temporarily_unavailable=Pieteikšanās neizdevās, jo autentifikācijas serveris ir īslaicīgi nepieejams. Mēģiniet autorizēties vēlāk. openid_connect_submit=Pievienoties diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index f499685916..77bf2d2d59 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -322,7 +322,6 @@ oauth_signup_submit=Account voltooien oauth_signin_tab=Bestaand account koppelen oauth_signin_title=Inloggen om het gekoppelde account te machtigen oauth_signin_submit=Account koppelen -oauth.signin.error=Er is een fout opgetreden bij het verwerken van het autorisatieverzoek. Als deze fout zich blijft voordoen, neem dan contact op met de sitebeheerder. oauth.signin.error.access_denied=Het autorisatieverzoek is geweigerd. oauth.signin.error.temporarily_unavailable=Autorisatie mislukt omdat de verificatieserver tijdelijk niet beschikbaar is. Probeer het later opnieuw. openid_connect_submit=Verbinden diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index b76a6e548d..204fedc311 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -390,7 +390,6 @@ oauth_signup_submit=Completar conta oauth_signin_tab=Vincular à uma conta existente oauth_signin_title=Acesse com uma conta vinculada oauth_signin_submit=Vincular conta -oauth.signin.error=Ocorreu um erro durante o processamento do pedido de autorização. Se este erro persistir, contate o administrador. oauth.signin.error.access_denied=O pedido de autorização foi negado. oauth.signin.error.temporarily_unavailable=A autorização falhou porque o servidor de autenticação está temporariamente indisponível. Por favor, tente novamente mais tarde. openid_connect_submit=Conectar diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 12a7e146c2..d4b73244df 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -457,7 +457,6 @@ oauth_signup_submit=Completar conta oauth_signin_tab=Vincular a uma conta existente oauth_signin_title=Inicie a sessão para autorizar a vinculação à conta oauth_signin_submit=Vincular conta -oauth.signin.error=Ocorreu um erro durante o processamento do pedido de autorização. Se este erro persistir, contacte o administrador. oauth.signin.error.access_denied=O pedido de autorização foi negado. oauth.signin.error.temporarily_unavailable=A autorização falhou porque o servidor de autenticação está temporariamente indisponível. Tente mais tarde. oauth_callback_unable_auto_reg=O registo automático está habilitado, mas o fornecedor OAuth2 %[1]s sinalizou campos em falta: %[2]s, por isso não foi possível criar uma conta automaticamente. Crie ou vincule uma conta ou contacte o administrador do sítio. @@ -1547,6 +1546,7 @@ issues.filter_project_all=Todos os planeamentos issues.filter_project_none=Nenhum planeamento issues.filter_assignee=Encarregado issues.filter_assginee_no_assignee=Sem encarregado +issues.filter_assignee_any_assignee=Atribuído a qualquer pessoa issues.filter_poster=Autor(a) issues.filter_user_placeholder=Procurar utilizadores issues.filter_user_no_select=Todos os utilizadores diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index e53d483f2c..fe52165837 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -388,7 +388,6 @@ oauth_signup_submit=Полная учётная запись oauth_signin_tab=Ссылка на существующую учётную запись oauth_signin_title=Войдите, чтобы авторизовать связанную учётную запись oauth_signin_submit=Привязать учётную запись -oauth.signin.error=Произошла ошибка при обработке запроса авторизации. Если эта ошибка повторяется, обратитесь к администратору сайта. oauth.signin.error.access_denied=Запрос на авторизацию был отклонен. oauth.signin.error.temporarily_unavailable=Произошла ошибка авторизации, так как сервер аутентификации временно недоступен. Пожалуйста, повторите попытку позже. openid_connect_submit=Подключить diff --git a/options/locale/locale_sk-SK.ini b/options/locale/locale_sk-SK.ini index 53ea17b43e..20f26db801 100644 --- a/options/locale/locale_sk-SK.ini +++ b/options/locale/locale_sk-SK.ini @@ -377,7 +377,6 @@ oauth_signup_submit=Dokončiť účet oauth_signin_tab=Prepojiť s existujúcim účtom oauth_signin_title=Prihláste sa na overenie prepojeného účtu oauth_signin_submit=Prepojiť účet -oauth.signin.error=Vyskytla sa chyba počas spracovania vašej autorizačnej žiadosti. Ak chyba pretrváva, kontaktujte, prosím, správcu. oauth.signin.error.access_denied=Žiadosť o autorizáciu bola zamietnutá. oauth.signin.error.temporarily_unavailable=Autorizácia zlyhala, pretože overovací server je dočasne nedostupný. Skúste to prosím neskôr. openid_connect_submit=Pripojiť diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index d639c05c2f..1a044fca83 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -441,7 +441,6 @@ oauth_signup_submit=Hesabı Tamamla oauth_signin_tab=Mevcut Hesaba Bağla oauth_signin_title=Bağlantılı Hesabı Yetkilendirmek için Giriş Yapın oauth_signin_submit=Hesabı Bağla -oauth.signin.error=Yetkilendirme isteğini işlerken bir hata oluştu. Eğer hata devam ederse lütfen site yöneticisiyle bağlantıya geçin. oauth.signin.error.access_denied=Yetkilendirme isteği reddedildi. oauth.signin.error.temporarily_unavailable=Yetkilendirme sunucusu geçici olarak erişilemez olduğu için yetkilendirme başarısız oldu. Lütfen daha sonra tekrar deneyin. oauth_callback_unable_auto_reg=Otomatik kayıt etkin ancak OAuth2 Sağlayıcı %[1] eksik sahalar döndürdü: %[2]s, otomatik olarak hesap oluşturulamıyor, lütfen bir hesap oluşturun veya bağlantı verin, veya site yöneticisiyle iletişim kurun. diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 5f9a07dbf6..f36789921e 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -446,7 +446,6 @@ oauth_signup_submit=完成账号 oauth_signin_tab=绑定到现有帐号 oauth_signin_title=登录以授权绑定帐户 oauth_signin_submit=绑定账号 -oauth.signin.error=处理授权请求时出错。 如果此错误仍然存​​在,请联系站点管理员。 oauth.signin.error.access_denied=授权请求被拒绝。 oauth.signin.error.temporarily_unavailable=授权失败,因为认证服务器暂时不可用。请稍后再试。 oauth_callback_unable_auto_reg=自动注册已启用,但OAuth2 提供商 %[1]s 返回缺失的字段:%[2]s,无法自动创建帐户,请创建或链接到一个帐户,或联系站点管理员。 diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index a4af247ea0..10d6676ac5 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -444,7 +444,6 @@ oauth_signup_submit=完成帳戶 oauth_signin_tab=連結到現有帳戶 oauth_signin_title=登入以授權連結帳戶 oauth_signin_submit=連結帳戶 -oauth.signin.error=處理授權請求時發生錯誤。如果這個問題持續發生,請聯絡網站管理員。 oauth.signin.error.access_denied=授權請求被拒絕。 oauth.signin.error.temporarily_unavailable=授權失敗,因為認證伺服器暫時無法使用。請稍後再試。 oauth_callback_unable_auto_reg=自助註冊已啟用,但是 OAuth2 提供者 %[1]s 回傳的結果缺少欄位:%[2]s,導致無法自動建立帳號。請建立新帳號或是連結至既存的帳號,或是聯絡網站管理者。 From 189873719b0c27b76b14d4148613d0578fe903fd Mon Sep 17 00:00:00 2001 From: TheFox0x7 Date: Sun, 23 Mar 2025 15:13:16 +0100 Subject: [PATCH 9/9] update jwt and redis packages (#33984) --- go.mod | 6 +++--- go.sum | 11 ++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 0a544a9100..b0e294565b 100644 --- a/go.mod +++ b/go.mod @@ -64,7 +64,7 @@ require ( github.com/gobwas/glob v0.2.3 github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 - github.com/golang-jwt/jwt/v5 v5.2.1 + github.com/golang-jwt/jwt/v5 v5.2.2 github.com/google/go-github/v61 v61.0.0 github.com/google/licenseclassifier/v2 v2.0.0 github.com/google/pprof v0.0.0-20250208200701-d0013a598941 @@ -99,7 +99,7 @@ require ( github.com/pquerna/otp v1.4.0 github.com/prometheus/client_golang v1.21.0 github.com/quasoft/websspi v1.1.2 - github.com/redis/go-redis/v9 v9.7.0 + github.com/redis/go-redis/v9 v9.7.3 github.com/robfig/cron/v3 v3.0.1 github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 github.com/sassoftware/go-rpmutils v0.4.0 @@ -215,7 +215,7 @@ require ( github.com/go-openapi/validate v0.24.0 // indirect github.com/go-webauthn/x v0.1.16 // indirect github.com/goccy/go-json v0.10.5 // indirect - github.com/golang-jwt/jwt/v4 v4.5.1 // indirect + github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang/geo v0.0.0-20230421003525-6adc56603217 // indirect diff --git a/go.sum b/go.sum index 6e0b0bde07..4c1af56868 100644 --- a/go.sum +++ b/go.sum @@ -374,10 +374,11 @@ github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f h1:3BSP1Tbs2djlpprl7w github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14= github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 h1:UjoPNDAQ5JPCjlxoJd6K8ALZqSDDhk2ymieAZOVaDg0= github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85/go.mod h1:fR6z1Ie6rtF7kl/vBYMfgD5/G5B1blui7z426/sj2DU= -github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= -github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= +github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= +github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= @@ -655,8 +656,8 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG github.com/quasoft/websspi v1.1.2 h1:/mA4w0LxWlE3novvsoEL6BBA1WnjJATbjkh1kFrTidw= github.com/quasoft/websspi v1.1.2/go.mod h1:HmVdl939dQ0WIXZhyik+ARdI03M6bQzaSEKcgpFmewk= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E= -github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw= +github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM= +github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA= github.com/redis/rueidis v1.0.19 h1:s65oWtotzlIFN8eMPhyYwxlwLR1lUdhza2KtWprKYSo= github.com/redis/rueidis v1.0.19/go.mod h1:8B+r5wdnjwK3lTFml5VtxjzGOQAC+5UmujoD12pDrEo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=