diff options
Diffstat (limited to 'internal/typeutils')
-rw-r--r-- | internal/typeutils/asinterfaces.go | 9 | ||||
-rw-r--r-- | internal/typeutils/astointernal.go | 35 | ||||
-rw-r--r-- | internal/typeutils/converter.go | 13 | ||||
-rw-r--r-- | internal/typeutils/internal.go | 1 | ||||
-rw-r--r-- | internal/typeutils/internaltoas.go | 70 | ||||
-rw-r--r-- | internal/typeutils/internaltofrontend.go | 33 |
6 files changed, 161 insertions, 0 deletions
diff --git a/internal/typeutils/asinterfaces.go b/internal/typeutils/asinterfaces.go index aae3ecf93..d0b1cf617 100644 --- a/internal/typeutils/asinterfaces.go +++ b/internal/typeutils/asinterfaces.go @@ -111,6 +111,15 @@ type Likeable interface { withObject } +// Blockable represents the minimum interface for an activitystreams 'block' activity. +type Blockable interface { + withJSONLDId + withTypeName + + withActor + withObject +} + // Announceable represents the minimum interface for an activitystreams 'announce' activity. type Announceable interface { withJSONLDId diff --git a/internal/typeutils/astointernal.go b/internal/typeutils/astointernal.go index dc58346fb..394de6e82 100644 --- a/internal/typeutils/astointernal.go +++ b/internal/typeutils/astointernal.go @@ -426,6 +426,41 @@ func (c *converter) ASLikeToFave(likeable Likeable) (*gtsmodel.StatusFave, error }, nil } +func (c *converter) ASBlockToBlock(blockable Blockable) (*gtsmodel.Block, error) { + idProp := blockable.GetJSONLDId() + if idProp == nil || !idProp.IsIRI() { + return nil, errors.New("ASBlockToBlock: no id property set on block, or was not an iri") + } + uri := idProp.GetIRI().String() + + origin, err := extractActor(blockable) + if err != nil { + return nil, errors.New("ASBlockToBlock: error extracting actor property from block") + } + originAccount := >smodel.Account{} + if err := c.db.GetWhere([]db.Where{{Key: "uri", Value: origin.String()}}, originAccount); err != nil { + return nil, fmt.Errorf("ASBlockToBlock: error extracting account with uri %s from the database: %s", origin.String(), err) + } + + target, err := extractObject(blockable) + if err != nil { + return nil, errors.New("ASBlockToBlock: error extracting object property from block") + } + + targetAccount := >smodel.Account{} + if err := c.db.GetWhere([]db.Where{{Key: "uri", Value: target.String(), CaseInsensitive: true}}, targetAccount); err != nil { + return nil, fmt.Errorf("ASBlockToBlock: error extracting account with uri %s from the database: %s", target.String(), err) + } + + return >smodel.Block{ + AccountID: originAccount.ID, + Account: originAccount, + TargetAccountID: targetAccount.ID, + TargetAccount: targetAccount, + URI: uri, + }, nil +} + func (c *converter) ASAnnounceToStatus(announceable Announceable) (*gtsmodel.Status, bool, error) { status := >smodel.Status{} isNew := true diff --git a/internal/typeutils/converter.go b/internal/typeutils/converter.go index 30c1c7d2c..57c2a1f6d 100644 --- a/internal/typeutils/converter.go +++ b/internal/typeutils/converter.go @@ -48,6 +48,10 @@ type TypeConverter interface { // if something goes wrong. The returned account should be ready to serialize on an API level, and may NOT have sensitive fields. // In other words, this is the public record that the server has of an account. AccountToMastoPublic(account *gtsmodel.Account) (*model.Account, error) + // AccountToMastoBlocked takes a db model account as a param, and returns a mastotype account, or an error if + // something goes wrong. The returned account will be a bare minimum representation of the account. This function should be used + // when someone wants to view an account they've blocked. + AccountToMastoBlocked(account *gtsmodel.Account) (*model.Account, error) // AppToMastoSensitive takes a db model application as a param, and returns a populated mastotype application, or an error // if something goes wrong. The returned application should be ready to serialize on an API level, and may have sensitive fields // (such as client id and client secret), so serve it only to an authorized user who should have permission to see it. @@ -104,6 +108,8 @@ type TypeConverter interface { ASFollowToFollow(followable Followable) (*gtsmodel.Follow, error) // ASLikeToFave converts a remote activitystreams 'like' representation into a gts model status fave. ASLikeToFave(likeable Likeable) (*gtsmodel.StatusFave, error) + // ASBlockToBlock converts a remote activity streams 'block' representation into a gts model block. + ASBlockToBlock(blockable Blockable) (*gtsmodel.Block, error) // ASAnnounceToStatus converts an activitystreams 'announce' into a status. // // The returned bool indicates whether this status is new (true) or not new (false). @@ -124,6 +130,11 @@ type TypeConverter interface { // AccountToAS converts a gts model account into an activity streams person, suitable for federation AccountToAS(a *gtsmodel.Account) (vocab.ActivityStreamsPerson, error) + // AccountToASMinimal converts a gts model account into an activity streams person, suitable for federation. + // + // The returned account will just have the Type, Username, PublicKey, and ID properties set. This is + // suitable for serving to requesters to whom we want to give as little information as possible because + // we don't trust them (yet). AccountToASMinimal(a *gtsmodel.Account) (vocab.ActivityStreamsPerson, error) // StatusToAS converts a gts model status into an activity streams note, suitable for federation StatusToAS(s *gtsmodel.Status) (vocab.ActivityStreamsNote, error) @@ -137,6 +148,8 @@ type TypeConverter interface { FaveToAS(f *gtsmodel.StatusFave) (vocab.ActivityStreamsLike, error) // BoostToAS converts a gts model boost into an activityStreams ANNOUNCE, suitable for federation BoostToAS(boostWrapperStatus *gtsmodel.Status, boostingAccount *gtsmodel.Account, boostedAccount *gtsmodel.Account) (vocab.ActivityStreamsAnnounce, error) + // BlockToAS converts a gts model block into an activityStreams BLOCK, suitable for federation. + BlockToAS(block *gtsmodel.Block) (vocab.ActivityStreamsBlock, error) /* INTERNAL (gts) MODEL TO INTERNAL MODEL diff --git a/internal/typeutils/internal.go b/internal/typeutils/internal.go index b081708a2..a46ad7fbd 100644 --- a/internal/typeutils/internal.go +++ b/internal/typeutils/internal.go @@ -67,6 +67,7 @@ func (c *converter) StatusToBoost(s *gtsmodel.Status, boostingAccount *gtsmodel. Language: s.Language, Text: s.Text, BoostOfID: s.ID, + BoostOfAccountID: s.AccountID, Visibility: s.Visibility, VisibilityAdvanced: s.VisibilityAdvanced, diff --git a/internal/typeutils/internaltoas.go b/internal/typeutils/internaltoas.go index 1760b8731..809cedc45 100644 --- a/internal/typeutils/internaltoas.go +++ b/internal/typeutils/internaltoas.go @@ -780,3 +780,73 @@ func (c *converter) BoostToAS(boostWrapperStatus *gtsmodel.Status, boostingAccou return announce, nil } + +/* + we want to end up with something like this: + + { + "@context": "https://www.w3.org/ns/activitystreams", + "actor": "https://example.org/users/some_user", + "id":"https://example.org/users/some_user/blocks/SOME_ULID_OF_A_BLOCK", + "object":"https://some_other.instance/users/some_other_user", + "type":"Block" + } +*/ +func (c *converter) BlockToAS(b *gtsmodel.Block) (vocab.ActivityStreamsBlock, error) { + if b.Account == nil { + a := >smodel.Account{} + if err := c.db.GetByID(b.AccountID, a); err != nil { + return nil, fmt.Errorf("BlockToAS: error getting block account from database: %s", err) + } + b.Account = a + } + + if b.TargetAccount == nil { + a := >smodel.Account{} + if err := c.db.GetByID(b.TargetAccountID, a); err != nil { + return nil, fmt.Errorf("BlockToAS: error getting block target account from database: %s", err) + } + b.TargetAccount = a + } + + // create the block + block := streams.NewActivityStreamsBlock() + + // set the actor property to the block-ing account's URI + actorProp := streams.NewActivityStreamsActorProperty() + actorIRI, err := url.Parse(b.Account.URI) + if err != nil { + return nil, fmt.Errorf("BlockToAS: error parsing uri %s: %s", b.Account.URI, err) + } + actorProp.AppendIRI(actorIRI) + block.SetActivityStreamsActor(actorProp) + + // set the ID property to the blocks's URI + idProp := streams.NewJSONLDIdProperty() + idIRI, err := url.Parse(b.URI) + if err != nil { + return nil, fmt.Errorf("BlockToAS: error parsing uri %s: %s", b.URI, err) + } + idProp.Set(idIRI) + block.SetJSONLDId(idProp) + + // set the object property to the target account's URI + objectProp := streams.NewActivityStreamsObjectProperty() + targetIRI, err := url.Parse(b.TargetAccount.URI) + if err != nil { + return nil, fmt.Errorf("BlockToAS: error parsing uri %s: %s", b.TargetAccount.URI, err) + } + objectProp.AppendIRI(targetIRI) + block.SetActivityStreamsObject(objectProp) + + // set the TO property to the target account's IRI + toProp := streams.NewActivityStreamsToProperty() + toIRI, err := url.Parse(b.TargetAccount.URI) + if err != nil { + return nil, fmt.Errorf("BlockToAS: error parsing uri %s: %s", b.TargetAccount.URI, err) + } + toProp.AppendIRI(toIRI) + block.SetActivityStreamsTo(toProp) + + return block, nil +} diff --git a/internal/typeutils/internaltofrontend.go b/internal/typeutils/internaltofrontend.go index 61c11b8ef..03e071981 100644 --- a/internal/typeutils/internaltofrontend.go +++ b/internal/typeutils/internaltofrontend.go @@ -150,6 +150,11 @@ func (c *converter) AccountToMastoPublic(a *gtsmodel.Account) (*model.Account, e acct = a.Username } + var suspended bool + if !a.SuspendedAt.IsZero() { + suspended = true + } + return &model.Account{ ID: a.ID, Username: a.Username, @@ -170,6 +175,34 @@ func (c *converter) AccountToMastoPublic(a *gtsmodel.Account) (*model.Account, e LastStatusAt: lastStatusAt, Emojis: emojis, // TODO: implement this Fields: fields, + Suspended: suspended, + }, nil +} + +func (c *converter) AccountToMastoBlocked(a *gtsmodel.Account) (*model.Account, error) { + var acct string + if a.Domain != "" { + // this is a remote user + acct = fmt.Sprintf("%s@%s", a.Username, a.Domain) + } else { + // this is a local user + acct = a.Username + } + + var suspended bool + if !a.SuspendedAt.IsZero() { + suspended = true + } + + return &model.Account{ + ID: a.ID, + Username: a.Username, + Acct: acct, + DisplayName: a.DisplayName, + Bot: a.Bot, + CreatedAt: a.CreatedAt.Format(time.RFC3339), + URL: a.URL, + Suspended: suspended, }, nil } |