feature,fix: add request validation and fix attachment

This commit is contained in:
doesnm 2024-05-16 22:31:02 +03:00
parent 3e0a6353c9
commit 8597ae7147
3 changed files with 42 additions and 38 deletions

View file

@ -28,12 +28,7 @@ import (
// Actor represents a local actor we can act on
// behalf of.
//type Attachment struct {
// Type string
// Name string
// Href string
// Rel string
//}
type Actor struct {
Name, summary, actorType, iri string
@ -70,7 +65,7 @@ func MakeActor(name, summary, actorType string) (Actor, error) {
following := make(map[string]interface{})
rejected := make(map[string]interface{})
requested := make(map[string]interface{})
var attachment []interface{}
attachment := make([]interface{},0)
followersIRI := baseURL + name + "/followers"
publicKeyID := baseURL + name + "#main-key"
iri := baseURL + name
@ -358,7 +353,7 @@ func (a *Actor) CreateNote(content, inReplyTo string,attachment []interface{}) {
if inReplyTo != "" {
note["inReplyTo"] = inReplyTo
}
if inReplyTo != nil {
if attachment != nil {
note["attachment"] = attachment
}
note["id"] = id

24
http.go
View file

@ -10,7 +10,7 @@ import (
"github.com/gologme/log"
"github.com/gorilla/mux"
"github.com/writefreely/go-nodeinfo"
"github.com/go-fed/httpsig"
"encoding/json"
)
@ -190,7 +190,27 @@ func Serve(actors map[string]Actor) {
return
}
// TODO check if it's actually an activity
verifier, err := httpsig.NewVerifier(r)
if err != nil {
log.Error("Error then creating verifier")
w.WriteHeader(http.StatusUnauthorized)
return
}
pubKeyId := verifier.KeyId()
algo := httpsig.RSA_SHA256
ra,err := NewRemoteActor(pubKeyId)
if err != nil {
log.Error("Can't fetch remote actor")
w.WriteHeader(http.StatusUnauthorized)
return
}
verified := verifier.Verify(ra.publicKey, algo)
log.Info(verified)
if verified != nil {
log.Error("Signature mismatch")
w.WriteHeader(http.StatusUnauthorized)
return
}
// check if case is going to be an issue
switch activity["type"] {
case "Follow":

View file

@ -1,35 +1,38 @@
package activityserve
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"encoding/pem"
"github.com/gologme/log"
"crypto/x509"
"crypto/rsa"
)
// RemoteActor is a type that holds an actor
// that we want to interact with
// that we want to interact with
type RemoteActor struct {
iri, outbox, inbox, sharedInbox string
url string
info map[string]interface{}
publicKey *rsa.PublicKey
}
// NewRemoteActor returns a remoteActor which holds
// all the info required for an actor we want to
// interact with (not essentially sitting in our instance)
func NewRemoteActor(iri string) (RemoteActor, error) {
info, err := get(iri)
if err != nil {
log.Info("Couldn't get remote actor information")
log.Info(err)
return RemoteActor{}, err
}
publicKeyBlock := info["publicKey"].(map[string]interface {})
publicKeyPem := publicKeyBlock["publicKeyPem"].(string)
spkiBlock, _ := pem.Decode([]byte(publicKeyPem))
var spkiKey *rsa.PublicKey
pubInterface, _ := x509.ParsePKIXPublicKey(spkiBlock.Bytes)
spkiKey = pubInterface.(*rsa.PublicKey)
outbox, _ := info["outbox"].(string)
inbox, _ := info["inbox"].(string)
url, _ := info["url"].(string)
@ -48,6 +51,7 @@ func NewRemoteActor(iri string) (RemoteActor, error) {
inbox: inbox,
sharedInbox: sharedInbox,
url: url,
publicKey: spkiKey,
}, err
}
@ -57,35 +61,20 @@ func (ra RemoteActor) getLatestPosts(number int) (map[string]interface{}, error)
func get(iri string) (info map[string]interface{}, err error) {
buf := new(bytes.Buffer)
req, err := http.NewRequest("GET", iri, buf)
sactor,err := GetActor("server","Internal service actor","Service")
if err != nil {
log.Info("Failed to get service actor")
log.Info(err)
return
}
req.Header.Add("Accept", "application/activity+json")
req.Header.Add("User-Agent", userAgent+" "+version)
req.Header.Add("Accept-Charset", "utf-8")
resp, err := client.Do(req)
responseData,err := sactor.signedHTTPGet(iri)
if err != nil {
log.Info("Cannot perform the request")
log.Info("Failed to make signed http get request")
log.Info(err)
return
}
responseData, _ := ioutil.ReadAll(resp.Body)
if !isSuccess(resp.StatusCode) {
err = fmt.Errorf("GET request to %s failed (%d): %s\nResponse: %s \nHeaders: %s", iri, resp.StatusCode, resp.Status, FormatJSON(responseData), FormatHeaders(req.Header))
log.Info(err)
return
}
var e interface{}
err = json.Unmarshal(responseData, &e)
err = json.Unmarshal([]byte(responseData), &e)
if err != nil {
log.Info("something went wrong when unmarshalling the json")