diff --git a/constants.go b/constants.go index 7d5c243..575a3f6 100644 --- a/constants.go +++ b/constants.go @@ -1,13 +1,11 @@ package goap -// JsonLD fields const ( KEY_ID = "@id" // Value of type string KEY_TYPE = "@type" // Value of type string slice / activitystreams object url slice KEY_VALUE = "@value" // Could be any type really ) -// Mastodon fields const ( KEY_MASTO_DEVICES = "http://joinmastodon.org/ns#devices" // No idea what this is, but Masto includes it KEY_MASTO_DISCOVERABLE = "http://joinmastodon.org/ns#discoverable" // iirc this is whether the object can be found by crawlers @@ -19,7 +17,6 @@ const ( KEY_MASTO_EMOJI = "http://joinmastodon.org/ns#Emoji" // Object is an emoji ) -// Generic W3 fields const ( KEY_W3_INBOX = "http://www.w3.org/ns/ldp#inbox" // Where to send activities to KEY_W3_SECURITY_OWNER = "https://w3id.org/security#owner" // Owner of the public key @@ -28,14 +25,9 @@ const ( KEY_W3_VCARD_ADDRESS = "http://www.w3.org/2006/vcard/ns#Address" // Vcard address of an account KEY_W3_VCARD_BIRTHDAY = "http://www.w3.org/2006/vcard/ns#bday" // Vcard birthday of an account -) - -// Generic W3 object type -const ( KEY_W3_SECURITY_KEY = "https://w3id.org/security#Key" // Object is a PublicKey ) -// W3 Activitystreams fields const ( KEY_ACTIVITYSTREAMS_ACTOR = "https://www.w3.org/ns/activitystreams#actor" KEY_ACTIVITYSTREAMS_ALSOKNOWNAS = "https://www.w3.org/ns/activitystreams#alsoKnownAs" // Lists of usernames? @@ -66,10 +58,7 @@ const ( KEY_ACTIVITYSTREAMS_UPDATED = "https://www.w3.org/ns/activitystreams#updated" // When the content was last updated KEY_ACTIVITYSTREAMS_INREPLYTO = "https://www.w3.org/ns/activitystreams#inReplyTo" // What the object is replying to KEY_ACTIVITYSTREAMS_QUOTEURL = "https://www.w3.org/ns/activitystreams#quoteUrl" // Url to the object being quoted -) -// W3 Activitystreams object types -const ( // Object types (I think) // Those are values the object type can have @@ -89,10 +78,7 @@ const ( KEY_ACTIVITYSTREAMS_ITEMS = "https://www.w3.org/ns/activitystreams#items" // Items in this collection page KEY_ACTIVITYSTREAMS_NEXT = "https://www.w3.org/ns/activitystreams#next" // Next page in a collection KEY_ACTIVITYSTREAMS_PARTOF = "https://www.w3.org/ns/activitystreams#partOf" // Collection the current page is a part of -) -// W3 Activitystreams unknown -const ( // Misc KEY_ACTIVITYSTREAMS_OAUTHAUTHORIZATION = "https://www.w3.org/ns/activitystreams#oauthAuthorizationEndpoint" // Endpoint url for oauth login? KEY_ACTIVITYSTREAMS_OAUTHTOKEN = "https://www.w3.org/ns/activitystreams#oauthTokenEndpoint" // Endpoint url for oauth token verification? @@ -100,14 +86,12 @@ const ( KEY_ACTIVITYSTREAMS_PUBLIC = "https://www.w3.org/ns/activitystreams#Public" // Note target ) -// schema fields const ( KEY_SCHEMA_VALUE = "http://schema.org#value" // The value for some field KEY_SCHEMA_PROPERTYVALUE = "http://schema.org#PropertyValue" // Object is of type property value ) -// Misskey and fork fields const ( KEY_MISSKEY_MKSUMMARY = "https://misskey-hub.net/ns#_misskey_summary" // Misskey specific formatted summary KEY_MISSKEY_ISCAT = "https://misskey-hub.net/ns#isCat" // Does the account identify as cat? @@ -116,20 +100,15 @@ const ( ) // No idea what either of those two do or are used for - -// Litepub fields const ( KEY_LITEPUB_CAPABILITIES = "http://litepub.social/ns#capabilities" KEY_LITEPUB_OAUTHREGISTRATION = "http://litepub.social/ns#oauthRegistrationEndpoint" ) -// W3 XML fields const ( KEY_XMLSCHEMA_DATETIME = "http://www.w3.org/2001/XMLSchema#dateTime" // Type value for published value field ) -// Ostatus fields -// // NOTE: ostatus.org seems to be redirecting to some weird scam(?) page const ( KEY_OSTATUS_ATOMURI = "http://ostatus.org#atomUri" // Same as @id I think @@ -137,14 +116,12 @@ const ( KEY_OSTATUS_INREPLYTOATOMURI = "http://ostatus.org#inReplyToAtomUri" // Same as InReplyTo, but with an atom uri as target ) -// Unknown origin fields const ( KEY_MYSTERIOUS_NOINDEX = "_:noindex" KEY_MYSTERIOUS_BACKGROUNDURL = "_:backgroundUrl" KEY_MYSTERIOUS_FEATURED = "_:featured" ) -// Fedibird fields const ( KEY_FEDIBIRD_QUOTEURI = "http://fedibird.com/ns#quoteUri" ) diff --git a/general/createEvent.go b/general/createEvent.go index 4283118..bc79c5d 100644 --- a/general/createEvent.go +++ b/general/createEvent.go @@ -3,7 +3,7 @@ package general import ( "time" - "git.mstar.dev/mstar/goap" + "gitlab.com/mstarongitlab/goap" ) type CreateEvent struct { diff --git a/go.mod b/go.mod index c1bc9e4..3af66f6 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module git.mstar.dev/mstar/goap +module gitlab.com/mstarongitlab/goap go 1.22.5 diff --git a/mastodon/account.go b/mastodon/account.go index 8397e22..9bfc683 100644 --- a/mastodon/account.go +++ b/mastodon/account.go @@ -3,7 +3,7 @@ package mastodon import ( "time" - "git.mstar.dev/mstar/goap" + "gitlab.com/mstarongitlab/goap" ) type Person struct { @@ -32,134 +32,3 @@ type Person struct { Tags []goap.Tag Url string } - -func PersonFromChain(base goap.BaseApChain) (*Person, error) { - id, ok := goap.FindAttribute[*goap.UDIdData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ID} - } - devices, ok := goap.FindAttribute[*goap.MastoDevicesData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_MASTO_DEVICES} - } - discoverable, ok := goap.FindAttribute[*goap.MastoDiscoverableData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_MASTO_DISCOVERABLE} - } - - featured, ok := goap.FindAttribute[*goap.MastoFeaturedData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_MASTO_FEATURED} - } - featuredTags, ok := goap.FindAttribute[*goap.MastoFeaturedTagsData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_MASTO_FEATURED_TAGS} - } - Indexable, ok := goap.FindAttribute[*goap.MastoIndexableData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_MASTO_INDEXABLE} - } - memorial, ok := goap.FindAttribute[*goap.MastoMemorialData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_MASTO_MEMORIAL} - } - inbox, ok := goap.FindAttribute[*goap.W3InboxData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_W3_INBOX} - } - publicKey, ok := goap.FindAttribute[*goap.W3SecurityPublicKeyData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_W3_SECURITY_PUBLICKEY} - } - alsoKnownAs, ok := goap.FindAttribute[*goap.ASAlsoKnownAsData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ACTIVITYSTREAMS_ALSOKNOWNAS} - } - attachments, ok := goap.FindAttribute[*goap.ASAttachmentsData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ACTIVITYSTREAMS_ATTACHMENTS} - } - endpoints, ok := goap.FindAttribute[*goap.ASEndpointsData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ACTIVITYSTREAMS_ENDPOINTS} - } - followers, ok := goap.FindAttribute[*goap.ASFollowersData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ACTIVITYSTREAMS_FOLLOWERS} - } - following, ok := goap.FindAttribute[*goap.ASFollowingData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ACTIVITYSTREAMS_FOLLOWING} - } - icon, ok := goap.FindAttribute[*goap.ASIconData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ACTIVITYSTREAMS_ICON} - } - image, ok := goap.FindAttribute[*goap.ASImageData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ACTIVITYSTREAMS_IMAGE_ATTRIBUTE} - } - approvesFollowers, ok := goap.FindAttribute[*goap.ASRestrictedFollowData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ACTIVITYSTREAMS_RESTRICTED_FOLLOW} - } - name, ok := goap.FindAttribute[*goap.ASNameData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ACTIVITYSTREAMS_NAME} - } - outbox, ok := goap.FindAttribute[*goap.ASOutboxData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ACTIVITYSTREAMS_OUTBOX} - } - preferredUsername, ok := goap.FindAttribute[*goap.ASPreferredNameData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ACTIVITYSTREAMS_PREFFEREDUSERNAME} - } - published, ok := goap.FindAttribute[*goap.ASPublishedData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ACTIVITYSTREAMS_PUBLISHED} - } - summary, ok := goap.FindAttribute[*goap.ASSummaryData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ACTIVITYSTREAMS_SUMMARY} - } - tags, ok := goap.FindAttribute[*goap.ASTagData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ACTIVITYSTREAMS_TAG} - } - url, ok := goap.FindAttribute[*goap.ASUrlData](base) - if !ok { - return nil, goap.NoRequiredFieldError{FieldName: goap.KEY_ACTIVITYSTREAMS_URL} - } - - return &Person{ - Id: id.Id, - Devices: devices.Id, - Discoverable: discoverable.Value.Value, - Featured: featured.Id, - FeaturedTags: featuredTags.Id, - Indexable: Indexable.Value.Value, - Memorial: memorial.Value.Value, - Inbox: inbox.Id, - PublicKey: goap.PublicKey{ - Id: publicKey.Id, - Owner: publicKey.Owner, - Pem: publicKey.Key, - }, - AlsoKnownAs: alsoKnownAs.Id, - Attachments: attachments.Attachments, - Endpoints: endpoints.Endpoints, - Followers: followers.Id, - Following: following.Id, - Icon: icon.Media, - Image: image.Media, - ApprovesFollowers: approvesFollowers.Value.Value, - Name: name.Value.Value, - Outbox: outbox.Id, - PreferredUsername: preferredUsername.Value.Value, - Published: published.Timestamp, - Summary: summary.Value.Value, - Tags: tags.Tags, - Url: url.Id, - }, nil -} diff --git a/nsActivitystreams.go b/nsActivitystreams.go index 8d06596..3c6e0af 100644 --- a/nsActivitystreams.go +++ b/nsActivitystreams.go @@ -3,7 +3,7 @@ package goap import ( "time" - xmldatetime "github.com/datainq/xml-date-time" + "github.com/datainq/xml-date-time" "gitlab.com/mstarongitlab/goutils/sliceutils" ) @@ -28,23 +28,54 @@ func ParseASActorData(raw map[string]any, next BaseApChain) (BaseApChain, error) } type ASAlsoKnownAsData struct { - FullIdType + Next BaseApChain + Urls []string } func (cc *ASAlsoKnownAsData) GetSelfOrBase() (BaseApChain, bool) { - return cc.FullIdType.GetSelfOrBase() + return cc.Next, true } func (cc *ASAlsoKnownAsData) MarshalToMap() map[string]any { - return cc.FullIdType.MarshalToMapWithName(KEY_ACTIVITYSTREAMS_ALSOKNOWNAS) + return appendWithKey( + cc.Next.MarshalToMap(), + KEY_ACTIVITYSTREAMS_ALSOKNOWNAS, + sliceutils.Map(cc.Urls, func(t string) map[string]any { + return map[string]any{KEY_ID: t} + }), + ) } func ParseASAlsoKnownAsData(raw map[string]any, next BaseApChain) (BaseApChain, error) { - id, err := ParseIdTypeWithName(raw, next, KEY_ACTIVITYSTREAMS_ALSOKNOWNAS) - if err != nil { - return nil, err + rawData1, ok := raw[KEY_ACTIVITYSTREAMS_ALSOKNOWNAS] + if !ok { + return nil, NoRequiredFieldError{KEY_ACTIVITYSTREAMS_ALSOKNOWNAS} } - return &ASAlsoKnownAsData{FullIdType: *id}, nil + data1, ok := rawData1.([]map[string]any) + if !ok { + return nil, BadFieldValueError[[]map[string]any]{ + KEY_ACTIVITYSTREAMS_ALSOKNOWNAS, + rawData1, + []map[string]any{}, + } + } + urls := []string{} + for _, v := range data1 { + rawData2, ok := v[KEY_ID] + if !ok { + return nil, NoRequiredSubFieldError{KEY_ACTIVITYSTREAMS_ALSOKNOWNAS, KEY_ID} + } + data2, ok := rawData2.(string) + if !ok { + return nil, BadFieldValueError[string]{KEY_ACTIVITYSTREAMS_ALSOKNOWNAS, rawData2, ""} + } + urls = append(urls, data2) + } + delete(raw, KEY_ACTIVITYSTREAMS_ALSOKNOWNAS) + return &ASAlsoKnownAsData{ + Next: next, + Urls: urls, + }, nil } type ASAttachmentsData struct { diff --git a/nsW3Security.go b/nsW3Security.go index 09bb03a..e22704b 100644 --- a/nsW3Security.go +++ b/nsW3Security.go @@ -21,7 +21,6 @@ func ParseW3SecurityOwnerData(raw map[string]any, next BaseApChain) (BaseApChain } // TODO: Handle case with multiple public keys (if allowed, idk if it is) - type W3SecurityPublicKeyData struct { Next BaseApChain Id string diff --git a/parser.go b/parser.go index 8af6b5c..4f5ed05 100644 --- a/parser.go +++ b/parser.go @@ -139,7 +139,7 @@ func UnmarshalPreprocessed( // Find an attribute in an ActivityPub object of the given type // Returns a pointer to the found attribute and whether it found it // 2nd parameter is true if the attribute was found, false otherwise -func FindAttribute[T BaseApChain](object BaseApChain) (T, bool) { +func FindAttribute[T BaseApChain](object BaseApChain) (*T, bool) { var obj T var ok bool // Try and cast object into wanted type @@ -150,8 +150,8 @@ func FindAttribute[T BaseApChain](object BaseApChain) (T, bool) { object, ok = object.GetSelfOrBase() // If this is the final object in the chain, cancel and return false if !ok { - return obj, false + return nil, false } } - return obj, true + return &obj, true }