From 997316d81e2dbd1a8f3a120e6d193fa66c8c37de Mon Sep 17 00:00:00 2001 From: Julio Capote Date: Fri, 6 Jan 2023 15:13:08 -0500 Subject: refactor signed request --- delivery/signed.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 delivery/signed.go (limited to 'delivery/signed.go') 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 +} -- cgit v1.2.3