aboutsummaryrefslogtreecommitdiff
path: root/delivery
diff options
context:
space:
mode:
authorJulio Capote <jcapote@gmail.com>2023-01-06 20:13:08 +0000
committerJulio Capote <jcapote@gmail.com>2023-01-06 20:13:08 +0000
commit997316d81e2dbd1a8f3a120e6d193fa66c8c37de (patch)
tree5a6f3ee0b3d99eace4f04dead45ce0f747294ce7 /delivery
parent77eefc2b9d955ef451ada989f8d15adc3d76885c (diff)
downloadcommunique-997316d81e2dbd1a8f3a120e6d193fa66c8c37de.tar.gz
refactor signed request
Diffstat (limited to 'delivery')
-rw-r--r--delivery/signed.go64
1 files changed, 64 insertions, 0 deletions
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
+}