diff options
author | Julio Capote <jcapote@gmail.com> | 2023-01-06 20:13:08 +0000 |
---|---|---|
committer | Julio Capote <jcapote@gmail.com> | 2023-01-06 20:13:08 +0000 |
commit | 997316d81e2dbd1a8f3a120e6d193fa66c8c37de (patch) | |
tree | 5a6f3ee0b3d99eace4f04dead45ce0f747294ce7 /delivery | |
parent | 77eefc2b9d955ef451ada989f8d15adc3d76885c (diff) | |
download | communique-997316d81e2dbd1a8f3a120e6d193fa66c8c37de.tar.gz |
refactor signed request
Diffstat (limited to 'delivery')
-rw-r--r-- | delivery/signed.go | 64 |
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 +} |