mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-11-28 20:43:32 -06:00
Block/unblock (#96)
* remote + local block logic, incl. federation * improve blocking stuff * fiddle with display of blocked profiles * go fmt
This commit is contained in:
parent
c7da64922f
commit
846057f0d6
45 changed files with 1405 additions and 63 deletions
|
|
@ -129,6 +129,7 @@ func (f *federatingDB) Create(ctx context.Context, asType vocab.Type) error {
|
|||
}
|
||||
}
|
||||
case gtsmodel.ActivityStreamsFollow:
|
||||
// FOLLOW SOMETHING
|
||||
follow, ok := asType.(vocab.ActivityStreamsFollow)
|
||||
if !ok {
|
||||
return errors.New("could not convert type to follow")
|
||||
|
|
@ -156,6 +157,7 @@ func (f *federatingDB) Create(ctx context.Context, asType vocab.Type) error {
|
|||
ReceivingAccount: targetAcct,
|
||||
}
|
||||
case gtsmodel.ActivityStreamsLike:
|
||||
// LIKE SOMETHING
|
||||
like, ok := asType.(vocab.ActivityStreamsLike)
|
||||
if !ok {
|
||||
return errors.New("could not convert type to like")
|
||||
|
|
@ -182,6 +184,34 @@ func (f *federatingDB) Create(ctx context.Context, asType vocab.Type) error {
|
|||
GTSModel: fave,
|
||||
ReceivingAccount: targetAcct,
|
||||
}
|
||||
case gtsmodel.ActivityStreamsBlock:
|
||||
// BLOCK SOMETHING
|
||||
blockable, ok := asType.(vocab.ActivityStreamsBlock)
|
||||
if !ok {
|
||||
return errors.New("could not convert type to block")
|
||||
}
|
||||
|
||||
block, err := f.typeConverter.ASBlockToBlock(blockable)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not convert Block to gts model block")
|
||||
}
|
||||
|
||||
newID, err := id.NewULID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
block.ID = newID
|
||||
|
||||
if err := f.db.Put(block); err != nil {
|
||||
return fmt.Errorf("database error inserting block: %s", err)
|
||||
}
|
||||
|
||||
fromFederatorChan <- gtsmodel.FromFederator{
|
||||
APObjectType: gtsmodel.ActivityStreamsBlock,
|
||||
APActivityType: gtsmodel.ActivityStreamsCreate,
|
||||
GTSModel: block,
|
||||
ReceivingAccount: targetAcct,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,16 +39,15 @@ func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) {
|
|||
"id": id.String(),
|
||||
},
|
||||
)
|
||||
l.Debugf("entering OWNS function with id %s", id.String())
|
||||
l.Tracef("entering OWNS function with id %s", id.String())
|
||||
|
||||
// if the id host isn't this instance host, we don't own this IRI
|
||||
if id.Host != f.config.Host {
|
||||
l.Debugf("we DO NOT own activity because the host is %s not %s", id.Host, f.config.Host)
|
||||
l.Tracef("we DO NOT own activity because the host is %s not %s", id.Host, f.config.Host)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// apparently it belongs to this host, so what *is* it?
|
||||
|
||||
// check if it's a status, eg /users/example_username/statuses/SOME_UUID_OF_A_STATUS
|
||||
if util.IsStatusesPath(id) {
|
||||
_, uid, err := util.ParseStatusesPath(id)
|
||||
|
|
@ -63,11 +62,10 @@ func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) {
|
|||
// an actual error happened
|
||||
return false, fmt.Errorf("database error fetching status with id %s: %s", uid, err)
|
||||
}
|
||||
l.Debug("we DO own this")
|
||||
l.Debugf("we own url %s", id.String())
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// check if it's a user, eg /users/example_username
|
||||
if util.IsUserPath(id) {
|
||||
username, err := util.ParseUserPath(id)
|
||||
if err != nil {
|
||||
|
|
@ -81,7 +79,7 @@ func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) {
|
|||
// an actual error happened
|
||||
return false, fmt.Errorf("database error fetching account with username %s: %s", username, err)
|
||||
}
|
||||
l.Debug("we DO own this")
|
||||
l.Debugf("we own url %s", id.String())
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +96,7 @@ func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) {
|
|||
// an actual error happened
|
||||
return false, fmt.Errorf("database error fetching account with username %s: %s", username, err)
|
||||
}
|
||||
l.Debug("we DO own this")
|
||||
l.Debugf("we own url %s", id.String())
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
|
@ -115,7 +113,57 @@ func (f *federatingDB) Owns(c context.Context, id *url.URL) (bool, error) {
|
|||
// an actual error happened
|
||||
return false, fmt.Errorf("database error fetching account with username %s: %s", username, err)
|
||||
}
|
||||
l.Debug("we DO own this")
|
||||
l.Debugf("we own url %s", id.String())
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if util.IsLikePath(id) {
|
||||
username, likeID, err := util.ParseLikedPath(id)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error parsing like path for url %s: %s", id.String(), err)
|
||||
}
|
||||
if err := f.db.GetLocalAccountByUsername(username, >smodel.Account{}); err != nil {
|
||||
if _, ok := err.(db.ErrNoEntries); ok {
|
||||
// there are no entries for this username
|
||||
return false, nil
|
||||
}
|
||||
// an actual error happened
|
||||
return false, fmt.Errorf("database error fetching account with username %s: %s", username, err)
|
||||
}
|
||||
if err := f.db.GetByID(likeID, >smodel.StatusFave{}); err != nil {
|
||||
if _, ok := err.(db.ErrNoEntries); ok {
|
||||
// there are no entries
|
||||
return false, nil
|
||||
}
|
||||
// an actual error happened
|
||||
return false, fmt.Errorf("database error fetching like with id %s: %s", likeID, err)
|
||||
}
|
||||
l.Debugf("we own url %s", id.String())
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if util.IsBlockPath(id) {
|
||||
username, blockID, err := util.ParseBlockPath(id)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error parsing block path for url %s: %s", id.String(), err)
|
||||
}
|
||||
if err := f.db.GetLocalAccountByUsername(username, >smodel.Account{}); err != nil {
|
||||
if _, ok := err.(db.ErrNoEntries); ok {
|
||||
// there are no entries for this username
|
||||
return false, nil
|
||||
}
|
||||
// an actual error happened
|
||||
return false, fmt.Errorf("database error fetching account with username %s: %s", username, err)
|
||||
}
|
||||
if err := f.db.GetByID(blockID, >smodel.Block{}); err != nil {
|
||||
if _, ok := err.(db.ErrNoEntries); ok {
|
||||
// there are no entries
|
||||
return false, nil
|
||||
}
|
||||
// an actual error happened
|
||||
return false, fmt.Errorf("database error fetching block with id %s: %s", blockID, err)
|
||||
}
|
||||
l.Debugf("we own url %s", id.String())
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,31 @@ func (f *federatingDB) Undo(ctx context.Context, undo vocab.ActivityStreamsUndo)
|
|||
// UNDO LIKE
|
||||
case string(gtsmodel.ActivityStreamsAnnounce):
|
||||
// UNDO BOOST/REBLOG/ANNOUNCE
|
||||
case string(gtsmodel.ActivityStreamsBlock):
|
||||
// UNDO BLOCK
|
||||
ASBlock, ok := iter.GetType().(vocab.ActivityStreamsBlock)
|
||||
if !ok {
|
||||
return errors.New("UNDO: couldn't parse block into vocab.ActivityStreamsBlock")
|
||||
}
|
||||
// make sure the actor owns the follow
|
||||
if !sameActor(undo.GetActivityStreamsActor(), ASBlock.GetActivityStreamsActor()) {
|
||||
return errors.New("UNDO: block actor and activity actor not the same")
|
||||
}
|
||||
// convert the block to something we can understand
|
||||
gtsBlock, err := f.typeConverter.ASBlockToBlock(ASBlock)
|
||||
if err != nil {
|
||||
return fmt.Errorf("UNDO: error converting asblock to gtsblock: %s", err)
|
||||
}
|
||||
// make sure the addressee of the original block is the same as whatever inbox this landed in
|
||||
if gtsBlock.TargetAccountID != targetAcct.ID {
|
||||
return errors.New("UNDO: block object account and inbox account were not the same")
|
||||
}
|
||||
// delete any existing BLOCK
|
||||
if err := f.db.DeleteWhere([]db.Where{{Key: "uri", Value: gtsBlock.URI}}, >smodel.Block{}); err != nil {
|
||||
return fmt.Errorf("UNDO: db error removing block: %s", err)
|
||||
}
|
||||
l.Debug("block undone")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ func (f *federatingDB) NewID(c context.Context, t vocab.Type) (idURL *url.URL, e
|
|||
// ID might already be set on an announce we've created, so check it here and return it if it is
|
||||
announce, ok := t.(vocab.ActivityStreamsAnnounce)
|
||||
if !ok {
|
||||
return nil, errors.New("newid: fave couldn't be parsed into vocab.ActivityStreamsAnnounce")
|
||||
return nil, errors.New("newid: announce couldn't be parsed into vocab.ActivityStreamsAnnounce")
|
||||
}
|
||||
idProp := announce.GetJSONLDId()
|
||||
if idProp != nil {
|
||||
|
|
@ -152,7 +152,7 @@ func (f *federatingDB) NewID(c context.Context, t vocab.Type) (idURL *url.URL, e
|
|||
// ID might already be set on an update we've created, so check it here and return it if it is
|
||||
update, ok := t.(vocab.ActivityStreamsUpdate)
|
||||
if !ok {
|
||||
return nil, errors.New("newid: fave couldn't be parsed into vocab.ActivityStreamsUpdate")
|
||||
return nil, errors.New("newid: update couldn't be parsed into vocab.ActivityStreamsUpdate")
|
||||
}
|
||||
idProp := update.GetJSONLDId()
|
||||
if idProp != nil {
|
||||
|
|
@ -160,6 +160,32 @@ func (f *federatingDB) NewID(c context.Context, t vocab.Type) (idURL *url.URL, e
|
|||
return idProp.GetIRI(), nil
|
||||
}
|
||||
}
|
||||
case gtsmodel.ActivityStreamsBlock:
|
||||
// BLOCK
|
||||
// ID might already be set on a block we've created, so check it here and return it if it is
|
||||
block, ok := t.(vocab.ActivityStreamsBlock)
|
||||
if !ok {
|
||||
return nil, errors.New("newid: block couldn't be parsed into vocab.ActivityStreamsBlock")
|
||||
}
|
||||
idProp := block.GetJSONLDId()
|
||||
if idProp != nil {
|
||||
if idProp.IsIRI() {
|
||||
return idProp.GetIRI(), nil
|
||||
}
|
||||
}
|
||||
case gtsmodel.ActivityStreamsUndo:
|
||||
// UNDO
|
||||
// ID might already be set on an undo we've created, so check it here and return it if it is
|
||||
undo, ok := t.(vocab.ActivityStreamsUndo)
|
||||
if !ok {
|
||||
return nil, errors.New("newid: undo couldn't be parsed into vocab.ActivityStreamsUndo")
|
||||
}
|
||||
idProp := undo.GetJSONLDId()
|
||||
if idProp != nil {
|
||||
if idProp.IsIRI() {
|
||||
return idProp.GetIRI(), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fallback default behavior: just return a random ULID after our protocol and host
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue