mirror of
https://github.com/writefreely/writefreely
synced 2024-11-24 01:23:04 +00:00
fixes issue #100 - can't follow from pubgate
this moves the unmarshaling of a remote actor out into a new helper which accounts for the possibility of a context being a list or a single entity. i.e. a string or an object. basics tests are provided for both situations also go fmt'd the file activitypub.go
This commit is contained in:
parent
3986c8eec1
commit
ff2d3fc3d5
3 changed files with 87 additions and 8 deletions
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"go.formatTool": "goimports"
|
||||||
|
}
|
|
@ -17,6 +17,13 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httputil"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/go-sql-driver/mysql"
|
"github.com/go-sql-driver/mysql"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/writeas/activity/streams"
|
"github.com/writeas/activity/streams"
|
||||||
|
@ -26,12 +33,6 @@ import (
|
||||||
"github.com/writeas/web-core/activitypub"
|
"github.com/writeas/web-core/activitypub"
|
||||||
"github.com/writeas/web-core/activitystreams"
|
"github.com/writeas/web-core/activitystreams"
|
||||||
"github.com/writeas/web-core/log"
|
"github.com/writeas/web-core/log"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httputil"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -647,8 +648,7 @@ func getActor(app *app, actorIRI string) (*activitystreams.Person, *RemoteUser,
|
||||||
log.Error("Unable to get actor! %v", err)
|
log.Error("Unable to get actor! %v", err)
|
||||||
return nil, nil, impart.HTTPError{http.StatusInternalServerError, "Couldn't fetch actor."}
|
return nil, nil, impart.HTTPError{http.StatusInternalServerError, "Couldn't fetch actor."}
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(actorResp, &actor); err != nil {
|
if err := unmarshalActor(actorResp, actor); err != nil {
|
||||||
// FIXME: Hubzilla has an object for the Actor's url: cannot unmarshal object into Go struct field Person.url of type string
|
|
||||||
log.Error("Unable to unmarshal actor! %v", err)
|
log.Error("Unable to unmarshal actor! %v", err)
|
||||||
return nil, nil, impart.HTTPError{http.StatusInternalServerError, "Couldn't parse actor."}
|
return nil, nil, impart.HTTPError{http.StatusInternalServerError, "Couldn't parse actor."}
|
||||||
}
|
}
|
||||||
|
@ -663,3 +663,48 @@ func getActor(app *app, actorIRI string) (*activitystreams.Person, *RemoteUser,
|
||||||
}
|
}
|
||||||
return actor, remoteUser, nil
|
return actor, remoteUser, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unmarshal actor normalizes the actor response to conform to
|
||||||
|
// the type Person from github.com/writeas/web-core/activitysteams
|
||||||
|
//
|
||||||
|
// some implementations return different context field types
|
||||||
|
// this converts any non-slice contexts into a slice
|
||||||
|
func unmarshalActor(actorResp []byte, actor *activitystreams.Person) error {
|
||||||
|
// FIXME: Hubzilla has an object for the Actor's url: cannot unmarshal object into Go struct field Person.url of type string
|
||||||
|
|
||||||
|
// flexActor overrides the Context field to allow
|
||||||
|
// all valid representations during unmarshal
|
||||||
|
flexActor := struct {
|
||||||
|
activitystreams.Person
|
||||||
|
Context json.RawMessage `json:"@context,omitempty"`
|
||||||
|
}{}
|
||||||
|
if err := json.Unmarshal(actorResp, &flexActor); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
actor.Endpoints = flexActor.Endpoints
|
||||||
|
actor.Followers = flexActor.Followers
|
||||||
|
actor.Following = flexActor.Following
|
||||||
|
actor.ID = flexActor.ID
|
||||||
|
actor.Icon = flexActor.Icon
|
||||||
|
actor.Inbox = flexActor.Inbox
|
||||||
|
actor.Name = flexActor.Name
|
||||||
|
actor.Outbox = flexActor.Outbox
|
||||||
|
actor.PreferredUsername = flexActor.PreferredUsername
|
||||||
|
actor.PublicKey = flexActor.PublicKey
|
||||||
|
actor.Summary = flexActor.Summary
|
||||||
|
actor.Type = flexActor.Type
|
||||||
|
actor.URL = flexActor.URL
|
||||||
|
|
||||||
|
func(val interface{}) {
|
||||||
|
switch val.(type) {
|
||||||
|
case []interface{}:
|
||||||
|
// already a slice, do nothing
|
||||||
|
actor.Context = val.([]interface{})
|
||||||
|
default:
|
||||||
|
actor.Context = []interface{}{val}
|
||||||
|
}
|
||||||
|
}(flexActor.Context)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
31
activitypub_test.go
Normal file
31
activitypub_test.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package writefreely
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/writeas/web-core/activitystreams"
|
||||||
|
)
|
||||||
|
|
||||||
|
var actorTestTable = []struct {
|
||||||
|
Name string
|
||||||
|
Resp []byte
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"Context as a string",
|
||||||
|
[]byte(`{"@context":"https://www.w3.org/ns/activitystreams"}`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Context as a list",
|
||||||
|
[]byte(`{"@context":["one string", "two strings"]}`),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalActor(t *testing.T) {
|
||||||
|
for _, tc := range actorTestTable {
|
||||||
|
actor := activitystreams.Person{}
|
||||||
|
err := unmarshalActor(tc.Resp, &actor)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%s failed with error %s", tc.Name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue