mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-11-11 02:47:29 -06:00
parse various types of actor
This commit is contained in:
parent
8104a03bd5
commit
064f961008
11 changed files with 264 additions and 110 deletions
|
|
@ -145,7 +145,7 @@ func (suite *UserGetTestSuite) TestGetUser() {
|
|||
|
||||
// convert person to account
|
||||
// since this account is already known, we should get a pretty full model of it from the conversion
|
||||
a, err := suite.tc.ASPersonToAccount(person)
|
||||
a, err := suite.tc.ASRepresentationToAccount(person)
|
||||
assert.NoError(suite.T(), err)
|
||||
assert.EqualValues(suite.T(), targetAccount.Username, a.Username)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ func (f *federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWr
|
|||
return ctx, false, fmt.Errorf("error dereferencing account with public key id %s: %s", publicKeyOwnerURI.String(), err)
|
||||
}
|
||||
|
||||
a, err := f.typeConverter.ASPersonToAccount(person)
|
||||
a, err := f.typeConverter.ASRepresentationToAccount(person)
|
||||
if err != nil {
|
||||
return ctx, false, fmt.Errorf("error converting person with public key id %s to account: %s", publicKeyOwnerURI.String(), err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import (
|
|||
"net/url"
|
||||
|
||||
"github.com/go-fed/activity/pub"
|
||||
"github.com/go-fed/activity/streams/vocab"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
|
|
@ -38,9 +37,9 @@ type Federator interface {
|
|||
// AuthenticateFederatedRequest can be used to check the authenticity of incoming http-signed requests for federating resources.
|
||||
// The given username will be used to create a transport for making outgoing requests. See the implementation for more detailed comments.
|
||||
AuthenticateFederatedRequest(username string, r *http.Request) (*url.URL, error)
|
||||
// DereferenceRemoteAccount can be used to get the ActivityStreamsPerson representation of a remote account, based on the account ID (which is a URI).
|
||||
// DereferenceRemoteAccount can be used to get the representation of a remote account, based on the account ID (which is a URI).
|
||||
// The given username will be used to create a transport for making outgoing requests. See the implementation for more detailed comments.
|
||||
DereferenceRemoteAccount(username string, remoteAccountID *url.URL) (vocab.ActivityStreamsPerson, error)
|
||||
DereferenceRemoteAccount(username string, remoteAccountID *url.URL) (typeutils.Accountable, error)
|
||||
// GetTransportForUser returns a new transport initialized with the key credentials belonging to the given username.
|
||||
// This can be used for making signed http requests.
|
||||
GetTransportForUser(username string) (pub.Transport, error)
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import (
|
|||
"github.com/go-fed/activity/streams/vocab"
|
||||
"github.com/go-fed/httpsig"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
|
||||
)
|
||||
|
||||
/*
|
||||
|
|
@ -177,7 +178,7 @@ func (f *federator) AuthenticateFederatedRequest(username string, r *http.Reques
|
|||
return pkOwnerURI, nil
|
||||
}
|
||||
|
||||
func (f *federator) DereferenceRemoteAccount(username string, remoteAccountID *url.URL) (vocab.ActivityStreamsPerson, error) {
|
||||
func (f *federator) DereferenceRemoteAccount(username string, remoteAccountID *url.URL) (typeutils.Accountable, error) {
|
||||
|
||||
transport, err := f.GetTransportForUser(username)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ func (p *processor) authenticateAndDereferenceFediRequest(username string, r *ht
|
|||
}
|
||||
|
||||
// convert it to our internal account representation
|
||||
requestingAccount, err = p.tc.ASPersonToAccount(requestingPerson)
|
||||
requestingAccount, err = p.tc.ASRepresentationToAccount(requestingPerson)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't convert dereferenced uri %s to gtsmodel account: %s", requestingAccountURI.String(), err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,30 +19,100 @@
|
|||
package typeutils
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/go-fed/activity/pub"
|
||||
"github.com/go-fed/activity/streams/vocab"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/media"
|
||||
)
|
||||
|
||||
type usernameable interface {
|
||||
// Accountable represents the minimum activitypub interface for representing an 'account'.
|
||||
// This interface is fulfilled by, for example, vocab.ActivityStreamsPerson and vocab.ActivityStreamsApplication
|
||||
type Accountable interface {
|
||||
withJSONLDId
|
||||
withGetTypeName
|
||||
withPreferredUsername
|
||||
withIcon
|
||||
withDisplayName
|
||||
withImage
|
||||
withSummary
|
||||
withDiscoverable
|
||||
withURL
|
||||
withPublicKey
|
||||
withInbox
|
||||
withOutbox
|
||||
withFollowing
|
||||
withFollowers
|
||||
withFeatured
|
||||
}
|
||||
|
||||
// all the interfaces below narrow down one particular field of an activity streams object for easy extraction
|
||||
|
||||
type withJSONLDId interface {
|
||||
GetJSONLDId() vocab.JSONLDIdProperty
|
||||
}
|
||||
|
||||
type withGetTypeName interface {
|
||||
GetTypeName() string
|
||||
}
|
||||
|
||||
type withPreferredUsername interface {
|
||||
GetActivityStreamsPreferredUsername() vocab.ActivityStreamsPreferredUsernameProperty
|
||||
}
|
||||
|
||||
type iconable interface {
|
||||
type withIcon interface {
|
||||
GetActivityStreamsIcon() vocab.ActivityStreamsIconProperty
|
||||
}
|
||||
|
||||
type displaynameable interface {
|
||||
type withDisplayName interface {
|
||||
GetActivityStreamsName() vocab.ActivityStreamsNameProperty
|
||||
}
|
||||
|
||||
type imageable interface {
|
||||
type withImage interface {
|
||||
GetActivityStreamsImage() vocab.ActivityStreamsImageProperty
|
||||
}
|
||||
|
||||
func extractPreferredUsername(i usernameable) (string, error) {
|
||||
type withSummary interface {
|
||||
GetActivityStreamsSummary() vocab.ActivityStreamsSummaryProperty
|
||||
}
|
||||
|
||||
type withDiscoverable interface {
|
||||
GetTootDiscoverable() vocab.TootDiscoverableProperty
|
||||
}
|
||||
|
||||
type withURL interface {
|
||||
GetActivityStreamsUrl() vocab.ActivityStreamsUrlProperty
|
||||
}
|
||||
|
||||
type withPublicKey interface {
|
||||
GetW3IDSecurityV1PublicKey() vocab.W3IDSecurityV1PublicKeyProperty
|
||||
}
|
||||
|
||||
type withInbox interface {
|
||||
GetActivityStreamsInbox() vocab.ActivityStreamsInboxProperty
|
||||
}
|
||||
|
||||
type withOutbox interface {
|
||||
GetActivityStreamsOutbox() vocab.ActivityStreamsOutboxProperty
|
||||
}
|
||||
|
||||
type withFollowing interface {
|
||||
GetActivityStreamsFollowing() vocab.ActivityStreamsFollowingProperty
|
||||
}
|
||||
|
||||
type withFollowers interface {
|
||||
GetActivityStreamsFollowers() vocab.ActivityStreamsFollowersProperty
|
||||
}
|
||||
|
||||
type withFeatured interface {
|
||||
GetTootFeatured() vocab.TootFeaturedProperty
|
||||
}
|
||||
|
||||
func extractPreferredUsername(i withPreferredUsername) (string, error) {
|
||||
u := i.GetActivityStreamsPreferredUsername()
|
||||
if u == nil || !u.IsXMLSchemaString() {
|
||||
return "", errors.New("preferredUsername was not a string")
|
||||
|
|
@ -53,7 +123,7 @@ func extractPreferredUsername(i usernameable) (string, error) {
|
|||
return u.GetXMLSchemaString(), nil
|
||||
}
|
||||
|
||||
func extractName(i displaynameable) (string, error) {
|
||||
func extractName(i withDisplayName) (string, error) {
|
||||
nameProp := i.GetActivityStreamsName()
|
||||
if nameProp == nil {
|
||||
return "", errors.New("activityStreamsName not found")
|
||||
|
|
@ -75,7 +145,7 @@ func extractName(i displaynameable) (string, error) {
|
|||
// "type": "Image",
|
||||
// "url": "http://example.org/path/to/some/file.jpeg"
|
||||
// },
|
||||
func extractIconURL(i iconable) (*url.URL, error) {
|
||||
func extractIconURL(i withIcon) (*url.URL, error) {
|
||||
iconProp := i.GetActivityStreamsIcon()
|
||||
if iconProp == nil {
|
||||
return nil, errors.New("icon property was nil")
|
||||
|
|
@ -84,8 +154,7 @@ func extractIconURL(i iconable) (*url.URL, error) {
|
|||
// icon can potentially contain multiple entries, so we iterate through all of them
|
||||
// here in order to find the first one that meets these criteria:
|
||||
// 1. is an image
|
||||
// 2. is a supported type
|
||||
// 3. has a URL so we can grab it
|
||||
// 2. has a URL so we can grab it
|
||||
for iconIter := iconProp.Begin(); iconIter != iconProp.End(); iconIter = iconIter.Next() {
|
||||
// 1. is an image
|
||||
if !iconIter.IsActivityStreamsImage() {
|
||||
|
|
@ -96,43 +165,23 @@ func extractIconURL(i iconable) (*url.URL, error) {
|
|||
continue
|
||||
}
|
||||
|
||||
// 2. is a supported type
|
||||
imageType := imageValue.GetActivityStreamsMediaType()
|
||||
if imageType == nil || !media.SupportedImageType(imageType.Get()) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 3. has a URL so we can grab it
|
||||
imageURLProp := imageValue.GetActivityStreamsUrl()
|
||||
if imageURLProp == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// URL is also an iterable!
|
||||
// so let's take the first valid one we can find
|
||||
for urlIter := imageURLProp.Begin(); urlIter != imageURLProp.End(); urlIter = urlIter.Next() {
|
||||
if !urlIter.IsIRI() {
|
||||
continue
|
||||
}
|
||||
if urlIter.GetIRI() == nil {
|
||||
continue
|
||||
}
|
||||
// found it!!!
|
||||
return urlIter.GetIRI(), nil
|
||||
// 2. has a URL so we can grab it
|
||||
url, err := extractURL(imageValue)
|
||||
if err == nil && url != nil {
|
||||
return url, nil
|
||||
}
|
||||
}
|
||||
// if we get to this point we didn't find an icon meeting our criteria :'(
|
||||
return nil, errors.New("could not extract valid image from icon")
|
||||
}
|
||||
|
||||
|
||||
// extractImageURL extracts a URL to a supported image file from something like:
|
||||
// "image": {
|
||||
// "mediaType": "image/jpeg",
|
||||
// "type": "Image",
|
||||
// "url": "http://example.org/path/to/some/file.jpeg"
|
||||
// },
|
||||
func extractImageURL(i imageable) (*url.URL, error) {
|
||||
func extractImageURL(i withImage) (*url.URL, error) {
|
||||
imageProp := i.GetActivityStreamsImage()
|
||||
if imageProp == nil {
|
||||
return nil, errors.New("icon property was nil")
|
||||
|
|
@ -141,8 +190,7 @@ func extractImageURL(i imageable) (*url.URL, error) {
|
|||
// icon can potentially contain multiple entries, so we iterate through all of them
|
||||
// here in order to find the first one that meets these criteria:
|
||||
// 1. is an image
|
||||
// 2. is a supported type
|
||||
// 3. has a URL so we can grab it
|
||||
// 2. has a URL so we can grab it
|
||||
for imageIter := imageProp.Begin(); imageIter != imageProp.End(); imageIter = imageIter.Next() {
|
||||
// 1. is an image
|
||||
if !imageIter.IsActivityStreamsImage() {
|
||||
|
|
@ -153,31 +201,99 @@ func extractImageURL(i imageable) (*url.URL, error) {
|
|||
continue
|
||||
}
|
||||
|
||||
// 2. is a supported type
|
||||
imageType := imageValue.GetActivityStreamsMediaType()
|
||||
if imageType == nil || !media.SupportedImageType(imageType.Get()) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 3. has a URL so we can grab it
|
||||
imageURLProp := imageValue.GetActivityStreamsUrl()
|
||||
if imageURLProp == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// URL is also an iterable!
|
||||
// so let's take the first valid one we can find
|
||||
for urlIter := imageURLProp.Begin(); urlIter != imageURLProp.End(); urlIter = urlIter.Next() {
|
||||
if !urlIter.IsIRI() {
|
||||
continue
|
||||
}
|
||||
if urlIter.GetIRI() == nil {
|
||||
continue
|
||||
}
|
||||
// found it!!!
|
||||
return urlIter.GetIRI(), nil
|
||||
// 2. has a URL so we can grab it
|
||||
url, err := extractURL(imageValue)
|
||||
if err == nil && url != nil {
|
||||
return url, nil
|
||||
}
|
||||
}
|
||||
// if we get to this point we didn't find an image meeting our criteria :'(
|
||||
return nil, errors.New("could not extract valid image from image property")
|
||||
}
|
||||
|
||||
func extractSummary(i withSummary) (string, error) {
|
||||
summaryProp := i.GetActivityStreamsSummary()
|
||||
if summaryProp == nil {
|
||||
return "", errors.New("summary property was nil")
|
||||
}
|
||||
|
||||
for summaryIter := summaryProp.Begin(); summaryIter != summaryProp.End(); summaryIter = summaryIter.Next() {
|
||||
if summaryIter.IsXMLSchemaString() && summaryIter.GetXMLSchemaString() != "" {
|
||||
return summaryIter.GetXMLSchemaString(), nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", errors.New("could not extract summary")
|
||||
}
|
||||
|
||||
func extractDiscoverable(i withDiscoverable) (bool, error) {
|
||||
if i.GetTootDiscoverable() == nil {
|
||||
return false, errors.New("discoverable was nil")
|
||||
}
|
||||
return i.GetTootDiscoverable().Get(), nil
|
||||
}
|
||||
|
||||
func extractURL(i withURL) (*url.URL, error) {
|
||||
urlProp := i.GetActivityStreamsUrl()
|
||||
if urlProp == nil {
|
||||
return nil, errors.New("url property was nil")
|
||||
}
|
||||
|
||||
for urlIter := urlProp.Begin(); urlIter != urlProp.End(); urlIter = urlIter.Next() {
|
||||
if urlIter.IsIRI() && urlIter.GetIRI() != nil {
|
||||
return urlIter.GetIRI(), nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("could not extract url")
|
||||
}
|
||||
|
||||
func extractPublicKeyForOwner(i withPublicKey, forOwner *url.URL) (*rsa.PublicKey, *url.URL, error) {
|
||||
publicKeyProp := i.GetW3IDSecurityV1PublicKey()
|
||||
if publicKeyProp == nil {
|
||||
return nil, nil, errors.New("public key property was nil")
|
||||
}
|
||||
|
||||
for publicKeyIter := publicKeyProp.Begin(); publicKeyIter != publicKeyProp.End(); publicKeyIter = publicKeyIter.Next() {
|
||||
pkey := publicKeyIter.Get()
|
||||
if pkey == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
pkeyID, err := pub.GetId(pkey)
|
||||
if err != nil || pkeyID == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if pkey.GetW3IDSecurityV1Owner() == nil || pkey.GetW3IDSecurityV1Owner().Get() == nil || pkey.GetW3IDSecurityV1Owner().Get().String() != forOwner.String() {
|
||||
continue
|
||||
}
|
||||
|
||||
if pkey.GetW3IDSecurityV1PublicKeyPem() == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
pkeyPem := pkey.GetW3IDSecurityV1PublicKeyPem().Get()
|
||||
if pkeyPem == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
block, _ := pem.Decode([]byte(pkeyPem))
|
||||
if block == nil || block.Type != "PUBLIC KEY" {
|
||||
return nil, nil, errors.New("could not decode publicKeyPem to PUBLIC KEY pem block type")
|
||||
}
|
||||
|
||||
p, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("could not parse public key from block bytes: %s", err)
|
||||
}
|
||||
if p == nil {
|
||||
return nil, nil, errors.New("returned public key was empty")
|
||||
}
|
||||
|
||||
if publicKey, ok := p.(*rsa.PublicKey); ok {
|
||||
return publicKey, pkeyID, nil
|
||||
}
|
||||
}
|
||||
return nil, nil, errors.New("couldn't find public key")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,14 +22,13 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-fed/activity/streams/vocab"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
)
|
||||
|
||||
func (c *converter) ASPersonToAccount(person vocab.ActivityStreamsPerson) (*gtsmodel.Account, error) {
|
||||
// first check if we actually already know this person
|
||||
uriProp := person.GetJSONLDId()
|
||||
func (c *converter) ASRepresentationToAccount(accountable Accountable) (*gtsmodel.Account, error) {
|
||||
// first check if we actually already know this account
|
||||
uriProp := accountable.GetJSONLDId()
|
||||
if uriProp == nil || !uriProp.IsIRI() {
|
||||
return nil, errors.New("no id property found on person, or id was not an iri")
|
||||
}
|
||||
|
|
@ -52,7 +51,7 @@ func (c *converter) ASPersonToAccount(person vocab.ActivityStreamsPerson) (*gtsm
|
|||
|
||||
// Username aka preferredUsername
|
||||
// We need this one so bail if it's not set.
|
||||
username, err := extractPreferredUsername(person)
|
||||
username, err := extractPreferredUsername(accountable)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't extract username: %s", err)
|
||||
}
|
||||
|
|
@ -63,64 +62,103 @@ func (c *converter) ASPersonToAccount(person vocab.ActivityStreamsPerson) (*gtsm
|
|||
|
||||
// avatar aka icon
|
||||
// if this one isn't extractable in a format we recognise we'll just skip it
|
||||
if avatarURL, err := extractIconURL(person); err == nil {
|
||||
if avatarURL, err := extractIconURL(accountable); err == nil {
|
||||
acct.AvatarRemoteURL = avatarURL.String()
|
||||
}
|
||||
|
||||
// header aka image
|
||||
// if this one isn't extractable in a format we recognise we'll just skip it
|
||||
if headerURL, err := extractImageURL(person); err == nil {
|
||||
if headerURL, err := extractImageURL(accountable); err == nil {
|
||||
acct.HeaderRemoteURL = headerURL.String()
|
||||
}
|
||||
|
||||
// display name aka name
|
||||
// we default to the username, but take the more nuanced name property if it exists
|
||||
acct.DisplayName = username
|
||||
if displayName, err := extractName(person); err == nil {
|
||||
if displayName, err := extractName(accountable); err == nil {
|
||||
acct.DisplayName = displayName
|
||||
}
|
||||
|
||||
// fields aka attachment array
|
||||
// TODO
|
||||
// TODO: fields aka attachment array
|
||||
|
||||
// note aka summary
|
||||
// TODO
|
||||
note, err := extractSummary(accountable)
|
||||
if err == nil && note != "" {
|
||||
acct.Note = note
|
||||
}
|
||||
|
||||
// bot
|
||||
// TODO: parse this from application vs. person type
|
||||
// check for bot and actor type
|
||||
switch gtsmodel.ActivityStreamsActor(accountable.GetTypeName()) {
|
||||
case gtsmodel.ActivityStreamsPerson, gtsmodel.ActivityStreamsGroup, gtsmodel.ActivityStreamsOrganization:
|
||||
// people, groups, and organizations aren't bots
|
||||
acct.Bot = false
|
||||
// apps and services are
|
||||
case gtsmodel.ActivityStreamsApplication, gtsmodel.ActivityStreamsService:
|
||||
acct.Bot = true
|
||||
default:
|
||||
// we don't know what this is!
|
||||
return nil, fmt.Errorf("type name %s not recognised or not convertible to gtsmodel.ActivityStreamsActor", accountable.GetTypeName())
|
||||
}
|
||||
acct.ActorType = gtsmodel.ActivityStreamsActor(accountable.GetTypeName())
|
||||
|
||||
// locked aka manuallyApprovesFollowers
|
||||
// TODO
|
||||
// TODO: locked aka manuallyApprovesFollowers
|
||||
|
||||
// discoverable
|
||||
// TODO
|
||||
// default to false -- take custom value if it's set though
|
||||
acct.Discoverable = false
|
||||
discoverable, err := extractDiscoverable(accountable)
|
||||
if err == nil {
|
||||
acct.Discoverable = discoverable
|
||||
}
|
||||
|
||||
// url property
|
||||
// TODO
|
||||
url, err := extractURL(accountable)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not extract url for person with id %s: %s", uri.String(), err)
|
||||
}
|
||||
acct.URL = url.String()
|
||||
|
||||
// InboxURI
|
||||
// TODO
|
||||
if accountable.GetActivityStreamsInbox() == nil || accountable.GetActivityStreamsInbox().GetIRI() == nil {
|
||||
return nil, fmt.Errorf("person with id %s had no inbox uri", uri.String())
|
||||
}
|
||||
acct.InboxURI = accountable.GetActivityStreamsInbox().GetIRI().String()
|
||||
|
||||
// OutboxURI
|
||||
// TODO
|
||||
if accountable.GetActivityStreamsOutbox() == nil || accountable.GetActivityStreamsOutbox().GetIRI() == nil {
|
||||
return nil, fmt.Errorf("person with id %s had no outbox uri", uri.String())
|
||||
}
|
||||
acct.OutboxURI = accountable.GetActivityStreamsOutbox().GetIRI().String()
|
||||
|
||||
// FollowingURI
|
||||
// TODO
|
||||
if accountable.GetActivityStreamsFollowing() == nil || accountable.GetActivityStreamsFollowing().GetIRI() == nil {
|
||||
return nil, fmt.Errorf("person with id %s had no following uri", uri.String())
|
||||
}
|
||||
acct.FollowingURI = accountable.GetActivityStreamsFollowing().GetIRI().String()
|
||||
|
||||
// FollowersURI
|
||||
// TODO
|
||||
if accountable.GetActivityStreamsFollowers() == nil || accountable.GetActivityStreamsFollowers().GetIRI() == nil {
|
||||
return nil, fmt.Errorf("person with id %s had no followers uri", uri.String())
|
||||
}
|
||||
acct.FollowersURI = accountable.GetActivityStreamsFollowers().GetIRI().String()
|
||||
|
||||
// FeaturedURI
|
||||
// TODO
|
||||
// very much optional
|
||||
if accountable.GetTootFeatured() != nil && accountable.GetTootFeatured().GetIRI() != nil {
|
||||
acct.FeaturedCollectionURI = accountable.GetTootFeatured().GetIRI().String()
|
||||
}
|
||||
|
||||
// FeaturedTagsURI
|
||||
// TODO
|
||||
// TODO: FeaturedTagsURI
|
||||
|
||||
// alsoKnownAs
|
||||
// TODO
|
||||
// TODO: alsoKnownAs
|
||||
|
||||
// publicKey
|
||||
// TODO
|
||||
pkey, pkeyURL, err := extractPublicKeyForOwner(accountable, uri)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't get public key for person %s: %s", uri.String(), err)
|
||||
}
|
||||
acct.PublicKey = pkey
|
||||
acct.PublicKeyURI = pkeyURL.String()
|
||||
|
||||
return acct, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,11 +45,11 @@ func (suite *ASToInternalTestSuite) SetupTest() {
|
|||
testrig.StandardDBSetup(suite.db)
|
||||
}
|
||||
|
||||
func (suite *ASToInternalTestSuite) TestASPersonToAccount() {
|
||||
func (suite *ASToInternalTestSuite) TestASRepresentationToAccount() {
|
||||
|
||||
testPerson := suite.people["new_person_1"]
|
||||
|
||||
acct, err := suite.typeconverter.ASPersonToAccount(testPerson)
|
||||
acct, err := suite.typeconverter.ASRepresentationToAccount(testPerson)
|
||||
assert.NoError(suite.T(), err)
|
||||
|
||||
fmt.Printf("%+v", acct)
|
||||
|
|
|
|||
|
|
@ -85,8 +85,8 @@ type TypeConverter interface {
|
|||
ACTIVITYSTREAMS MODEL TO INTERNAL (gts) MODEL
|
||||
*/
|
||||
|
||||
// ASPersonToAccount converts an activitystreams person into a gts model account
|
||||
ASPersonToAccount(person vocab.ActivityStreamsPerson) (*gtsmodel.Account, error)
|
||||
// ASPersonToAccount converts a remote account/person/application representation into a gts model account
|
||||
ASRepresentationToAccount(accountable Accountable) (*gtsmodel.Account, error)
|
||||
|
||||
/*
|
||||
INTERNAL (gts) MODEL TO ACTIVITYSTREAMS MODEL
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
package typeutils_test
|
||||
|
||||
import (
|
||||
"github.com/go-fed/activity/streams/vocab"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
|
|
@ -34,7 +33,7 @@ type ConverterStandardTestSuite struct {
|
|||
db db.DB
|
||||
log *logrus.Logger
|
||||
accounts map[string]*gtsmodel.Account
|
||||
people map[string]vocab.ActivityStreamsPerson
|
||||
people map[string]typeutils.Accountable
|
||||
|
||||
typeconverter typeutils.TypeConverter
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import (
|
|||
"github.com/go-fed/activity/streams/vocab"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
|
||||
)
|
||||
|
||||
// NewTestTokens returns a map of tokens keyed according to which account the token belongs to.
|
||||
|
|
@ -1050,14 +1051,14 @@ func NewTestActivities(accounts map[string]*gtsmodel.Account) map[string]Activit
|
|||
}
|
||||
|
||||
// NewTestFediPeople returns a bunch of activity pub Person representations for testing converters and so on.
|
||||
func NewTestFediPeople() map[string]vocab.ActivityStreamsPerson {
|
||||
func NewTestFediPeople() map[string]typeutils.Accountable {
|
||||
new_person_1priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
new_person_1pub := &new_person_1priv.PublicKey
|
||||
|
||||
return map[string]vocab.ActivityStreamsPerson{
|
||||
return map[string]typeutils.Accountable{
|
||||
"new_person_1": newPerson(
|
||||
URLMustParse("https://unknown-instance.com/users/brand_new_person"),
|
||||
URLMustParse("https://unknown-instance.com/users/brand_new_person/following"),
|
||||
|
|
@ -1184,7 +1185,7 @@ func newPerson(
|
|||
avatarURL *url.URL,
|
||||
avatarContentType string,
|
||||
headerURL *url.URL,
|
||||
headerContentType string) vocab.ActivityStreamsPerson {
|
||||
headerContentType string) typeutils.Accountable {
|
||||
person := streams.NewActivityStreamsPerson()
|
||||
|
||||
// id should be the activitypub URI of this user
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue