followrequest.go (4415B)
1 // GoToSocial 2 // Copyright (C) GoToSocial Authors admin@gotosocial.org 3 // SPDX-License-Identifier: AGPL-3.0-or-later 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package processing 19 20 import ( 21 "context" 22 "errors" 23 24 "github.com/superseriousbusiness/gotosocial/internal/ap" 25 apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" 26 "github.com/superseriousbusiness/gotosocial/internal/db" 27 "github.com/superseriousbusiness/gotosocial/internal/gtserror" 28 "github.com/superseriousbusiness/gotosocial/internal/log" 29 "github.com/superseriousbusiness/gotosocial/internal/messages" 30 "github.com/superseriousbusiness/gotosocial/internal/oauth" 31 ) 32 33 func (p *Processor) FollowRequestsGet(ctx context.Context, auth *oauth.Auth) ([]apimodel.Account, gtserror.WithCode) { 34 followRequests, err := p.state.DB.GetAccountFollowRequests(ctx, auth.Account.ID) 35 if err != nil && !errors.Is(err, db.ErrNoEntries) { 36 return nil, gtserror.NewErrorInternalError(err) 37 } 38 39 accts := make([]apimodel.Account, 0, len(followRequests)) 40 for _, followRequest := range followRequests { 41 if followRequest.Account == nil { 42 // The creator of the follow doesn't exist, 43 // just skip this one. 44 log.WithContext(ctx).WithField("followRequest", followRequest).Warn("follow request had no associated account") 45 continue 46 } 47 48 apiAcct, err := p.tc.AccountToAPIAccountPublic(ctx, followRequest.Account) 49 if err != nil { 50 return nil, gtserror.NewErrorInternalError(err) 51 } 52 53 accts = append(accts, *apiAcct) 54 } 55 56 return accts, nil 57 } 58 59 func (p *Processor) FollowRequestAccept(ctx context.Context, auth *oauth.Auth, accountID string) (*apimodel.Relationship, gtserror.WithCode) { 60 follow, err := p.state.DB.AcceptFollowRequest(ctx, accountID, auth.Account.ID) 61 if err != nil { 62 return nil, gtserror.NewErrorNotFound(err) 63 } 64 65 if follow.Account == nil { 66 // The creator of the follow doesn't exist, 67 // so we can't do further processing. 68 log.WithContext(ctx).WithField("follow", follow).Warn("follow had no associated account") 69 return p.relationship(ctx, auth.Account.ID, accountID) 70 } 71 72 p.state.Workers.EnqueueClientAPI(ctx, messages.FromClientAPI{ 73 APObjectType: ap.ActivityFollow, 74 APActivityType: ap.ActivityAccept, 75 GTSModel: follow, 76 OriginAccount: follow.Account, 77 TargetAccount: follow.TargetAccount, 78 }) 79 80 return p.relationship(ctx, auth.Account.ID, accountID) 81 } 82 83 func (p *Processor) FollowRequestReject(ctx context.Context, auth *oauth.Auth, accountID string) (*apimodel.Relationship, gtserror.WithCode) { 84 followRequest, err := p.state.DB.GetFollowRequest(ctx, accountID, auth.Account.ID) 85 if err != nil { 86 return nil, gtserror.NewErrorNotFound(err) 87 } 88 89 err = p.state.DB.RejectFollowRequest(ctx, accountID, auth.Account.ID) 90 if err != nil { 91 return nil, gtserror.NewErrorNotFound(err) 92 } 93 94 if followRequest.Account == nil { 95 // The creator of the request doesn't exist, 96 // so we can't do further processing. 97 return p.relationship(ctx, auth.Account.ID, accountID) 98 } 99 100 p.state.Workers.EnqueueClientAPI(ctx, messages.FromClientAPI{ 101 APObjectType: ap.ActivityFollow, 102 APActivityType: ap.ActivityReject, 103 GTSModel: followRequest, 104 OriginAccount: followRequest.Account, 105 TargetAccount: followRequest.TargetAccount, 106 }) 107 108 return p.relationship(ctx, auth.Account.ID, accountID) 109 } 110 111 func (p *Processor) relationship(ctx context.Context, accountID string, targetAccountID string) (*apimodel.Relationship, gtserror.WithCode) { 112 relationship, err := p.state.DB.GetRelationship(ctx, accountID, targetAccountID) 113 if err != nil { 114 return nil, gtserror.NewErrorInternalError(err) 115 } 116 117 apiRelationship, err := p.tc.RelationshipToAPIRelationship(ctx, relationship) 118 if err != nil { 119 return nil, gtserror.NewErrorInternalError(err) 120 } 121 122 return apiRelationship, nil 123 }