summaryrefslogtreecommitdiff
path: root/internal/typeutils/asextractionutil.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/typeutils/asextractionutil.go')
-rw-r--r--internal/typeutils/asextractionutil.go570
1 files changed, 0 insertions, 570 deletions
diff --git a/internal/typeutils/asextractionutil.go b/internal/typeutils/asextractionutil.go
deleted file mode 100644
index b3e6eb2c4..000000000
--- a/internal/typeutils/asextractionutil.go
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package typeutils
-
-import (
- "crypto/rsa"
- "crypto/x509"
- "encoding/pem"
- "errors"
- "fmt"
- "net/url"
- "strings"
- "time"
-
- "github.com/go-fed/activity/pub"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/util"
-)
-
-func extractPreferredUsername(i withPreferredUsername) (string, error) {
- u := i.GetActivityStreamsPreferredUsername()
- if u == nil || !u.IsXMLSchemaString() {
- return "", errors.New("preferredUsername was not a string")
- }
- if u.GetXMLSchemaString() == "" {
- return "", errors.New("preferredUsername was empty")
- }
- return u.GetXMLSchemaString(), nil
-}
-
-func extractName(i withName) (string, error) {
- nameProp := i.GetActivityStreamsName()
- if nameProp == nil {
- return "", errors.New("activityStreamsName not found")
- }
-
- // take the first name string we can find
- for iter := nameProp.Begin(); iter != nameProp.End(); iter = iter.Next() {
- if iter.IsXMLSchemaString() && iter.GetXMLSchemaString() != "" {
- return iter.GetXMLSchemaString(), nil
- }
- }
-
- return "", errors.New("activityStreamsName not found")
-}
-
-func extractInReplyToURI(i withInReplyTo) (*url.URL, error) {
- inReplyToProp := i.GetActivityStreamsInReplyTo()
- if inReplyToProp == nil {
- return nil, errors.New("in reply to prop was nil")
- }
- for iter := inReplyToProp.Begin(); iter != inReplyToProp.End(); iter = iter.Next() {
- if iter.IsIRI() {
- if iter.GetIRI() != nil {
- return iter.GetIRI(), nil
- }
- }
- }
- return nil, errors.New("couldn't find iri for in reply to")
-}
-
-func extractTos(i withTo) ([]*url.URL, error) {
- to := []*url.URL{}
- toProp := i.GetActivityStreamsTo()
- if toProp == nil {
- return nil, errors.New("toProp was nil")
- }
- for iter := toProp.Begin(); iter != toProp.End(); iter = iter.Next() {
- if iter.IsIRI() {
- if iter.GetIRI() != nil {
- to = append(to, iter.GetIRI())
- }
- }
- }
- return to, nil
-}
-
-func extractCCs(i withCC) ([]*url.URL, error) {
- cc := []*url.URL{}
- ccProp := i.GetActivityStreamsCc()
- if ccProp == nil {
- return cc, nil
- }
- for iter := ccProp.Begin(); iter != ccProp.End(); iter = iter.Next() {
- if iter.IsIRI() {
- if iter.GetIRI() != nil {
- cc = append(cc, iter.GetIRI())
- }
- }
- }
- return cc, nil
-}
-
-func extractAttributedTo(i withAttributedTo) (*url.URL, error) {
- attributedToProp := i.GetActivityStreamsAttributedTo()
- if attributedToProp == nil {
- return nil, errors.New("attributedToProp was nil")
- }
- for iter := attributedToProp.Begin(); iter != attributedToProp.End(); iter = iter.Next() {
- if iter.IsIRI() {
- if iter.GetIRI() != nil {
- return iter.GetIRI(), nil
- }
- }
- }
- return nil, errors.New("couldn't find iri for attributed to")
-}
-
-func extractPublished(i withPublished) (time.Time, error) {
- publishedProp := i.GetActivityStreamsPublished()
- if publishedProp == nil {
- return time.Time{}, errors.New("published prop was nil")
- }
-
- if !publishedProp.IsXMLSchemaDateTime() {
- return time.Time{}, errors.New("published prop was not date time")
- }
-
- t := publishedProp.Get()
- if t.IsZero() {
- return time.Time{}, errors.New("published time was zero")
- }
- return t, nil
-}
-
-// extractIconURL extracts a URL to a supported image file from something like:
-// "icon": {
-// "mediaType": "image/jpeg",
-// "type": "Image",
-// "url": "http://example.org/path/to/some/file.jpeg"
-// },
-func extractIconURL(i withIcon) (*url.URL, error) {
- iconProp := i.GetActivityStreamsIcon()
- if iconProp == nil {
- return nil, errors.New("icon property was nil")
- }
-
- // 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. has a URL so we can grab it
- for iter := iconProp.Begin(); iter != iconProp.End(); iter = iter.Next() {
- // 1. is an image
- if !iter.IsActivityStreamsImage() {
- continue
- }
- imageValue := iter.GetActivityStreamsImage()
- if imageValue == nil {
- continue
- }
-
- // 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 withImage) (*url.URL, error) {
- imageProp := i.GetActivityStreamsImage()
- if imageProp == nil {
- return nil, errors.New("icon property was nil")
- }
-
- // 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. has a URL so we can grab it
- for iter := imageProp.Begin(); iter != imageProp.End(); iter = iter.Next() {
- // 1. is an image
- if !iter.IsActivityStreamsImage() {
- continue
- }
- imageValue := iter.GetActivityStreamsImage()
- if imageValue == nil {
- continue
- }
-
- // 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 iter := summaryProp.Begin(); iter != summaryProp.End(); iter = iter.Next() {
- if iter.IsXMLSchemaString() && iter.GetXMLSchemaString() != "" {
- return iter.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 iter := urlProp.Begin(); iter != urlProp.End(); iter = iter.Next() {
- if iter.IsIRI() && iter.GetIRI() != nil {
- return iter.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 iter := publicKeyProp.Begin(); iter != publicKeyProp.End(); iter = iter.Next() {
- pkey := iter.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")
-}
-
-func extractContent(i withContent) (string, error) {
- contentProperty := i.GetActivityStreamsContent()
- if contentProperty == nil {
- return "", errors.New("content property was nil")
- }
- for iter := contentProperty.Begin(); iter != contentProperty.End(); iter = iter.Next() {
- if iter.IsXMLSchemaString() && iter.GetXMLSchemaString() != "" {
- return iter.GetXMLSchemaString(), nil
- }
- }
- return "", errors.New("no content found")
-}
-
-func extractAttachments(i withAttachment) ([]*gtsmodel.MediaAttachment, error) {
- attachments := []*gtsmodel.MediaAttachment{}
- attachmentProp := i.GetActivityStreamsAttachment()
- if attachmentProp == nil {
- return attachments, nil
- }
- for iter := attachmentProp.Begin(); iter != attachmentProp.End(); iter = iter.Next() {
- t := iter.GetType()
- if t == nil {
- continue
- }
- attachmentable, ok := t.(Attachmentable)
- if !ok {
- continue
- }
- attachment, err := extractAttachment(attachmentable)
- if err != nil {
- continue
- }
- attachments = append(attachments, attachment)
- }
- return attachments, nil
-}
-
-func extractAttachment(i Attachmentable) (*gtsmodel.MediaAttachment, error) {
- attachment := &gtsmodel.MediaAttachment{
- File: gtsmodel.File{},
- }
-
- attachmentURL, err := extractURL(i)
- if err != nil {
- return nil, err
- }
- attachment.RemoteURL = attachmentURL.String()
-
- mediaType := i.GetActivityStreamsMediaType()
- if mediaType == nil {
- return nil, errors.New("no media type")
- }
- if mediaType.Get() == "" {
- return nil, errors.New("no media type")
- }
- attachment.File.ContentType = mediaType.Get()
- attachment.Type = gtsmodel.FileTypeImage
-
- name, err := extractName(i)
- if err == nil {
- attachment.Description = name
- }
-
- attachment.Processing = gtsmodel.ProcessingStatusReceived
-
- return attachment, nil
-}
-
-// func extractBlurhash(i withBlurhash) (string, error) {
-// if i.GetTootBlurhashProperty() == nil {
-// return "", errors.New("blurhash property was nil")
-// }
-// if i.GetTootBlurhashProperty().Get() == "" {
-// return "", errors.New("empty blurhash string")
-// }
-// return i.GetTootBlurhashProperty().Get(), nil
-// }
-
-func extractHashtags(i withTag) ([]*gtsmodel.Tag, error) {
- tags := []*gtsmodel.Tag{}
- tagsProp := i.GetActivityStreamsTag()
- if tagsProp == nil {
- return tags, nil
- }
- for iter := tagsProp.Begin(); iter != tagsProp.End(); iter = iter.Next() {
- t := iter.GetType()
- if t == nil {
- continue
- }
-
- if t.GetTypeName() != "Hashtag" {
- continue
- }
-
- hashtaggable, ok := t.(Hashtaggable)
- if !ok {
- continue
- }
-
- tag, err := extractHashtag(hashtaggable)
- if err != nil {
- continue
- }
-
- tags = append(tags, tag)
- }
- return tags, nil
-}
-
-func extractHashtag(i Hashtaggable) (*gtsmodel.Tag, error) {
- tag := &gtsmodel.Tag{}
-
- hrefProp := i.GetActivityStreamsHref()
- if hrefProp == nil || !hrefProp.IsIRI() {
- return nil, errors.New("no href prop")
- }
- tag.URL = hrefProp.GetIRI().String()
-
- name, err := extractName(i)
- if err != nil {
- return nil, err
- }
- tag.Name = strings.TrimPrefix(name, "#")
-
- return tag, nil
-}
-
-func extractEmojis(i withTag) ([]*gtsmodel.Emoji, error) {
- emojis := []*gtsmodel.Emoji{}
- tagsProp := i.GetActivityStreamsTag()
- if tagsProp == nil {
- return emojis, nil
- }
- for iter := tagsProp.Begin(); iter != tagsProp.End(); iter = iter.Next() {
- t := iter.GetType()
- if t == nil {
- continue
- }
-
- if t.GetTypeName() != "Emoji" {
- continue
- }
-
- emojiable, ok := t.(Emojiable)
- if !ok {
- continue
- }
-
- emoji, err := extractEmoji(emojiable)
- if err != nil {
- continue
- }
-
- emojis = append(emojis, emoji)
- }
- return emojis, nil
-}
-
-func extractEmoji(i Emojiable) (*gtsmodel.Emoji, error) {
- emoji := &gtsmodel.Emoji{}
-
- idProp := i.GetJSONLDId()
- if idProp == nil || !idProp.IsIRI() {
- return nil, errors.New("no id for emoji")
- }
- uri := idProp.GetIRI()
- emoji.URI = uri.String()
- emoji.Domain = uri.Host
-
- name, err := extractName(i)
- if err != nil {
- return nil, err
- }
- emoji.Shortcode = strings.Trim(name, ":")
-
- if i.GetActivityStreamsIcon() == nil {
- return nil, errors.New("no icon for emoji")
- }
- imageURL, err := extractIconURL(i)
- if err != nil {
- return nil, errors.New("no url for emoji image")
- }
- emoji.ImageRemoteURL = imageURL.String()
-
- return emoji, nil
-}
-
-func extractMentions(i withTag) ([]*gtsmodel.Mention, error) {
- mentions := []*gtsmodel.Mention{}
- tagsProp := i.GetActivityStreamsTag()
- if tagsProp == nil {
- return mentions, nil
- }
- for iter := tagsProp.Begin(); iter != tagsProp.End(); iter = iter.Next() {
- t := iter.GetType()
- if t == nil {
- continue
- }
-
- if t.GetTypeName() != "Mention" {
- continue
- }
-
- mentionable, ok := t.(Mentionable)
- if !ok {
- continue
- }
-
- mention, err := extractMention(mentionable)
- if err != nil {
- continue
- }
-
- mentions = append(mentions, mention)
- }
- return mentions, nil
-}
-
-func extractMention(i Mentionable) (*gtsmodel.Mention, error) {
- mention := &gtsmodel.Mention{}
-
- mentionString, err := extractName(i)
- if err != nil {
- return nil, err
- }
-
- // just make sure the mention string is valid so we can handle it properly later on...
- username, domain, err := util.ExtractMentionParts(mentionString)
- if err != nil {
- return nil, err
- }
- if username == "" || domain == "" {
- return nil, errors.New("username or domain was empty")
- }
- mention.NameString = mentionString
-
- // the href prop should be the AP URI of a user we know, eg https://example.org/users/whatever_user
- hrefProp := i.GetActivityStreamsHref()
- if hrefProp == nil || !hrefProp.IsIRI() {
- return nil, errors.New("no href prop")
- }
- mention.MentionedAccountURI = hrefProp.GetIRI().String()
- return mention, nil
-}
-
-func extractActor(i withActor) (*url.URL, error) {
- actorProp := i.GetActivityStreamsActor()
- if actorProp == nil {
- return nil, errors.New("actor property was nil")
- }
- for iter := actorProp.Begin(); iter != actorProp.End(); iter = iter.Next() {
- if iter.IsIRI() && iter.GetIRI() != nil {
- return iter.GetIRI(), nil
- }
- }
- return nil, errors.New("no iri found for actor prop")
-}
-
-func extractObject(i withObject) (*url.URL, error) {
- objectProp := i.GetActivityStreamsObject()
- if objectProp == nil {
- return nil, errors.New("object property was nil")
- }
- for iter := objectProp.Begin(); iter != objectProp.End(); iter = iter.Next() {
- if iter.IsIRI() && iter.GetIRI() != nil {
- return iter.GetIRI(), nil
- }
- }
- return nil, errors.New("no iri found for object prop")
-}