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

24
http.go
View file

@ -10,7 +10,7 @@ import (
"github.com/gologme/log" "github.com/gologme/log"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/writefreely/go-nodeinfo" "github.com/writefreely/go-nodeinfo"
"github.com/go-fed/httpsig"
"encoding/json" "encoding/json"
) )
@ -190,7 +190,27 @@ func Serve(actors map[string]Actor) {
return return
} }
// TODO check if it's actually an activity // 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 // check if case is going to be an issue
switch activity["type"] { switch activity["type"] {
case "Follow": case "Follow":

View file

@ -1,13 +1,11 @@
package activityserve package activityserve
import ( import (
"bytes"
"encoding/json" "encoding/json"
"fmt" "encoding/pem"
"io/ioutil"
"net/http"
"github.com/gologme/log" "github.com/gologme/log"
"crypto/x509"
"crypto/rsa"
) )
// RemoteActor is a type that holds an actor // RemoteActor is a type that holds an actor
@ -16,20 +14,25 @@ type RemoteActor struct {
iri, outbox, inbox, sharedInbox string iri, outbox, inbox, sharedInbox string
url string url string
info map[string]interface{} info map[string]interface{}
publicKey *rsa.PublicKey
} }
// NewRemoteActor returns a remoteActor which holds // NewRemoteActor returns a remoteActor which holds
// all the info required for an actor we want to // all the info required for an actor we want to
// interact with (not essentially sitting in our instance) // interact with (not essentially sitting in our instance)
func NewRemoteActor(iri string) (RemoteActor, error) { func NewRemoteActor(iri string) (RemoteActor, error) {
info, err := get(iri) info, err := get(iri)
if err != nil { if err != nil {
log.Info("Couldn't get remote actor information") log.Info("Couldn't get remote actor information")
log.Info(err) log.Info(err)
return RemoteActor{}, 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) outbox, _ := info["outbox"].(string)
inbox, _ := info["inbox"].(string) inbox, _ := info["inbox"].(string)
url, _ := info["url"].(string) url, _ := info["url"].(string)
@ -48,6 +51,7 @@ func NewRemoteActor(iri string) (RemoteActor, error) {
inbox: inbox, inbox: inbox,
sharedInbox: sharedInbox, sharedInbox: sharedInbox,
url: url, url: url,
publicKey: spkiKey,
}, err }, 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) { func get(iri string) (info map[string]interface{}, err error) {
buf := new(bytes.Buffer) sactor,err := GetActor("server","Internal service actor","Service")
req, err := http.NewRequest("GET", iri, buf)
if err != nil { if err != nil {
log.Info("Failed to get service actor")
log.Info(err) log.Info(err)
return return
} }
req.Header.Add("Accept", "application/activity+json") responseData,err := sactor.signedHTTPGet(iri)
req.Header.Add("User-Agent", userAgent+" "+version)
req.Header.Add("Accept-Charset", "utf-8")
resp, err := client.Do(req)
if err != nil { if err != nil {
log.Info("Cannot perform the request") log.Info("Failed to make signed http get request")
log.Info(err) log.Info(err)
return 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{} var e interface{}
err = json.Unmarshal(responseData, &e) err = json.Unmarshal([]byte(responseData), &e)
if err != nil { if err != nil {
log.Info("something went wrong when unmarshalling the json") log.Info("something went wrong when unmarshalling the json")