diff options
-rw-r--r-- | cgi/servers.go | 5 | ||||
-rw-r--r-- | delivery/signed.go | 64 | ||||
-rw-r--r-- | registry/registry.go | 32 |
3 files changed, 72 insertions, 29 deletions
diff --git a/cgi/servers.go b/cgi/servers.go index 0a87a62..44ffb1c 100644 --- a/cgi/servers.go +++ b/cgi/servers.go @@ -135,8 +135,9 @@ func processTick(h config.Handler, output []byte, persister *models.Persister, l } for _, v := range keys { parts := strings.Split(string(v), ":") - url := parts[2:] - logger.With("payload", payload).With("inboxUrl", url).Debugf("deliverying activity") + url := strings.Join(parts[2:], "") + logger.With("payload", payload).With("inboxUrl", url).Debugf("delivering activity") + } }) if err != nil { diff --git a/delivery/signed.go b/delivery/signed.go new file mode 100644 index 0000000..acf4df5 --- /dev/null +++ b/delivery/signed.go @@ -0,0 +1,64 @@ +package delivery + +import ( + "bytes" + "encoding/gob" + "net/http" + "net/url" + "sync" + "time" + + "git.capotej.com/capotej/communique/config" + "git.capotej.com/capotej/communique/models" + "github.com/go-fed/httpsig" +) + +type Signed struct { + signer httpsig.Signer + mu sync.Mutex + persister *models.Persister +} + +func NewSigned(persister *models.Persister) (*Signed, error) { + signed := &Signed{persister: persister} + var err error + prefs := []httpsig.Algorithm{} + digestAlgorithm := httpsig.DigestSha256 + headersToSign := []string{httpsig.RequestTarget, "host", "date", "digest"} + signed.signer, _, err = httpsig.NewSigner(prefs, digestAlgorithm, headersToSign, httpsig.Signature, 0) + if err != nil { + return nil, err + } + return signed, nil +} + +func (s *Signed) SignedRequest(handler config.Handler, payload []byte, inboxUrl, actorKeyUrl *url.URL) (*http.Request, error) { + aso := models.NewKeypair(handler) + result, err := s.persister.Find(aso) + if err != nil { + return nil, err + } + buf := bytes.NewBuffer(result) + dec := gob.NewDecoder(buf) + var keypair models.Keypair + err = dec.Decode(&keypair) + if err != nil { + return nil, err + } + privKey := &keypair.PrivateKey + + request, err := http.NewRequest("POST", inboxUrl.String(), bytes.NewBuffer(payload)) + date := time.Now().UTC().Format(http.TimeFormat) + request.Header.Set("Date", date) + request.Header.Set("Content-Type", "application/activity+json") + request.Header.Set("Host", inboxUrl.Host) + + s.mu.Lock() + err = s.signer.SignRequest(privKey, actorKeyUrl.String(), request, payload) + s.mu.Unlock() + + if err != nil { + return nil, err + } + return request, nil +} diff --git a/registry/registry.go b/registry/registry.go index e15d861..aa61d58 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -12,17 +12,15 @@ import ( "net/http" "net/url" "strings" - "sync" - "time" "git.capotej.com/capotej/communique/config" + "git.capotej.com/capotej/communique/delivery" "git.capotej.com/capotej/communique/models" "git.capotej.com/capotej/communique/tools" "git.capotej.com/capotej/communique/urls" "git.capotej.com/capotej/communique/views" "github.com/go-fed/activity/streams" "github.com/go-fed/activity/streams/vocab" - "github.com/go-fed/httpsig" "go.uber.org/zap" ) @@ -36,8 +34,7 @@ type Registry struct { persister *models.Persister handlerMap map[string]Handler log *zap.SugaredLogger - signer httpsig.Signer - mu sync.Mutex + delivery *delivery.Signed } func NewRegistry(cfg config.Config, persister *models.Persister, log *zap.SugaredLogger) (*Registry, error) { @@ -51,10 +48,7 @@ func NewRegistry(cfg config.Config, persister *models.Persister, log *zap.Sugare return nil, err } } - prefs := []httpsig.Algorithm{} - digestAlgorithm := httpsig.DigestSha256 - headersToSign := []string{httpsig.RequestTarget, "host", "date", "digest"} - reg.signer, _, err = httpsig.NewSigner(prefs, digestAlgorithm, headersToSign, httpsig.Signature, 0) + reg.delivery, err = delivery.NewSigned(persister) if err != nil { return nil, err } @@ -261,30 +255,14 @@ func (r *Registry) deliverAcceptToInbox(url, actorUrl, actorKeyUrl *url.URL, fol return err } jsonData, err := json.Marshal(payload) - - aso := models.NewKeypair(handler) - result, err := r.persister.Find(aso) if err != nil { return err } - buf := bytes.NewBuffer(result) - dec := gob.NewDecoder(buf) - var keypair models.Keypair - err = dec.Decode(&keypair) + + request, err := r.delivery.SignedRequest(handler, jsonData, url, actorKeyUrl) if err != nil { return err } - privKey := &keypair.PrivateKey - - request, err := http.NewRequest("POST", url.String(), bytes.NewBuffer(jsonData)) - date := time.Now().UTC().Format(http.TimeFormat) - request.Header.Set("Date", date) - request.Header.Set("Content-Type", "application/activity+json") - request.Header.Set("Host", url.Host) - - r.mu.Lock() - err = r.signer.SignRequest(privKey, actorKeyUrl.String(), request, jsonData) - r.mu.Unlock() r.log.With( "type", |