aboutsummaryrefslogtreecommitdiff
path: root/registry/registry.go
diff options
context:
space:
mode:
authorJulio Capote <jcapote@gmail.com>2023-01-05 02:15:57 +0000
committerJulio Capote <jcapote@gmail.com>2023-01-05 02:15:57 +0000
commite9124914cd6b05502cb5dd7f34720b27657560aa (patch)
tree72c68e673a88e8bd88d02ff22c80d0d17ccb8b88 /registry/registry.go
parent6736b04552c582ab5a07556ba20eca92612daf51 (diff)
downloadcommunique-e9124914cd6b05502cb5dd7f34720b27657560aa.tar.gz
refactor verification into verifier tool, start follow/undo
Diffstat (limited to 'registry/registry.go')
-rw-r--r--registry/registry.go79
1 files changed, 25 insertions, 54 deletions
diff --git a/registry/registry.go b/registry/registry.go
index 6f47f8a..aca1db7 100644
--- a/registry/registry.go
+++ b/registry/registry.go
@@ -7,19 +7,17 @@ import (
"encoding/gob"
"encoding/json"
"encoding/pem"
- "fmt"
- "io"
"net/http"
"net/url"
"strings"
"git.capotej.com/capotej/communique/config"
"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"
)
@@ -157,81 +155,54 @@ func (r *Registry) Followers(name string) (map[string]interface{}, error) {
return result, nil
}
-func (r *Registry) Inbox(name string, req *http.Request) error {
+func (r *Registry) Inbox(name string, req *http.Request, payload []byte) error {
handler := r.findByName(name)
if handler == nil {
return nil
}
- logger := r.log.With("type", "inbox")
domainUrl, err := url.Parse(r.cfg.Domain)
if err != nil {
return err
}
+ logger := r.log.With("type", "inbox")
+
if req.Host != domainUrl.Host {
logger.Warnf("%s != %s, configured domain should match incoming Host: header otherwise things may not work right. You'll need to enable 'ProxyPreserveHost' (for apache2) or proxy_set_header Host $host; (for nginx)", req.Host, r.cfg.Domain)
}
- verifier, err := httpsig.NewVerifier(req)
- if err != nil {
- return err
- }
-
- keyId := verifier.KeyId()
- logger.With("keyId", keyId).Debugf("fetching")
- req, err = http.NewRequest("GET", keyId, nil)
- req.Header.Set("Accept", "application/json; charset=UTF-8")
+ ctx := context.Background()
- client := &http.Client{}
- resp, err := client.Do(req)
- if err != nil {
- return err
+ person, verifyError := tools.VerifyRequest(ctx, req, r.log)
+ if verifyError != nil {
+ return verifyError
}
- defer resp.Body.Close()
- keyPage, err := io.ReadAll(resp.Body)
- logger.With("keyId", keyId).With("response", string(keyPage)).Debugf("received response")
- var keyPageData map[string]interface{}
- err = json.Unmarshal(keyPage, &keyPageData)
+
+ var followData map[string]interface{}
+ err = json.Unmarshal(payload, &followData)
if err != nil {
return err
}
- var person vocab.ActivityStreamsPerson
-
- resolver, err := streams.NewJSONResolver(func(c context.Context, p vocab.ActivityStreamsPerson) error {
- // Store the person in the enclosing scope, for later.
- person = p
+ resolver, err := streams.NewJSONResolver(func(c context.Context, p vocab.ActivityStreamsFollow) error {
+ idProp := person.GetJSONLDId()
+ idPropUrl := idProp.Get()
+ inboxProp := person.GetActivityStreamsInbox()
+ url := inboxProp.GetIRI()
+ logger.With("actor", idPropUrl).With("inbox", url).Debugf("follow")
return nil
- }, func(c context.Context, note vocab.ActivityStreamsNote) error {
- //TODO not needed, need to figure out how to only pass one func
+ }, func(c context.Context, note vocab.ActivityStreamsUndo) error {
+ idProp := person.GetJSONLDId()
+ idPropUrl := idProp.Get()
+ inboxProp := person.GetActivityStreamsInbox()
+ url := inboxProp.GetIRI()
+ logger.With("actor", idPropUrl).With("inbox", url).Debugf("undo")
return nil
})
+ err = resolver.Resolve(ctx, followData)
- ctx := context.Background()
- err = resolver.Resolve(ctx, keyPageData)
-
- pubKeyProp := person.GetW3IDSecurityV1PublicKey()
- iter := pubKeyProp.At(0) // TODO not safe
- pubKey := iter.Get()
- pemProp := pubKey.GetW3IDSecurityV1PublicKeyPem()
- pemStr := pemProp.Get()
- logger.With("keyId", keyId).With("pem", pemStr).Debugf("extracted pem")
- pemObj, _ := pem.Decode([]byte(pemStr))
- if pemObj == nil {
- return fmt.Errorf("no PEM block found")
- }
- if pemObj.Type != "PUBLIC KEY" {
- return fmt.Errorf("no public key found in PEM block")
- }
-
- decodedKey, err := x509.ParsePKIXPublicKey(pemObj.Bytes)
- if err != nil {
- return err
- }
- logger.With("keyId", keyId).With("pem", pemStr).Debugf("got %T", decodedKey)
- algo := httpsig.RSA_SHA256
- return verifier.Verify(decodedKey, algo)
+ return nil
}
func (r *Registry) ActivityOrNote(activityOrNote, name, id string) (map[string]interface{}, error) {