reject.go (3609B)
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 federatingdb 19 20 import ( 21 "context" 22 "errors" 23 "fmt" 24 25 "codeberg.org/gruf/go-logger/v2/level" 26 "github.com/superseriousbusiness/activity/streams/vocab" 27 "github.com/superseriousbusiness/gotosocial/internal/ap" 28 "github.com/superseriousbusiness/gotosocial/internal/log" 29 "github.com/superseriousbusiness/gotosocial/internal/uris" 30 ) 31 32 func (f *federatingDB) Reject(ctx context.Context, reject vocab.ActivityStreamsReject) error { 33 if log.Level() >= level.DEBUG { 34 i, err := marshalItem(reject) 35 if err != nil { 36 return err 37 } 38 l := log.WithContext(ctx). 39 WithField("reject", i) 40 l.Debug("entering Reject") 41 } 42 43 receivingAccount, _, internal := extractFromCtx(ctx) 44 if internal { 45 return nil // Already processed. 46 } 47 48 rejectObject := reject.GetActivityStreamsObject() 49 if rejectObject == nil { 50 return errors.New("Reject: no object set on vocab.ActivityStreamsReject") 51 } 52 53 for iter := rejectObject.Begin(); iter != rejectObject.End(); iter = iter.Next() { 54 // check if the object is an IRI 55 if iter.IsIRI() { 56 // we have just the URI of whatever is being rejected, so we need to find out what it is 57 rejectedObjectIRI := iter.GetIRI() 58 if uris.IsFollowPath(rejectedObjectIRI) { 59 // REJECT FOLLOW 60 followReq, err := f.state.DB.GetFollowRequestByURI(ctx, rejectedObjectIRI.String()) 61 if err != nil { 62 return fmt.Errorf("Reject: couldn't get follow request with id %s from the database: %s", rejectedObjectIRI.String(), err) 63 } 64 65 // make sure the addressee of the original follow is the same as whatever inbox this landed in 66 if followReq.AccountID != receivingAccount.ID { 67 return errors.New("Reject: follow object account and inbox account were not the same") 68 } 69 70 return f.state.DB.RejectFollowRequest(ctx, followReq.AccountID, followReq.TargetAccountID) 71 } 72 } 73 74 // check if iter is an AP object / type 75 if iter.GetType() == nil { 76 continue 77 } 78 79 if iter.GetType().GetTypeName() == ap.ActivityFollow { 80 // we have the whole object so we can figure out what we're rejecting 81 // REJECT FOLLOW 82 asFollow, ok := iter.GetType().(vocab.ActivityStreamsFollow) 83 if !ok { 84 return errors.New("Reject: couldn't parse follow into vocab.ActivityStreamsFollow") 85 } 86 87 // convert the follow to something we can understand 88 gtsFollow, err := f.typeConverter.ASFollowToFollow(ctx, asFollow) 89 if err != nil { 90 return fmt.Errorf("Reject: error converting asfollow to gtsfollow: %s", err) 91 } 92 93 // make sure the addressee of the original follow is the same as whatever inbox this landed in 94 if gtsFollow.AccountID != receivingAccount.ID { 95 return errors.New("Reject: follow object account and inbox account were not the same") 96 } 97 98 return f.state.DB.RejectFollowRequest(ctx, gtsFollow.AccountID, gtsFollow.TargetAccountID) 99 } 100 } 101 102 return nil 103 }