mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-03-03 15:54:47 +01:00
fix(web): forbid blocked users from reopening issues (#7010)
Some checks are pending
/ release (push) Waiting to run
testing / backend-checks (push) Waiting to run
testing / frontend-checks (push) Waiting to run
testing / test-unit (push) Blocked by required conditions
testing / test-e2e (push) Blocked by required conditions
testing / test-remote-cacher (redis) (push) Blocked by required conditions
testing / test-remote-cacher (valkey) (push) Blocked by required conditions
testing / test-remote-cacher (garnet) (push) Blocked by required conditions
testing / test-remote-cacher (redict) (push) Blocked by required conditions
testing / test-mysql (push) Blocked by required conditions
testing / test-pgsql (push) Blocked by required conditions
testing / test-sqlite (push) Blocked by required conditions
testing / security-check (push) Blocked by required conditions
Some checks are pending
/ release (push) Waiting to run
testing / backend-checks (push) Waiting to run
testing / frontend-checks (push) Waiting to run
testing / test-unit (push) Blocked by required conditions
testing / test-e2e (push) Blocked by required conditions
testing / test-remote-cacher (redis) (push) Blocked by required conditions
testing / test-remote-cacher (valkey) (push) Blocked by required conditions
testing / test-remote-cacher (garnet) (push) Blocked by required conditions
testing / test-remote-cacher (redict) (push) Blocked by required conditions
testing / test-mysql (push) Blocked by required conditions
testing / test-pgsql (push) Blocked by required conditions
testing / test-sqlite (push) Blocked by required conditions
testing / security-check (push) Blocked by required conditions
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>
This commit is contained in:
parent
ac08fc5b40
commit
9dd47d932f
6 changed files with 69 additions and 4 deletions
|
@ -64,6 +64,10 @@ func changeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.User,
|
|||
}
|
||||
|
||||
func doChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.User, isMergePull bool) (*Comment, error) {
|
||||
if user_model.IsBlockedMultiple(ctx, []int64{issue.Repo.OwnerID, issue.PosterID}, doer.ID) {
|
||||
return nil, user_model.ErrBlockedByUser
|
||||
}
|
||||
|
||||
// Check for open dependencies
|
||||
if issue.IsClosed && issue.Repo.IsDependenciesEnabled(ctx) {
|
||||
// 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
|
||||
|
|
|
@ -1878,7 +1878,8 @@ issues.content_history.delete_from_history_confirm = Delete from history?
|
|||
issues.content_history.options = Options
|
||||
issues.reference_link = Reference: %s
|
||||
issues.blocked_by_user = You cannot create a issue on this repository because you are blocked by the repository owner.
|
||||
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.
|
||||
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.
|
||||
issues.reopen.blocked_by_user = You cannot reopen this issue because you are blocked by the repository owner or the poster of this issue.
|
||||
issues.summary_card_alt = Summary card of an issue titled "%s" in repository %s
|
||||
|
||||
compare.compare_base = base
|
||||
|
@ -1962,6 +1963,7 @@ pulls.waiting_count_1 = %d waiting review
|
|||
pulls.waiting_count_n = %d waiting reviews
|
||||
pulls.wrong_commit_id = commit id must be a commit id on the target branch
|
||||
pulls.blocked_by_user = You cannot create a pull request on this repository because you are blocked by the repository owner.
|
||||
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.
|
||||
|
||||
pulls.no_merge_desc = This pull request cannot be merged because all repository merge options are disabled.
|
||||
pulls.no_merge_helper = Enable merge options in the repository settings or merge the pull request manually.
|
||||
|
|
|
@ -1260,7 +1260,11 @@ func NewIssuePost(ctx *context.Context) {
|
|||
|
||||
if err := issue_service.NewIssue(ctx, repo, issue, labelIDs, attachments, assigneeIDs); err != nil {
|
||||
if errors.Is(err, user_model.ErrBlockedByUser) {
|
||||
ctx.JSONError(ctx.Tr("repo.issues.blocked_by_user"))
|
||||
if issue.IsPull {
|
||||
ctx.JSONError(ctx.Tr("repo.pulls.blocked_by_user"))
|
||||
} else {
|
||||
ctx.JSONError(ctx.Tr("repo.issues.blocked_by_user"))
|
||||
}
|
||||
return
|
||||
} else if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) {
|
||||
ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error())
|
||||
|
@ -2081,6 +2085,7 @@ func ViewIssue(ctx *context.Context) {
|
|||
ctx.Data["OpenGraphDescription"] = issue.Content
|
||||
ctx.Data["OpenGraphImageURL"] = issue.SummaryCardURL()
|
||||
ctx.Data["OpenGraphImageAltText"] = ctx.Tr("repo.issues.summary_card_alt", issue.Title, issue.Repo.FullName())
|
||||
ctx.Data["IsBlocked"] = ctx.Doer != nil && user_model.IsBlockedMultiple(ctx, []int64{issue.PosterID, issue.Repo.OwnerID}, ctx.Doer.ID)
|
||||
|
||||
prepareHiddenCommentType(ctx)
|
||||
if ctx.Written() {
|
||||
|
@ -3199,6 +3204,15 @@ func NewComment(ctx *context.Context) {
|
|||
} else {
|
||||
isClosed := form.Status == "close"
|
||||
if err := issue_service.ChangeStatus(ctx, issue, ctx.Doer, "", isClosed); err != nil {
|
||||
if errors.Is(err, user_model.ErrBlockedByUser) {
|
||||
if issue.IsPull {
|
||||
ctx.JSONError(ctx.Tr("repo.pulls.blocked_by_user"))
|
||||
} else {
|
||||
ctx.JSONError(ctx.Tr("repo.issues.blocked_by_user"))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
log.Error("ChangeStatus: %v", err)
|
||||
|
||||
if issues_model.IsErrDependenciesLeft(err) {
|
||||
|
@ -3240,7 +3254,11 @@ func NewComment(ctx *context.Context) {
|
|||
comment, err := issue_service.CreateIssueComment(ctx, ctx.Doer, ctx.Repo.Repository, issue, form.Content, attachments)
|
||||
if err != nil {
|
||||
if errors.Is(err, user_model.ErrBlockedByUser) {
|
||||
ctx.JSONError(ctx.Tr("repo.issues.comment.blocked_by_user"))
|
||||
if issue.IsPull {
|
||||
ctx.JSONError(ctx.Tr("repo.pulls.comment.blocked_by_user"))
|
||||
} else {
|
||||
ctx.JSONError(ctx.Tr("repo.issues.comment.blocked_by_user"))
|
||||
}
|
||||
} else {
|
||||
ctx.ServerError("CreateIssueComment", err)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
model "code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
@ -89,4 +90,24 @@ func TestBlockUser(t *testing.T) {
|
|||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3, OwnerID: blockedUser.ID})
|
||||
assert.Equal(t, repo_model.RepositoryReady, repo.Status)
|
||||
})
|
||||
|
||||
t.Run("Issues", func(t *testing.T) {
|
||||
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
blockedUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
|
||||
defer user_model.UnblockUser(db.DefaultContext, doer.ID, blockedUser.ID)
|
||||
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2, OwnerID: doer.ID})
|
||||
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4, RepoID: repo.ID}, "is_closed = true")
|
||||
|
||||
_, err := issues_model.ChangeIssueStatus(db.DefaultContext, issue, blockedUser, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = issues_model.ChangeIssueStatus(db.DefaultContext, issue, doer, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, BlockUser(db.DefaultContext, doer.ID, blockedUser.ID))
|
||||
|
||||
_, err = issues_model.ChangeIssueStatus(db.DefaultContext, issue, blockedUser, false)
|
||||
require.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
{{template "repo/issue/view_content/pull".}}
|
||||
{{end}}
|
||||
|
||||
{{if .IsSigned}}
|
||||
{{if and .IsSigned (not .IsBlocked)}}
|
||||
{{if and (or .IsRepoAdmin .HasIssuesOrPullsWritePermission (not .Issue.IsLocked)) (not .Repository.IsArchived)}}
|
||||
<div class="timeline-item comment form">
|
||||
<a class="timeline-avatar" href="{{.SignedUser.HomeLink}}">
|
||||
|
@ -123,6 +123,14 @@
|
|||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{else if .IsBlocked}}
|
||||
<div class="ui warning message">
|
||||
{{if .Issue.IsPull}}
|
||||
{{ctx.Locale.Tr "repo.pulls.comment.blocked_by_user"}}
|
||||
{{else}}
|
||||
{{ctx.Locale.Tr "repo.issues.comment.blocked_by_user"}}
|
||||
{{end}}
|
||||
</div>
|
||||
{{else}} {{/* not .IsSigned */}}
|
||||
{{if .Repository.IsArchived}}
|
||||
<div class="ui warning message tw-text-center">
|
||||
|
|
|
@ -253,6 +253,12 @@ func TestBlockActions(t *testing.T) {
|
|||
DecodeJSON(t, resp, &errorResp)
|
||||
|
||||
assert.EqualValues(t, expectedMessage, errorResp.Error)
|
||||
|
||||
req = NewRequest(t, "GET", issue10URL)
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
msg := htmlDoc.doc.Find("div .warning").Text()
|
||||
assert.Contains(t, msg, "You cannot comment on this issue because you are blocked")
|
||||
})
|
||||
|
||||
t.Run("Blocked by issue poster", func(t *testing.T) {
|
||||
|
@ -274,6 +280,12 @@ func TestBlockActions(t *testing.T) {
|
|||
DecodeJSON(t, resp, &errorResp)
|
||||
|
||||
assert.EqualValues(t, expectedMessage, errorResp.Error)
|
||||
|
||||
req = NewRequest(t, "GET", issue10URL)
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
msg := htmlDoc.doc.Find("div .warning").Text()
|
||||
assert.Contains(t, msg, "You cannot comment on this issue because you are blocked")
|
||||
})
|
||||
})
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue