mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 03:12:25 -05:00 
			
		
		
		
	tidy up some federation stuff
This commit is contained in:
		
					parent
					
						
							
								621e59fd42
							
						
					
				
			
			
				commit
				
					
						211c43073f
					
				
			
		
					 11 changed files with 199 additions and 86 deletions
				
			
		|  | @ -32,8 +32,13 @@ import ( | ||||||
| type Distributor interface { | type Distributor interface { | ||||||
| 	// FromClientAPI returns a channel for accepting messages that come from the gts client API. | 	// FromClientAPI returns a channel for accepting messages that come from the gts client API. | ||||||
| 	FromClientAPI() chan FromClientAPI | 	FromClientAPI() chan FromClientAPI | ||||||
| 	// ClientAPIOut returns a channel for putting in messages that need to go to the gts client API. | 	// ToClientAPI returns a channel for putting in messages that need to go to the gts client API. | ||||||
| 	ToClientAPI() chan ToClientAPI | 	ToClientAPI() chan ToClientAPI | ||||||
|  | 	// FromFederator returns a channel for accepting messages that come from the federator (activitypub). | ||||||
|  | 	FromFederator() chan FromFederator | ||||||
|  | 	// ToFederator returns a channel for putting in messages that need to go to the federator (activitypub). | ||||||
|  | 	ToFederator() chan ToFederator | ||||||
|  | 
 | ||||||
| 	// Start starts the Distributor, reading from its channels and passing messages back and forth. | 	// Start starts the Distributor, reading from its channels and passing messages back and forth. | ||||||
| 	Start() error | 	Start() error | ||||||
| 	// Stop stops the distributor cleanly, finishing handling any remaining messages before closing down. | 	// Stop stops the distributor cleanly, finishing handling any remaining messages before closing down. | ||||||
|  | @ -45,6 +50,8 @@ type distributor struct { | ||||||
| 	// federator     pub.FederatingActor | 	// federator     pub.FederatingActor | ||||||
| 	fromClientAPI chan FromClientAPI | 	fromClientAPI chan FromClientAPI | ||||||
| 	toClientAPI   chan ToClientAPI | 	toClientAPI   chan ToClientAPI | ||||||
|  | 	fromFederator chan FromFederator | ||||||
|  | 	toFederator   chan ToFederator | ||||||
| 	stop          chan interface{} | 	stop          chan interface{} | ||||||
| 	log           *logrus.Logger | 	log           *logrus.Logger | ||||||
| } | } | ||||||
|  | @ -55,21 +62,29 @@ func New(log *logrus.Logger) Distributor { | ||||||
| 		// federator:     federator, | 		// federator:     federator, | ||||||
| 		fromClientAPI: make(chan FromClientAPI, 100), | 		fromClientAPI: make(chan FromClientAPI, 100), | ||||||
| 		toClientAPI:   make(chan ToClientAPI, 100), | 		toClientAPI:   make(chan ToClientAPI, 100), | ||||||
|  | 		fromFederator: make(chan FromFederator, 100), | ||||||
|  | 		toFederator:   make(chan ToFederator, 100), | ||||||
| 		stop:          make(chan interface{}), | 		stop:          make(chan interface{}), | ||||||
| 		log:           log, | 		log:           log, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ClientAPIIn returns a channel for accepting messages that come from the gts client API. |  | ||||||
| func (d *distributor) FromClientAPI() chan FromClientAPI { | func (d *distributor) FromClientAPI() chan FromClientAPI { | ||||||
| 	return d.fromClientAPI | 	return d.fromClientAPI | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ClientAPIOut returns a channel for putting in messages that need to go to the gts client API. |  | ||||||
| func (d *distributor) ToClientAPI() chan ToClientAPI { | func (d *distributor) ToClientAPI() chan ToClientAPI { | ||||||
| 	return d.toClientAPI | 	return d.toClientAPI | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (d *distributor) FromFederator() chan FromFederator { | ||||||
|  | 	return d.fromFederator | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (d *distributor) ToFederator() chan ToFederator { | ||||||
|  | 	return d.toFederator | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Start starts the Distributor, reading from its channels and passing messages back and forth. | // Start starts the Distributor, reading from its channels and passing messages back and forth. | ||||||
| func (d *distributor) Start() error { | func (d *distributor) Start() error { | ||||||
| 	go func() { | 	go func() { | ||||||
|  | @ -80,6 +95,10 @@ func (d *distributor) Start() error { | ||||||
| 				d.log.Infof("received message FROM client API: %+v", clientMsg) | 				d.log.Infof("received message FROM client API: %+v", clientMsg) | ||||||
| 			case clientMsg := <-d.toClientAPI: | 			case clientMsg := <-d.toClientAPI: | ||||||
| 				d.log.Infof("received message TO client API: %+v", clientMsg) | 				d.log.Infof("received message TO client API: %+v", clientMsg) | ||||||
|  | 			case federatorMsg := <-d.fromFederator: | ||||||
|  | 				d.log.Infof("received message FROM federator: %+v", federatorMsg) | ||||||
|  | 			case federatorMsg := <-d.toFederator: | ||||||
|  | 				d.log.Infof("received message TO federator: %+v", federatorMsg) | ||||||
| 			case <-d.stop: | 			case <-d.stop: | ||||||
| 				break DistLoop | 				break DistLoop | ||||||
| 			} | 			} | ||||||
|  | @ -108,3 +127,17 @@ type ToClientAPI struct { | ||||||
| 	APActivityType gtsmodel.ActivityStreamsActivity | 	APActivityType gtsmodel.ActivityStreamsActivity | ||||||
| 	Activity       interface{} | 	Activity       interface{} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // FromFederator wraps a message that travels from the federator into the distributor | ||||||
|  | type FromFederator struct { | ||||||
|  | 	APObjectType   gtsmodel.ActivityStreamsObject | ||||||
|  | 	APActivityType gtsmodel.ActivityStreamsActivity | ||||||
|  | 	Activity       interface{} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ToFederator wraps a message that travels from the distributor into the federator | ||||||
|  | type ToFederator struct { | ||||||
|  | 	APObjectType   gtsmodel.ActivityStreamsObject | ||||||
|  | 	APActivityType gtsmodel.ActivityStreamsActivity | ||||||
|  | 	Activity       interface{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -24,21 +24,14 @@ import ( | ||||||
| 	"github.com/sirupsen/logrus" | 	"github.com/sirupsen/logrus" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/config" | 	"github.com/superseriousbusiness/gotosocial/internal/config" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/transport" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // New returns a go-fed compatible federating actor | // NewFederatingActor returns a go-fed compatible federating actor | ||||||
| func New(db db.DB, config *config.Config, log *logrus.Logger) pub.FederatingActor { | func NewFederatingActor(db db.DB, transportController transport.Controller, config *config.Config, log *logrus.Logger) pub.FederatingActor { | ||||||
| 
 | 	c := NewCommonBehavior(db, log, config, transportController) | ||||||
| 	c := &Commoner{ | 	f := NewFederatingProtocol(db, log, config, transportController) | ||||||
| 		db:     db, | 	pubDatabase := db.Federation() | ||||||
| 		log:    log, | 	clock := &Clock{} | ||||||
| 		config: config, | 	return pub.NewFederatingActor(c, f, pubDatabase, clock) | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	f := &Federator{ |  | ||||||
| 		db:     db, |  | ||||||
| 		log:    log, |  | ||||||
| 		config: config, |  | ||||||
| 	} |  | ||||||
| 	return pub.NewFederatingActor(c, f, db.Federation(), &Clock{}) |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -20,6 +20,7 @@ package federation | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"fmt" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 
 | 
 | ||||||
|  | @ -28,13 +29,27 @@ import ( | ||||||
| 	"github.com/sirupsen/logrus" | 	"github.com/sirupsen/logrus" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/config" | 	"github.com/superseriousbusiness/gotosocial/internal/config" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/db/gtsmodel" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/transport" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/util" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Commoner implements the go-fed common behavior interface | // commonBehavior implements the go-fed common behavior interface | ||||||
| type Commoner struct { | type commonBehavior struct { | ||||||
| 	db     db.DB | 	db                  db.DB | ||||||
| 	log    *logrus.Logger | 	log                 *logrus.Logger | ||||||
| 	config *config.Config | 	config              *config.Config | ||||||
|  | 	transportController transport.Controller | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewCommonBehavior returns an implementation of the pub.CommonBehavior interface that uses the given db, log, config, and transportController | ||||||
|  | func NewCommonBehavior(db db.DB, log *logrus.Logger, config *config.Config, transportController transport.Controller) pub.CommonBehavior { | ||||||
|  | 	return &commonBehavior{ | ||||||
|  | 		db:                  db, | ||||||
|  | 		log:                 log, | ||||||
|  | 		config:              config, | ||||||
|  | 		transportController: transportController, | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
|  | @ -63,7 +78,7 @@ type Commoner struct { | ||||||
| // 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 (c *Commoner) AuthenticateGetInbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool, error) { | func (c *commonBehavior) AuthenticateGetInbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool, error) { | ||||||
| 	// TODO | 	// TODO | ||||||
| 	// use context.WithValue() and context.Value() to set and get values through here | 	// use context.WithValue() and context.Value() to set and get values through here | ||||||
| 	return nil, false, nil | 	return nil, false, nil | ||||||
|  | @ -88,7 +103,7 @@ func (c *Commoner) AuthenticateGetInbox(ctx context.Context, w http.ResponseWrit | ||||||
| // 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 (c *Commoner) AuthenticateGetOutbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool, error) { | func (c *commonBehavior) AuthenticateGetOutbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool, error) { | ||||||
| 	// TODO | 	// TODO | ||||||
| 	return nil, false, nil | 	return nil, false, nil | ||||||
| } | } | ||||||
|  | @ -101,7 +116,7 @@ func (c *Commoner) AuthenticateGetOutbox(ctx context.Context, w http.ResponseWri | ||||||
| // | // | ||||||
| // 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 (c *Commoner) GetOutbox(ctx context.Context, r *http.Request) (vocab.ActivityStreamsOrderedCollectionPage, error) { | func (c *commonBehavior) GetOutbox(ctx context.Context, r *http.Request) (vocab.ActivityStreamsOrderedCollectionPage, error) { | ||||||
| 	// TODO | 	// TODO | ||||||
| 	return nil, nil | 	return nil, nil | ||||||
| } | } | ||||||
|  | @ -129,34 +144,29 @@ func (c *Commoner) GetOutbox(ctx context.Context, r *http.Request) (vocab.Activi | ||||||
| // 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 (c *Commoner) NewTransport(ctx context.Context, actorBoxIRI *url.URL, gofedAgent string) (pub.Transport, error) { | func (c *commonBehavior) NewTransport(ctx context.Context, actorBoxIRI *url.URL, gofedAgent string) (pub.Transport, error) { | ||||||
| 	// TODO |  | ||||||
| 	// prefs := []httpsig.Algorithm{httpsig.RSA_SHA256} |  | ||||||
| 	// digestPref := httpsig.DigestSha256 |  | ||||||
| 	// getHeadersToSign := []string{httpsig.RequestTarget, "Date"} |  | ||||||
| 	// postHeadersToSign := []string{httpsig.RequestTarget, "Date", "Digest"} |  | ||||||
| 	// // Using github.com/go-fed/httpsig for HTTP Signatures: |  | ||||||
| 	// getSigner, _, err := httpsig.NewSigner(prefs, digestPref, getHeadersToSign, httpsig.Signature) |  | ||||||
| 	// if err != nil { |  | ||||||
| 	// 	return nil, err |  | ||||||
| 	// } |  | ||||||
| 	// postSigner, _, err := httpsig.NewSigner(prefs, digestPref, postHeadersToSign, httpsig.Signature) |  | ||||||
| 	// if err != nil { |  | ||||||
| 	// 	return nil, err |  | ||||||
| 	// } |  | ||||||
| 	// pubKeyId, privKey, err := s.getKeysForActorBoxIRI(actorBoxIRI) |  | ||||||
| 	// client := &http.Client{ |  | ||||||
| 	// 	Timeout: time.Second * 30, |  | ||||||
| 	// } |  | ||||||
| 	// t := pub.NewHttpSigTransport( |  | ||||||
| 	// 	client, |  | ||||||
| 	// 	f.config.Host, |  | ||||||
| 	// 	&Clock{}, |  | ||||||
| 	// 	getSigner, |  | ||||||
| 	// 	postSigner, |  | ||||||
| 	// 	pubKeyId, |  | ||||||
| 	// 	privKey) |  | ||||||
| 
 | 
 | ||||||
| 	return nil, nil | 	var username string | ||||||
|  | 	var err error | ||||||
| 
 | 
 | ||||||
|  | 	if util.IsInboxPath(actorBoxIRI) { | ||||||
|  | 		username, err = util.ParseInboxPath(actorBoxIRI) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf("couldn't parse path %s as an inbox: %s", actorBoxIRI.String(), err) | ||||||
|  | 		} | ||||||
|  | 	} else if util.IsOutboxPath(actorBoxIRI) { | ||||||
|  | 		username, err = util.ParseOutboxPath(actorBoxIRI) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf("couldn't parse path %s as an outbox: %s", actorBoxIRI.String(), err) | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		return nil, fmt.Errorf("id %s was neither an inbox path nor an outbox path", actorBoxIRI.String()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	account := >smodel.Account{} | ||||||
|  | 	if err := c.db.GetWhere("username", username, account); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return c.transportController.NewTransport(account.PublicKeyURI, account.PrivateKey) | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										41
									
								
								internal/federation/federator.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								internal/federation/federator.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,41 @@ | ||||||
|  | /* | ||||||
|  |    GoToSocial | ||||||
|  |    Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org | ||||||
|  | 
 | ||||||
|  |    This program is free software: you can redistribute it and/or modify | ||||||
|  |    it under the terms of the GNU Affero General Public License as published by | ||||||
|  |    the Free Software Foundation, either version 3 of the License, or | ||||||
|  |    (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |    This program is distributed in the hope that it will be useful, | ||||||
|  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |    GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  |    You should have received a copy of the GNU Affero General Public License | ||||||
|  |    along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | package federation | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"github.com/go-fed/activity/pub" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/distributor" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Federator wraps everything needed to manage activitypub federation from gotosocial | ||||||
|  | type Federator interface { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type federator struct { | ||||||
|  | 	actor       pub.FederatingActor | ||||||
|  | 	distributor distributor.Distributor | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewFederator returns a new federator that uses the given actor and distributor | ||||||
|  | func NewFederator(actor pub.FederatingActor, distributor distributor.Distributor) Federator { | ||||||
|  | 	return &federator{ | ||||||
|  | 		actor:       actor, | ||||||
|  | 		distributor: distributor, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -34,17 +34,17 @@ import ( | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/util" | 	"github.com/superseriousbusiness/gotosocial/internal/util" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Federator implements the go-fed federating protocol interface | // FederatingProtocol implements the go-fed federating protocol interface | ||||||
| type Federator struct { | type FederatingProtocol struct { | ||||||
| 	db                  db.DB | 	db                  db.DB | ||||||
| 	log                 *logrus.Logger | 	log                 *logrus.Logger | ||||||
| 	config              *config.Config | 	config              *config.Config | ||||||
| 	transportController transport.Controller | 	transportController transport.Controller | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NewFederator returns the gotosocial implementation of the go-fed FederatingProtocol interface | // NewFederatingProtocol returns the gotosocial implementation of the go-fed FederatingProtocol interface | ||||||
| func NewFederator(db db.DB, log *logrus.Logger, config *config.Config, transportController transport.Controller) pub.FederatingProtocol { | func NewFederatingProtocol(db db.DB, log *logrus.Logger, config *config.Config, transportController transport.Controller) pub.FederatingProtocol { | ||||||
| 	return &Federator{ | 	return &FederatingProtocol{ | ||||||
| 		db:                  db, | 		db:                  db, | ||||||
| 		log:                 log, | 		log:                 log, | ||||||
| 		config:              config, | 		config:              config, | ||||||
|  | @ -78,7 +78,7 @@ func NewFederator(db db.DB, log *logrus.Logger, config *config.Config, transport | ||||||
| // PostInbox. In this case, the DelegateActor implementation must not | // PostInbox. In this case, the DelegateActor implementation must not | ||||||
| // write a response to the ResponseWriter as is expected that the caller | // write a response to the ResponseWriter as is expected that the caller | ||||||
| // to PostInbox will do so when handling the error. | // to PostInbox will do so when handling the error. | ||||||
| func (f *Federator) PostInboxRequestBodyHook(ctx context.Context, r *http.Request, activity pub.Activity) (context.Context, error) { | func (f *FederatingProtocol) PostInboxRequestBodyHook(ctx context.Context, r *http.Request, activity pub.Activity) (context.Context, error) { | ||||||
| 	l := f.log.WithFields(logrus.Fields{ | 	l := f.log.WithFields(logrus.Fields{ | ||||||
| 		"func":      "PostInboxRequestBodyHook", | 		"func":      "PostInboxRequestBodyHook", | ||||||
| 		"useragent": r.UserAgent(), | 		"useragent": r.UserAgent(), | ||||||
|  | @ -128,7 +128,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 *FederatingProtocol) AuthenticatePostInbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool, error) { | ||||||
| 	l := f.log.WithFields(logrus.Fields{ | 	l := f.log.WithFields(logrus.Fields{ | ||||||
| 		"func":      "AuthenticatePostInbox", | 		"func":      "AuthenticatePostInbox", | ||||||
| 		"useragent": r.UserAgent(), | 		"useragent": r.UserAgent(), | ||||||
|  | @ -167,7 +167,7 @@ func (f *Federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWr | ||||||
| // Finally, if the authentication and authorization succeeds, then | // Finally, if the authentication and authorization succeeds, then | ||||||
| // blocked must be false and error nil. The request will continue | // blocked must be false and error nil. The request will continue | ||||||
| // to be processed. | // to be processed. | ||||||
| func (f *Federator) Blocked(ctx context.Context, actorIRIs []*url.URL) (bool, error) { | func (f *FederatingProtocol) Blocked(ctx context.Context, actorIRIs []*url.URL) (bool, error) { | ||||||
| 	// TODO | 	// TODO | ||||||
| 	return false, nil | 	return false, nil | ||||||
| } | } | ||||||
|  | @ -191,7 +191,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) (pub.FederatingWrappedCallbacks, []interface{}, error) { | func (f *FederatingProtocol) FederatingCallbacks(ctx context.Context) (pub.FederatingWrappedCallbacks, []interface{}, error) { | ||||||
| 	// TODO | 	// TODO | ||||||
| 	return pub.FederatingWrappedCallbacks{}, nil, nil | 	return pub.FederatingWrappedCallbacks{}, nil, nil | ||||||
| } | } | ||||||
|  | @ -203,7 +203,7 @@ func (f *Federator) FederatingCallbacks(ctx context.Context) (pub.FederatingWrap | ||||||
| // 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 *FederatingProtocol) DefaultCallback(ctx context.Context, activity pub.Activity) error { | ||||||
| 	l := f.log.WithFields(logrus.Fields{ | 	l := f.log.WithFields(logrus.Fields{ | ||||||
| 		"func":   "DefaultCallback", | 		"func":   "DefaultCallback", | ||||||
| 		"aptype": activity.GetTypeName(), | 		"aptype": activity.GetTypeName(), | ||||||
|  | @ -216,7 +216,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 *FederatingProtocol) MaxInboxForwardingRecursionDepth(ctx context.Context) int { | ||||||
| 	// TODO | 	// TODO | ||||||
| 	return 0 | 	return 0 | ||||||
| } | } | ||||||
|  | @ -226,7 +226,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 *FederatingProtocol) MaxDeliveryRecursionDepth(ctx context.Context) int { | ||||||
| 	// TODO | 	// TODO | ||||||
| 	return 0 | 	return 0 | ||||||
| } | } | ||||||
|  | @ -238,7 +238,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 *FederatingProtocol) FilterForwarding(ctx context.Context, potentialRecipients []*url.URL, a pub.Activity) ([]*url.URL, error) { | ||||||
| 	// TODO | 	// TODO | ||||||
| 	return nil, nil | 	return nil, nil | ||||||
| } | } | ||||||
|  | @ -251,7 +251,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 *FederatingProtocol) GetInbox(ctx context.Context, r *http.Request) (vocab.ActivityStreamsOrderedCollectionPage, error) { | ||||||
| 	// TODO | 	// TODO | ||||||
| 	return nil, nil | 	return nil, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -83,7 +83,7 @@ func (suite *ProtocolTestSuite) TestPostInboxRequestBodyHook() { | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	})) | 	})) | ||||||
| 	// setup module being tested | 	// setup module being tested | ||||||
| 	federator := federation.NewFederator(suite.db, suite.log, suite.config, tc).(*federation.Federator) | 	federator := federation.NewFederatingProtocol(suite.db, suite.log, suite.config, tc).(*federation.FederatingProtocol) | ||||||
| 
 | 
 | ||||||
| 	// setup request | 	// setup request | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
|  | @ -156,7 +156,7 @@ func (suite *ProtocolTestSuite) TestAuthenticatePostInbox() { | ||||||
| 	})) | 	})) | ||||||
| 
 | 
 | ||||||
| 	// now setup module being tested, with the mock transport controller | 	// now setup module being tested, with the mock transport controller | ||||||
| 	federator := federation.NewFederator(suite.db, suite.log, suite.config, tc) | 	federator := federation.NewFederatingProtocol(suite.db, suite.log, suite.config, tc) | ||||||
| 
 | 
 | ||||||
| 	// setup request | 	// setup request | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ package gotosocial | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"net/http" | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/signal" | 	"os/signal" | ||||||
| 	"syscall" | 	"syscall" | ||||||
|  | @ -45,6 +46,7 @@ import ( | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/oauth" | 	"github.com/superseriousbusiness/gotosocial/internal/oauth" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/router" | 	"github.com/superseriousbusiness/gotosocial/internal/router" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/storage" | 	"github.com/superseriousbusiness/gotosocial/internal/storage" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/transport" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/typeutils" | 	"github.com/superseriousbusiness/gotosocial/internal/typeutils" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -72,6 +74,9 @@ var Run action.GTSAction = func(ctx context.Context, c *config.Config, log *logr | ||||||
| 	if err := distributor.Start(); err != nil { | 	if err := distributor.Start(); err != nil { | ||||||
| 		return fmt.Errorf("error starting distributor: %s", err) | 		return fmt.Errorf("error starting distributor: %s", err) | ||||||
| 	} | 	} | ||||||
|  | 	transportController := transport.NewController(c, &federation.Clock{}, http.DefaultClient, log) | ||||||
|  | 	federatingActor := federation.NewFederatingActor(dbService, transportController, c, log) | ||||||
|  | 	federator := federation.NewFederator(federatingActor, distributor) | ||||||
| 
 | 
 | ||||||
| 	// build converters and util | 	// build converters and util | ||||||
| 	ic := typeutils.NewConverter(c, dbService) | 	ic := typeutils.NewConverter(c, dbService) | ||||||
|  | @ -113,7 +118,7 @@ var Run action.GTSAction = func(ctx context.Context, c *config.Config, log *logr | ||||||
| 		return fmt.Errorf("error creating instance account: %s", err) | 		return fmt.Errorf("error creating instance account: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	gts, err := New(dbService, &cache.MockCache{}, router, federation.New(dbService, c, log), c) | 	gts, err := New(dbService, &cache.MockCache{}, router, federator, c) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("error creating gotosocial service: %s", err) | 		return fmt.Errorf("error creating gotosocial service: %s", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -21,10 +21,10 @@ package gotosocial | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-fed/activity/pub" |  | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/cache" | 	"github.com/superseriousbusiness/gotosocial/internal/cache" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/config" | 	"github.com/superseriousbusiness/gotosocial/internal/config" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/federation" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/router" | 	"github.com/superseriousbusiness/gotosocial/internal/router" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -38,23 +38,23 @@ type Gotosocial interface { | ||||||
| // New returns a new gotosocial server, initialized with the given configuration. | // New 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 New(db db.DB, cache cache.Cache, apiRouter router.Router, federationAPI pub.FederatingActor, config *config.Config) (Gotosocial, error) { | func New(db db.DB, cache cache.Cache, apiRouter router.Router, federator federation.Federator, config *config.Config) (Gotosocial, error) { | ||||||
| 	return &gotosocial{ | 	return &gotosocial{ | ||||||
| 		db:            db, | 		db:        db, | ||||||
| 		cache:         cache, | 		cache:     cache, | ||||||
| 		apiRouter:     apiRouter, | 		apiRouter: apiRouter, | ||||||
| 		federationAPI: federationAPI, | 		federator: federator, | ||||||
| 		config:        config, | 		config:    config, | ||||||
| 	}, nil | 	}, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // gotosocial fulfils the gotosocial interface. | // gotosocial fulfils the gotosocial interface. | ||||||
| type gotosocial struct { | type gotosocial struct { | ||||||
| 	db            db.DB | 	db        db.DB | ||||||
| 	cache         cache.Cache | 	cache     cache.Cache | ||||||
| 	apiRouter     router.Router | 	apiRouter router.Router | ||||||
| 	federationAPI pub.FederatingActor | 	federator federation.Federator | ||||||
| 	config        *config.Config | 	config    *config.Config | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Start starts up the gotosocial server. If something goes wrong | // Start starts up the gotosocial server. If something goes wrong | ||||||
|  |  | ||||||
|  | @ -64,6 +64,10 @@ var ( | ||||||
| 	// inboxPathRegex parses a path that validates and captures the username part from eg /users/example_username/inbox | 	// inboxPathRegex parses a path that validates and captures the username part from eg /users/example_username/inbox | ||||||
| 	inboxPathRegex = regexp.MustCompile(inboxPathRegexString) | 	inboxPathRegex = regexp.MustCompile(inboxPathRegexString) | ||||||
| 
 | 
 | ||||||
|  | 	outboxPathRegexString = fmt.Sprintf(`^/?%s/(%s)/%s$`, UsersPath, usernameRegexString, OutboxPath) | ||||||
|  | 	// outboxPathRegex parses a path that validates and captures the username part from eg /users/example_username/outbox | ||||||
|  | 	outboxPathRegex = regexp.MustCompile(outboxPathRegexString) | ||||||
|  | 
 | ||||||
| 	actorPathRegexString = fmt.Sprintf(`^?/%s/(%s)$`, ActorsPath, usernameRegexString) | 	actorPathRegexString = fmt.Sprintf(`^?/%s/(%s)$`, ActorsPath, usernameRegexString) | ||||||
| 	// actorPathRegex parses a path that validates and captures the username part from eg /actors/example_username | 	// actorPathRegex parses a path that validates and captures the username part from eg /actors/example_username | ||||||
| 	actorPathRegex = regexp.MustCompile(actorPathRegexString) | 	actorPathRegex = regexp.MustCompile(actorPathRegexString) | ||||||
|  |  | ||||||
|  | @ -137,6 +137,11 @@ func IsInboxPath(id *url.URL) bool { | ||||||
| 	return inboxPathRegex.MatchString(strings.ToLower(id.Path)) | 	return inboxPathRegex.MatchString(strings.ToLower(id.Path)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // IsOutboxPath returns true if the given URL path corresponds to eg /users/example_username/outbox | ||||||
|  | func IsOutboxPath(id *url.URL) bool { | ||||||
|  | 	return outboxPathRegex.MatchString(strings.ToLower(id.Path)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // IsInstanceActorPath returns true if the given URL path corresponds to eg /actors/example_username | // IsInstanceActorPath returns true if the given URL path corresponds to eg /actors/example_username | ||||||
| func IsInstanceActorPath(id *url.URL) bool { | func IsInstanceActorPath(id *url.URL) bool { | ||||||
| 	return actorPathRegex.MatchString(strings.ToLower(id.Path)) | 	return actorPathRegex.MatchString(strings.ToLower(id.Path)) | ||||||
|  | @ -195,3 +200,14 @@ func ParseInboxPath(id *url.URL) (username string, err error) { | ||||||
| 	username = matches[1] | 	username = matches[1] | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // ParseOutboxPath returns the username from a path such as /users/example_username/outbox | ||||||
|  | func ParseOutboxPath(id *url.URL) (username string, err error) { | ||||||
|  | 	matches := outboxPathRegex.FindStringSubmatch(id.Path) | ||||||
|  | 	if len(matches) != 2 { | ||||||
|  | 		err = fmt.Errorf("expected 2 matches but matches length was %d", len(matches)) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	username = matches[1] | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -19,8 +19,11 @@ | ||||||
| package testrig | package testrig | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"bytes" | ||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"net/http" | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/signal" | 	"os/signal" | ||||||
| 	"syscall" | 	"syscall" | ||||||
|  | @ -44,6 +47,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| // Run creates and starts a gotosocial testrig server | // Run creates and starts a gotosocial testrig server | ||||||
| var Run action.GTSAction = func(ctx context.Context, _ *config.Config, log *logrus.Logger) error { | var Run action.GTSAction = func(ctx context.Context, _ *config.Config, log *logrus.Logger) error { | ||||||
|  | 	c := NewTestConfig() | ||||||
| 	dbService := NewTestDB() | 	dbService := NewTestDB() | ||||||
| 	router := NewTestRouter() | 	router := NewTestRouter() | ||||||
| 	storageBackend := NewTestStorage() | 	storageBackend := NewTestStorage() | ||||||
|  | @ -54,8 +58,15 @@ var Run action.GTSAction = func(ctx context.Context, _ *config.Config, log *logr | ||||||
| 		return fmt.Errorf("error starting distributor: %s", err) | 		return fmt.Errorf("error starting distributor: %s", err) | ||||||
| 	} | 	} | ||||||
| 	mastoConverter := NewTestTypeConverter(dbService) | 	mastoConverter := NewTestTypeConverter(dbService) | ||||||
| 
 | 	transportController := NewTestTransportController(NewMockHTTPClient(func(req *http.Request) (*http.Response, error) { | ||||||
| 	c := NewTestConfig() | 		r := ioutil.NopCloser(bytes.NewReader([]byte{})) | ||||||
|  | 		return &http.Response{ | ||||||
|  | 			StatusCode: 200, | ||||||
|  | 			Body:       r, | ||||||
|  | 		}, nil | ||||||
|  | 	})) | ||||||
|  | 	federatingActor := federation.NewFederatingActor(dbService, transportController, c, log) | ||||||
|  | 	federator := federation.NewFederator(federatingActor, distributor) | ||||||
| 
 | 
 | ||||||
| 	StandardDBSetup(dbService) | 	StandardDBSetup(dbService) | ||||||
| 	StandardStorageSetup(storageBackend, "./testrig/media") | 	StandardStorageSetup(storageBackend, "./testrig/media") | ||||||
|  | @ -97,7 +108,7 @@ var Run action.GTSAction = func(ctx context.Context, _ *config.Config, log *logr | ||||||
| 	// 	return fmt.Errorf("error creating instance account: %s", err) | 	// 	return fmt.Errorf("error creating instance account: %s", err) | ||||||
| 	// } | 	// } | ||||||
| 
 | 
 | ||||||
| 	gts, err := gotosocial.New(dbService, &cache.MockCache{}, router, federation.New(dbService, c, log), c) | 	gts, err := gotosocial.New(dbService, &cache.MockCache{}, router, federator, c) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("error creating gotosocial service: %s", err) | 		return fmt.Errorf("error creating gotosocial service: %s", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue