mirror of
https://github.com/go-gitea/gitea
synced 2025-07-23 02:38:35 +00:00
Add user blocking (#29028)
Fixes #17453 This PR adds the abbility to block a user from a personal account or organization to restrict how the blocked user can interact with the blocker. The docs explain what's the consequence of blocking a user. Screenshots:    --------- Co-authored-by: Lauris BH <lauris@nix.lv>
This commit is contained in:
@@ -8,7 +8,6 @@ import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
@@ -54,15 +53,10 @@ func ListCollaborators(ctx *context.APIContext) {
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
count, err := db.Count[repo_model.Collaboration](ctx, repo_model.FindCollaborationOptions{
|
||||
RepoID: ctx.Repo.Repository.ID,
|
||||
collaborators, total, err := repo_model.GetCollaborators(ctx, &repo_model.FindCollaborationOptions{
|
||||
ListOptions: utils.GetListOptions(ctx),
|
||||
RepoID: ctx.Repo.Repository.ID,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
collaborators, err := repo_model.GetCollaborators(ctx, ctx.Repo.Repository.ID, utils.GetListOptions(ctx))
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "ListCollaborators", err)
|
||||
return
|
||||
@@ -73,7 +67,7 @@ func ListCollaborators(ctx *context.APIContext) {
|
||||
users[i] = convert.ToUser(ctx, collaborator.User, ctx.Doer)
|
||||
}
|
||||
|
||||
ctx.SetTotalCountHeader(count)
|
||||
ctx.SetTotalCountHeader(total)
|
||||
ctx.JSON(http.StatusOK, users)
|
||||
}
|
||||
|
||||
@@ -159,6 +153,8 @@ func AddCollaborator(ctx *context.APIContext) {
|
||||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
// "422":
|
||||
@@ -182,7 +178,11 @@ func AddCollaborator(ctx *context.APIContext) {
|
||||
}
|
||||
|
||||
if err := repo_module.AddCollaborator(ctx, ctx.Repo.Repository, collaborator); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "AddCollaborator", err)
|
||||
if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.Error(http.StatusForbidden, "AddCollaborator", err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "AddCollaborator", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ func DeleteCollaborator(ctx *context.APIContext) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := repo_service.DeleteCollaboration(ctx, ctx.Repo.Repository, collaborator.ID); err != nil {
|
||||
if err := repo_service.DeleteCollaboration(ctx, ctx.Repo.Repository, collaborator); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "DeleteCollaboration", err)
|
||||
return
|
||||
}
|
||||
|
@@ -149,6 +149,8 @@ func CreateFork(ctx *context.APIContext) {
|
||||
if err != nil {
|
||||
if errors.Is(err, util.ErrAlreadyExist) || repo_model.IsErrReachLimitOfRepo(err) {
|
||||
ctx.Error(http.StatusConflict, "ForkRepository", err)
|
||||
} else if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.Error(http.StatusForbidden, "ForkRepository", err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "ForkRepository", err)
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@@ -653,6 +654,7 @@ func CreateIssue(ctx *context.APIContext) {
|
||||
// "$ref": "#/responses/validationError"
|
||||
// "423":
|
||||
// "$ref": "#/responses/repoArchivedError"
|
||||
|
||||
form := web.GetForm(ctx).(*api.CreateIssueOption)
|
||||
var deadlineUnix timeutil.TimeStamp
|
||||
if form.Deadline != nil && ctx.Repo.CanWrite(unit.TypeIssues) {
|
||||
@@ -710,9 +712,11 @@ func CreateIssue(ctx *context.APIContext) {
|
||||
if err := issue_service.NewIssue(ctx, ctx.Repo.Repository, issue, form.Labels, nil, assigneeIDs); err != nil {
|
||||
if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) {
|
||||
ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err)
|
||||
return
|
||||
} else if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.Error(http.StatusForbidden, "NewIssue", err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "NewIssue", err)
|
||||
}
|
||||
ctx.Error(http.StatusInternalServerError, "NewIssue", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -848,7 +852,11 @@ func EditIssue(ctx *context.APIContext) {
|
||||
|
||||
err = issue_service.UpdateAssignees(ctx, issue, oneAssignee, form.Assignees, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateAssignees", err)
|
||||
if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.Error(http.StatusForbidden, "UpdateAssignees", err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateAssignees", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@@ -382,6 +382,7 @@ func CreateIssueComment(ctx *context.APIContext) {
|
||||
// "$ref": "#/responses/notFound"
|
||||
// "423":
|
||||
// "$ref": "#/responses/repoArchivedError"
|
||||
|
||||
form := web.GetForm(ctx).(*api.CreateIssueCommentOption)
|
||||
issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
@@ -401,7 +402,11 @@ func CreateIssueComment(ctx *context.APIContext) {
|
||||
|
||||
comment, err := issue_service.CreateIssueComment(ctx, ctx.Doer, ctx.Repo.Repository, issue, form.Body, nil)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "CreateIssueComment", err)
|
||||
if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.Error(http.StatusForbidden, "CreateIssueComment", err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "CreateIssueComment", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -522,6 +527,7 @@ func EditIssueComment(ctx *context.APIContext) {
|
||||
// "$ref": "#/responses/notFound"
|
||||
// "423":
|
||||
// "$ref": "#/responses/repoArchivedError"
|
||||
|
||||
form := web.GetForm(ctx).(*api.EditIssueCommentOption)
|
||||
editIssueComment(ctx, *form)
|
||||
}
|
||||
@@ -610,7 +616,11 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption)
|
||||
oldContent := comment.Content
|
||||
comment.Content = form.Body
|
||||
if err := issue_service.UpdateComment(ctx, comment, ctx.Doer, oldContent); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateComment", err)
|
||||
if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.Error(http.StatusForbidden, "UpdateComment", err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateComment", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -4,10 +4,12 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
@@ -154,6 +156,8 @@ func CreateIssueCommentAttachment(ctx *context.APIContext) {
|
||||
// "$ref": "#/responses/Attachment"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "404":
|
||||
// "$ref": "#/responses/error"
|
||||
// "423":
|
||||
@@ -199,7 +203,11 @@ func CreateIssueCommentAttachment(ctx *context.APIContext) {
|
||||
}
|
||||
|
||||
if err = issue_service.UpdateComment(ctx, comment, ctx.Doer, comment.Content); err != nil {
|
||||
ctx.ServerError("UpdateComment", err)
|
||||
if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.Error(http.StatusForbidden, "UpdateComment", err)
|
||||
} else {
|
||||
ctx.ServerError("UpdateComment", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -8,11 +8,13 @@ import (
|
||||
"net/http"
|
||||
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/routers/api/v1/utils"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
"code.gitea.io/gitea/services/convert"
|
||||
issue_service "code.gitea.io/gitea/services/issue"
|
||||
)
|
||||
|
||||
// GetIssueCommentReactions list reactions of a comment from an issue
|
||||
@@ -218,9 +220,9 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp
|
||||
|
||||
if isCreateType {
|
||||
// PostIssueCommentReaction part
|
||||
reaction, err := issues_model.CreateCommentReaction(ctx, ctx.Doer.ID, comment.Issue.ID, comment.ID, form.Reaction)
|
||||
reaction, err := issue_service.CreateCommentReaction(ctx, ctx.Doer, comment, form.Reaction)
|
||||
if err != nil {
|
||||
if issues_model.IsErrForbiddenIssueReaction(err) {
|
||||
if issues_model.IsErrForbiddenIssueReaction(err) || errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.Error(http.StatusForbidden, err.Error(), err)
|
||||
} else if issues_model.IsErrReactionAlreadyExist(err) {
|
||||
ctx.JSON(http.StatusOK, api.Reaction{
|
||||
@@ -434,9 +436,9 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i
|
||||
|
||||
if isCreateType {
|
||||
// PostIssueReaction part
|
||||
reaction, err := issues_model.CreateIssueReaction(ctx, ctx.Doer.ID, issue.ID, form.Reaction)
|
||||
reaction, err := issue_service.CreateIssueReaction(ctx, ctx.Doer, issue, form.Reaction)
|
||||
if err != nil {
|
||||
if issues_model.IsErrForbiddenIssueReaction(err) {
|
||||
if issues_model.IsErrForbiddenIssueReaction(err) || errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.Error(http.StatusForbidden, err.Error(), err)
|
||||
} else if issues_model.IsErrReactionAlreadyExist(err) {
|
||||
ctx.JSON(http.StatusOK, api.Reaction{
|
||||
@@ -445,7 +447,7 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i
|
||||
Created: reaction.CreatedUnix.AsTime(),
|
||||
})
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "CreateCommentReaction", err)
|
||||
ctx.Error(http.StatusInternalServerError, "CreateIssueReaction", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@@ -362,6 +362,8 @@ func CreatePullRequest(ctx *context.APIContext) {
|
||||
// responses:
|
||||
// "201":
|
||||
// "$ref": "#/responses/PullRequest"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
// "409":
|
||||
@@ -510,9 +512,11 @@ func CreatePullRequest(ctx *context.APIContext) {
|
||||
if err := pull_service.NewPullRequest(ctx, repo, prIssue, labelIDs, []string{}, pr, assigneeIDs); err != nil {
|
||||
if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) {
|
||||
ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err)
|
||||
return
|
||||
} else if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.Error(http.StatusForbidden, "BlockedUser", err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "NewPullRequest", err)
|
||||
}
|
||||
ctx.Error(http.StatusInternalServerError, "NewPullRequest", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -630,6 +634,8 @@ func EditPullRequest(ctx *context.APIContext) {
|
||||
if err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err))
|
||||
} else if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.Error(http.StatusForbidden, "UpdateAssignees", err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateAssignees", err)
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
@@ -117,7 +118,11 @@ func Transfer(ctx *context.APIContext) {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.InternalServerError(err)
|
||||
if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.Error(http.StatusForbidden, "BlockedUser", err)
|
||||
} else {
|
||||
ctx.InternalServerError(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user