diff options
Diffstat (limited to 'internal/federation')
25 files changed, 356 insertions, 124 deletions
diff --git a/internal/federation/dereference.go b/internal/federation/dereference.go index 07901d5b1..96a662e32 100644 --- a/internal/federation/dereference.go +++ b/internal/federation/dereference.go @@ -1,3 +1,21 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + package federation import ( diff --git a/internal/federation/dereferencing/account.go b/internal/federation/dereferencing/account.go index 72d2e44d7..ba6766061 100644 --- a/internal/federation/dereferencing/account.go +++ b/internal/federation/dereferencing/account.go @@ -29,7 +29,6 @@ import ( "github.com/go-fed/activity/streams/vocab" "github.com/sirupsen/logrus" "github.com/superseriousbusiness/gotosocial/internal/ap" - "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/transport" @@ -65,8 +64,8 @@ func (d *deref) GetRemoteAccount(username string, remoteAccountID *url.URL, refr new := true // check if we already have the account in our db - maybeAccount := >smodel.Account{} - if err := d.db.GetWhere([]db.Where{{Key: "uri", Value: remoteAccountID.String()}}, maybeAccount); err == nil { + maybeAccount, err := d.db.GetAccountByURI(remoteAccountID.String()) + if err == nil { // we've seen this account before so it's not new new = false if !refresh { diff --git a/internal/federation/dereferencing/announce.go b/internal/federation/dereferencing/announce.go index 2522a4034..6773db425 100644 --- a/internal/federation/dereferencing/announce.go +++ b/internal/federation/dereferencing/announce.go @@ -27,14 +27,14 @@ import ( ) func (d *deref) DereferenceAnnounce(announce *gtsmodel.Status, requestingUsername string) error { - if announce.GTSBoostedStatus == nil || announce.GTSBoostedStatus.URI == "" { + if announce.BoostOf == nil || announce.BoostOf.URI == "" { // we can't do anything unfortunately return errors.New("DereferenceAnnounce: no URI to dereference") } - boostedStatusURI, err := url.Parse(announce.GTSBoostedStatus.URI) + boostedStatusURI, err := url.Parse(announce.BoostOf.URI) if err != nil { - return fmt.Errorf("DereferenceAnnounce: couldn't parse boosted status URI %s: %s", announce.GTSBoostedStatus.URI, err) + return fmt.Errorf("DereferenceAnnounce: couldn't parse boosted status URI %s: %s", announce.BoostOf.URI, err) } if blocked, err := d.blockedDomain(boostedStatusURI.Host); blocked || err != nil { return fmt.Errorf("DereferenceAnnounce: domain %s is blocked", boostedStatusURI.Host) @@ -47,7 +47,7 @@ func (d *deref) DereferenceAnnounce(announce *gtsmodel.Status, requestingUsernam boostedStatus, _, _, err := d.GetRemoteStatus(requestingUsername, boostedStatusURI, false) if err != nil { - return fmt.Errorf("DereferenceAnnounce: error dereferencing remote status with id %s: %s", announce.GTSBoostedStatus.URI, err) + return fmt.Errorf("DereferenceAnnounce: error dereferencing remote status with id %s: %s", announce.BoostOf.URI, err) } announce.Content = boostedStatus.Content @@ -60,6 +60,6 @@ func (d *deref) DereferenceAnnounce(announce *gtsmodel.Status, requestingUsernam announce.BoostOfAccountID = boostedStatus.AccountID announce.Visibility = boostedStatus.Visibility announce.VisibilityAdvanced = boostedStatus.VisibilityAdvanced - announce.GTSBoostedStatus = boostedStatus + announce.BoostOf = boostedStatus return nil } diff --git a/internal/federation/dereferencing/blocked.go b/internal/federation/dereferencing/blocked.go index a66afbb60..c8a4c6ade 100644 --- a/internal/federation/dereferencing/blocked.go +++ b/internal/federation/dereferencing/blocked.go @@ -31,7 +31,7 @@ func (d *deref) blockedDomain(host string) (bool, error) { return true, nil } - if _, ok := err.(db.ErrNoEntries); ok { + if err == db.ErrNoEntries { // there are no entries so there's no block return false, nil } diff --git a/internal/federation/dereferencing/status.go b/internal/federation/dereferencing/status.go index b05f6e72c..68693c021 100644 --- a/internal/federation/dereferencing/status.go +++ b/internal/federation/dereferencing/status.go @@ -66,8 +66,8 @@ func (d *deref) GetRemoteStatus(username string, remoteStatusID *url.URL, refres new := true // check if we already have the status in our db - maybeStatus := >smodel.Status{} - if err := d.db.GetWhere([]db.Where{{Key: "uri", Value: remoteStatusID.String()}}, maybeStatus); err == nil { + maybeStatus, err := d.db.GetStatusByURI(remoteStatusID.String()) + if err == nil { // we've seen this status before so it's not new new = false @@ -109,7 +109,7 @@ func (d *deref) GetRemoteStatus(username string, remoteStatusID *url.URL, refres return nil, statusable, new, fmt.Errorf("GetRemoteStatus: error populating status fields: %s", err) } - if err := d.db.Put(gtsStatus); err != nil { + if err := d.db.PutStatus(gtsStatus); err != nil { return nil, statusable, new, fmt.Errorf("GetRemoteStatus: error putting new status: %s", err) } } else { @@ -276,7 +276,7 @@ func (d *deref) populateStatusFields(status *gtsmodel.Status, requestingUsername // * the remote URL (a.RemoteURL) // This should be enough to pass along to the media processor. attachmentIDs := []string{} - for _, a := range status.GTSMediaAttachments { + for _, a := range status.Attachments { l.Tracef("dereferencing attachment: %+v", a) // it might have been processed elsewhere so check first if it's already in the database or not @@ -288,7 +288,7 @@ func (d *deref) populateStatusFields(status *gtsmodel.Status, requestingUsername attachmentIDs = append(attachmentIDs, maybeAttachment.ID) continue } - if _, ok := err.(db.ErrNoEntries); !ok { + if err != db.ErrNoEntries { // we have a real error return fmt.Errorf("error checking db for existence of attachment with remote url %s: %s", a.RemoteURL, err) } @@ -307,7 +307,7 @@ func (d *deref) populateStatusFields(status *gtsmodel.Status, requestingUsername } attachmentIDs = append(attachmentIDs, deferencedAttachment.ID) } - status.Attachments = attachmentIDs + status.AttachmentIDs = attachmentIDs // 2. Hashtags @@ -317,53 +317,84 @@ func (d *deref) populateStatusFields(status *gtsmodel.Status, requestingUsername // At this point, mentions should have the namestring and mentionedAccountURI set on them. // // We should dereference any accounts mentioned here which we don't have in our db yet, by their URI. - mentions := []string{} - for _, m := range status.GTSMentions { - + mentionIDs := []string{} + for _, m := range status.Mentions { if m.ID != "" { - continue // we've already populated this mention, since it has an ID + l.Debug("mention already populated") + continue } - mID, err := id.NewRandomULID() - if err != nil { - return err + if m.TargetAccountURI == "" { + // can't do anything with this mention + l.Debug("target URI not set on mention") + continue } - m.ID = mID - uri, err := url.Parse(m.MentionedAccountURI) + targetAccountURI, err := url.Parse(m.TargetAccountURI) if err != nil { - l.Debugf("error parsing mentioned account uri %s: %s", m.MentionedAccountURI, err) + l.Debugf("error parsing mentioned account uri %s: %s", m.TargetAccountURI, err) continue } - m.StatusID = status.ID - m.OriginAccountID = status.GTSAuthorAccount.ID - m.OriginAccountURI = status.GTSAuthorAccount.URI + var targetAccount *gtsmodel.Account + if a, err := d.db.GetAccountByURL(targetAccountURI.String()); err == nil { + targetAccount = a + } else if a, _, err := d.GetRemoteAccount(requestingUsername, targetAccountURI, false); err == nil { + targetAccount = a + } else { + // we can't find the target account so bail + l.Debug("can't retrieve account targeted by mention") + continue + } - targetAccount, _, err := d.GetRemoteAccount(requestingUsername, uri, false) + mID, err := id.NewRandomULID() if err != nil { - continue + return err + } + + m = >smodel.Mention{ + ID: mID, + StatusID: status.ID, + Status: m.Status, + CreatedAt: status.CreatedAt, + UpdatedAt: status.UpdatedAt, + OriginAccountID: status.Account.ID, + OriginAccountURI: status.AccountURI, + OriginAccount: status.Account, + TargetAccountID: targetAccount.ID, + TargetAccount: targetAccount, + NameString: m.NameString, + TargetAccountURI: targetAccount.URI, + TargetAccountURL: targetAccount.URL, } - // by this point, we know the targetAccount exists in our database with an ID :) - m.TargetAccountID = targetAccount.ID if err := d.db.Put(m); err != nil { return fmt.Errorf("error creating mention: %s", err) } - mentions = append(mentions, m.ID) + mentionIDs = append(mentionIDs, m.ID) } - status.Mentions = mentions + status.MentionIDs = mentionIDs // status has replyToURI but we don't have an ID yet for the status it replies to if status.InReplyToURI != "" && status.InReplyToID == "" { - replyToStatus := >smodel.Status{} - if err := d.db.GetWhere([]db.Where{{Key: "uri", Value: status.InReplyToURI}}, replyToStatus); err == nil { + statusURI, err := url.Parse(status.InReplyToURI) + if err != nil { + return err + } + if replyToStatus, err := d.db.GetStatusByURI(status.InReplyToURI); err == nil { // we have the status status.InReplyToID = replyToStatus.ID + status.InReplyTo = replyToStatus status.InReplyToAccountID = replyToStatus.AccountID + status.InReplyToAccount = replyToStatus.Account + } else if replyToStatus, _, _, err := d.GetRemoteStatus(requestingUsername, statusURI, false); err == nil { + // we got the status + status.InReplyToID = replyToStatus.ID + status.InReplyTo = replyToStatus + status.InReplyToAccountID = replyToStatus.AccountID + status.InReplyToAccount = replyToStatus.Account } } - return nil } diff --git a/internal/federation/federatingdb/accept.go b/internal/federation/federatingdb/accept.go index 4d11ea62a..91d9df86f 100644 --- a/internal/federation/federatingdb/accept.go +++ b/internal/federation/federatingdb/accept.go @@ -1,3 +1,21 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + package federatingdb import ( diff --git a/internal/federation/federatingdb/announce.go b/internal/federation/federatingdb/announce.go index a70c0c3a6..981eaf1ef 100644 --- a/internal/federation/federatingdb/announce.go +++ b/internal/federation/federatingdb/announce.go @@ -1,3 +1,21 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + package federatingdb import ( diff --git a/internal/federation/federatingdb/create.go b/internal/federation/federatingdb/create.go index 2ac4890e8..fb4353cd4 100644 --- a/internal/federation/federatingdb/create.go +++ b/internal/federation/federatingdb/create.go @@ -112,8 +112,8 @@ func (f *federatingDB) Create(ctx context.Context, asType vocab.Type) error { } status.ID = statusID - if err := f.db.Put(status); err != nil { - if _, ok := err.(db.ErrAlreadyExists); ok { + if err := f.db.PutStatus(status); err != nil { + if err == db.ErrAlreadyExists { // the status already exists in the database, which means we've already handled everything else, // so we can just return nil here and be done with it. return nil diff --git a/internal/federation/federatingdb/delete.go b/internal/federation/federatingdb/delete.go index 02ce43620..ee9310789 100644 --- a/internal/federation/federatingdb/delete.go +++ b/internal/federation/federatingdb/delete.go @@ -1,3 +1,21 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + package federatingdb import ( @@ -6,7 +24,6 @@ import ( "net/url" "github.com/sirupsen/logrus" - "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/util" ) @@ -52,10 +69,8 @@ func (f *federatingDB) Delete(ctx context.Context, id *url.URL) error { // in a delete we only get the URI, we can't know if we have a status or a profile or something else, // so we have to try a few different things... - where := []db.Where{{Key: "uri", Value: id.String()}} - - s := >smodel.Status{} - if err := f.db.GetWhere(where, s); err == nil { + s, err := f.db.GetStatusByURI(id.String()) + if err == nil { // it's a status l.Debugf("uri is for status with id: %s", s.ID) if err := f.db.DeleteByID(s.ID, >smodel.Status{}); err != nil { @@ -69,8 +84,8 @@ func (f *federatingDB) Delete(ctx context.Context, id *url.URL) error { } } - a := >smodel.Account{} - if err := f.db.GetWhere(where, a); err == nil { + a, err := f.db.GetAccountByURI(id.String()) + if err == nil { // it's an account l.Debugf("uri is for an account with id: %s", s.ID) if err := f.db.DeleteByID(a.ID, >smodel.Account{}); err != nil { diff --git a/internal/federation/federatingdb/exists.go b/internal/federation/federatingdb/exists.go index b5c10b895..0e13c1196 100644 --- a/internal/federation/federatingdb/exists.go +++ b/internal/federation/federatingdb/exists.go @@ -1,3 +1,21 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + package federatingdb import ( diff --git a/internal/federation/federatingdb/followers.go b/internal/federation/federatingdb/followers.go index 1f111dd34..241362fc1 100644 --- a/internal/federation/federatingdb/followers.go +++ b/internal/federation/federatingdb/followers.go @@ -31,7 +31,8 @@ func (f *federatingDB) Followers(c context.Context, actorIRI *url.URL) (follower acct := >smodel.Account{} if util.IsUserPath(actorIRI) { - if err := f.db.GetWhere([]db.Where{{Key: "uri", Value: actorIRI.String()}}, acct); err != nil { + acct, err = f.db.GetAccountByURI(actorIRI.String()) + if err != nil { return nil, fmt.Errorf("FOLLOWERS: db error getting account with uri %s: %s", actorIRI.String(), err) } } else if util.IsFollowersPath(actorIRI) { @@ -42,8 +43,8 @@ func (f *federatingDB) Followers(c context.Context, actorIRI *url.URL) (follower return nil, fmt.Errorf("FOLLOWERS: could not parse actor IRI %s as users or followers path", actorIRI.String()) } - acctFollowers := []gtsmodel.Follow{} - if err := f.db.GetFollowersByAccountID(acct.ID, &acctFollowers, false); err != nil { + acctFollowers, err := f.db.GetAccountFollowedBy(acct.ID, false) + if err != nil { return nil, fmt.Errorf("FOLLOWERS: db error getting followers for account id %s: %s", acct.ID, err) } diff --git a/internal/federation/federatingdb/following.go b/internal/federation/federatingdb/following.go index f92041e1e..45785c671 100644 --- a/internal/federation/federatingdb/following.go +++ b/internal/federation/federatingdb/following.go @@ -8,7 +8,6 @@ import ( "github.com/go-fed/activity/streams" "github.com/go-fed/activity/streams/vocab" "github.com/sirupsen/logrus" - "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/util" ) @@ -28,21 +27,37 @@ func (f *federatingDB) Following(c context.Context, actorIRI *url.URL) (followin ) l.Debugf("entering FOLLOWING function with actorIRI %s", actorIRI.String()) - acct := >smodel.Account{} + var acct *gtsmodel.Account if util.IsUserPath(actorIRI) { - if err := f.db.GetWhere([]db.Where{{Key: "uri", Value: actorIRI.String()}}, acct); err != nil { + username, err := util.ParseUserPath(actorIRI) + if err != nil { + return nil, fmt.Errorf("FOLLOWING: error parsing user path: %s", err) + } + + a, err := f.db.GetLocalAccountByUsername(username) + if err != nil { return nil, fmt.Errorf("FOLLOWING: db error getting account with uri %s: %s", actorIRI.String(), err) } + + acct = a } else if util.IsFollowingPath(actorIRI) { - if err := f.db.GetWhere([]db.Where{{Key: "following_uri", Value: actorIRI.String()}}, acct); err != nil { + username, err := util.ParseFollowingPath(actorIRI) + if err != nil { + return nil, fmt.Errorf("FOLLOWING: error parsing following path: %s", err) + } + + a, err := f.db.GetLocalAccountByUsername(username) + if err != nil { return nil, fmt.Errorf("FOLLOWING: db error getting account with following uri %s: %s", actorIRI.String(), err) } + + acct = a } else { return nil, fmt.Errorf("FOLLOWING: could not parse actor IRI %s as users or following path", actorIRI.String()) } - acctFollowing := []gtsmodel.Follow{} - if err := f.db.GetFollowingByAccountID(acct.ID, &acctFollowing); err != nil { + acctFollowing, err := f.db.GetAccountFollows(acct.ID) + if err != nil { return nil, fmt.Errorf("FOLLOWING: db error getting following for account id %s: %s", acct.ID, err) } diff --git a/internal/federation/federatingdb/get.go b/internal/federation/federatingdb/get.go index 77a24bf43..0265080f9 100644 --- a/internal/federation/federatingdb/get.go +++ b/internal/federation/federatingdb/get.go @@ -43,8 +43,8 @@ func (f *federatingDB) Get(c context.Context, id *url.URL) (value vocab.Type, er l.Debug("entering GET function") if util.IsUserPath(id) { - acct := >smodel.Account{} - if err := f.db.GetWhere([]db.Where{{Key: "uri", Value: id.String()}}, acct); err != nil { + acct, err := f.db.GetAccountByURI(id.String()) + if err != nil { return nil, err } l.Debug("is user path! returning account") diff --git a/internal/federation/federatingdb/inbox.go b/internal/federation/federatingdb/inbox.go index 25ef2cda5..4390a8b4b 100644 --- a/internal/federation/federatingdb/inbox.go +++ b/internal/federation/federatingdb/inbox.go @@ -1,3 +1,21 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + package federatingdb import ( diff --git a/internal/federation/federatingdb/liked.go b/internal/federation/federatingdb/liked.go index 5645d6f1e..b85398fef 100644 --- a/internal/federation/federatingdb/liked.go +++ b/internal/federation/federatingdb/liked.go @@ -1,3 +1,21 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + package federatingdb import ( diff --git a/internal/federation/federatingdb/outbox.go b/internal/federation/federatingdb/outbox.go index 1568e0017..849014432 100644 --- a/internal/federation/federatingdb/outbox.go +++ b/internal/federation/federatingdb/outbox.go @@ -1,3 +1,21 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + package federatingdb import ( @@ -62,7 +80,7 @@ func (f *federatingDB) OutboxForInbox(c context.Context, inboxIRI *url.URL) (out } acct := >smodel.Account{} if err := f.db.GetWhere([]db.Where{{Key: "inbox_uri", Value: inboxIRI.String()}}, acct); err != nil { - if _, ok := err.(db.ErrNoEntries); ok { + if err == db.ErrNoEntries { return nil, fmt.Errorf("no actor found that corresponds to inbox %s", inboxIRI.String()) } return nil, fmt.Errorf("db error searching for actor with inbox %s", inboxIRI.String()) diff --git a/internal/federation/federatingdb/owns.go b/internal/federation/federatingdb/owns.go index 51b20151a..0a65397ff 100644 --- a/internal/federation/federatingdb/owns.go +++ b/internal/federation/federatingdb/owns.go @@ -54,16 +54,16 @@ func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) { if err != nil { return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err) } - if err := f.db.GetWhere([]db.Where{{Key: "uri", Value: uid}}, >smodel.Status{}); err != nil { - if _, ok := err.(db.ErrNoEntries); ok { + status, err := f.db.GetStatusByURI(uid) + if err != nil { + if err == db.ErrNoEntries { // there are no entries for this status return false, nil } // an actual error happened return false, fmt.Errorf("database error fetching status with id %s: %s", uid, err) } - l.Debugf("we own url %s", id.String()) - return true, nil + return status.Local, nil } if util.IsUserPath(id) { @@ -71,8 +71,8 @@ func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) { if err != nil { return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err) } - if err := f.db.GetLocalAccountByUsername(username, >smodel.Account{}); err != nil { - if _, ok := err.(db.ErrNoEntries); ok { + if _, err := f.db.GetLocalAccountByUsername(username); err != nil { + if err == db.ErrNoEntries { // there are no entries for this username return false, nil } @@ -88,8 +88,8 @@ func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) { if err != nil { return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err) } - if err := f.db.GetLocalAccountByUsername(username, >smodel.Account{}); err != nil { - if _, ok := err.(db.ErrNoEntries); ok { + if _, err := f.db.GetLocalAccountByUsername(username); err != nil { + if err == db.ErrNoEntries { // there are no entries for this username return false, nil } @@ -105,8 +105,8 @@ func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) { if err != nil { return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err) } - if err := f.db.GetLocalAccountByUsername(username, >smodel.Account{}); err != nil { - if _, ok := err.(db.ErrNoEntries); ok { + if _, err := f.db.GetLocalAccountByUsername(username); err != nil { + if err == db.ErrNoEntries { // there are no entries for this username return false, nil } @@ -122,8 +122,8 @@ func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) { if err != nil { return false, fmt.Errorf("error parsing like path for url %s: %s", id.String(), err) } - if err := f.db.GetLocalAccountByUsername(username, >smodel.Account{}); err != nil { - if _, ok := err.(db.ErrNoEntries); ok { + if _, err := f.db.GetLocalAccountByUsername(username); err != nil { + if err == db.ErrNoEntries { // there are no entries for this username return false, nil } @@ -131,7 +131,7 @@ func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) { return false, fmt.Errorf("database error fetching account with username %s: %s", username, err) } if err := f.db.GetByID(likeID, >smodel.StatusFave{}); err != nil { - if _, ok := err.(db.ErrNoEntries); ok { + if err == db.ErrNoEntries { // there are no entries return false, nil } @@ -147,8 +147,8 @@ func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) { if err != nil { return false, fmt.Errorf("error parsing block path for url %s: %s", id.String(), err) } - if err := f.db.GetLocalAccountByUsername(username, >smodel.Account{}); err != nil { - if _, ok := err.(db.ErrNoEntries); ok { + if _, err := f.db.GetLocalAccountByUsername(username); err != nil { + if err == db.ErrNoEntries { // there are no entries for this username return false, nil } @@ -156,7 +156,7 @@ func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) { return false, fmt.Errorf("database error fetching account with username %s: %s", username, err) } if err := f.db.GetByID(blockID, >smodel.Block{}); err != nil { - if _, ok := err.(db.ErrNoEntries); ok { + if err == db.ErrNoEntries { // there are no entries return false, nil } diff --git a/internal/federation/federatingdb/undo.go b/internal/federation/federatingdb/undo.go index dd82e7bac..c527833b4 100644 --- a/internal/federation/federatingdb/undo.go +++ b/internal/federation/federatingdb/undo.go @@ -1,3 +1,21 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + package federatingdb import ( diff --git a/internal/federation/federatingdb/update.go b/internal/federation/federatingdb/update.go index 3f4e3e413..88ffc23b4 100644 --- a/internal/federation/federatingdb/update.go +++ b/internal/federation/federatingdb/update.go @@ -1,3 +1,21 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + package federatingdb import ( diff --git a/internal/federation/federatingdb/util.go b/internal/federation/federatingdb/util.go index 28f4c5a21..eac70d85c 100644 --- a/internal/federation/federatingdb/util.go +++ b/internal/federation/federatingdb/util.go @@ -97,8 +97,8 @@ func (f *federatingDB) NewID(c context.Context, t vocab.Type) (idURL *url.URL, e for iter := actorProp.Begin(); iter != actorProp.End(); iter = iter.Next() { // take the IRI of the first actor we can find (there should only be one) if iter.IsIRI() { - actorAccount := >smodel.Account{} - if err := f.db.GetWhere([]db.Where{{Key: "uri", Value: iter.GetIRI().String()}}, actorAccount); err == nil { // if there's an error here, just use the fallback behavior -- we don't need to return an error here + // if there's an error here, just use the fallback behavior -- we don't need to return an error here + if actorAccount, err := f.db.GetAccountByURI(iter.GetIRI().String()); err == nil { newID, err := id.NewRandomULID() if err != nil { return nil, err @@ -213,7 +213,7 @@ func (f *federatingDB) ActorForOutbox(c context.Context, outboxIRI *url.URL) (ac } acct := >smodel.Account{} if err := f.db.GetWhere([]db.Where{{Key: "outbox_uri", Value: outboxIRI.String()}}, acct); err != nil { - if _, ok := err.(db.ErrNoEntries); ok { + if err == db.ErrNoEntries { return nil, fmt.Errorf("no actor found that corresponds to outbox %s", outboxIRI.String()) } return nil, fmt.Errorf("db error searching for actor with outbox %s", outboxIRI.String()) @@ -238,7 +238,7 @@ func (f *federatingDB) ActorForInbox(c context.Context, inboxIRI *url.URL) (acto } acct := >smodel.Account{} if err := f.db.GetWhere([]db.Where{{Key: "inbox_uri", Value: inboxIRI.String()}}, acct); err != nil { - if _, ok := err.(db.ErrNoEntries); ok { + if err == db.ErrNoEntries { return nil, fmt.Errorf("no actor found that corresponds to inbox %s", inboxIRI.String()) } return nil, fmt.Errorf("db error searching for actor with inbox %s", inboxIRI.String()) diff --git a/internal/federation/federatingprotocol.go b/internal/federation/federatingprotocol.go index 9e21b43bf..5da68afd3 100644 --- a/internal/federation/federatingprotocol.go +++ b/internal/federation/federatingprotocol.go @@ -113,8 +113,8 @@ func (f *federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWr return nil, false, errors.New("username was empty") } - requestedAccount := >smodel.Account{} - if err := f.db.GetLocalAccountByUsername(username, requestedAccount); err != nil { + requestedAccount, err := f.db.GetLocalAccountByUsername(username) + if err != nil { return nil, false, fmt.Errorf("could not fetch requested account with username %s: %s", username, err) } @@ -132,7 +132,7 @@ func (f *federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWr // authentication has passed, so add an instance entry for this instance if it hasn't been done already i := >smodel.Instance{} if err := f.db.GetWhere([]db.Where{{Key: "domain", Value: publicKeyOwnerURI.Host, CaseInsensitive: true}}, i); err != nil { - if _, ok := err.(db.ErrNoEntries); !ok { + if err != db.ErrNoEntries { // there's been an actual error return ctx, false, fmt.Errorf("error getting requesting account with public key id %s: %s", publicKeyOwnerURI.String(), err) } @@ -176,8 +176,6 @@ func (f *federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWr // Finally, if the authentication and authorization succeeds, then // blocked must be false and error nil. The request will continue // to be processed. -// -// TODO: implement domain block checking here as well func (f *federator) Blocked(ctx context.Context, actorIRIs []*url.URL) (bool, error) { l := f.log.WithFields(logrus.Fields{ "func": "Blocked", @@ -191,19 +189,18 @@ func (f *federator) Blocked(ctx context.Context, actorIRIs []*url.URL) (bool, er return false, errors.New("requested account not set on request context, so couldn't determine blocks") } + blocked, err := f.db.AreURIsBlocked(actorIRIs) + if err != nil { + return false, fmt.Errorf("error checking domain blocks: %s", err) + } + if blocked { + return blocked, nil + } + for _, uri := range actorIRIs { - blockedDomain, err := f.blockedDomain(uri.Host) + requestingAccount, err := f.db.GetAccountByURI(uri.String()) if err != nil { - return false, fmt.Errorf("error checking domain block: %s", err) - } - if blockedDomain { - return true, nil - } - - requestingAccount := >smodel.Account{} - if err := f.db.GetWhere([]db.Where{{Key: "uri", Value: uri.String()}}, requestingAccount); err != nil { - _, ok := err.(db.ErrNoEntries) - if ok { + if err == db.ErrNoEntries { // we don't have an entry for this account so it's not blocked // TODO: allow a different default to be set for this behavior continue @@ -211,12 +208,11 @@ func (f *federator) Blocked(ctx context.Context, actorIRIs []*url.URL) (bool, er return false, fmt.Errorf("error getting account with uri %s: %s", uri.String(), err) } - // check if requested account blocks requesting account - if err := f.db.GetWhere([]db.Where{ - {Key: "account_id", Value: requestedAccount.ID}, - {Key: "target_account_id", Value: requestingAccount.ID}, - }, >smodel.Block{}); err == nil { - // a block exists + blocked, err = f.db.IsBlocked(requestedAccount.ID, requestingAccount.ID, true) + if err != nil { + return false, fmt.Errorf("error checking account block: %s", err) + } + if blocked { return true, nil } } diff --git a/internal/federation/finger.go b/internal/federation/finger.go index 0ffc60e5a..a5a4fa0e7 100644 --- a/internal/federation/finger.go +++ b/internal/federation/finger.go @@ -30,7 +30,7 @@ import ( ) func (f *federator) FingerRemoteAccount(requestingUsername string, targetUsername string, targetDomain string) (*url.URL, error) { - if blocked, err := f.blockedDomain(targetDomain); blocked || err != nil { + if blocked, err := f.db.IsDomainBlocked(targetDomain); blocked || err != nil { return nil, fmt.Errorf("FingerRemoteAccount: domain %s is blocked", targetDomain) } diff --git a/internal/federation/handshake.go b/internal/federation/handshake.go index 47c8a6c84..0671e78a9 100644 --- a/internal/federation/handshake.go +++ b/internal/federation/handshake.go @@ -1,3 +1,21 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + package federation import "net/url" diff --git a/internal/federation/transport.go b/internal/federation/transport.go index ed28749a1..20aee964b 100644 --- a/internal/federation/transport.go +++ b/internal/federation/transport.go @@ -1,3 +1,21 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + package federation import ( diff --git a/internal/federation/util.go b/internal/federation/util.go deleted file mode 100644 index de8654d32..000000000 --- a/internal/federation/util.go +++ /dev/null @@ -1,23 +0,0 @@ -package federation - -import ( - "github.com/superseriousbusiness/gotosocial/internal/db" - "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" -) - -func (f *federator) blockedDomain(host string) (bool, error) { - b := >smodel.DomainBlock{} - err := f.db.GetWhere([]db.Where{{Key: "domain", Value: host, CaseInsensitive: true}}, b) - if err == nil { - // block exists - return true, nil - } - - if _, ok := err.(db.ErrNoEntries); ok { - // there are no entries so there's no block - return false, nil - } - - // there's an actual error - return false, err -} |