summaryrefslogtreecommitdiff
path: root/internal/ap
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2023-11-30 16:22:34 +0000
committerLibravatar GitHub <noreply@github.com>2023-11-30 16:22:34 +0000
commiteb170003b81504ba6eb85f950c223dc9eaf1cfca (patch)
treef1f9779e14875faa70f4db85a8cf19100633884d /internal/ap
parent[bugfix] always go through status parent dereferencing on isNew, even on data... (diff)
downloadgotosocial-eb170003b81504ba6eb85f950c223dc9eaf1cfca.tar.xz
[bugfix] return 400 Bad Request on more cases of malformed AS data (#2399)
Diffstat (limited to 'internal/ap')
-rw-r--r--internal/ap/extract.go23
-rw-r--r--internal/ap/interfaces.go6
-rw-r--r--internal/ap/properties.go195
-rw-r--r--internal/ap/resolve_test.go2
4 files changed, 185 insertions, 41 deletions
diff --git a/internal/ap/extract.go b/internal/ap/extract.go
index 3d92fa2ba..987ff5e55 100644
--- a/internal/ap/extract.go
+++ b/internal/ap/extract.go
@@ -328,29 +328,6 @@ func ExtractAttributedToURI(i WithAttributedTo) (*url.URL, error) {
return nil, gtserror.New("couldn't find iri for attributed to")
}
-// ExtractPublished extracts the published time from the given
-// WithPublished. Will return an error if the published property
-// is not set, is not a time.Time, or is zero.
-func ExtractPublished(i WithPublished) (time.Time, error) {
- t := time.Time{}
-
- publishedProp := i.GetActivityStreamsPublished()
- if publishedProp == nil {
- return t, gtserror.New("published prop was nil")
- }
-
- if !publishedProp.IsXMLSchemaDateTime() {
- return t, gtserror.New("published prop was not date time")
- }
-
- t = publishedProp.Get()
- if t.IsZero() {
- return t, gtserror.New("published time was zero")
- }
-
- return t, nil
-}
-
// ExtractIconURI extracts the first URI it can find from
// the given WithIcon which links to a supported image file.
// Input will look something like this:
diff --git a/internal/ap/interfaces.go b/internal/ap/interfaces.go
index fed69d69d..f548dff0b 100644
--- a/internal/ap/interfaces.go
+++ b/internal/ap/interfaces.go
@@ -416,6 +416,12 @@ type WithOutbox interface {
SetActivityStreamsOutbox(vocab.ActivityStreamsOutboxProperty)
}
+// WithSharedInbox represents an activity with ActivityStreamsSharedInboxProperty
+type WithSharedInbox interface {
+ GetActivityStreamsSharedInbox() vocab.ActivityStreamsSharedInboxProperty
+ SetActivityStreamsSharedInbox(vocab.ActivityStreamsSharedInboxProperty)
+}
+
// WithFollowing represents an activity with ActivityStreamsFollowingProperty
type WithFollowing interface {
GetActivityStreamsFollowing() vocab.ActivityStreamsFollowingProperty
diff --git a/internal/ap/properties.go b/internal/ap/properties.go
index 788b8ac4e..2b23c7cb2 100644
--- a/internal/ap/properties.go
+++ b/internal/ap/properties.go
@@ -55,14 +55,10 @@ func MustSet[W, T any](fn func(W, T) error, with W, value T) {
// GetJSONLDId returns the ID of 'with', or nil.
func GetJSONLDId(with WithJSONLDId) *url.URL {
idProp := with.GetJSONLDId()
- if idProp == nil {
- return nil
- }
- id := idProp.Get()
- if id == nil {
+ if idProp == nil || !idProp.IsXMLSchemaAnyURI() {
return nil
}
- return id
+ return idProp.Get()
}
// SetJSONLDId sets the given URL to the JSONLD ID of 'with'.
@@ -70,9 +66,9 @@ func SetJSONLDId(with WithJSONLDId, id *url.URL) {
idProp := with.GetJSONLDId()
if idProp == nil {
idProp = streams.NewJSONLDIdProperty()
+ with.SetJSONLDId(idProp)
}
idProp.SetIRI(id)
- with.SetJSONLDId(idProp)
}
// SetJSONLDIdStr sets the given string to the JSONLDID of 'with'. Returns error
@@ -139,14 +135,46 @@ func AppendBcc(with WithBcc, bcc ...*url.URL) {
}, bcc...)
}
-// GetActor returns the IRIs contained in the Actor property of 'with'. Panics on entries with missing ID.
-func GetActor(with WithActor) []*url.URL {
+// GetURL returns the IRIs contained in the URL property of 'with'.
+func GetURL(with WithURL) []*url.URL {
+ urlProp := with.GetActivityStreamsUrl()
+ if urlProp == nil || urlProp.Len() == 0 {
+ return nil
+ }
+ urls := make([]*url.URL, 0, urlProp.Len())
+ for i := 0; i < urlProp.Len(); i++ {
+ at := urlProp.At(i)
+ if at.IsXMLSchemaAnyURI() {
+ u := at.GetXMLSchemaAnyURI()
+ urls = append(urls, u)
+ }
+ }
+ return urls
+}
+
+// AppendURL appends the given URLs to the URL property of 'with'.
+func AppendURL(with WithURL, url ...*url.URL) {
+ if len(url) == 0 {
+ return
+ }
+ urlProp := with.GetActivityStreamsUrl()
+ if urlProp == nil {
+ urlProp = streams.NewActivityStreamsUrlProperty()
+ with.SetActivityStreamsUrl(urlProp)
+ }
+ for _, u := range url {
+ urlProp.AppendXMLSchemaAnyURI(u)
+ }
+}
+
+// GetActorIRIs returns the IRIs contained in the Actor property of 'with'.
+func GetActorIRIs(with WithActor) []*url.URL {
actorProp := with.GetActivityStreamsActor()
return getIRIs[vocab.ActivityStreamsActorPropertyIterator](actorProp)
}
-// AppendActor appends the given IRIs to the Actor property of 'with'.
-func AppendActor(with WithActor, actor ...*url.URL) {
+// AppendActorIRIs appends the given IRIs to the Actor property of 'with'.
+func AppendActorIRIs(with WithActor, actor ...*url.URL) {
appendIRIs(func() Property[vocab.ActivityStreamsActorPropertyIterator] {
actorProp := with.GetActivityStreamsActor()
if actorProp == nil {
@@ -157,7 +185,25 @@ func AppendActor(with WithActor, actor ...*url.URL) {
}, actor...)
}
-// GetAttributedTo returns the IRIs contained in the AttributedTo property of 'with'. Panics on entries with missing ID.
+// GetObjectIRIs returns the IRIs contained in the Object property of 'with'.
+func GetObjectIRIs(with WithObject) []*url.URL {
+ objectProp := with.GetActivityStreamsObject()
+ return getIRIs[vocab.ActivityStreamsObjectPropertyIterator](objectProp)
+}
+
+// AppendObjectIRIs appends the given IRIs to the Object property of 'with'.
+func AppendObjectIRIs(with WithObject) {
+ appendIRIs(func() Property[vocab.ActivityStreamsObjectPropertyIterator] {
+ objectProp := with.GetActivityStreamsObject()
+ if objectProp == nil {
+ objectProp = streams.NewActivityStreamsObjectProperty()
+ with.SetActivityStreamsObject(objectProp)
+ }
+ return objectProp
+ })
+}
+
+// GetAttributedTo returns the IRIs contained in the AttributedTo property of 'with'.
func GetAttributedTo(with WithAttributedTo) []*url.URL {
attribProp := with.GetActivityStreamsAttributedTo()
return getIRIs[vocab.ActivityStreamsAttributedToPropertyIterator](attribProp)
@@ -175,7 +221,7 @@ func AppendAttributedTo(with WithAttributedTo, attribTo ...*url.URL) {
}, attribTo...)
}
-// GetInReplyTo returns the IRIs contained in the InReplyTo property of 'with'. Panics on entries with missing ID.
+// GetInReplyTo returns the IRIs contained in the InReplyTo property of 'with'.
func GetInReplyTo(with WithInReplyTo) []*url.URL {
replyProp := with.GetActivityStreamsInReplyTo()
return getIRIs[vocab.ActivityStreamsInReplyToPropertyIterator](replyProp)
@@ -193,10 +239,105 @@ func AppendInReplyTo(with WithInReplyTo, replyTo ...*url.URL) {
}, replyTo...)
}
+// GetInbox returns the IRI contained in the Inbox property of 'with'.
+func GetInbox(with WithInbox) *url.URL {
+ inboxProp := with.GetActivityStreamsInbox()
+ if inboxProp == nil || !inboxProp.IsIRI() {
+ return nil
+ }
+ return inboxProp.GetIRI()
+}
+
+// SetInbox sets the given IRI on the Inbox property of 'with'.
+func SetInbox(with WithInbox, inbox *url.URL) {
+ inboxProp := with.GetActivityStreamsInbox()
+ if inboxProp == nil {
+ inboxProp = streams.NewActivityStreamsInboxProperty()
+ with.SetActivityStreamsInbox(inboxProp)
+ }
+ inboxProp.SetIRI(inbox)
+}
+
+// GetOutbox returns the IRI contained in the Outbox property of 'with'.
+func GetOutbox(with WithOutbox) *url.URL {
+ outboxProp := with.GetActivityStreamsOutbox()
+ if outboxProp == nil || !outboxProp.IsIRI() {
+ return nil
+ }
+ return outboxProp.GetIRI()
+}
+
+// SetOutbox sets the given IRI on the Outbox property of 'with'.
+func SetOutbox(with WithOutbox, outbox *url.URL) {
+ outboxProp := with.GetActivityStreamsOutbox()
+ if outboxProp == nil {
+ outboxProp = streams.NewActivityStreamsOutboxProperty()
+ with.SetActivityStreamsOutbox(outboxProp)
+ }
+ outboxProp.SetIRI(outbox)
+}
+
+// GetFollowers returns the IRI contained in the Following property of 'with'.
+func GetFollowing(with WithFollowing) *url.URL {
+ followProp := with.GetActivityStreamsFollowing()
+ if followProp == nil || !followProp.IsIRI() {
+ return nil
+ }
+ return followProp.GetIRI()
+}
+
+// SetFollowers sets the given IRI on the Following property of 'with'.
+func SetFollowing(with WithFollowing, following *url.URL) {
+ followProp := with.GetActivityStreamsFollowing()
+ if followProp == nil {
+ followProp = streams.NewActivityStreamsFollowingProperty()
+ with.SetActivityStreamsFollowing(followProp)
+ }
+ followProp.SetIRI(following)
+}
+
+// GetFollowers returns the IRI contained in the Followers property of 'with'.
+func GetFollowers(with WithFollowers) *url.URL {
+ followProp := with.GetActivityStreamsFollowers()
+ if followProp == nil || !followProp.IsIRI() {
+ return nil
+ }
+ return followProp.GetIRI()
+}
+
+// SetFollowers sets the given IRI on the Followers property of 'with'.
+func SetFollowers(with WithFollowers, followers *url.URL) {
+ followProp := with.GetActivityStreamsFollowers()
+ if followProp == nil {
+ followProp = streams.NewActivityStreamsFollowersProperty()
+ with.SetActivityStreamsFollowers(followProp)
+ }
+ followProp.SetIRI(followers)
+}
+
+// GetFeatured returns the IRI contained in the Featured property of 'with'.
+func GetFeatured(with WithFeatured) *url.URL {
+ featuredProp := with.GetTootFeatured()
+ if featuredProp == nil || !featuredProp.IsIRI() {
+ return nil
+ }
+ return featuredProp.GetIRI()
+}
+
+// SetFeatured sets the given IRI on the Featured property of 'with'.
+func SetFeatured(with WithFeatured, featured *url.URL) {
+ featuredProp := with.GetTootFeatured()
+ if featuredProp == nil {
+ featuredProp = streams.NewTootFeaturedProperty()
+ with.SetTootFeatured(featuredProp)
+ }
+ featuredProp.SetIRI(featured)
+}
+
// GetPublished returns the time contained in the Published property of 'with'.
func GetPublished(with WithPublished) time.Time {
publishProp := with.GetActivityStreamsPublished()
- if publishProp == nil {
+ if publishProp == nil || !publishProp.IsXMLSchemaDateTime() {
return time.Time{}
}
return publishProp.Get()
@@ -215,7 +356,7 @@ func SetPublished(with WithPublished, published time.Time) {
// GetEndTime returns the time contained in the EndTime property of 'with'.
func GetEndTime(with WithEndTime) time.Time {
endTimeProp := with.GetActivityStreamsEndTime()
- if endTimeProp == nil {
+ if endTimeProp == nil || !endTimeProp.IsXMLSchemaDateTime() {
return time.Time{}
}
return endTimeProp.Get()
@@ -240,7 +381,8 @@ func GetClosed(with WithClosed) []time.Time {
closed := make([]time.Time, 0, closedProp.Len())
for i := 0; i < closedProp.Len(); i++ {
at := closedProp.At(i)
- if t := at.GetXMLSchemaDateTime(); !t.IsZero() {
+ if at.IsXMLSchemaDateTime() {
+ t := at.GetXMLSchemaDateTime()
closed = append(closed, t)
}
}
@@ -265,7 +407,7 @@ func AppendClosed(with WithClosed, closed ...time.Time) {
// GetVotersCount returns the integer contained in the VotersCount property of 'with', if found.
func GetVotersCount(with WithVotersCount) int {
votersProp := with.GetTootVotersCount()
- if votersProp == nil {
+ if votersProp == nil || !votersProp.IsXMLSchemaNonNegativeInteger() {
return 0
}
return votersProp.Get()
@@ -281,6 +423,25 @@ func SetVotersCount(with WithVotersCount, count int) {
votersProp.Set(count)
}
+// GetDiscoverable returns the boolean contained in the Discoverable property of 'with'.
+func GetDiscoverable(with WithDiscoverable) bool {
+ discoverProp := with.GetTootDiscoverable()
+ if discoverProp == nil || !discoverProp.IsXMLSchemaBoolean() {
+ return false
+ }
+ return discoverProp.Get()
+}
+
+// SetDiscoverable sets the given boolean on the Discoverable property of 'with'.
+func SetDiscoverable(with WithDiscoverable, discoverable bool) {
+ discoverProp := with.GetTootDiscoverable()
+ if discoverProp == nil {
+ discoverProp = streams.NewTootDiscoverableProperty()
+ with.SetTootDiscoverable(discoverProp)
+ }
+ discoverProp.Set(discoverable)
+}
+
func getIRIs[T TypeOrIRI](prop Property[T]) []*url.URL {
if prop == nil || prop.Len() == 0 {
return nil
diff --git a/internal/ap/resolve_test.go b/internal/ap/resolve_test.go
index 5ec1c4234..0b2c8fb0c 100644
--- a/internal/ap/resolve_test.go
+++ b/internal/ap/resolve_test.go
@@ -42,7 +42,7 @@ func (suite *ResolveTestSuite) TestResolveDocumentAsAccountable() {
b := []byte(suite.typeToJson(suite.document1))
accountable, err := ap.ResolveAccountable(context.Background(), b)
- suite.True(gtserror.WrongType(err))
+ suite.True(gtserror.IsWrongType(err))
suite.EqualError(err, "ResolveAccountable: cannot resolve vocab type *typedocument.ActivityStreamsDocument as accountable")
suite.Nil(accountable)
}