diff --git a/internal/db/account.go b/internal/db/account.go index 08777fccc..0e1575f9b 100644 --- a/internal/db/account.go +++ b/internal/db/account.go @@ -38,29 +38,8 @@ type Account interface { // GetLocalAccountByUsername returns an account on this instance by its username. GetLocalAccountByUsername(username string) (*gtsmodel.Account, Error) - // GetAccountFollowRequests returns all follow requests targeting the given account. - GetAccountFollowRequests(accountID string) ([]bbbbbbbbbbbbbbbbgtsmodel.FollowRequest, Error) - - // GetAccountFollows returns a slice of follows owned by the given accountID. - GetAccountFollows(accountID string, following *[]gtsmodel.Follow) Error - - // CountAccountFollowing returns the amount of accounts that the given accountID is following. - CountAccountFollowing(accountID string, localOnly bool) (int, Error) - - // GetAccountFollowers is a shortcut for the common action of fetching a list of accounts that accountID is followed by. - // The given slice 'followers' will be set to the result of the query, whatever it is. - // In case of no entries, a 'no entries' error will be returned - // - // If localOnly is set to true, then only followers from *this instance* will be returned. - GetAccountFollowers(accountID string, followers *[]gtsmodel.Follow, localOnly bool) Error - - // CountAccountFollowers returns the amounts that the given ID is followed by. - CountAccountFollowers(accountID string, localOnly bool) (int, Error) - - // GetAccountFaves is a shortcut for the common action of fetching a list of faves made by the given accountID. - // The given slice 'faves' will be set to the result of the query, whatever it is. - // In case of no entries, a 'no entries' error will be returned - GetAccountFaves(accountID string, faves *[]gtsmodel.StatusFave) Error + // GetAccountFaves fetches faves/likes created by the target accountID. + GetAccountFaves(accountID string) ([]*gtsmodel.StatusFave, Error) // GetAccountStatusesCount is a shortcut for the common action of counting statuses produced by accountID. CountAccountStatuses(accountID string) (int, Error) diff --git a/internal/db/notification.go b/internal/db/notification.go index 576e87825..326f0f149 100644 --- a/internal/db/notification.go +++ b/internal/db/notification.go @@ -23,9 +23,9 @@ import "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" // Notification contains functions for creating and getting notifications. type Notification interface { // GetNotifications returns a slice of notifications that pertain to the given accountID. - // - // Returned notifications will be ordered ID descending (ie., highest/newest to lowest/oldest). + // + // Returned notifications will be ordered ID descending (ie., highest/newest to lowest/oldest). GetNotifications(accountID string, limit int, maxID string, sinceID string) ([]*gtsmodel.Notification, Error) - // GetNotification returns one notification according to its id. - GetNotification(id string) (*gtsmodel.Notification, Error) + // GetNotification returns one notification according to its id. + GetNotification(id string) (*gtsmodel.Notification, Error) } diff --git a/internal/db/pg/account.go b/internal/db/pg/account.go index ea3f1ca23..3889c6601 100644 --- a/internal/db/pg/account.go +++ b/internal/db/pg/account.go @@ -149,74 +149,18 @@ func (a *accountDB) GetLocalAccountByUsername(username string) (*gtsmodel.Accoun return account, err } -func (a *accountDB) GetAccountFollowRequests(accountID string) ([]*gtsmodel.FollowRequest, db.Error) { - followRequests := []*gtsmodel.FollowRequest{} +func (a *accountDB) GetAccountFaves(accountID string) ([]*gtsmodel.StatusFave, db.Error) { + faves := []*gtsmodel.StatusFave{} - q := a.conn. - Model(&followRequests). - Where("target_account_id = ?", accountID)] - - err := processErrorResponse(q.Select()) - - return followRequests, err -} - -func (a *accountDB) GetAccountFollowing(accountID string, following *[]gtsmodel.Follow) db.Error { - if err := a.conn.Model(following).Where("account_id = ?", accountID).Select(); err != nil { + if err := a.conn.Model(&faves). + Where("account_id = ?", accountID). + Select(); err != nil { if err == pg.ErrNoRows { - return nil + return faves, nil } - return err + return nil, err } - return nil -} - -func (a *accountDB) CountAccountFollowing(accountID string, localOnly bool) (int, db.Error) { - return a.conn.Model(&[]*gtsmodel.Follow{}).Where("account_id = ?", accountID).Count() -} - -func (a *accountDB) GetAccountFollowers(accountID string, followers *[]gtsmodel.Follow, localOnly bool) db.Error { - - q := a.conn.Model(followers) - - if localOnly { - // for local accounts let's get where domain is null OR where domain is an empty string, just to be safe - whereGroup := func(q *pg.Query) (*pg.Query, error) { - q = q. - WhereOr("? IS NULL", pg.Ident("a.domain")). - WhereOr("a.domain = ?", "") - return q, nil - } - - q = q.ColumnExpr("follow.*"). - Join("JOIN accounts AS a ON follow.account_id = TEXT(a.id)"). - Where("follow.target_account_id = ?", accountID). - WhereGroup(whereGroup) - } else { - q = q.Where("target_account_id = ?", accountID) - } - - if err := q.Select(); err != nil { - if err == pg.ErrNoRows { - return nil - } - return err - } - return nil -} - -func (a *accountDB) CountAccountFollowers(accountID string, localOnly bool) (int, db.Error) { - return a.conn.Model(&[]*gtsmodel.Follow{}).Where("target_account_id = ?", accountID).Count() -} - -func (a *accountDB) GetAccountFaves(accountID string, faves *[]gtsmodel.StatusFave) db.Error { - if err := a.conn.Model(faves).Where("account_id = ?", accountID).Select(); err != nil { - if err == pg.ErrNoRows { - return nil - } - return err - } - return nil + return faves, nil } func (a *accountDB) CountAccountStatuses(accountID string) (int, db.Error) { diff --git a/internal/db/pg/relationship.go b/internal/db/pg/relationship.go index a9d200f9a..76bd50c76 100644 --- a/internal/db/pg/relationship.go +++ b/internal/db/pg/relationship.go @@ -43,22 +43,22 @@ func (r *relationshipDB) newBlockQ(block *gtsmodel.Block) *orm.Query { Relation("TargetAccount") } -func (r *relationshipDB) processResponse(block *gtsmodel.Block, err error) (*gtsmodel.Block, db.Error) { - switch err { - case pg.ErrNoRows: - return nil, db.ErrNoEntries - case nil: - return block, nil - default: - return nil, err - } +func (r *relationshipDB) newFollowQ(follow interface{}) *orm.Query { + return r.conn.Model(follow). + Relation("Account"). + Relation("TargetAccount") } func (r *relationshipDB) IsBlocked(account1 string, account2 string, eitherDirection bool) (bool, db.Error) { - q := r.conn.Model(>smodel.Block{}).Where("account_id = ?", account1).Where("target_account_id = ?", account2) + q := r.conn. + Model(>smodel.Block{}). + Where("account_id = ?", account1). + Where("target_account_id = ?", account2) if eitherDirection { - q = q.WhereOr("target_account_id = ?", account1).Where("account_id = ?", account2) + q = q. + WhereOr("target_account_id = ?", account1). + Where("account_id = ?", account2) } return q.Exists() @@ -71,7 +71,9 @@ func (r *relationshipDB) GetBlock(account1 string, account2 string) (*gtsmodel.B Where("block.account_id = ?", account1). Where("block.target_account_id = ?", account2) - return r.processResponse(block, q.Select()) + err := processErrorResponse(q.Select()) + + return block, err } func (r *relationshipDB) GetRelationship(requestingAccount string, targetAccount string) (*gtsmodel.Relationship, db.Error) { @@ -133,7 +135,12 @@ func (r *relationshipDB) IsFollowing(sourceAccount *gtsmodel.Account, targetAcco return false, nil } - return r.conn.Model(>smodel.Follow{}).Where("account_id = ?", sourceAccount.ID).Where("target_account_id = ?", targetAccount.ID).Exists() + q := r.conn. + Model(>smodel.Follow{}). + Where("account_id = ?", sourceAccount.ID). + Where("target_account_id = ?", targetAccount.ID) + + return q.Exists() } func (r *relationshipDB) IsFollowRequested(sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, db.Error) { @@ -141,7 +148,12 @@ func (r *relationshipDB) IsFollowRequested(sourceAccount *gtsmodel.Account, targ return false, nil } - return r.conn.Model(>smodel.FollowRequest{}).Where("account_id = ?", sourceAccount.ID).Where("target_account_id = ?", targetAccount.ID).Exists() + q := r.conn. + Model(>smodel.FollowRequest{}). + Where("account_id = ?", sourceAccount.ID). + Where("target_account_id = ?", targetAccount.ID) + + return q.Exists() } func (r *relationshipDB) IsMutualFollowing(account1 *gtsmodel.Account, account2 *gtsmodel.Account) (bool, db.Error) { @@ -150,21 +162,15 @@ func (r *relationshipDB) IsMutualFollowing(account1 *gtsmodel.Account, account2 } // make sure account 1 follows account 2 - f1, err := r.conn.Model(>smodel.Follow{}).Where("account_id = ?", account1.ID).Where("target_account_id = ?", account2.ID).Exists() + f1, err := r.IsFollowing(account1, account2) if err != nil { - if err == pg.ErrNoRows { - return false, nil - } - return false, err + return false, processErrorResponse(err) } // make sure account 2 follows account 1 - f2, err := r.conn.Model(>smodel.Follow{}).Where("account_id = ?", account2.ID).Where("target_account_id = ?", account1.ID).Exists() + f2, err := r.IsFollowing(account2, account1) if err != nil { - if err == pg.ErrNoRows { - return false, nil - } - return false, err + return false, processErrorResponse(err) } return f1 && f2, nil @@ -200,3 +206,71 @@ func (r *relationshipDB) AcceptFollowRequest(originAccountID string, targetAccou return follow, nil } + +func (r *relationshipDB) GetAccountFollowRequests(accountID string) ([]*gtsmodel.FollowRequest, db.Error) { + followRequests := []*gtsmodel.FollowRequest{} + + q := r.newFollowQ(&followRequests). + Where("target_account_id = ?", accountID) + + err := processErrorResponse(q.Select()) + + return followRequests, err +} + +func (r *relationshipDB) GetAccountFollows(accountID string) ([]*gtsmodel.Follow, db.Error) { + follows := []*gtsmodel.Follow{} + + q := r.newFollowQ(&follows). + Where("account_id = ?", accountID) + + err := processErrorResponse(q.Select()) + + return follows, err +} + +func (r *relationshipDB) CountAccountFollows(accountID string, localOnly bool) (int, db.Error) { + return r.conn. + Model(&[]*gtsmodel.Follow{}). + Where("account_id = ?", accountID). + Count() +} + +func (r *relationshipDB) GetAccountFollowedBy(accountID string, localOnly bool) ([]*gtsmodel.Follow, db.Error) { + + follows := []*gtsmodel.Follow{} + + q := r.conn.Model(&follows) + + if localOnly { + // for local accounts let's get where domain is null OR where domain is an empty string, just to be safe + whereGroup := func(q *pg.Query) (*pg.Query, error) { + q = q. + WhereOr("? IS NULL", pg.Ident("a.domain")). + WhereOr("a.domain = ?", "") + return q, nil + } + + q = q.ColumnExpr("follow.*"). + Join("JOIN accounts AS a ON follow.account_id = TEXT(a.id)"). + Where("follow.target_account_id = ?", accountID). + WhereGroup(whereGroup) + } else { + q = q.Where("target_account_id = ?", accountID) + } + + if err := q.Select(); err != nil { + if err == pg.ErrNoRows { + return follows, nil + } + return nil, err + } + return follows, nil +} + +func (r *relationshipDB) CountAccountFollowedBy(accountID string, localOnly bool) (int, db.Error) { + return r.conn. + Model(&[]*gtsmodel.Follow{}). + Where("target_account_id = ?", accountID). + Count() +} diff --git a/internal/db/relationship.go b/internal/db/relationship.go index e54e776d7..85f64d72b 100644 --- a/internal/db/relationship.go +++ b/internal/db/relationship.go @@ -49,4 +49,23 @@ type Relationship interface { // // It will return the newly created follow for further processing. AcceptFollowRequest(originAccountID string, targetAccountID string) (*gtsmodel.Follow, Error) + + // GetAccountFollowRequests returns all follow requests targeting the given account. + GetAccountFollowRequests(accountID string) ([]*gtsmodel.FollowRequest, Error) + + // GetAccountFollows returns a slice of follows owned by the given accountID. + GetAccountFollows(accountID string) ([]*gtsmodel.Follow, Error) + + // CountAccountFollows returns the amount of accounts that the given accountID is following. + // + // If localOnly is set to true, then only follows from *this instance* will be returned. + CountAccountFollows(accountID string, localOnly bool) (int, Error) + + // GetAccountFollowedBy fetches follows that target given accountID. + // + // If localOnly is set to true, then only follows from *this instance* will be returned. + GetAccountFollowedBy(accountID string, localOnly bool) ([]*gtsmodel.Follow, Error) + + // CountAccountFollowedBy returns the amounts that the given ID is followed by. + CountAccountFollowedBy(accountID string, localOnly bool) (int, Error) } 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 . +*/ + package federation import ( 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 . +*/ + 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 . +*/ + package federatingdb import ( diff --git a/internal/federation/federatingdb/delete.go b/internal/federation/federatingdb/delete.go index 4e95c9770..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 . +*/ + package federatingdb import ( 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 . +*/ + package federatingdb import ( diff --git a/internal/federation/federatingdb/followers.go b/internal/federation/federatingdb/followers.go index 9034e90fd..241362fc1 100644 --- a/internal/federation/federatingdb/followers.go +++ b/internal/federation/federatingdb/followers.go @@ -43,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.GetAccountFollowers(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 ac671968d..45785c671 100644 --- a/internal/federation/federatingdb/following.go +++ b/internal/federation/federatingdb/following.go @@ -56,8 +56,8 @@ func (f *federatingDB) Following(c context.Context, actorIRI *url.URL) (followin 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.GetAccountFollows(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/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 . +*/ + 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 . +*/ + package federatingdb import ( diff --git a/internal/federation/federatingdb/outbox.go b/internal/federation/federatingdb/outbox.go index 7985a31d0..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 . +*/ + package federatingdb import ( 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 . +*/ + 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 . +*/ + package federatingdb import ( diff --git a/internal/federation/federatingprotocol.go b/internal/federation/federatingprotocol.go index ee235cd7b..5da68afd3 100644 --- a/internal/federation/federatingprotocol.go +++ b/internal/federation/federatingprotocol.go @@ -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,15 +189,15 @@ 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") } - for _, uri := range actorIRIs { - blockedDomain, err := f.blockedDomain(uri.Host) - if err != nil { - return false, fmt.Errorf("error checking domain block: %s", err) - } - if blockedDomain { - return true, nil - } + 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 { requestingAccount, err := f.db.GetAccountByURI(uri.String()) if err != nil { if err == db.ErrNoEntries { @@ -210,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 . +*/ + 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 . +*/ + package federation import ( diff --git a/internal/federation/util.go b/internal/federation/util.go deleted file mode 100644 index 7971f6172..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 err == db.ErrNoEntries { - // there are no entries so there's no block - return false, nil - } - - // there's an actual error - return false, err -} diff --git a/internal/processing/account/getfollowers.go b/internal/processing/account/getfollowers.go index fd2792471..4f66b40ee 100644 --- a/internal/processing/account/getfollowers.go +++ b/internal/processing/account/getfollowers.go @@ -34,16 +34,16 @@ func (p *processor) FollowersGet(requestingAccount *gtsmodel.Account, targetAcco return nil, gtserror.NewErrorNotFound(fmt.Errorf("block exists between accounts")) } - followers := []gtsmodel.Follow{} accounts := []apimodel.Account{} - if err := p.db.GetAccountFollowers(targetAccountID, &followers, false); err != nil { + follows, err := p.db.GetAccountFollowedBy(targetAccountID, false) + if err != nil { if err == db.ErrNoEntries { return accounts, nil } return nil, gtserror.NewErrorInternalError(err) } - for _, f := range followers { + for _, f := range follows { blocked, err := p.db.IsBlocked(requestingAccount.ID, f.AccountID, true) if err != nil { return nil, gtserror.NewErrorInternalError(err) @@ -52,15 +52,18 @@ func (p *processor) FollowersGet(requestingAccount *gtsmodel.Account, targetAcco continue } - a := >smodel.Account{} - if err := p.db.GetByID(f.AccountID, a); err != nil { - if err == db.ErrNoEntries { - continue + if f.Account == nil { + a, err := p.db.GetAccountByID(f.AccountID) + if err != nil { + if err == db.ErrNoEntries { + continue + } + return nil, gtserror.NewErrorInternalError(err) } - return nil, gtserror.NewErrorInternalError(err) + f.Account = a } - account, err := p.tc.AccountToMastoPublic(a) + account, err := p.tc.AccountToMastoPublic(f.Account) if err != nil { return nil, gtserror.NewErrorInternalError(err) } diff --git a/internal/processing/account/getfollowing.go b/internal/processing/account/getfollowing.go index 69f0c1d8a..c7fb426f9 100644 --- a/internal/processing/account/getfollowing.go +++ b/internal/processing/account/getfollowing.go @@ -34,16 +34,16 @@ func (p *processor) FollowingGet(requestingAccount *gtsmodel.Account, targetAcco return nil, gtserror.NewErrorNotFound(fmt.Errorf("block exists between accounts")) } - following := []gtsmodel.Follow{} accounts := []apimodel.Account{} - if err := p.db.GetAccountFollows(targetAccountID, &following); err != nil { + follows, err := p.db.GetAccountFollows(targetAccountID) + if err != nil { if err == db.ErrNoEntries { return accounts, nil } return nil, gtserror.NewErrorInternalError(err) } - for _, f := range following { + for _, f := range follows { blocked, err := p.db.IsBlocked(requestingAccount.ID, f.AccountID, true) if err != nil { return nil, gtserror.NewErrorInternalError(err) @@ -52,15 +52,18 @@ func (p *processor) FollowingGet(requestingAccount *gtsmodel.Account, targetAcco continue } - a := >smodel.Account{} - if err := p.db.GetByID(f.TargetAccountID, a); err != nil { - if err == db.ErrNoEntries { - continue + if f.TargetAccount == nil { + a, err := p.db.GetAccountByID(f.TargetAccountID) + if err != nil { + if err == db.ErrNoEntries { + continue + } + return nil, gtserror.NewErrorInternalError(err) } - return nil, gtserror.NewErrorInternalError(err) + f.TargetAccount = a } - account, err := p.tc.AccountToMastoPublic(a) + account, err := p.tc.AccountToMastoPublic(f.TargetAccount) if err != nil { return nil, gtserror.NewErrorInternalError(err) } diff --git a/internal/processing/fromcommon.go b/internal/processing/fromcommon.go index 82f80a479..2c2635175 100644 --- a/internal/processing/fromcommon.go +++ b/internal/processing/fromcommon.go @@ -320,23 +320,24 @@ func (p *processor) timelineStatus(status *gtsmodel.Status) error { } // get local followers of the account that posted the status - followers := []gtsmodel.Follow{} - if err := p.db.GetAccountFollowers(status.AccountID, &followers, true); err != nil { + follows, err := p.db.GetAccountFollowedBy(status.AccountID, true) + if err != nil { return fmt.Errorf("timelineStatus: error getting followers for account id %s: %s", status.AccountID, err) } // if the poster is local, add a fake entry for them to the followers list so they can see their own status in their timeline if status.Account.Domain == "" { - followers = append(followers, gtsmodel.Follow{ + follows = append(follows, >smodel.Follow{ AccountID: status.AccountID, + Account: status.Account, }) } wg := sync.WaitGroup{} - wg.Add(len(followers)) - errors := make(chan error, len(followers)) + wg.Add(len(follows)) + errors := make(chan error, len(follows)) - for _, f := range followers { + for _, f := range follows { go p.timelineStatusForAccount(status, f.AccountID, errors, &wg) } diff --git a/internal/processing/streaming.go b/internal/processing/streaming.go index 1e566da81..457db0576 100644 --- a/internal/processing/streaming.go +++ b/internal/processing/streaming.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 . +*/ + package processing import ( diff --git a/internal/typeutils/internaltofrontend.go b/internal/typeutils/internaltofrontend.go index cedd6c3d8..caa14e211 100644 --- a/internal/typeutils/internaltofrontend.go +++ b/internal/typeutils/internaltofrontend.go @@ -43,7 +43,7 @@ func (c *converter) AccountToMastoSensitive(a *gtsmodel.Account) (*model.Account if err != db.ErrNoEntries { return nil, fmt.Errorf("error getting follow requests: %s", err) } - } + } var frc int if frs != nil { frc = len(frs) @@ -71,13 +71,13 @@ func (c *converter) AccountToMastoPublic(a *gtsmodel.Account) (*model.Account, e } // count followers - followersCount, err := c.db.CountAccountFollowers(a.ID, false) + followersCount, err := c.db.CountAccountFollowedBy(a.ID, false) if err != nil { return nil, fmt.Errorf("error counting followers: %s", err) } // count following - followingCount, err := c.db.CountAccountFollowing(a.ID, false) + followingCount, err := c.db.CountAccountFollows(a.ID, false) if err != nil { return nil, fmt.Errorf("error counting following: %s", err) }