remote + local block logic, incl. federation

This commit is contained in:
tsmethurst 2021-07-10 17:51:20 +02:00
commit 861cc1dff1
32 changed files with 1126 additions and 44 deletions

View file

@ -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

View file

@ -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 := &gtsmodel.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 := &gtsmodel.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 &gtsmodel.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 := &gtsmodel.Status{}
isNew := true

View file

@ -104,6 +104,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 +126,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 +144,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

View file

@ -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 := &gtsmodel.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 := &gtsmodel.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
}