mirror of
https://github.com/go-gitea/gitea.git
synced 2025-06-22 22:18:02 +02: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:
38
routers/web/org/block.go
Normal file
38
routers/web/org/block.go
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package org
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
shared_user "code.gitea.io/gitea/routers/web/shared/user"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
)
|
||||
|
||||
const (
|
||||
tplSettingsBlockedUsers base.TplName = "org/settings/blocked_users"
|
||||
)
|
||||
|
||||
func BlockedUsers(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("user.block.list")
|
||||
ctx.Data["PageIsOrgSettings"] = true
|
||||
ctx.Data["PageIsSettingsBlockedUsers"] = true
|
||||
|
||||
shared_user.BlockedUsers(ctx, ctx.ContextUser)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.HTML(http.StatusOK, tplSettingsBlockedUsers)
|
||||
}
|
||||
|
||||
func BlockedUsersPost(ctx *context.Context) {
|
||||
shared_user.BlockedUsersPost(ctx, ctx.ContextUser)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Redirect(ctx.ContextUser.OrganisationLink() + "/settings/blocked_users")
|
||||
}
|
@ -9,6 +9,7 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
@ -78,40 +79,43 @@ func Members(ctx *context.Context) {
|
||||
|
||||
// MembersAction response for operation to a member of organization
|
||||
func MembersAction(ctx *context.Context) {
|
||||
uid := ctx.FormInt64("uid")
|
||||
if uid == 0 {
|
||||
member, err := user_model.GetUserByID(ctx, ctx.FormInt64("uid"))
|
||||
if err != nil {
|
||||
log.Error("GetUserByID: %v", err)
|
||||
}
|
||||
if member == nil {
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/members")
|
||||
return
|
||||
}
|
||||
|
||||
org := ctx.Org.Organization
|
||||
var err error
|
||||
|
||||
switch ctx.Params(":action") {
|
||||
case "private":
|
||||
if ctx.Doer.ID != uid && !ctx.Org.IsOwner {
|
||||
if ctx.Doer.ID != member.ID && !ctx.Org.IsOwner {
|
||||
ctx.Error(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
err = organization.ChangeOrgUserStatus(ctx, org.ID, uid, false)
|
||||
err = organization.ChangeOrgUserStatus(ctx, org.ID, member.ID, false)
|
||||
case "public":
|
||||
if ctx.Doer.ID != uid && !ctx.Org.IsOwner {
|
||||
if ctx.Doer.ID != member.ID && !ctx.Org.IsOwner {
|
||||
ctx.Error(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
err = organization.ChangeOrgUserStatus(ctx, org.ID, uid, true)
|
||||
err = organization.ChangeOrgUserStatus(ctx, org.ID, member.ID, true)
|
||||
case "remove":
|
||||
if !ctx.Org.IsOwner {
|
||||
ctx.Error(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
err = models.RemoveOrgUser(ctx, org.ID, uid)
|
||||
err = models.RemoveOrgUser(ctx, org, member)
|
||||
if organization.IsErrLastOrgOwner(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
|
||||
ctx.JSONRedirect(ctx.Org.OrgLink + "/members")
|
||||
return
|
||||
}
|
||||
case "leave":
|
||||
err = models.RemoveOrgUser(ctx, org.ID, ctx.Doer.ID)
|
||||
err = models.RemoveOrgUser(ctx, org, ctx.Doer)
|
||||
if err == nil {
|
||||
ctx.Flash.Success(ctx.Tr("form.organization_leave_success", org.DisplayName()))
|
||||
ctx.JSON(http.StatusOK, map[string]any{
|
||||
|
@ -5,6 +5,7 @@
|
||||
package org
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@ -77,9 +78,9 @@ func TeamsAction(ctx *context.Context) {
|
||||
ctx.Error(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
err = models.AddTeamMember(ctx, ctx.Org.Team, ctx.Doer.ID)
|
||||
err = models.AddTeamMember(ctx, ctx.Org.Team, ctx.Doer)
|
||||
case "leave":
|
||||
err = models.RemoveTeamMember(ctx, ctx.Org.Team, ctx.Doer.ID)
|
||||
err = models.RemoveTeamMember(ctx, ctx.Org.Team, ctx.Doer)
|
||||
if err != nil {
|
||||
if org_model.IsErrLastOrgOwner(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
|
||||
@ -100,13 +101,13 @@ func TeamsAction(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
uid := ctx.FormInt64("uid")
|
||||
if uid == 0 {
|
||||
user, _ := user_model.GetUserByID(ctx, ctx.FormInt64("uid"))
|
||||
if user == nil {
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/teams")
|
||||
return
|
||||
}
|
||||
|
||||
err = models.RemoveTeamMember(ctx, ctx.Org.Team, uid)
|
||||
err = models.RemoveTeamMember(ctx, ctx.Org.Team, user)
|
||||
if err != nil {
|
||||
if org_model.IsErrLastOrgOwner(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
|
||||
@ -161,7 +162,7 @@ func TeamsAction(ctx *context.Context) {
|
||||
if ctx.Org.Team.IsMember(ctx, u.ID) {
|
||||
ctx.Flash.Error(ctx.Tr("org.teams.add_duplicate_users"))
|
||||
} else {
|
||||
err = models.AddTeamMember(ctx, ctx.Org.Team, u.ID)
|
||||
err = models.AddTeamMember(ctx, ctx.Org.Team, u)
|
||||
}
|
||||
|
||||
page = "team"
|
||||
@ -189,6 +190,8 @@ func TeamsAction(ctx *context.Context) {
|
||||
if err != nil {
|
||||
if org_model.IsErrLastOrgOwner(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
|
||||
} else if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.Flash.Error(ctx.Tr("org.teams.members.blocked_user"))
|
||||
} else {
|
||||
log.Error("Action(%s): %v", ctx.Params(":action"), err)
|
||||
ctx.JSON(http.StatusOK, map[string]any{
|
||||
@ -590,7 +593,7 @@ func TeamInvitePost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.AddTeamMember(ctx, team, ctx.Doer.ID); err != nil {
|
||||
if err := models.AddTeamMember(ctx, team, ctx.Doer); err != nil {
|
||||
ctx.ServerError("AddTeamMember", err)
|
||||
return
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ import (
|
||||
issue_service "code.gitea.io/gitea/services/issue"
|
||||
pull_service "code.gitea.io/gitea/services/pull"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
user_service "code.gitea.io/gitea/services/user"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -1258,9 +1259,11 @@ func NewIssuePost(ctx *context.Context) {
|
||||
if err := issue_service.NewIssue(ctx, repo, issue, labelIDs, attachments, assigneeIDs); err != nil {
|
||||
if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) {
|
||||
ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error())
|
||||
return
|
||||
} else if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.JSONError(ctx.Tr("repo.issues.new.blocked_user"))
|
||||
} else {
|
||||
ctx.ServerError("NewIssue", err)
|
||||
}
|
||||
ctx.ServerError("NewIssue", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -2047,6 +2050,10 @@ func ViewIssue(ctx *context.Context) {
|
||||
}
|
||||
ctx.Data["Tags"] = tags
|
||||
|
||||
ctx.Data["CanBlockUser"] = func(blocker, blockee *user_model.User) bool {
|
||||
return user_service.CanBlockUser(ctx, ctx.Doer, blocker, blockee)
|
||||
}
|
||||
|
||||
ctx.HTML(http.StatusOK, tplIssueView)
|
||||
}
|
||||
|
||||
@ -2250,7 +2257,11 @@ func UpdateIssueContent(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if err := issue_service.ChangeContent(ctx, issue, ctx.Doer, ctx.Req.FormValue("content")); err != nil {
|
||||
ctx.ServerError("ChangeContent", err)
|
||||
if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.JSONError(ctx.Tr("repo.issues.edit.blocked_user"))
|
||||
} else {
|
||||
ctx.ServerError("ChangeContent", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -3108,7 +3119,11 @@ func NewComment(ctx *context.Context) {
|
||||
|
||||
comment, err := issue_service.CreateIssueComment(ctx, ctx.Doer, ctx.Repo.Repository, issue, form.Content, attachments)
|
||||
if err != nil {
|
||||
ctx.ServerError("CreateIssueComment", err)
|
||||
if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.JSONError(ctx.Tr("repo.issues.comment.blocked_user"))
|
||||
} else {
|
||||
ctx.ServerError("CreateIssueComment", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -3152,7 +3167,11 @@ func UpdateCommentContent(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
if err = issue_service.UpdateComment(ctx, comment, ctx.Doer, oldContent); err != nil {
|
||||
ctx.ServerError("UpdateComment", err)
|
||||
if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.JSONError(ctx.Tr("repo.issues.comment.blocked_user"))
|
||||
} else {
|
||||
ctx.ServerError("UpdateComment", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -3260,9 +3279,9 @@ func ChangeIssueReaction(ctx *context.Context) {
|
||||
|
||||
switch ctx.Params(":action") {
|
||||
case "react":
|
||||
reaction, err := issues_model.CreateIssueReaction(ctx, ctx.Doer.ID, issue.ID, form.Content)
|
||||
reaction, err := issue_service.CreateIssueReaction(ctx, ctx.Doer, issue, form.Content)
|
||||
if err != nil {
|
||||
if issues_model.IsErrForbiddenIssueReaction(err) {
|
||||
if issues_model.IsErrForbiddenIssueReaction(err) || errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.ServerError("ChangeIssueReaction", err)
|
||||
return
|
||||
}
|
||||
@ -3367,9 +3386,9 @@ func ChangeCommentReaction(ctx *context.Context) {
|
||||
|
||||
switch ctx.Params(":action") {
|
||||
case "react":
|
||||
reaction, err := issues_model.CreateCommentReaction(ctx, ctx.Doer.ID, comment.Issue.ID, comment.ID, form.Content)
|
||||
reaction, err := issue_service.CreateCommentReaction(ctx, ctx.Doer, comment, form.Content)
|
||||
if err != nil {
|
||||
if issues_model.IsErrForbiddenIssueReaction(err) {
|
||||
if issues_model.IsErrForbiddenIssueReaction(err) || errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.ServerError("ChangeIssueReaction", err)
|
||||
return
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ import (
|
||||
notify_service "code.gitea.io/gitea/services/notify"
|
||||
pull_service "code.gitea.io/gitea/services/pull"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
user_service "code.gitea.io/gitea/services/user"
|
||||
|
||||
"github.com/gobwas/glob"
|
||||
)
|
||||
@ -308,6 +309,8 @@ func ForkPost(ctx *context.Context) {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(db.ErrNameReserved).Name), tplFork, &form)
|
||||
case db.IsErrNamePatternNotAllowed(err):
|
||||
ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(db.ErrNamePatternNotAllowed).Pattern), tplFork, &form)
|
||||
case errors.Is(err, user_model.ErrBlockedUser):
|
||||
ctx.RenderWithErr(ctx.Tr("repo.fork.blocked_user"), tplFork, form)
|
||||
default:
|
||||
ctx.ServerError("ForkPost", err)
|
||||
}
|
||||
@ -1065,6 +1068,10 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi
|
||||
}
|
||||
upload.AddUploadContext(ctx, "comment")
|
||||
|
||||
ctx.Data["CanBlockUser"] = func(blocker, blockee *user_model.User) bool {
|
||||
return user_service.CanBlockUser(ctx, ctx.Doer, blocker, blockee)
|
||||
}
|
||||
|
||||
ctx.HTML(http.StatusOK, tplPullFiles)
|
||||
}
|
||||
|
||||
@ -1483,7 +1490,6 @@ func CompareAndPullRequestPost(ctx *context.Context) {
|
||||
if err := pull_service.NewPullRequest(ctx, repo, pullIssue, labelIDs, attachments, pullRequest, assigneeIDs); err != nil {
|
||||
if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) {
|
||||
ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error())
|
||||
return
|
||||
} else if git.IsErrPushRejected(err) {
|
||||
pushrejErr := err.(*git.ErrPushRejected)
|
||||
message := pushrejErr.Message
|
||||
@ -1501,9 +1507,17 @@ func CompareAndPullRequestPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
ctx.JSONError(flashError)
|
||||
return
|
||||
} else if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
flashError, err := ctx.RenderToHTML(tplAlertDetails, map[string]any{
|
||||
"Message": ctx.Tr("repo.pulls.push_rejected"),
|
||||
"Summary": ctx.Tr("repo.pulls.new.blocked_user"),
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("CompareAndPullRequest.HTMLString", err)
|
||||
return
|
||||
}
|
||||
ctx.JSONError(flashError)
|
||||
}
|
||||
ctx.ServerError("NewPullRequest", err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -313,13 +313,13 @@ func Action(ctx *context.Context) {
|
||||
var err error
|
||||
switch ctx.Params(":action") {
|
||||
case "watch":
|
||||
err = repo_model.WatchRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID, true)
|
||||
err = repo_model.WatchRepo(ctx, ctx.Doer, ctx.Repo.Repository, true)
|
||||
case "unwatch":
|
||||
err = repo_model.WatchRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID, false)
|
||||
err = repo_model.WatchRepo(ctx, ctx.Doer, ctx.Repo.Repository, false)
|
||||
case "star":
|
||||
err = repo_model.StarRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID, true)
|
||||
err = repo_model.StarRepo(ctx, ctx.Doer, ctx.Repo.Repository, true)
|
||||
case "unstar":
|
||||
err = repo_model.StarRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID, false)
|
||||
err = repo_model.StarRepo(ctx, ctx.Doer, ctx.Repo.Repository, false)
|
||||
case "accept_transfer":
|
||||
err = acceptOrRejectRepoTransfer(ctx, true)
|
||||
case "reject_transfer":
|
||||
@ -336,8 +336,12 @@ func Action(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.Params(":action")), err)
|
||||
return
|
||||
if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.action.blocked_user"))
|
||||
} else {
|
||||
ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.Params(":action")), err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
switch ctx.Params(":action") {
|
||||
|
@ -4,10 +4,10 @@
|
||||
package setting
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
@ -27,7 +27,7 @@ func Collaboration(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.settings.collaboration")
|
||||
ctx.Data["PageIsSettingsCollaboration"] = true
|
||||
|
||||
users, err := repo_model.GetCollaborators(ctx, ctx.Repo.Repository.ID, db.ListOptions{})
|
||||
users, _, err := repo_model.GetCollaborators(ctx, &repo_model.FindCollaborationOptions{RepoID: ctx.Repo.Repository.ID})
|
||||
if err != nil {
|
||||
ctx.ServerError("GetCollaborators", err)
|
||||
return
|
||||
@ -101,7 +101,12 @@ func CollaborationPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if err = repo_module.AddCollaborator(ctx, ctx.Repo.Repository, u); err != nil {
|
||||
ctx.ServerError("AddCollaborator", err)
|
||||
if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.add_collaborator.blocked_user"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
|
||||
} else {
|
||||
ctx.ServerError("AddCollaborator", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -126,10 +131,19 @@ func ChangeCollaborationAccessMode(ctx *context.Context) {
|
||||
|
||||
// DeleteCollaboration delete a collaboration for a repository
|
||||
func DeleteCollaboration(ctx *context.Context) {
|
||||
if err := repo_service.DeleteCollaboration(ctx, ctx.Repo.Repository, ctx.FormInt64("id")); err != nil {
|
||||
ctx.Flash.Error("DeleteCollaboration: " + err.Error())
|
||||
if collaborator, err := user_model.GetUserByID(ctx, ctx.FormInt64("id")); err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.user_not_exist"))
|
||||
} else {
|
||||
ctx.ServerError("GetUserByName", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.remove_collaborator_success"))
|
||||
if err := repo_service.DeleteCollaboration(ctx, ctx.Repo.Repository, collaborator); err != nil {
|
||||
ctx.Flash.Error("DeleteCollaboration: " + err.Error())
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.remove_collaborator_success"))
|
||||
}
|
||||
}
|
||||
|
||||
ctx.JSONRedirect(ctx.Repo.RepoLink + "/settings/collaboration")
|
||||
|
@ -5,6 +5,7 @@
|
||||
package setting
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@ -782,6 +783,8 @@ func SettingsPost(ctx *context.Context) {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil)
|
||||
} else if models.IsErrRepoTransferInProgress(err) {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.settings.transfer_in_progress"), tplSettingsOptions, nil)
|
||||
} else if errors.Is(err, user_model.ErrBlockedUser) {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.settings.transfer.blocked_user"), tplSettingsOptions, nil)
|
||||
} else {
|
||||
ctx.ServerError("TransferOwnership", err)
|
||||
}
|
||||
|
76
routers/web/shared/user/block.go
Normal file
76
routers/web/shared/user/block.go
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
user_service "code.gitea.io/gitea/services/user"
|
||||
)
|
||||
|
||||
func BlockedUsers(ctx *context.Context, blocker *user_model.User) {
|
||||
blocks, _, err := user_model.FindBlockings(ctx, &user_model.FindBlockingOptions{
|
||||
BlockerID: blocker.ID,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("FindBlockings", err)
|
||||
return
|
||||
}
|
||||
if err := user_model.BlockingList(blocks).LoadAttributes(ctx); err != nil {
|
||||
ctx.ServerError("LoadAttributes", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["UserBlocks"] = blocks
|
||||
}
|
||||
|
||||
func BlockedUsersPost(ctx *context.Context, blocker *user_model.User) {
|
||||
form := web.GetForm(ctx).(*forms.BlockUserForm)
|
||||
if ctx.HasError() {
|
||||
ctx.ServerError("FormValidation", nil)
|
||||
return
|
||||
}
|
||||
|
||||
blockee, err := user_model.GetUserByName(ctx, form.Blockee)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserByName", nil)
|
||||
return
|
||||
}
|
||||
|
||||
switch form.Action {
|
||||
case "block":
|
||||
if err := user_service.BlockUser(ctx, ctx.Doer, blocker, blockee, form.Note); err != nil {
|
||||
if errors.Is(err, user_model.ErrCanNotBlock) || errors.Is(err, user_model.ErrBlockOrganization) {
|
||||
ctx.Flash.Error(ctx.Tr("user.block.block.failure", err.Error()))
|
||||
} else {
|
||||
ctx.ServerError("BlockUser", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
case "unblock":
|
||||
if err := user_service.UnblockUser(ctx, ctx.Doer, blocker, blockee); err != nil {
|
||||
if errors.Is(err, user_model.ErrCanNotUnblock) || errors.Is(err, user_model.ErrBlockOrganization) {
|
||||
ctx.Flash.Error(ctx.Tr("user.block.unblock.failure", err.Error()))
|
||||
} else {
|
||||
ctx.ServerError("UnblockUser", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
case "note":
|
||||
block, err := user_model.GetBlocking(ctx, blocker.ID, blockee.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetBlocking", err)
|
||||
return
|
||||
}
|
||||
if block != nil {
|
||||
if err := user_model.UpdateBlockingNote(ctx, block.ID, form.Note); err != nil {
|
||||
ctx.ServerError("UpdateBlockingNote", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -72,6 +72,14 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) {
|
||||
if _, ok := ctx.Data["NumFollowing"]; !ok {
|
||||
_, ctx.Data["NumFollowing"], _ = user_model.GetUserFollowing(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{PageSize: 1, Page: 1})
|
||||
}
|
||||
|
||||
if ctx.Doer != nil {
|
||||
if block, err := user_model.GetBlocking(ctx, ctx.Doer.ID, ctx.ContextUser.ID); err != nil {
|
||||
ctx.ServerError("GetBlocking", err)
|
||||
} else {
|
||||
ctx.Data["UserBlocking"] = block
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func FindUserProfileReadme(ctx *context.Context, doer *user_model.User) (profileDbRepo *repo_model.Repository, profileGitRepo *git.Repository, profileReadmeBlob *git.Blob, profileClose func()) {
|
||||
|
@ -339,7 +339,7 @@ func Action(ctx *context.Context) {
|
||||
var err error
|
||||
switch ctx.FormString("action") {
|
||||
case "follow":
|
||||
err = user_model.FollowUser(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
|
||||
err = user_model.FollowUser(ctx, ctx.Doer, ctx.ContextUser)
|
||||
case "unfollow":
|
||||
err = user_model.UnfollowUser(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
|
||||
}
|
||||
|
38
routers/web/user/setting/block.go
Normal file
38
routers/web/user/setting/block.go
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package setting
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
shared_user "code.gitea.io/gitea/routers/web/shared/user"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
)
|
||||
|
||||
const (
|
||||
tplSettingsBlockedUsers base.TplName = "user/settings/blocked_users"
|
||||
)
|
||||
|
||||
func BlockedUsers(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("user.block.list")
|
||||
ctx.Data["PageIsSettingsBlockedUsers"] = true
|
||||
|
||||
shared_user.BlockedUsers(ctx, ctx.Doer)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.HTML(http.StatusOK, tplSettingsBlockedUsers)
|
||||
}
|
||||
|
||||
func BlockedUsersPost(ctx *context.Context) {
|
||||
shared_user.BlockedUsersPost(ctx, ctx.Doer)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Redirect(setting.AppSubURL + "/user/settings/blocked_users")
|
||||
}
|
@ -647,6 +647,11 @@ func registerRoutes(m *web.Route) {
|
||||
})
|
||||
addWebhookEditRoutes()
|
||||
}, webhooksEnabled)
|
||||
|
||||
m.Group("/blocked_users", func() {
|
||||
m.Get("", user_setting.BlockedUsers)
|
||||
m.Post("", web.Bind(forms.BlockUserForm{}), user_setting.BlockedUsersPost)
|
||||
})
|
||||
}, reqSignIn, ctxDataSet("PageIsUserSettings", true, "AllThemes", setting.UI.Themes, "EnablePackages", setting.Packages.Enabled))
|
||||
|
||||
m.Group("/user", func() {
|
||||
@ -945,6 +950,11 @@ func registerRoutes(m *web.Route) {
|
||||
m.Post("/rebuild", org.RebuildCargoIndex)
|
||||
})
|
||||
}, packagesEnabled)
|
||||
|
||||
m.Group("/blocked_users", func() {
|
||||
m.Get("", org.BlockedUsers)
|
||||
m.Post("", web.Bind(forms.BlockUserForm{}), org.BlockedUsersPost)
|
||||
})
|
||||
}, ctxDataSet("EnableOAuth2", setting.OAuth2.Enabled, "EnablePackages", setting.Packages.Enabled, "PageIsOrgSettings", true))
|
||||
}, context.OrgAssignment(true, true))
|
||||
}, reqSignIn)
|
||||
|
Reference in New Issue
Block a user