loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(web): forbid blocked users from reopening issues (#7010)

Closes https://codeberg.org/forgejo/forgejo/issues/6841.

Signed-off-by: Litchi Pi <litchi.pi@proton.me>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7010
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Co-authored-by: Litchi Pi <litchi.pi@proton.me>
Co-committed-by: Litchi Pi <litchi.pi@proton.me>

authored by

Litchi Pi
Litchi Pi
and committed by
0ko
9dd47d93 ac08fc5b

+69 -4
+4
models/issues/issue_update.go
··· 64 64 } 65 65 66 66 func doChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.User, isMergePull bool) (*Comment, error) { 67 + if user_model.IsBlockedMultiple(ctx, []int64{issue.Repo.OwnerID, issue.PosterID}, doer.ID) { 68 + return nil, user_model.ErrBlockedByUser 69 + } 70 + 67 71 // Check for open dependencies 68 72 if issue.IsClosed && issue.Repo.IsDependenciesEnabled(ctx) { 69 73 // only check if dependencies are enabled and we're about to close an issue, otherwise reopening an issue would fail when there are unsatisfied dependencies
+3 -1
options/locale/locale_en-US.ini
··· 1878 1878 issues.content_history.options = Options 1879 1879 issues.reference_link = Reference: %s 1880 1880 issues.blocked_by_user = You cannot create a issue on this repository because you are blocked by the repository owner. 1881 - issues.comment.blocked_by_user = You cannot create a comment on this issue because you are blocked by the repository owner or the poster of the issue. 1881 + issues.comment.blocked_by_user = You cannot comment on this issue because you are blocked by the repository owner or the poster of the issue. 1882 + issues.reopen.blocked_by_user = You cannot reopen this issue because you are blocked by the repository owner or the poster of this issue. 1882 1883 issues.summary_card_alt = Summary card of an issue titled "%s" in repository %s 1883 1884 1884 1885 compare.compare_base = base ··· 1962 1963 pulls.waiting_count_n = %d waiting reviews 1963 1964 pulls.wrong_commit_id = commit id must be a commit id on the target branch 1964 1965 pulls.blocked_by_user = You cannot create a pull request on this repository because you are blocked by the repository owner. 1966 + pulls.comment.blocked_by_user = You cannot comment on this pull request because you are blocked by the repository owner or the poster of the pull request. 1965 1967 1966 1968 pulls.no_merge_desc = This pull request cannot be merged because all repository merge options are disabled. 1967 1969 pulls.no_merge_helper = Enable merge options in the repository settings or merge the pull request manually.
+20 -2
routers/web/repo/issue.go
··· 1260 1260 1261 1261 if err := issue_service.NewIssue(ctx, repo, issue, labelIDs, attachments, assigneeIDs); err != nil { 1262 1262 if errors.Is(err, user_model.ErrBlockedByUser) { 1263 - ctx.JSONError(ctx.Tr("repo.issues.blocked_by_user")) 1263 + if issue.IsPull { 1264 + ctx.JSONError(ctx.Tr("repo.pulls.blocked_by_user")) 1265 + } else { 1266 + ctx.JSONError(ctx.Tr("repo.issues.blocked_by_user")) 1267 + } 1264 1268 return 1265 1269 } else if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { 1266 1270 ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error()) ··· 2081 2085 ctx.Data["OpenGraphDescription"] = issue.Content 2082 2086 ctx.Data["OpenGraphImageURL"] = issue.SummaryCardURL() 2083 2087 ctx.Data["OpenGraphImageAltText"] = ctx.Tr("repo.issues.summary_card_alt", issue.Title, issue.Repo.FullName()) 2088 + ctx.Data["IsBlocked"] = ctx.Doer != nil && user_model.IsBlockedMultiple(ctx, []int64{issue.PosterID, issue.Repo.OwnerID}, ctx.Doer.ID) 2084 2089 2085 2090 prepareHiddenCommentType(ctx) 2086 2091 if ctx.Written() { ··· 3199 3204 } else { 3200 3205 isClosed := form.Status == "close" 3201 3206 if err := issue_service.ChangeStatus(ctx, issue, ctx.Doer, "", isClosed); err != nil { 3207 + if errors.Is(err, user_model.ErrBlockedByUser) { 3208 + if issue.IsPull { 3209 + ctx.JSONError(ctx.Tr("repo.pulls.blocked_by_user")) 3210 + } else { 3211 + ctx.JSONError(ctx.Tr("repo.issues.blocked_by_user")) 3212 + } 3213 + return 3214 + } 3215 + 3202 3216 log.Error("ChangeStatus: %v", err) 3203 3217 3204 3218 if issues_model.IsErrDependenciesLeft(err) { ··· 3240 3254 comment, err := issue_service.CreateIssueComment(ctx, ctx.Doer, ctx.Repo.Repository, issue, form.Content, attachments) 3241 3255 if err != nil { 3242 3256 if errors.Is(err, user_model.ErrBlockedByUser) { 3243 - ctx.JSONError(ctx.Tr("repo.issues.comment.blocked_by_user")) 3257 + if issue.IsPull { 3258 + ctx.JSONError(ctx.Tr("repo.pulls.comment.blocked_by_user")) 3259 + } else { 3260 + ctx.JSONError(ctx.Tr("repo.issues.comment.blocked_by_user")) 3261 + } 3244 3262 } else { 3245 3263 ctx.ServerError("CreateIssueComment", err) 3246 3264 }
+21
services/user/block_test.go
··· 8 8 9 9 model "code.gitea.io/gitea/models" 10 10 "code.gitea.io/gitea/models/db" 11 + issues_model "code.gitea.io/gitea/models/issues" 11 12 repo_model "code.gitea.io/gitea/models/repo" 12 13 "code.gitea.io/gitea/models/unittest" 13 14 user_model "code.gitea.io/gitea/models/user" ··· 88 89 // Don't use AssertExistsIf, as it doesn't include the zero values in the condition such as `repo_model.RepositoryReady`. 89 90 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3, OwnerID: blockedUser.ID}) 90 91 assert.Equal(t, repo_model.RepositoryReady, repo.Status) 92 + }) 93 + 94 + t.Run("Issues", func(t *testing.T) { 95 + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) 96 + blockedUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) 97 + defer user_model.UnblockUser(db.DefaultContext, doer.ID, blockedUser.ID) 98 + 99 + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2, OwnerID: doer.ID}) 100 + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4, RepoID: repo.ID}, "is_closed = true") 101 + 102 + _, err := issues_model.ChangeIssueStatus(db.DefaultContext, issue, blockedUser, false) 103 + require.NoError(t, err) 104 + 105 + _, err = issues_model.ChangeIssueStatus(db.DefaultContext, issue, doer, true) 106 + require.NoError(t, err) 107 + 108 + require.NoError(t, BlockUser(db.DefaultContext, doer.ID, blockedUser.ID)) 109 + 110 + _, err = issues_model.ChangeIssueStatus(db.DefaultContext, issue, blockedUser, false) 111 + require.Error(t, err) 91 112 }) 92 113 }
+9 -1
templates/repo/issue/view_content.tmpl
··· 79 79 {{template "repo/issue/view_content/pull".}} 80 80 {{end}} 81 81 82 - {{if .IsSigned}} 82 + {{if and .IsSigned (not .IsBlocked)}} 83 83 {{if and (or .IsRepoAdmin .HasIssuesOrPullsWritePermission (not .Issue.IsLocked)) (not .Repository.IsArchived)}} 84 84 <div class="timeline-item comment form"> 85 85 <a class="timeline-avatar" href="{{.SignedUser.HomeLink}}"> ··· 123 123 {{end}} 124 124 </div> 125 125 {{end}} 126 + {{else if .IsBlocked}} 127 + <div class="ui warning message"> 128 + {{if .Issue.IsPull}} 129 + {{ctx.Locale.Tr "repo.pulls.comment.blocked_by_user"}} 130 + {{else}} 131 + {{ctx.Locale.Tr "repo.issues.comment.blocked_by_user"}} 132 + {{end}} 133 + </div> 126 134 {{else}} {{/* not .IsSigned */}} 127 135 {{if .Repository.IsArchived}} 128 136 <div class="ui warning message tw-text-center">
+12
tests/integration/block_test.go
··· 253 253 DecodeJSON(t, resp, &errorResp) 254 254 255 255 assert.EqualValues(t, expectedMessage, errorResp.Error) 256 + 257 + req = NewRequest(t, "GET", issue10URL) 258 + resp = session.MakeRequest(t, req, http.StatusOK) 259 + htmlDoc := NewHTMLParser(t, resp.Body) 260 + msg := htmlDoc.doc.Find("div .warning").Text() 261 + assert.Contains(t, msg, "You cannot comment on this issue because you are blocked") 256 262 }) 257 263 258 264 t.Run("Blocked by issue poster", func(t *testing.T) { ··· 274 280 DecodeJSON(t, resp, &errorResp) 275 281 276 282 assert.EqualValues(t, expectedMessage, errorResp.Error) 283 + 284 + req = NewRequest(t, "GET", issue10URL) 285 + resp = session.MakeRequest(t, req, http.StatusOK) 286 + htmlDoc := NewHTMLParser(t, resp.Body) 287 + msg := htmlDoc.doc.Find("div .warning").Text() 288 + assert.Contains(t, msg, "You cannot comment on this issue because you are blocked") 277 289 }) 278 290 }) 279 291