summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Kangas <gabek@real-ity.com>2022-01-06 21:12:29 -0800
committerGabe Kangas <gabek@real-ity.com>2022-01-06 23:02:49 -0800
commit9500ea560e4599cb4a81568996e89843a59173f4 (patch)
tree54585dd4e87d489a59fc7f0c1556975aed57e326
parent4f283e04f4774f177d99f30a4d882c6815085447 (diff)
Do not allow old posts to be liked/shared. Closes #1652
-rw-r--r--.golangci.yml4
-rw-r--r--activitypub/controllers/object.go2
-rw-r--r--activitypub/controllers/outbox.go2
-rw-r--r--activitypub/inbox/announce.go7
-rw-r--r--activitypub/inbox/constants.go7
-rw-r--r--activitypub/inbox/like.go7
-rw-r--r--activitypub/persistence/persistence.go4
-rw-r--r--db/query.sql2
-rw-r--r--db/query.sql.go5
9 files changed, 31 insertions, 9 deletions
diff --git a/.golangci.yml b/.golangci.yml
index a7cba8764..75bc787dd 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -81,3 +81,7 @@ linters-settings:
# Logging via Print bypasses our logging framework.
- ^(fmt\.Print(|f|ln)|print|println)
- ^panic.*$
+
+ dupl:
+ # tokens count to trigger issue, 150 by default
+ threshold: 160
diff --git a/activitypub/controllers/object.go b/activitypub/controllers/object.go
index 595304f5e..bdb03d748 100644
--- a/activitypub/controllers/object.go
+++ b/activitypub/controllers/object.go
@@ -26,7 +26,7 @@ func ObjectHandler(w http.ResponseWriter, r *http.Request) {
}
iri := strings.Join([]string{strings.TrimSuffix(data.GetServerURL(), "/"), r.URL.Path}, "")
- object, _, err := persistence.GetObjectByIRI(iri)
+ object, _, _, err := persistence.GetObjectByIRI(iri)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
diff --git a/activitypub/controllers/outbox.go b/activitypub/controllers/outbox.go
index c3560faf1..5aa75df0f 100644
--- a/activitypub/controllers/outbox.go
+++ b/activitypub/controllers/outbox.go
@@ -58,7 +58,7 @@ func OutboxHandler(w http.ResponseWriter, r *http.Request) {
// ActorObjectHandler will handle the request for a single ActivityPub object.
func ActorObjectHandler(w http.ResponseWriter, r *http.Request) {
- object, _, err := persistence.GetObjectByIRI(r.URL.Path)
+ object, _, _, err := persistence.GetObjectByIRI(r.URL.Path)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
diff --git a/activitypub/inbox/announce.go b/activitypub/inbox/announce.go
index 11737d3a3..db79393f7 100644
--- a/activitypub/inbox/announce.go
+++ b/activitypub/inbox/announce.go
@@ -21,11 +21,16 @@ func handleAnnounceRequest(c context.Context, activity vocab.ActivityStreamsAnno
}
// Shares need to match a post we had already sent.
- _, isLiveNotification, err := persistence.GetObjectByIRI(objectIRI)
+ _, isLiveNotification, timestamp, err := persistence.GetObjectByIRI(objectIRI)
if err != nil {
return errors.Wrap(err, "Could not find post locally")
}
+ // Don't allow old activities to be liked
+ if time.Since(timestamp) > maxAgeForEngagement {
+ return errors.New("Activity is too old to be shared")
+ }
+
// Save as an accepted activity
if err := persistence.SaveInboundFediverseActivity(objectIRI, actorIRI, events.FediverseEngagementRepost, time.Now()); err != nil {
return errors.Wrap(err, "unable to save inbound share/re-post activity")
diff --git a/activitypub/inbox/constants.go b/activitypub/inbox/constants.go
new file mode 100644
index 000000000..a7dac5890
--- /dev/null
+++ b/activitypub/inbox/constants.go
@@ -0,0 +1,7 @@
+package inbox
+
+import "time"
+
+const (
+ maxAgeForEngagement = time.Hour * 36
+)
diff --git a/activitypub/inbox/like.go b/activitypub/inbox/like.go
index 9bee5b507..d457de19d 100644
--- a/activitypub/inbox/like.go
+++ b/activitypub/inbox/like.go
@@ -21,11 +21,16 @@ func handleLikeRequest(c context.Context, activity vocab.ActivityStreamsLike) er
}
// Likes need to match a post we had already sent.
- _, isLiveNotification, err := persistence.GetObjectByIRI(objectIRI)
+ _, isLiveNotification, timestamp, err := persistence.GetObjectByIRI(objectIRI)
if err != nil {
return errors.Wrap(err, "Could not find post locally")
}
+ // Don't allow old activities to be liked
+ if time.Since(timestamp) > maxAgeForEngagement {
+ return errors.New("Activity is too old to be liked")
+ }
+
// Save as an accepted activity
if err := persistence.SaveInboundFediverseActivity(objectIRI, actorIRI, events.FediverseEngagementLike, time.Now()); err != nil {
return errors.Wrap(err, "unable to save inbound like activity")
diff --git a/activitypub/persistence/persistence.go b/activitypub/persistence/persistence.go
index 1858aa858..842cce712 100644
--- a/activitypub/persistence/persistence.go
+++ b/activitypub/persistence/persistence.go
@@ -292,9 +292,9 @@ func GetObjectByID(id string) (string, error) {
}
// GetObjectByIRI will return a string representation of a single object by the IRI.
-func GetObjectByIRI(iri string) (string, bool, error) {
+func GetObjectByIRI(iri string) (string, bool, time.Time, error) {
row, err := _datastore.GetQueries().GetObjectFromOutboxByIRI(context.Background(), iri)
- return string(row.Value), row.LiveNotification.Bool, err
+ return string(row.Value), row.LiveNotification.Bool, row.CreatedAt.Time, err
}
// GetLocalPostCount will return the number of posts existing locally.
diff --git a/db/query.sql b/db/query.sql
index bc2f24a0e..7aae2d51f 100644
--- a/db/query.sql
+++ b/db/query.sql
@@ -33,7 +33,7 @@ SELECT value FROM ap_outbox LIMIT $1 OFFSET $2;
SELECT value FROM ap_outbox WHERE iri = $1;
-- name: GetObjectFromOutboxByIRI :one
-SELECT value, live_notification FROM ap_outbox WHERE iri = $1;
+SELECT value, live_notification, created_at FROM ap_outbox WHERE iri = $1;
-- name: RemoveFollowerByIRI :exec
DELETE FROM ap_followers WHERE iri = $1;
diff --git a/db/query.sql.go b/db/query.sql.go
index 6c28d5164..7cec05aa6 100644
--- a/db/query.sql.go
+++ b/db/query.sql.go
@@ -303,18 +303,19 @@ func (q *Queries) GetObjectFromOutboxByID(ctx context.Context, iri string) ([]by
}
const getObjectFromOutboxByIRI = `-- name: GetObjectFromOutboxByIRI :one
-SELECT value, live_notification FROM ap_outbox WHERE iri = $1
+SELECT value, live_notification, created_at FROM ap_outbox WHERE iri = $1
`
type GetObjectFromOutboxByIRIRow struct {
Value []byte
LiveNotification sql.NullBool
+ CreatedAt sql.NullTime
}
func (q *Queries) GetObjectFromOutboxByIRI(ctx context.Context, iri string) (GetObjectFromOutboxByIRIRow, error) {
row := q.db.QueryRowContext(ctx, getObjectFromOutboxByIRI, iri)
var i GetObjectFromOutboxByIRIRow
- err := row.Scan(&i.Value, &i.LiveNotification)
+ err := row.Scan(&i.Value, &i.LiveNotification, &i.CreatedAt)
return i, err
}