Dereference remote replies (#132)

* decided where to put reply dereferencing

* fiddling with dereferencing threads

* further adventures

* tidy up some stuff

* move dereferencing functionality

* a bunch of refactoring

* go fmt

* more refactoring

* bleep bloop

* docs and linting

* start implementing replies collection on gts side

* fiddling around

* allow dereferencing our replies

* lint, fmt
This commit is contained in:
Tobi Smethurst 2021-08-10 13:32:39 +02:00 committed by GitHub
commit 0f2de6394a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 2946 additions and 1393 deletions

View file

@ -27,15 +27,19 @@ import (
"github.com/go-fed/httpsig"
"github.com/sirupsen/logrus"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
)
// Controller generates transports for use in making federation requests to other servers.
type Controller interface {
NewTransport(pubKeyID string, privkey crypto.PrivateKey) (Transport, error)
NewTransportForUsername(username string) (Transport, error)
}
type controller struct {
config *config.Config
db db.DB
clock pub.Clock
client pub.HttpClient
appAgent string
@ -43,9 +47,10 @@ type controller struct {
}
// NewController returns an implementation of the Controller interface for creating new transports
func NewController(config *config.Config, clock pub.Clock, client pub.HttpClient, log *logrus.Logger) Controller {
func NewController(config *config.Config, db db.DB, clock pub.Clock, client pub.HttpClient, log *logrus.Logger) Controller {
return &controller{
config: config,
db: db,
clock: clock,
client: client,
appAgent: fmt.Sprintf("%s %s", config.ApplicationName, config.Host),
@ -55,10 +60,10 @@ func NewController(config *config.Config, clock pub.Clock, client pub.HttpClient
// NewTransport returns a new http signature transport with the given public key id (a URL), and the given private key.
func (c *controller) NewTransport(pubKeyID string, privkey crypto.PrivateKey) (Transport, error) {
prefs := []httpsig.Algorithm{httpsig.RSA_SHA256, httpsig.RSA_SHA512}
prefs := []httpsig.Algorithm{httpsig.RSA_SHA512}
digestAlgo := httpsig.DigestSha256
getHeaders := []string{"(request-target)", "host", "date"}
postHeaders := []string{"(request-target)", "host", "date", "digest"}
getHeaders := []string{httpsig.RequestTarget, "host", "date"}
postHeaders := []string{httpsig.RequestTarget, "host", "date", "digest"}
getSigner, _, err := httpsig.NewSigner(prefs, digestAlgo, getHeaders, httpsig.Signature, 120)
if err != nil {
@ -85,3 +90,25 @@ func (c *controller) NewTransport(pubKeyID string, privkey crypto.PrivateKey) (T
log: c.log,
}, nil
}
func (c *controller) NewTransportForUsername(username string) (Transport, error) {
// We need an account to use to create a transport for dereferecing something.
// If a username has been given, we can fetch the account with that username and use it.
// Otherwise, we can take the instance account and use those credentials to make the request.
ourAccount := &gtsmodel.Account{}
var u string
if username == "" {
u = c.config.Host
} else {
u = username
}
if err := c.db.GetLocalAccountByUsername(u, ourAccount); err != nil {
return nil, fmt.Errorf("error getting account %s from db: %s", username, err)
}
transport, err := c.NewTransport(ourAccount.PublicKeyURI, ourAccount.PrivateKey)
if err != nil {
return nil, fmt.Errorf("error creating transport for user %s: %s", username, err)
}
return transport, nil
}