feature,fix: add request validation and fix attachment
This commit is contained in:
parent
3e0a6353c9
commit
8597ae7147
3 changed files with 42 additions and 38 deletions
11
actor.go
11
actor.go
|
@ -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
24
http.go
|
@ -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":
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
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
|
||||
|
@ -16,20 +14,25 @@ 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")
|
||||
|
|
Loading…
Reference in a new issue