mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-12-25 08:30:29 +00:00
[chore] de-interface{} the federator and dereferencer structs (#2285)
* de-interface{} the federator and dereferencer structs * fix broken type signatures
This commit is contained in:
parent
3dcc94940d
commit
69ba9a79a1
55 changed files with 151 additions and 199 deletions
|
@ -45,7 +45,7 @@ type EmojiGetTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
tc *typeutils.Converter
|
tc *typeutils.Converter
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
|
|
|
@ -41,7 +41,7 @@ type UserStandardTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
tc *typeutils.Converter
|
tc *typeutils.Converter
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
|
|
|
@ -47,7 +47,7 @@ type AuthStandardTestSuite struct {
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
state state.State
|
state state.State
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
idp oidc.IDP
|
idp oidc.IDP
|
||||||
|
|
|
@ -47,7 +47,7 @@ type AccountStandardTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
sentEmails map[string]string
|
sentEmails map[string]string
|
||||||
|
|
|
@ -47,7 +47,7 @@ type AdminStandardTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
sentEmails map[string]string
|
sentEmails map[string]string
|
||||||
|
|
|
@ -52,7 +52,7 @@ type BookmarkTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
tc *typeutils.Converter
|
tc *typeutils.Converter
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
|
|
|
@ -39,7 +39,7 @@ type FavouritesStandardTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
tc *typeutils.Converter
|
tc *typeutils.Converter
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
|
|
|
@ -45,7 +45,7 @@ type FollowRequestStandardTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
state state.State
|
state state.State
|
||||||
|
|
|
@ -46,7 +46,7 @@ type InstanceStandardTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
sentEmails map[string]string
|
sentEmails map[string]string
|
||||||
|
|
|
@ -39,7 +39,7 @@ type ListsStandardTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
state state.State
|
state state.State
|
||||||
|
|
|
@ -55,7 +55,7 @@ type MediaCreateTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
tc *typeutils.Converter
|
tc *typeutils.Converter
|
||||||
oauthServer oauth.Server
|
oauthServer oauth.Server
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
|
|
|
@ -51,7 +51,7 @@ type MediaUpdateTestSuite struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
db db.DB
|
db db.DB
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
tc *typeutils.Converter
|
tc *typeutils.Converter
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
oauthServer oauth.Server
|
oauthServer oauth.Server
|
||||||
|
|
|
@ -38,7 +38,7 @@ type ReportsStandardTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
sentEmails map[string]string
|
sentEmails map[string]string
|
||||||
|
|
|
@ -46,7 +46,7 @@ type SearchStandardTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
sentEmails map[string]string
|
sentEmails map[string]string
|
||||||
|
|
|
@ -39,7 +39,7 @@ type StatusStandardTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
tc *typeutils.Converter
|
tc *typeutils.Converter
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
|
|
|
@ -51,7 +51,7 @@ type StreamingTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
tc *typeutils.Converter
|
tc *typeutils.Converter
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
|
|
|
@ -38,7 +38,7 @@ type UserStandardTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
tc *typeutils.Converter
|
tc *typeutils.Converter
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
|
|
|
@ -41,7 +41,7 @@ type FileserverTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
state state.State
|
state state.State
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
tc *typeutils.Converter
|
tc *typeutils.Converter
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
|
|
|
@ -41,7 +41,7 @@ type WebfingerStandardTestSuite struct {
|
||||||
state state.State
|
state state.State
|
||||||
tc *typeutils.Converter
|
tc *typeutils.Converter
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
|
|
|
@ -109,7 +109,7 @@ type PubKeyAuth struct {
|
||||||
// Also note that this function *does not* dereference the remote account that
|
// Also note that this function *does not* dereference the remote account that
|
||||||
// the signature key is associated with. Other functions should use the returned
|
// the signature key is associated with. Other functions should use the returned
|
||||||
// URL to dereference the remote account, if required.
|
// URL to dereference the remote account, if required.
|
||||||
func (f *federator) AuthenticateFederatedRequest(ctx context.Context, requestedUsername string) (*PubKeyAuth, gtserror.WithCode) {
|
func (f *Federator) AuthenticateFederatedRequest(ctx context.Context, requestedUsername string) (*PubKeyAuth, gtserror.WithCode) {
|
||||||
// Thanks to the signature check middleware,
|
// Thanks to the signature check middleware,
|
||||||
// we should already have an http signature
|
// we should already have an http signature
|
||||||
// verifier set on the context. If we don't,
|
// verifier set on the context. If we don't,
|
||||||
|
@ -215,7 +215,7 @@ func (f *federator) AuthenticateFederatedRequest(ctx context.Context, requestedU
|
||||||
//
|
//
|
||||||
// In case an entry for the pubKey owner just doesn't
|
// In case an entry for the pubKey owner just doesn't
|
||||||
// exist in the db (yet), will return nil, nil.
|
// exist in the db (yet), will return nil, nil.
|
||||||
func (f *federator) derefPubKeyDBOnly(
|
func (f *Federator) derefPubKeyDBOnly(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
pubKeyIDStr string,
|
pubKeyIDStr string,
|
||||||
) (*PubKeyAuth, gtserror.WithCode) {
|
) (*PubKeyAuth, gtserror.WithCode) {
|
||||||
|
@ -248,7 +248,7 @@ func (f *federator) derefPubKeyDBOnly(
|
||||||
// checking in the database, and then (if no entry found, or entry
|
// checking in the database, and then (if no entry found, or entry
|
||||||
// found but pubKey expired) calling the remote pub key URI and
|
// found but pubKey expired) calling the remote pub key URI and
|
||||||
// extracting the key.
|
// extracting the key.
|
||||||
func (f *federator) derefPubKey(
|
func (f *Federator) derefPubKey(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
requestedUsername string,
|
requestedUsername string,
|
||||||
pubKeyIDStr string,
|
pubKeyIDStr string,
|
||||||
|
@ -363,7 +363,7 @@ func (f *federator) derefPubKey(
|
||||||
// callForPubKey handles the nitty gritty of actually
|
// callForPubKey handles the nitty gritty of actually
|
||||||
// making a request for the given pubKeyID with a
|
// making a request for the given pubKeyID with a
|
||||||
// transport created on behalf of requestedUsername.
|
// transport created on behalf of requestedUsername.
|
||||||
func (f *federator) callForPubKey(
|
func (f *Federator) callForPubKey(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
requestedUsername string,
|
requestedUsername string,
|
||||||
pubKeyID *url.URL,
|
pubKeyID *url.URL,
|
||||||
|
|
|
@ -51,7 +51,7 @@ import (
|
||||||
// Finally, if the authentication and authorization succeeds, then
|
// Finally, if the authentication and authorization succeeds, then
|
||||||
// authenticated must be true and error nil. The request will continue
|
// authenticated must be true and error nil. The request will continue
|
||||||
// to be processed.
|
// to be processed.
|
||||||
func (f *federator) AuthenticateGetInbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool, error) {
|
func (f *Federator) AuthenticateGetInbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool, error) {
|
||||||
// IMPLEMENTATION NOTE: For GoToSocial, we serve GETS to outboxes and inboxes through
|
// IMPLEMENTATION NOTE: For GoToSocial, we serve GETS to outboxes and inboxes through
|
||||||
// the CLIENT API, not through the federation API, so we just do nothing here.
|
// the CLIENT API, not through the federation API, so we just do nothing here.
|
||||||
return ctx, false, nil
|
return ctx, false, nil
|
||||||
|
@ -76,7 +76,7 @@ func (f *federator) AuthenticateGetInbox(ctx context.Context, w http.ResponseWri
|
||||||
// Finally, if the authentication and authorization succeeds, then
|
// Finally, if the authentication and authorization succeeds, then
|
||||||
// authenticated must be true and error nil. The request will continue
|
// authenticated must be true and error nil. The request will continue
|
||||||
// to be processed.
|
// to be processed.
|
||||||
func (f *federator) AuthenticateGetOutbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool, error) {
|
func (f *Federator) AuthenticateGetOutbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool, error) {
|
||||||
// IMPLEMENTATION NOTE: For GoToSocial, we serve GETS to outboxes and inboxes through
|
// IMPLEMENTATION NOTE: For GoToSocial, we serve GETS to outboxes and inboxes through
|
||||||
// the CLIENT API, not through the federation API, so we just do nothing here.
|
// the CLIENT API, not through the federation API, so we just do nothing here.
|
||||||
return ctx, false, nil
|
return ctx, false, nil
|
||||||
|
@ -90,7 +90,7 @@ func (f *federator) AuthenticateGetOutbox(ctx context.Context, w http.ResponseWr
|
||||||
//
|
//
|
||||||
// Always called, regardless whether the Federated Protocol or Social
|
// Always called, regardless whether the Federated Protocol or Social
|
||||||
// API is enabled.
|
// API is enabled.
|
||||||
func (f *federator) GetOutbox(ctx context.Context, r *http.Request) (vocab.ActivityStreamsOrderedCollectionPage, error) {
|
func (f *Federator) GetOutbox(ctx context.Context, r *http.Request) (vocab.ActivityStreamsOrderedCollectionPage, error) {
|
||||||
// IMPLEMENTATION NOTE: For GoToSocial, we serve GETS to outboxes and inboxes through
|
// IMPLEMENTATION NOTE: For GoToSocial, we serve GETS to outboxes and inboxes through
|
||||||
// the CLIENT API, not through the federation API, so we just do nothing here.
|
// the CLIENT API, not through the federation API, so we just do nothing here.
|
||||||
return streams.NewActivityStreamsOrderedCollectionPage(), nil
|
return streams.NewActivityStreamsOrderedCollectionPage(), nil
|
||||||
|
|
|
@ -60,8 +60,10 @@ func accountUpToDate(account *gtsmodel.Account) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccountByURI: implements Dereferencer{}.GetAccountByURI.
|
// GetAccountByURI will attempt to fetch an accounts by its URI, first checking the database. In the case of a newly-met remote model, or a remote model
|
||||||
func (d *deref) GetAccountByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Account, ap.Accountable, error) {
|
// whose last_fetched date is beyond a certain interval, the account will be dereferenced. In the case of dereferencing, some low-priority account information
|
||||||
|
// may be enqueued for asynchronous fetching, e.g. featured account statuses (pins). An ActivityPub object indicates the account was dereferenced.
|
||||||
|
func (d *Dereferencer) GetAccountByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Account, ap.Accountable, error) {
|
||||||
// Fetch and dereference account if necessary.
|
// Fetch and dereference account if necessary.
|
||||||
account, apubAcc, err := d.getAccountByURI(ctx,
|
account, apubAcc, err := d.getAccountByURI(ctx,
|
||||||
requestUser,
|
requestUser,
|
||||||
|
@ -84,7 +86,7 @@ func (d *deref) GetAccountByURI(ctx context.Context, requestUser string, uri *ur
|
||||||
}
|
}
|
||||||
|
|
||||||
// getAccountByURI is a package internal form of .GetAccountByURI() that doesn't bother dereferencing featured posts on update.
|
// getAccountByURI is a package internal form of .GetAccountByURI() that doesn't bother dereferencing featured posts on update.
|
||||||
func (d *deref) getAccountByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Account, ap.Accountable, error) {
|
func (d *Dereferencer) getAccountByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Account, ap.Accountable, error) {
|
||||||
var (
|
var (
|
||||||
account *gtsmodel.Account
|
account *gtsmodel.Account
|
||||||
uriStr = uri.String()
|
uriStr = uri.String()
|
||||||
|
@ -157,8 +159,10 @@ func (d *deref) getAccountByURI(ctx context.Context, requestUser string, uri *ur
|
||||||
return latest, apubAcc, nil
|
return latest, apubAcc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccountByUsernameDomain: implements Dereferencer{}.GetAccountByUsernameDomain.
|
// GetAccountByUsernameDomain will attempt to fetch an accounts by its username@domain, first checking the database. In the case of a newly-met remote model,
|
||||||
func (d *deref) GetAccountByUsernameDomain(ctx context.Context, requestUser string, username string, domain string) (*gtsmodel.Account, ap.Accountable, error) {
|
// or a remote model whose last_fetched date is beyond a certain interval, the account will be dereferenced. In the case of dereferencing, some low-priority
|
||||||
|
// account information may be enqueued for asynchronous fetching, e.g. featured account statuses (pins). An ActivityPub object indicates the account was dereferenced.
|
||||||
|
func (d *Dereferencer) GetAccountByUsernameDomain(ctx context.Context, requestUser string, username string, domain string) (*gtsmodel.Account, ap.Accountable, error) {
|
||||||
if domain == config.GetHost() || domain == config.GetAccountDomain() {
|
if domain == config.GetHost() || domain == config.GetAccountDomain() {
|
||||||
// We do local lookups using an empty domain,
|
// We do local lookups using an empty domain,
|
||||||
// else it will fail the db search below.
|
// else it will fail the db search below.
|
||||||
|
@ -224,8 +228,10 @@ func (d *deref) GetAccountByUsernameDomain(ctx context.Context, requestUser stri
|
||||||
return latest, apubAcc, nil
|
return latest, apubAcc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefreshAccount: implements Dereferencer{}.RefreshAccount.
|
// RefreshAccount updates the given account if remote and last_fetched is beyond fetch interval, or if force is set. An updated account model is returned,
|
||||||
func (d *deref) RefreshAccount(ctx context.Context, requestUser string, account *gtsmodel.Account, apubAcc ap.Accountable, force bool) (*gtsmodel.Account, ap.Accountable, error) {
|
// but in the case of dereferencing, some low-priority account information may be enqueued for asynchronous fetching, e.g. featured account statuses (pins).
|
||||||
|
// An ActivityPub object indicates the account was dereferenced (i.e. updated).
|
||||||
|
func (d *Dereferencer) RefreshAccount(ctx context.Context, requestUser string, account *gtsmodel.Account, apubAcc ap.Accountable, force bool) (*gtsmodel.Account, ap.Accountable, error) {
|
||||||
// Check whether needs update (and not forced).
|
// Check whether needs update (and not forced).
|
||||||
if accountUpToDate(account) && !force {
|
if accountUpToDate(account) && !force {
|
||||||
return account, nil, nil
|
return account, nil, nil
|
||||||
|
@ -264,8 +270,9 @@ func (d *deref) RefreshAccount(ctx context.Context, requestUser string, account
|
||||||
return latest, apubAcc, nil
|
return latest, apubAcc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefreshAccountAsync: implements Dereferencer{}.RefreshAccountAsync.
|
// RefreshAccountAsync enqueues the given account for an asychronous update fetching, if last_fetched is beyond fetch interval, or if forcc is set.
|
||||||
func (d *deref) RefreshAccountAsync(ctx context.Context, requestUser string, account *gtsmodel.Account, apubAcc ap.Accountable, force bool) {
|
// This is a more optimized form of manually enqueueing .UpdateAccount() to the federation worker, since it only enqueues update if necessary.
|
||||||
|
func (d *Dereferencer) RefreshAccountAsync(ctx context.Context, requestUser string, account *gtsmodel.Account, apubAcc ap.Accountable, force bool) {
|
||||||
// Check whether needs update (and not forced).
|
// Check whether needs update (and not forced).
|
||||||
if accountUpToDate(account) && !force {
|
if accountUpToDate(account) && !force {
|
||||||
return
|
return
|
||||||
|
@ -294,7 +301,7 @@ func (d *deref) RefreshAccountAsync(ctx context.Context, requestUser string, acc
|
||||||
}
|
}
|
||||||
|
|
||||||
// enrichAccount will enrich the given account, whether a new barebones model, or existing model from the database. It handles necessary dereferencing, webfingering etc.
|
// enrichAccount will enrich the given account, whether a new barebones model, or existing model from the database. It handles necessary dereferencing, webfingering etc.
|
||||||
func (d *deref) enrichAccount(ctx context.Context, requestUser string, uri *url.URL, account *gtsmodel.Account, apubAcc ap.Accountable) (*gtsmodel.Account, ap.Accountable, error) {
|
func (d *Dereferencer) enrichAccount(ctx context.Context, requestUser string, uri *url.URL, account *gtsmodel.Account, apubAcc ap.Accountable) (*gtsmodel.Account, ap.Accountable, error) {
|
||||||
// Pre-fetch a transport for requesting username, used by later deref procedures.
|
// Pre-fetch a transport for requesting username, used by later deref procedures.
|
||||||
tsport, err := d.transportController.NewTransportForUsername(ctx, requestUser)
|
tsport, err := d.transportController.NewTransportForUsername(ctx, requestUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -472,7 +479,7 @@ func (d *deref) enrichAccount(ctx context.Context, requestUser string, uri *url.
|
||||||
return latestAcc, apubAcc, nil
|
return latestAcc, apubAcc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deref) fetchRemoteAccountAvatar(ctx context.Context, tsport transport.Transport, existing, latestAcc *gtsmodel.Account) error {
|
func (d *Dereferencer) fetchRemoteAccountAvatar(ctx context.Context, tsport transport.Transport, existing, latestAcc *gtsmodel.Account) error {
|
||||||
if latestAcc.AvatarRemoteURL == "" {
|
if latestAcc.AvatarRemoteURL == "" {
|
||||||
// No avatar set on newest model, leave
|
// No avatar set on newest model, leave
|
||||||
// latest avatar attachment ID empty.
|
// latest avatar attachment ID empty.
|
||||||
|
@ -562,7 +569,7 @@ func (d *deref) fetchRemoteAccountAvatar(ctx context.Context, tsport transport.T
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deref) fetchRemoteAccountHeader(ctx context.Context, tsport transport.Transport, existing, latestAcc *gtsmodel.Account) error {
|
func (d *Dereferencer) fetchRemoteAccountHeader(ctx context.Context, tsport transport.Transport, existing, latestAcc *gtsmodel.Account) error {
|
||||||
if latestAcc.HeaderRemoteURL == "" {
|
if latestAcc.HeaderRemoteURL == "" {
|
||||||
// No header set on newest model, leave
|
// No header set on newest model, leave
|
||||||
// latest header attachment ID empty.
|
// latest header attachment ID empty.
|
||||||
|
@ -652,7 +659,7 @@ func (d *deref) fetchRemoteAccountHeader(ctx context.Context, tsport transport.T
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deref) fetchRemoteAccountEmojis(ctx context.Context, targetAccount *gtsmodel.Account, requestingUsername string) (bool, error) {
|
func (d *Dereferencer) fetchRemoteAccountEmojis(ctx context.Context, targetAccount *gtsmodel.Account, requestingUsername string) (bool, error) {
|
||||||
maybeEmojis := targetAccount.Emojis
|
maybeEmojis := targetAccount.Emojis
|
||||||
maybeEmojiIDs := targetAccount.EmojiIDs
|
maybeEmojiIDs := targetAccount.EmojiIDs
|
||||||
|
|
||||||
|
@ -766,7 +773,7 @@ func (d *deref) fetchRemoteAccountEmojis(ctx context.Context, targetAccount *gts
|
||||||
|
|
||||||
// dereferenceAccountFeatured dereferences an account's featuredCollectionURI (if not empty). For each discovered status, this status will
|
// dereferenceAccountFeatured dereferences an account's featuredCollectionURI (if not empty). For each discovered status, this status will
|
||||||
// be dereferenced (if necessary) and marked as pinned (if necessary). Then, old pins will be removed if they're not included in new pins.
|
// be dereferenced (if necessary) and marked as pinned (if necessary). Then, old pins will be removed if they're not included in new pins.
|
||||||
func (d *deref) dereferenceAccountFeatured(ctx context.Context, requestUser string, account *gtsmodel.Account) error {
|
func (d *Dereferencer) dereferenceAccountFeatured(ctx context.Context, requestUser string, account *gtsmodel.Account) error {
|
||||||
uri, err := url.Parse(account.FeaturedCollectionURI)
|
uri, err := url.Parse(account.FeaturedCollectionURI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -27,7 +27,7 @@ import (
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *deref) DereferenceAnnounce(ctx context.Context, announce *gtsmodel.Status, requestingUsername string) error {
|
func (d *Dereferencer) DereferenceAnnounce(ctx context.Context, announce *gtsmodel.Status, requestingUsername string) error {
|
||||||
if announce.BoostOf == nil {
|
if announce.BoostOf == nil {
|
||||||
// we can't do anything unfortunately
|
// we can't do anything unfortunately
|
||||||
return errors.New("DereferenceAnnounce: no URI to dereference")
|
return errors.New("DereferenceAnnounce: no URI to dereference")
|
||||||
|
|
|
@ -30,7 +30,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// dereferenceCollectionPage returns the activitystreams CollectionPage at the specified IRI, or an error if something goes wrong.
|
// dereferenceCollectionPage returns the activitystreams CollectionPage at the specified IRI, or an error if something goes wrong.
|
||||||
func (d *deref) dereferenceCollectionPage(ctx context.Context, username string, pageIRI *url.URL) (ap.CollectionPageIterator, error) {
|
func (d *Dereferencer) dereferenceCollectionPage(ctx context.Context, username string, pageIRI *url.URL) (ap.CollectionPageIterator, error) {
|
||||||
if blocked, err := d.state.DB.IsDomainBlocked(ctx, pageIRI.Host); blocked || err != nil {
|
if blocked, err := d.state.DB.IsDomainBlocked(ctx, pageIRI.Host); blocked || err != nil {
|
||||||
return nil, gtserror.Newf("domain %s is blocked", pageIRI.Host)
|
return nil, gtserror.Newf("domain %s is blocked", pageIRI.Host)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,72 +18,19 @@
|
||||||
package dereferencing
|
package dereferencing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"codeberg.org/gruf/go-mutexes"
|
"codeberg.org/gruf/go-mutexes"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/ap"
|
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/media"
|
"github.com/superseriousbusiness/gotosocial/internal/media"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/state"
|
"github.com/superseriousbusiness/gotosocial/internal/state"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/transport"
|
"github.com/superseriousbusiness/gotosocial/internal/transport"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
|
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Dereferencer wraps logic and functionality for doing dereferencing of remote accounts, statuses, etc, from federated instances.
|
// Dereferencer wraps logic and functionality for doing dereferencing
|
||||||
type Dereferencer interface {
|
// of remote accounts, statuses, etc, from federated instances.
|
||||||
// GetAccountByURI will attempt to fetch an accounts by its URI, first checking the database. In the case of a newly-met remote model, or a remote model
|
type Dereferencer struct {
|
||||||
// whose last_fetched date is beyond a certain interval, the account will be dereferenced. In the case of dereferencing, some low-priority account information
|
|
||||||
// may be enqueued for asynchronous fetching, e.g. featured account statuses (pins). An ActivityPub object indicates the account was dereferenced.
|
|
||||||
GetAccountByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Account, ap.Accountable, error)
|
|
||||||
|
|
||||||
// GetAccountByUsernameDomain will attempt to fetch an accounts by its username@domain, first checking the database. In the case of a newly-met remote model,
|
|
||||||
// or a remote model whose last_fetched date is beyond a certain interval, the account will be dereferenced. In the case of dereferencing, some low-priority
|
|
||||||
// account information may be enqueued for asynchronous fetching, e.g. featured account statuses (pins). An ActivityPub object indicates the account was dereferenced.
|
|
||||||
GetAccountByUsernameDomain(ctx context.Context, requestUser string, username string, domain string) (*gtsmodel.Account, ap.Accountable, error)
|
|
||||||
|
|
||||||
// RefreshAccount updates the given account if remote and last_fetched is beyond fetch interval, or if force is set. An updated account model is returned,
|
|
||||||
// but in the case of dereferencing, some low-priority account information may be enqueued for asynchronous fetching, e.g. featured account statuses (pins).
|
|
||||||
// An ActivityPub object indicates the account was dereferenced (i.e. updated).
|
|
||||||
RefreshAccount(ctx context.Context, requestUser string, account *gtsmodel.Account, apubAcc ap.Accountable, force bool) (*gtsmodel.Account, ap.Accountable, error)
|
|
||||||
|
|
||||||
// RefreshAccountAsync enqueues the given account for an asychronous update fetching, if last_fetched is beyond fetch interval, or if forcc is set.
|
|
||||||
// This is a more optimized form of manually enqueueing .UpdateAccount() to the federation worker, since it only enqueues update if necessary.
|
|
||||||
RefreshAccountAsync(ctx context.Context, requestUser string, account *gtsmodel.Account, apubAcc ap.Accountable, force bool)
|
|
||||||
|
|
||||||
// GetStatusByURI will attempt to fetch a status by its URI, first checking the database. In the case of a newly-met remote model, or a remote model
|
|
||||||
// whose last_fetched date is beyond a certain interval, the status will be dereferenced. In the case of dereferencing, some low-priority status information
|
|
||||||
// may be enqueued for asynchronous fetching, e.g. dereferencing the remainder of the status thread. An ActivityPub object indicates the status was dereferenced.
|
|
||||||
GetStatusByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Status, ap.Statusable, error)
|
|
||||||
|
|
||||||
// RefreshStatus updates the given status if remote and last_fetched is beyond fetch interval, or if force is set. An updated status model is returned,
|
|
||||||
// but in the case of dereferencing, some low-priority status information may be enqueued for asynchronous fetching, e.g. dereferencing the remainder of the
|
|
||||||
// status thread. An ActivityPub object indicates the status was dereferenced (i.e. updated).
|
|
||||||
RefreshStatus(ctx context.Context, requestUser string, status *gtsmodel.Status, apubStatus ap.Statusable, force bool) (*gtsmodel.Status, ap.Statusable, error)
|
|
||||||
|
|
||||||
// RefreshStatusAsync enqueues the given status for an asychronous update fetching, if last_fetched is beyond fetch interval, or if force is set.
|
|
||||||
// This is a more optimized form of manually enqueueing .UpdateStatus() to the federation worker, since it only enqueues update if necessary.
|
|
||||||
RefreshStatusAsync(ctx context.Context, requestUser string, status *gtsmodel.Status, apubStatus ap.Statusable, force bool)
|
|
||||||
|
|
||||||
// DereferenceStatusAncestors iterates upwards from the given status, using InReplyToURI, to ensure that as many parent statuses as possible are dereferenced.
|
|
||||||
DereferenceStatusAncestors(ctx context.Context, requestUser string, status *gtsmodel.Status) error
|
|
||||||
|
|
||||||
// DereferenceStatusDescendents iterates downwards from the given status, using its replies, to ensure that as many children statuses as possible are dereferenced.
|
|
||||||
DereferenceStatusDescendants(ctx context.Context, requestUser string, statusIRI *url.URL, parent ap.Statusable) error
|
|
||||||
|
|
||||||
GetRemoteInstance(ctx context.Context, username string, remoteInstanceURI *url.URL) (*gtsmodel.Instance, error)
|
|
||||||
|
|
||||||
DereferenceAnnounce(ctx context.Context, announce *gtsmodel.Status, requestingUsername string) error
|
|
||||||
|
|
||||||
GetRemoteMedia(ctx context.Context, requestingUsername string, accountID string, remoteURL string, ai *media.AdditionalMediaInfo) (*media.ProcessingMedia, error)
|
|
||||||
|
|
||||||
GetRemoteEmoji(ctx context.Context, requestingUsername string, remoteURL string, shortcode string, domain string, id string, emojiURI string, ai *media.AdditionalEmojiInfo, refresh bool) (*media.ProcessingEmoji, error)
|
|
||||||
|
|
||||||
Handshaking(username string, remoteAccountID *url.URL) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type deref struct {
|
|
||||||
state *state.State
|
state *state.State
|
||||||
converter *typeutils.Converter
|
converter *typeutils.Converter
|
||||||
transportController transport.Controller
|
transportController transport.Controller
|
||||||
|
@ -99,8 +46,13 @@ type deref struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDereferencer returns a Dereferencer initialized with the given parameters.
|
// NewDereferencer returns a Dereferencer initialized with the given parameters.
|
||||||
func NewDereferencer(state *state.State, converter *typeutils.Converter, transportController transport.Controller, mediaManager *media.Manager) Dereferencer {
|
func NewDereferencer(
|
||||||
return &deref{
|
state *state.State,
|
||||||
|
converter *typeutils.Converter,
|
||||||
|
transportController transport.Controller,
|
||||||
|
mediaManager *media.Manager,
|
||||||
|
) Dereferencer {
|
||||||
|
return Dereferencer{
|
||||||
state: state,
|
state: state,
|
||||||
converter: converter,
|
converter: converter,
|
||||||
transportController: transportController,
|
transportController: transportController,
|
||||||
|
|
|
@ -30,7 +30,7 @@ import (
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/media"
|
"github.com/superseriousbusiness/gotosocial/internal/media"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *deref) GetRemoteEmoji(ctx context.Context, requestingUsername string, remoteURL string, shortcode string, domain string, id string, emojiURI string, ai *media.AdditionalEmojiInfo, refresh bool) (*media.ProcessingEmoji, error) {
|
func (d *Dereferencer) GetRemoteEmoji(ctx context.Context, requestingUsername string, remoteURL string, shortcode string, domain string, id string, emojiURI string, ai *media.AdditionalEmojiInfo, refresh bool) (*media.ProcessingEmoji, error) {
|
||||||
var (
|
var (
|
||||||
shortcodeDomain = shortcode + "@" + domain
|
shortcodeDomain = shortcode + "@" + domain
|
||||||
processingEmoji *media.ProcessingEmoji
|
processingEmoji *media.ProcessingEmoji
|
||||||
|
@ -88,7 +88,7 @@ func (d *deref) GetRemoteEmoji(ctx context.Context, requestingUsername string, r
|
||||||
return processingEmoji, nil
|
return processingEmoji, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deref) populateEmojis(ctx context.Context, rawEmojis []*gtsmodel.Emoji, requestingUsername string) ([]*gtsmodel.Emoji, error) {
|
func (d *Dereferencer) populateEmojis(ctx context.Context, rawEmojis []*gtsmodel.Emoji, requestingUsername string) ([]*gtsmodel.Emoji, error) {
|
||||||
// At this point we should know:
|
// At this point we should know:
|
||||||
// * the AP uri of the emoji
|
// * the AP uri of the emoji
|
||||||
// * the domain of the emoji
|
// * the domain of the emoji
|
||||||
|
|
|
@ -30,7 +30,7 @@ import (
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/util"
|
"github.com/superseriousbusiness/gotosocial/internal/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *deref) fingerRemoteAccount(ctx context.Context, transport transport.Transport, targetUsername string, targetHost string) (accountDomain string, accountURI *url.URL, err error) {
|
func (d *Dereferencer) fingerRemoteAccount(ctx context.Context, transport transport.Transport, targetUsername string, targetHost string) (accountDomain string, accountURI *url.URL, err error) {
|
||||||
b, err := transport.Finger(ctx, targetUsername, targetHost)
|
b, err := transport.Finger(ctx, targetUsername, targetHost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("fingerRemoteAccount: error fingering @%s@%s: %s", targetUsername, targetHost, err)
|
err = fmt.Errorf("fingerRemoteAccount: error fingering @%s@%s: %s", targetUsername, targetHost, err)
|
||||||
|
|
|
@ -21,7 +21,7 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *deref) Handshaking(username string, remoteAccountID *url.URL) bool {
|
func (d *Dereferencer) Handshaking(username string, remoteAccountID *url.URL) bool {
|
||||||
d.handshakesMu.Lock()
|
d.handshakesMu.Lock()
|
||||||
defer d.handshakesMu.Unlock()
|
defer d.handshakesMu.Unlock()
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ func (d *deref) Handshaking(username string, remoteAccountID *url.URL) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deref) startHandshake(username string, remoteAccountID *url.URL) {
|
func (d *Dereferencer) startHandshake(username string, remoteAccountID *url.URL) {
|
||||||
d.handshakesMu.Lock()
|
d.handshakesMu.Lock()
|
||||||
defer d.handshakesMu.Unlock()
|
defer d.handshakesMu.Unlock()
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ func (d *deref) startHandshake(username string, remoteAccountID *url.URL) {
|
||||||
d.handshakes[username] = remoteIDs
|
d.handshakes[username] = remoteIDs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deref) stopHandshake(username string, remoteAccountID *url.URL) {
|
func (d *Dereferencer) stopHandshake(username string, remoteAccountID *url.URL) {
|
||||||
d.handshakesMu.Lock()
|
d.handshakesMu.Lock()
|
||||||
defer d.handshakesMu.Unlock()
|
defer d.handshakesMu.Unlock()
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import (
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *deref) GetRemoteInstance(ctx context.Context, username string, remoteInstanceURI *url.URL) (*gtsmodel.Instance, error) {
|
func (d *Dereferencer) GetRemoteInstance(ctx context.Context, username string, remoteInstanceURI *url.URL) (*gtsmodel.Instance, error) {
|
||||||
if blocked, err := d.state.DB.IsDomainBlocked(ctx, remoteInstanceURI.Host); blocked || err != nil {
|
if blocked, err := d.state.DB.IsDomainBlocked(ctx, remoteInstanceURI.Host); blocked || err != nil {
|
||||||
return nil, fmt.Errorf("GetRemoteInstance: domain %s is blocked", remoteInstanceURI.Host)
|
return nil, fmt.Errorf("GetRemoteInstance: domain %s is blocked", remoteInstanceURI.Host)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import (
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/media"
|
"github.com/superseriousbusiness/gotosocial/internal/media"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *deref) GetRemoteMedia(ctx context.Context, requestingUsername string, accountID string, remoteURL string, ai *media.AdditionalMediaInfo) (*media.ProcessingMedia, error) {
|
func (d *Dereferencer) GetRemoteMedia(ctx context.Context, requestingUsername string, accountID string, remoteURL string, ai *media.AdditionalMediaInfo) (*media.ProcessingMedia, error) {
|
||||||
if accountID == "" {
|
if accountID == "" {
|
||||||
return nil, fmt.Errorf("GetRemoteMedia: account ID was empty")
|
return nil, fmt.Errorf("GetRemoteMedia: account ID was empty")
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,10 @@ func statusUpToDate(status *gtsmodel.Status) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStatus: implements Dereferencer{}.GetStatus().
|
// GetStatusByURI will attempt to fetch a status by its URI, first checking the database. In the case of a newly-met remote model, or a remote model
|
||||||
func (d *deref) GetStatusByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Status, ap.Statusable, error) {
|
// whose last_fetched date is beyond a certain interval, the status will be dereferenced. In the case of dereferencing, some low-priority status information
|
||||||
|
// may be enqueued for asynchronous fetching, e.g. dereferencing the remainder of the status thread. An ActivityPub object indicates the status was dereferenced.
|
||||||
|
func (d *Dereferencer) GetStatusByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Status, ap.Statusable, error) {
|
||||||
// Fetch and dereference status if necessary.
|
// Fetch and dereference status if necessary.
|
||||||
status, apubStatus, err := d.getStatusByURI(ctx,
|
status, apubStatus, err := d.getStatusByURI(ctx,
|
||||||
requestUser,
|
requestUser,
|
||||||
|
@ -74,7 +76,7 @@ func (d *deref) GetStatusByURI(ctx context.Context, requestUser string, uri *url
|
||||||
}
|
}
|
||||||
|
|
||||||
// getStatusByURI is a package internal form of .GetStatusByURI() that doesn't bother dereferencing the whole thread on update.
|
// getStatusByURI is a package internal form of .GetStatusByURI() that doesn't bother dereferencing the whole thread on update.
|
||||||
func (d *deref) getStatusByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Status, ap.Statusable, error) {
|
func (d *Dereferencer) getStatusByURI(ctx context.Context, requestUser string, uri *url.URL) (*gtsmodel.Status, ap.Statusable, error) {
|
||||||
var (
|
var (
|
||||||
status *gtsmodel.Status
|
status *gtsmodel.Status
|
||||||
uriStr = uri.String()
|
uriStr = uri.String()
|
||||||
|
@ -146,8 +148,10 @@ func (d *deref) getStatusByURI(ctx context.Context, requestUser string, uri *url
|
||||||
return latest, apubStatus, nil
|
return latest, apubStatus, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefreshStatus: implements Dereferencer{}.RefreshStatus().
|
// RefreshStatus updates the given status if remote and last_fetched is beyond fetch interval, or if force is set. An updated status model is returned,
|
||||||
func (d *deref) RefreshStatus(ctx context.Context, requestUser string, status *gtsmodel.Status, apubStatus ap.Statusable, force bool) (*gtsmodel.Status, ap.Statusable, error) {
|
// but in the case of dereferencing, some low-priority status information may be enqueued for asynchronous fetching, e.g. dereferencing the remainder of the
|
||||||
|
// status thread. An ActivityPub object indicates the status was dereferenced (i.e. updated).
|
||||||
|
func (d *Dereferencer) RefreshStatus(ctx context.Context, requestUser string, status *gtsmodel.Status, apubStatus ap.Statusable, force bool) (*gtsmodel.Status, ap.Statusable, error) {
|
||||||
// Check whether needs update.
|
// Check whether needs update.
|
||||||
if !force && statusUpToDate(status) {
|
if !force && statusUpToDate(status) {
|
||||||
return status, nil, nil
|
return status, nil, nil
|
||||||
|
@ -178,8 +182,9 @@ func (d *deref) RefreshStatus(ctx context.Context, requestUser string, status *g
|
||||||
return latest, apubStatus, nil
|
return latest, apubStatus, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefreshStatusAsync: implements Dereferencer{}.RefreshStatusAsync().
|
// RefreshStatusAsync enqueues the given status for an asychronous update fetching, if last_fetched is beyond fetch interval, or if force is set.
|
||||||
func (d *deref) RefreshStatusAsync(ctx context.Context, requestUser string, status *gtsmodel.Status, apubStatus ap.Statusable, force bool) {
|
// This is a more optimized form of manually enqueueing .UpdateStatus() to the federation worker, since it only enqueues update if necessary.
|
||||||
|
func (d *Dereferencer) RefreshStatusAsync(ctx context.Context, requestUser string, status *gtsmodel.Status, apubStatus ap.Statusable, force bool) {
|
||||||
// Check whether needs update.
|
// Check whether needs update.
|
||||||
if statusUpToDate(status) {
|
if statusUpToDate(status) {
|
||||||
return
|
return
|
||||||
|
@ -208,7 +213,7 @@ func (d *deref) RefreshStatusAsync(ctx context.Context, requestUser string, stat
|
||||||
// enrichStatus will enrich the given status, whether a new
|
// enrichStatus will enrich the given status, whether a new
|
||||||
// barebones model, or existing model from the database.
|
// barebones model, or existing model from the database.
|
||||||
// It handles necessary dereferencing, database updates, etc.
|
// It handles necessary dereferencing, database updates, etc.
|
||||||
func (d *deref) enrichStatus(
|
func (d *Dereferencer) enrichStatus(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
requestUser string,
|
requestUser string,
|
||||||
uri *url.URL,
|
uri *url.URL,
|
||||||
|
@ -329,7 +334,7 @@ func (d *deref) enrichStatus(
|
||||||
return latestStatus, apubStatus, nil
|
return latestStatus, apubStatus, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deref) fetchStatusMentions(ctx context.Context, requestUser string, existing, status *gtsmodel.Status) error {
|
func (d *Dereferencer) fetchStatusMentions(ctx context.Context, requestUser string, existing, status *gtsmodel.Status) error {
|
||||||
// Allocate new slice to take the yet-to-be created mention IDs.
|
// Allocate new slice to take the yet-to-be created mention IDs.
|
||||||
status.MentionIDs = make([]string, len(status.Mentions))
|
status.MentionIDs = make([]string, len(status.Mentions))
|
||||||
|
|
||||||
|
@ -405,7 +410,7 @@ func (d *deref) fetchStatusMentions(ctx context.Context, requestUser string, exi
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deref) fetchStatusTags(ctx context.Context, status *gtsmodel.Status) error {
|
func (d *Dereferencer) fetchStatusTags(ctx context.Context, status *gtsmodel.Status) error {
|
||||||
// Allocate new slice to take the yet-to-be determined tag IDs.
|
// Allocate new slice to take the yet-to-be determined tag IDs.
|
||||||
status.TagIDs = make([]string, len(status.Tags))
|
status.TagIDs = make([]string, len(status.Tags))
|
||||||
|
|
||||||
|
@ -455,7 +460,7 @@ func (d *deref) fetchStatusTags(ctx context.Context, status *gtsmodel.Status) er
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deref) fetchStatusAttachments(ctx context.Context, tsport transport.Transport, existing, status *gtsmodel.Status) error {
|
func (d *Dereferencer) fetchStatusAttachments(ctx context.Context, tsport transport.Transport, existing, status *gtsmodel.Status) error {
|
||||||
// Allocate new slice to take the yet-to-be fetched attachment IDs.
|
// Allocate new slice to take the yet-to-be fetched attachment IDs.
|
||||||
status.AttachmentIDs = make([]string, len(status.Attachments))
|
status.AttachmentIDs = make([]string, len(status.Attachments))
|
||||||
|
|
||||||
|
@ -519,7 +524,7 @@ func (d *deref) fetchStatusAttachments(ctx context.Context, tsport transport.Tra
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deref) fetchStatusEmojis(ctx context.Context, requestUser string, status *gtsmodel.Status) error {
|
func (d *Dereferencer) fetchStatusEmojis(ctx context.Context, requestUser string, status *gtsmodel.Status) error {
|
||||||
// Fetch the full-fleshed-out emoji objects for our status.
|
// Fetch the full-fleshed-out emoji objects for our status.
|
||||||
emojis, err := d.populateEmojis(ctx, status.Emojis, requestUser)
|
emojis, err := d.populateEmojis(ctx, status.Emojis, requestUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -38,7 +38,7 @@ import (
|
||||||
// ancesters we are willing to follow before returning error.
|
// ancesters we are willing to follow before returning error.
|
||||||
const maxIter = 1000
|
const maxIter = 1000
|
||||||
|
|
||||||
func (d *deref) dereferenceThread(ctx context.Context, username string, statusIRI *url.URL, status *gtsmodel.Status, statusable ap.Statusable) {
|
func (d *Dereferencer) dereferenceThread(ctx context.Context, username string, statusIRI *url.URL, status *gtsmodel.Status, statusable ap.Statusable) {
|
||||||
// Ensure that ancestors have been fully dereferenced
|
// Ensure that ancestors have been fully dereferenced
|
||||||
if err := d.DereferenceStatusAncestors(ctx, username, status); err != nil {
|
if err := d.DereferenceStatusAncestors(ctx, username, status); err != nil {
|
||||||
log.Error(ctx, err)
|
log.Error(ctx, err)
|
||||||
|
@ -50,11 +50,8 @@ func (d *deref) dereferenceThread(ctx context.Context, username string, statusIR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deref) DereferenceStatusAncestors(
|
// DereferenceStatusAncestors iterates upwards from the given status, using InReplyToURI, to ensure that as many parent statuses as possible are dereferenced.
|
||||||
ctx context.Context,
|
func (d *Dereferencer) DereferenceStatusAncestors(ctx context.Context, username string, status *gtsmodel.Status) error {
|
||||||
username string,
|
|
||||||
status *gtsmodel.Status,
|
|
||||||
) error {
|
|
||||||
// Start log entry with fields
|
// Start log entry with fields
|
||||||
l := log.WithContext(ctx).
|
l := log.WithContext(ctx).
|
||||||
WithFields(kv.Fields{
|
WithFields(kv.Fields{
|
||||||
|
@ -220,7 +217,8 @@ func (d *deref) DereferenceStatusAncestors(
|
||||||
return gtserror.Newf("reached %d ancestor iterations for %q", maxIter, status.URI)
|
return gtserror.Newf("reached %d ancestor iterations for %q", maxIter, status.URI)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deref) DereferenceStatusDescendants(ctx context.Context, username string, statusIRI *url.URL, parent ap.Statusable) error {
|
// DereferenceStatusDescendents iterates downwards from the given status, using its replies, to ensure that as many children statuses as possible are dereferenced.
|
||||||
|
func (d *Dereferencer) DereferenceStatusDescendants(ctx context.Context, username string, statusIRI *url.URL, parent ap.Statusable) error {
|
||||||
statusIRIStr := statusIRI.String()
|
statusIRIStr := statusIRI.String()
|
||||||
|
|
||||||
// Start log entry with fields
|
// Start log entry with fields
|
||||||
|
|
|
@ -93,7 +93,7 @@ func newErrOtherIRIBlocked(
|
||||||
// In this case, the DelegateActor implementation must not write a response
|
// In this case, the DelegateActor implementation must not write a response
|
||||||
// to the ResponseWriter as is expected that the caller to PostInbox will
|
// to the ResponseWriter as is expected that the caller to PostInbox will
|
||||||
// do so when handling the error.
|
// do so when handling the error.
|
||||||
func (f *federator) PostInboxRequestBodyHook(ctx context.Context, r *http.Request, activity pub.Activity) (context.Context, error) {
|
func (f *Federator) PostInboxRequestBodyHook(ctx context.Context, r *http.Request, activity pub.Activity) (context.Context, error) {
|
||||||
// Extract any other IRIs involved in this activity.
|
// Extract any other IRIs involved in this activity.
|
||||||
otherIRIs := []*url.URL{}
|
otherIRIs := []*url.URL{}
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ func (f *federator) PostInboxRequestBodyHook(ctx context.Context, r *http.Reques
|
||||||
// Finally, if the authentication and authorization succeeds, then
|
// Finally, if the authentication and authorization succeeds, then
|
||||||
// authenticated must be true and error nil. The request will continue
|
// authenticated must be true and error nil. The request will continue
|
||||||
// to be processed.
|
// to be processed.
|
||||||
func (f *federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool, error) {
|
func (f *Federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool, error) {
|
||||||
log.Tracef(ctx, "received request to authenticate inbox %s", r.URL.String())
|
log.Tracef(ctx, "received request to authenticate inbox %s", r.URL.String())
|
||||||
|
|
||||||
// Ensure this is an inbox path, and fetch the inbox owner
|
// Ensure this is an inbox path, and fetch the inbox owner
|
||||||
|
@ -298,7 +298,7 @@ func (f *federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWr
|
||||||
// Blocked should determine whether to permit a set of actors given by
|
// Blocked should determine whether to permit a set of actors given by
|
||||||
// their ids are able to interact with this particular end user due to
|
// their ids are able to interact with this particular end user due to
|
||||||
// being blocked or other application-specific logic.
|
// being blocked or other application-specific logic.
|
||||||
func (f *federator) Blocked(ctx context.Context, actorIRIs []*url.URL) (bool, error) {
|
func (f *Federator) Blocked(ctx context.Context, actorIRIs []*url.URL) (bool, error) {
|
||||||
// Fetch relevant items from request context.
|
// Fetch relevant items from request context.
|
||||||
// These should have been set further up the flow.
|
// These should have been set further up the flow.
|
||||||
receivingAccount := gtscontext.ReceivingAccount(ctx)
|
receivingAccount := gtscontext.ReceivingAccount(ctx)
|
||||||
|
@ -498,7 +498,7 @@ func (f *federator) Blocked(ctx context.Context, actorIRIs []*url.URL) (bool, er
|
||||||
//
|
//
|
||||||
// Applications are not expected to handle every single ActivityStreams
|
// Applications are not expected to handle every single ActivityStreams
|
||||||
// type and extension. The unhandled ones are passed to DefaultCallback.
|
// type and extension. The unhandled ones are passed to DefaultCallback.
|
||||||
func (f *federator) FederatingCallbacks(ctx context.Context) (wrapped pub.FederatingWrappedCallbacks, other []interface{}, err error) {
|
func (f *Federator) FederatingCallbacks(ctx context.Context) (wrapped pub.FederatingWrappedCallbacks, other []interface{}, err error) {
|
||||||
wrapped = pub.FederatingWrappedCallbacks{
|
wrapped = pub.FederatingWrappedCallbacks{
|
||||||
// OnFollow determines what action to take for this
|
// OnFollow determines what action to take for this
|
||||||
// particular callback if a Follow Activity is handled.
|
// particular callback if a Follow Activity is handled.
|
||||||
|
@ -537,7 +537,7 @@ func (f *federator) FederatingCallbacks(ctx context.Context) (wrapped pub.Federa
|
||||||
// Applications are not expected to handle every single ActivityStreams
|
// Applications are not expected to handle every single ActivityStreams
|
||||||
// type and extension, so the unhandled ones are passed to
|
// type and extension, so the unhandled ones are passed to
|
||||||
// DefaultCallback.
|
// DefaultCallback.
|
||||||
func (f *federator) DefaultCallback(ctx context.Context, activity pub.Activity) error {
|
func (f *Federator) DefaultCallback(ctx context.Context, activity pub.Activity) error {
|
||||||
log.Debugf(ctx, "received unhandle-able activity type (%s) so ignoring it", activity.GetTypeName())
|
log.Debugf(ctx, "received unhandle-able activity type (%s) so ignoring it", activity.GetTypeName())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -546,7 +546,7 @@ func (f *federator) DefaultCallback(ctx context.Context, activity pub.Activity)
|
||||||
// an activity to determine if inbox forwarding needs to occur.
|
// an activity to determine if inbox forwarding needs to occur.
|
||||||
//
|
//
|
||||||
// Zero or negative numbers indicate infinite recursion.
|
// Zero or negative numbers indicate infinite recursion.
|
||||||
func (f *federator) MaxInboxForwardingRecursionDepth(ctx context.Context) int {
|
func (f *Federator) MaxInboxForwardingRecursionDepth(ctx context.Context) int {
|
||||||
// TODO
|
// TODO
|
||||||
return 4
|
return 4
|
||||||
}
|
}
|
||||||
|
@ -556,7 +556,7 @@ func (f *federator) MaxInboxForwardingRecursionDepth(ctx context.Context) int {
|
||||||
// delivery.
|
// delivery.
|
||||||
//
|
//
|
||||||
// Zero or negative numbers indicate infinite recursion.
|
// Zero or negative numbers indicate infinite recursion.
|
||||||
func (f *federator) MaxDeliveryRecursionDepth(ctx context.Context) int {
|
func (f *Federator) MaxDeliveryRecursionDepth(ctx context.Context) int {
|
||||||
// TODO
|
// TODO
|
||||||
return 4
|
return 4
|
||||||
}
|
}
|
||||||
|
@ -568,7 +568,7 @@ func (f *federator) MaxDeliveryRecursionDepth(ctx context.Context) int {
|
||||||
//
|
//
|
||||||
// The activity is provided as a reference for more intelligent
|
// The activity is provided as a reference for more intelligent
|
||||||
// logic to be used, but the implementation must not modify it.
|
// logic to be used, but the implementation must not modify it.
|
||||||
func (f *federator) FilterForwarding(ctx context.Context, potentialRecipients []*url.URL, a pub.Activity) ([]*url.URL, error) {
|
func (f *Federator) FilterForwarding(ctx context.Context, potentialRecipients []*url.URL, a pub.Activity) ([]*url.URL, error) {
|
||||||
// TODO
|
// TODO
|
||||||
return []*url.URL{}, nil
|
return []*url.URL{}, nil
|
||||||
}
|
}
|
||||||
|
@ -581,7 +581,7 @@ func (f *federator) FilterForwarding(ctx context.Context, potentialRecipients []
|
||||||
//
|
//
|
||||||
// Always called, regardless whether the Federated Protocol or Social
|
// Always called, regardless whether the Federated Protocol or Social
|
||||||
// API is enabled.
|
// API is enabled.
|
||||||
func (f *federator) GetInbox(ctx context.Context, r *http.Request) (vocab.ActivityStreamsOrderedCollectionPage, error) {
|
func (f *Federator) GetInbox(ctx context.Context, r *http.Request) (vocab.ActivityStreamsOrderedCollectionPage, error) {
|
||||||
// IMPLEMENTATION NOTE: For GoToSocial, we serve GETS to outboxes and inboxes through
|
// IMPLEMENTATION NOTE: For GoToSocial, we serve GETS to outboxes and inboxes through
|
||||||
// the CLIENT API, not through the federation API, so we just do nothing here.
|
// the CLIENT API, not through the federation API, so we just do nothing here.
|
||||||
return streams.NewActivityStreamsOrderedCollectionPage(), nil
|
return streams.NewActivityStreamsOrderedCollectionPage(), nil
|
||||||
|
|
|
@ -18,44 +18,22 @@
|
||||||
package federation
|
package federation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/superseriousbusiness/activity/pub"
|
"github.com/superseriousbusiness/activity/pub"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
|
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/federation/federatingdb"
|
"github.com/superseriousbusiness/gotosocial/internal/federation/federatingdb"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/media"
|
"github.com/superseriousbusiness/gotosocial/internal/media"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/state"
|
"github.com/superseriousbusiness/gotosocial/internal/state"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/transport"
|
"github.com/superseriousbusiness/gotosocial/internal/transport"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
|
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Federator wraps various interfaces and functions to manage activitypub federation from gotosocial
|
var _ interface {
|
||||||
type Federator interface {
|
|
||||||
// FederatingActor returns the underlying pub.FederatingActor, which can be used to send activities, and serve actors at inboxes/outboxes.
|
|
||||||
FederatingActor() pub.FederatingActor
|
|
||||||
// FederatingDB returns the underlying FederatingDB interface.
|
|
||||||
FederatingDB() federatingdb.DB
|
|
||||||
// TransportController returns the underlying transport controller.
|
|
||||||
TransportController() transport.Controller
|
|
||||||
|
|
||||||
// AuthenticateFederatedRequest can be used to check the authenticity of incoming http-signed requests for federating resources.
|
|
||||||
// The given username will be used to create a transport for making outgoing requests. See the implementation for more detailed comments.
|
|
||||||
//
|
|
||||||
// If the request is valid and passes authentication, the URL of the key owner ID will be returned, as well as true, and nil.
|
|
||||||
//
|
|
||||||
// If the request does not pass authentication, or there's a domain block, nil, false, nil will be returned.
|
|
||||||
//
|
|
||||||
// If something goes wrong during authentication, nil, false, and an error will be returned.
|
|
||||||
AuthenticateFederatedRequest(ctx context.Context, username string) (*PubKeyAuth, gtserror.WithCode)
|
|
||||||
|
|
||||||
pub.CommonBehavior
|
pub.CommonBehavior
|
||||||
pub.FederatingProtocol
|
pub.FederatingProtocol
|
||||||
dereferencing.Dereferencer
|
} = &Federator{}
|
||||||
}
|
|
||||||
|
|
||||||
type federator struct {
|
type Federator struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
federatingDB federatingdb.DB
|
federatingDB federatingdb.DB
|
||||||
clock pub.Clock
|
clock pub.Clock
|
||||||
|
@ -66,33 +44,40 @@ type federator struct {
|
||||||
dereferencing.Dereferencer
|
dereferencing.Dereferencer
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFederator returns a new federator
|
// NewFederator returns a new federator instance.
|
||||||
func NewFederator(state *state.State, federatingDB federatingdb.DB, transportController transport.Controller, converter *typeutils.Converter, mediaManager *media.Manager) Federator {
|
func NewFederator(
|
||||||
dereferencer := dereferencing.NewDereferencer(state, converter, transportController, mediaManager)
|
state *state.State,
|
||||||
|
federatingDB federatingdb.DB,
|
||||||
|
transportController transport.Controller,
|
||||||
|
converter *typeutils.Converter,
|
||||||
|
mediaManager *media.Manager,
|
||||||
|
) *Federator {
|
||||||
clock := &Clock{}
|
clock := &Clock{}
|
||||||
f := &federator{
|
f := &Federator{
|
||||||
db: state.DB,
|
db: state.DB,
|
||||||
federatingDB: federatingDB,
|
federatingDB: federatingDB,
|
||||||
clock: &Clock{},
|
clock: clock,
|
||||||
converter: converter,
|
converter: converter,
|
||||||
transportController: transportController,
|
transportController: transportController,
|
||||||
mediaManager: mediaManager,
|
mediaManager: mediaManager,
|
||||||
Dereferencer: dereferencer,
|
Dereferencer: dereferencing.NewDereferencer(state, converter, transportController, mediaManager),
|
||||||
}
|
}
|
||||||
actor := newFederatingActor(f, f, federatingDB, clock)
|
actor := newFederatingActor(f, f, federatingDB, clock)
|
||||||
f.actor = actor
|
f.actor = actor
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *federator) FederatingActor() pub.FederatingActor {
|
// FederatingActor returns the underlying pub.FederatingActor, which can be used to send activities, and serve actors at inboxes/outboxes.
|
||||||
|
func (f *Federator) FederatingActor() pub.FederatingActor {
|
||||||
return f.actor
|
return f.actor
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *federator) FederatingDB() federatingdb.DB {
|
// FederatingDB returns the underlying FederatingDB interface.
|
||||||
|
func (f *Federator) FederatingDB() federatingdb.DB {
|
||||||
return f.federatingDB
|
return f.federatingDB
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *federator) TransportController() transport.Controller {
|
// TransportController returns the underlying transport controller.
|
||||||
|
func (f *Federator) TransportController() transport.Controller {
|
||||||
return f.transportController
|
return f.transportController
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ type FederatorStandardTestSuite struct {
|
||||||
typeconverter *typeutils.Converter
|
typeconverter *typeutils.Converter
|
||||||
transportController transport.Controller
|
transportController transport.Controller
|
||||||
httpClient *testrig.MockHTTPClient
|
httpClient *testrig.MockHTTPClient
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
|
|
||||||
testAccounts map[string]*gtsmodel.Account
|
testAccounts map[string]*gtsmodel.Account
|
||||||
testStatuses map[string]*gtsmodel.Status
|
testStatuses map[string]*gtsmodel.Status
|
||||||
|
|
|
@ -26,12 +26,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// CheckGone checks if a tombstone exists in the database for AP Actor or Object with the given uri.
|
// CheckGone checks if a tombstone exists in the database for AP Actor or Object with the given uri.
|
||||||
func (f *federator) CheckGone(ctx context.Context, uri *url.URL) (bool, error) {
|
func (f *Federator) CheckGone(ctx context.Context, uri *url.URL) (bool, error) {
|
||||||
return f.db.TombstoneExistsWithURI(ctx, uri.String())
|
return f.db.TombstoneExistsWithURI(ctx, uri.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleGone puts a tombstone in the database, which marks an AP Actor or Object with the given uri as gone.
|
// HandleGone puts a tombstone in the database, which marks an AP Actor or Object with the given uri as gone.
|
||||||
func (f *federator) HandleGone(ctx context.Context, uri *url.URL) error {
|
func (f *Federator) HandleGone(ctx context.Context, uri *url.URL) error {
|
||||||
tombstone := >smodel.Tombstone{
|
tombstone := >smodel.Tombstone{
|
||||||
ID: id.NewULID(),
|
ID: id.NewULID(),
|
||||||
Domain: uri.Host,
|
Domain: uri.Host,
|
||||||
|
|
|
@ -49,7 +49,7 @@ import (
|
||||||
// Note that the library will not maintain a long-lived pointer to the
|
// Note that the library will not maintain a long-lived pointer to the
|
||||||
// returned Transport so that any private credentials are able to be
|
// returned Transport so that any private credentials are able to be
|
||||||
// garbage collected.
|
// garbage collected.
|
||||||
func (f *federator) NewTransport(ctx context.Context, actorBoxIRI *url.URL, gofedAgent string) (pub.Transport, error) {
|
func (f *Federator) NewTransport(ctx context.Context, actorBoxIRI *url.URL, gofedAgent string) (pub.Transport, error) {
|
||||||
var username string
|
var username string
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,12 @@ type Server interface {
|
||||||
// NewServer returns a new gotosocial server, initialized with the given configuration.
|
// NewServer returns a new gotosocial server, initialized with the given configuration.
|
||||||
// An error will be returned the caller if something goes wrong during initialization
|
// An error will be returned the caller if something goes wrong during initialization
|
||||||
// eg., no db or storage connection, port for router already in use, etc.
|
// eg., no db or storage connection, port for router already in use, etc.
|
||||||
func NewServer(db db.DB, apiRouter router.Router, federator federation.Federator, mediaManager *media.Manager) (Server, error) {
|
func NewServer(
|
||||||
|
db db.DB,
|
||||||
|
apiRouter router.Router,
|
||||||
|
federator *federation.Federator,
|
||||||
|
mediaManager *media.Manager,
|
||||||
|
) (Server, error) {
|
||||||
return &gotosocial{
|
return &gotosocial{
|
||||||
db: db,
|
db: db,
|
||||||
apiRouter: apiRouter,
|
apiRouter: apiRouter,
|
||||||
|
@ -54,7 +59,7 @@ func NewServer(db db.DB, apiRouter router.Router, federator federation.Federator
|
||||||
type gotosocial struct {
|
type gotosocial struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
apiRouter router.Router
|
apiRouter router.Router
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ type Processor struct {
|
||||||
oauthServer oauth.Server
|
oauthServer oauth.Server
|
||||||
filter *visibility.Filter
|
filter *visibility.Filter
|
||||||
formatter *text.Formatter
|
formatter *text.Formatter
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
parseMention gtsmodel.ParseMentionFunc
|
parseMention gtsmodel.ParseMentionFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ func New(
|
||||||
converter *typeutils.Converter,
|
converter *typeutils.Converter,
|
||||||
mediaManager *media.Manager,
|
mediaManager *media.Manager,
|
||||||
oauthServer oauth.Server,
|
oauthServer oauth.Server,
|
||||||
federator federation.Federator,
|
federator *federation.Federator,
|
||||||
filter *visibility.Filter,
|
filter *visibility.Filter,
|
||||||
parseMention gtsmodel.ParseMentionFunc,
|
parseMention gtsmodel.ParseMentionFunc,
|
||||||
) Processor {
|
) Processor {
|
||||||
|
|
|
@ -50,7 +50,7 @@ type AccountStandardTestSuite struct {
|
||||||
oauthServer oauth.Server
|
oauthServer oauth.Server
|
||||||
fromClientAPIChan chan messages.FromClientAPI
|
fromClientAPIChan chan messages.FromClientAPI
|
||||||
transportController transport.Controller
|
transportController transport.Controller
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
sentEmails map[string]string
|
sentEmails map[string]string
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ type AdminStandardTestSuite struct {
|
||||||
oauthServer oauth.Server
|
oauthServer oauth.Server
|
||||||
fromClientAPIChan chan messages.FromClientAPI
|
fromClientAPIChan chan messages.FromClientAPI
|
||||||
transportController transport.Controller
|
transportController transport.Controller
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
sentEmails map[string]string
|
sentEmails map[string]string
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
|
|
|
@ -30,7 +30,7 @@ import (
|
||||||
type Processor struct {
|
type Processor struct {
|
||||||
state *state.State
|
state *state.State
|
||||||
converter *typeutils.Converter
|
converter *typeutils.Converter
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
filter *visibility.Filter
|
filter *visibility.Filter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ type Processor struct {
|
||||||
func New(
|
func New(
|
||||||
state *state.State,
|
state *state.State,
|
||||||
converter *typeutils.Converter,
|
converter *typeutils.Converter,
|
||||||
federator federation.Federator,
|
federator *federation.Federator,
|
||||||
filter *visibility.Filter,
|
filter *visibility.Filter,
|
||||||
) Processor {
|
) Processor {
|
||||||
return Processor{
|
return Processor{
|
||||||
|
|
|
@ -26,13 +26,13 @@ import (
|
||||||
|
|
||||||
type Processor struct {
|
type Processor struct {
|
||||||
state *state.State
|
state *state.State
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
converter *typeutils.Converter
|
converter *typeutils.Converter
|
||||||
filter *visibility.Filter
|
filter *visibility.Filter
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new fedi processor.
|
// New returns a new fedi processor.
|
||||||
func New(state *state.State, converter *typeutils.Converter, federator federation.Federator, filter *visibility.Filter) Processor {
|
func New(state *state.State, converter *typeutils.Converter, federator *federation.Federator, filter *visibility.Filter) Processor {
|
||||||
return Processor{
|
return Processor{
|
||||||
state: state,
|
state: state,
|
||||||
federator: federator,
|
federator: federator,
|
||||||
|
|
|
@ -127,7 +127,7 @@ func (p *Processor) Workers() *workers.Processor {
|
||||||
// NewProcessor returns a new Processor.
|
// NewProcessor returns a new Processor.
|
||||||
func NewProcessor(
|
func NewProcessor(
|
||||||
converter *typeutils.Converter,
|
converter *typeutils.Converter,
|
||||||
federator federation.Federator,
|
federator *federation.Federator,
|
||||||
oauthServer oauth.Server,
|
oauthServer oauth.Server,
|
||||||
mediaManager *mm.Manager,
|
mediaManager *mm.Manager,
|
||||||
state *state.State,
|
state *state.State,
|
||||||
|
|
|
@ -47,7 +47,7 @@ type ProcessingStandardTestSuite struct {
|
||||||
typeconverter *typeutils.Converter
|
typeconverter *typeutils.Converter
|
||||||
httpClient *testrig.MockHTTPClient
|
httpClient *testrig.MockHTTPClient
|
||||||
transportController transport.Controller
|
transportController transport.Controller
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
oauthServer oauth.Server
|
oauthServer oauth.Server
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
|
|
||||||
|
|
|
@ -26,13 +26,13 @@ import (
|
||||||
|
|
||||||
type Processor struct {
|
type Processor struct {
|
||||||
state *state.State
|
state *state.State
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
converter *typeutils.Converter
|
converter *typeutils.Converter
|
||||||
filter *visibility.Filter
|
filter *visibility.Filter
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new status processor.
|
// New returns a new status processor.
|
||||||
func New(state *state.State, federator federation.Federator, converter *typeutils.Converter, filter *visibility.Filter) Processor {
|
func New(state *state.State, federator *federation.Federator, converter *typeutils.Converter, filter *visibility.Filter) Processor {
|
||||||
return Processor{
|
return Processor{
|
||||||
state: state,
|
state: state,
|
||||||
federator: federator,
|
federator: federator,
|
||||||
|
|
|
@ -28,7 +28,7 @@ import (
|
||||||
|
|
||||||
type Processor struct {
|
type Processor struct {
|
||||||
state *state.State
|
state *state.State
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
converter *typeutils.Converter
|
converter *typeutils.Converter
|
||||||
filter *visibility.Filter
|
filter *visibility.Filter
|
||||||
formatter *text.Formatter
|
formatter *text.Formatter
|
||||||
|
@ -36,7 +36,7 @@ type Processor struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new status processor.
|
// New returns a new status processor.
|
||||||
func New(state *state.State, federator federation.Federator, converter *typeutils.Converter, filter *visibility.Filter, parseMention gtsmodel.ParseMentionFunc) Processor {
|
func New(state *state.State, federator *federation.Federator, converter *typeutils.Converter, filter *visibility.Filter, parseMention gtsmodel.ParseMentionFunc) Processor {
|
||||||
return Processor{
|
return Processor{
|
||||||
state: state,
|
state: state,
|
||||||
federator: federator,
|
federator: federator,
|
||||||
|
|
|
@ -41,7 +41,7 @@ type StatusStandardTestSuite struct {
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
state state.State
|
state state.State
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
|
|
||||||
// standard suite models
|
// standard suite models
|
||||||
testTokens map[string]*gtsmodel.Token
|
testTokens map[string]*gtsmodel.Token
|
||||||
|
|
|
@ -30,7 +30,7 @@ import (
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/util"
|
"github.com/superseriousbusiness/gotosocial/internal/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetParseMentionFunc(dbConn db.DB, federator federation.Federator) gtsmodel.ParseMentionFunc {
|
func GetParseMentionFunc(dbConn db.DB, federator *federation.Federator) gtsmodel.ParseMentionFunc {
|
||||||
return func(ctx context.Context, targetAccount string, originAccountID string, statusID string) (*gtsmodel.Mention, error) {
|
return func(ctx context.Context, targetAccount string, originAccountID string, statusID string) (*gtsmodel.Mention, error) {
|
||||||
// get the origin account first since we'll need it to create the mention
|
// get the origin account first since we'll need it to create the mention
|
||||||
originAccount, err := dbConn.GetAccountByID(ctx, originAccountID)
|
originAccount, err := dbConn.GetAccountByID(ctx, originAccountID)
|
||||||
|
|
|
@ -36,7 +36,7 @@ import (
|
||||||
type federate struct {
|
type federate struct {
|
||||||
// Embed federator to give access
|
// Embed federator to give access
|
||||||
// to send and retrieve functions.
|
// to send and retrieve functions.
|
||||||
federation.Federator
|
*federation.Federator
|
||||||
state *state.State
|
state *state.State
|
||||||
converter *typeutils.Converter
|
converter *typeutils.Converter
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ type Processor struct {
|
||||||
|
|
||||||
func New(
|
func New(
|
||||||
state *state.State,
|
state *state.State,
|
||||||
federator federation.Federator,
|
federator *federation.Federator,
|
||||||
converter *typeutils.Converter,
|
converter *typeutils.Converter,
|
||||||
filter *visibility.Filter,
|
filter *visibility.Filter,
|
||||||
emailSender email.Sender,
|
emailSender email.Sender,
|
||||||
|
|
|
@ -47,7 +47,7 @@ type WorkersTestSuite struct {
|
||||||
typeconverter *typeutils.Converter
|
typeconverter *typeutils.Converter
|
||||||
httpClient *testrig.MockHTTPClient
|
httpClient *testrig.MockHTTPClient
|
||||||
transportController transport.Controller
|
transportController transport.Controller
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
oauthServer oauth.Server
|
oauthServer oauth.Server
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ type TransportTestSuite struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
storage *storage.Driver
|
storage *storage.Driver
|
||||||
mediaManager *media.Manager
|
mediaManager *media.Manager
|
||||||
federator federation.Federator
|
federator *federation.Federator
|
||||||
processor *processing.Processor
|
processor *processing.Processor
|
||||||
emailSender email.Sender
|
emailSender email.Sender
|
||||||
sentEmails map[string]string
|
sentEmails map[string]string
|
||||||
|
|
|
@ -26,6 +26,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewTestFederator returns a federator with the given database and (mock!!) transport controller.
|
// NewTestFederator returns a federator with the given database and (mock!!) transport controller.
|
||||||
func NewTestFederator(state *state.State, tc transport.Controller, mediaManager *media.Manager) federation.Federator {
|
func NewTestFederator(state *state.State, tc transport.Controller, mediaManager *media.Manager) *federation.Federator {
|
||||||
return federation.NewFederator(state, NewTestFederatingDB(state), tc, typeutils.NewConverter(state), mediaManager)
|
return federation.NewFederator(state, NewTestFederatingDB(state), tc, typeutils.NewConverter(state), mediaManager)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewTestProcessor returns a Processor suitable for testing purposes
|
// NewTestProcessor returns a Processor suitable for testing purposes
|
||||||
func NewTestProcessor(state *state.State, federator federation.Federator, emailSender email.Sender, mediaManager *media.Manager) *processing.Processor {
|
func NewTestProcessor(state *state.State, federator *federation.Federator, emailSender email.Sender, mediaManager *media.Manager) *processing.Processor {
|
||||||
p := processing.NewProcessor(typeutils.NewConverter(state), federator, NewTestOauthServer(state.DB), mediaManager, state, emailSender)
|
p := processing.NewProcessor(typeutils.NewConverter(state), federator, NewTestOauthServer(state.DB), mediaManager, state, emailSender)
|
||||||
state.Workers.EnqueueClientAPI = p.Workers().EnqueueClientAPI
|
state.Workers.EnqueueClientAPI = p.Workers().EnqueueClientAPI
|
||||||
state.Workers.EnqueueFediAPI = p.Workers().EnqueueFediAPI
|
state.Workers.EnqueueFediAPI = p.Workers().EnqueueFediAPI
|
||||||
|
|
Loading…
Reference in a new issue