code.gitea.io/gitea@v1.22.3/models/user/block.go (about) 1 // Copyright 2024 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package user 5 6 import ( 7 "context" 8 9 "code.gitea.io/gitea/models/db" 10 "code.gitea.io/gitea/modules/container" 11 "code.gitea.io/gitea/modules/timeutil" 12 "code.gitea.io/gitea/modules/util" 13 14 "xorm.io/builder" 15 ) 16 17 var ( 18 ErrBlockOrganization = util.NewInvalidArgumentErrorf("cannot block an organization") 19 ErrCanNotBlock = util.NewInvalidArgumentErrorf("cannot block the user") 20 ErrCanNotUnblock = util.NewInvalidArgumentErrorf("cannot unblock the user") 21 ErrBlockedUser = util.NewPermissionDeniedErrorf("user is blocked") 22 ) 23 24 type Blocking struct { 25 ID int64 `xorm:"pk autoincr"` 26 BlockerID int64 `xorm:"UNIQUE(block)"` 27 Blocker *User `xorm:"-"` 28 BlockeeID int64 `xorm:"UNIQUE(block)"` 29 Blockee *User `xorm:"-"` 30 Note string 31 CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` 32 } 33 34 func (*Blocking) TableName() string { 35 return "user_blocking" 36 } 37 38 func init() { 39 db.RegisterModel(new(Blocking)) 40 } 41 42 func UpdateBlockingNote(ctx context.Context, id int64, note string) error { 43 _, err := db.GetEngine(ctx).ID(id).Cols("note").Update(&Blocking{Note: note}) 44 return err 45 } 46 47 func IsUserBlockedBy(ctx context.Context, blockee *User, blockerIDs ...int64) bool { 48 if len(blockerIDs) == 0 { 49 return false 50 } 51 52 if blockee.IsAdmin { 53 return false 54 } 55 56 cond := builder.Eq{"user_blocking.blockee_id": blockee.ID}. 57 And(builder.In("user_blocking.blocker_id", blockerIDs)) 58 59 has, _ := db.GetEngine(ctx).Where(cond).Exist(&Blocking{}) 60 return has 61 } 62 63 type FindBlockingOptions struct { 64 db.ListOptions 65 BlockerID int64 66 BlockeeID int64 67 } 68 69 func (opts *FindBlockingOptions) ToConds() builder.Cond { 70 cond := builder.NewCond() 71 if opts.BlockerID != 0 { 72 cond = cond.And(builder.Eq{"user_blocking.blocker_id": opts.BlockerID}) 73 } 74 if opts.BlockeeID != 0 { 75 cond = cond.And(builder.Eq{"user_blocking.blockee_id": opts.BlockeeID}) 76 } 77 return cond 78 } 79 80 func FindBlockings(ctx context.Context, opts *FindBlockingOptions) ([]*Blocking, int64, error) { 81 return db.FindAndCount[Blocking](ctx, opts) 82 } 83 84 func GetBlocking(ctx context.Context, blockerID, blockeeID int64) (*Blocking, error) { 85 blocks, _, err := FindBlockings(ctx, &FindBlockingOptions{ 86 BlockerID: blockerID, 87 BlockeeID: blockeeID, 88 }) 89 if err != nil { 90 return nil, err 91 } 92 if len(blocks) == 0 { 93 return nil, nil 94 } 95 return blocks[0], nil 96 } 97 98 type BlockingList []*Blocking 99 100 func (blocks BlockingList) LoadAttributes(ctx context.Context) error { 101 ids := make(container.Set[int64], len(blocks)*2) 102 for _, b := range blocks { 103 ids.Add(b.BlockerID) 104 ids.Add(b.BlockeeID) 105 } 106 107 userList, err := GetUsersByIDs(ctx, ids.Values()) 108 if err != nil { 109 return err 110 } 111 112 userMap := make(map[int64]*User, len(userList)) 113 for _, u := range userList { 114 userMap[u.ID] = u 115 } 116 117 for _, b := range blocks { 118 b.Blocker = userMap[b.BlockerID] 119 b.Blockee = userMap[b.BlockeeID] 120 } 121 122 return nil 123 }