ActivityPub background actor validation, update and cleanup process (#4765)
* feat(ap): add validation+update+cleanup AP actor job * fix(test): use time.Time instead of sql.NullTime * feat(test): add integration test for AP follower cleanup/validation job
This commit is contained in:
+13
-11
@@ -18,17 +18,19 @@ type ApAcceptedActivity struct {
|
||||
}
|
||||
|
||||
type ApFollower struct {
|
||||
Iri string
|
||||
Inbox string
|
||||
SharedInbox sql.NullString
|
||||
Name sql.NullString
|
||||
Username string
|
||||
Image sql.NullString
|
||||
Request string
|
||||
RequestObject []byte
|
||||
CreatedAt sql.NullTime
|
||||
ApprovedAt sql.NullTime
|
||||
DisabledAt sql.NullTime
|
||||
Iri string
|
||||
Inbox string
|
||||
SharedInbox sql.NullString
|
||||
Name sql.NullString
|
||||
Username string
|
||||
Image sql.NullString
|
||||
Request string
|
||||
RequestObject []byte
|
||||
CreatedAt sql.NullTime
|
||||
ApprovedAt sql.NullTime
|
||||
DisabledAt sql.NullTime
|
||||
LastValidatedAt sql.NullTime
|
||||
FirstValidationFailureAt sql.NullTime
|
||||
}
|
||||
|
||||
type ApOutbox struct {
|
||||
|
||||
@@ -57,6 +57,23 @@ SELECT count(*) FROM ap_accepted_activities WHERE iri = $1 AND actor = $2 AND TY
|
||||
-- name: UpdateFollowerByIRI :exec
|
||||
UPDATE ap_followers SET inbox = $1, shared_inbox = $2, name = $3, username = $4, image = $5 WHERE iri = $6;
|
||||
|
||||
-- name: GetFollowersToValidate :many
|
||||
SELECT iri, inbox, shared_inbox, name, username, image, first_validation_failure_at
|
||||
FROM ap_followers
|
||||
WHERE approved_at IS NOT NULL AND disabled_at IS NULL
|
||||
ORDER BY last_validated_at ASC NULLS FIRST
|
||||
LIMIT $1;
|
||||
|
||||
-- name: UpdateFollowerValidationSuccess :exec
|
||||
UPDATE ap_followers
|
||||
SET last_validated_at = $1, first_validation_failure_at = NULL
|
||||
WHERE iri = $2;
|
||||
|
||||
-- name: UpdateFollowerValidationFailure :exec
|
||||
UPDATE ap_followers
|
||||
SET last_validated_at = $1, first_validation_failure_at = COALESCE(first_validation_failure_at, $1)
|
||||
WHERE iri = $2;
|
||||
|
||||
-- name: GetUniqueDeliveryInboxes :many
|
||||
SELECT COALESCE(shared_inbox, inbox) as delivery_inbox FROM ap_followers WHERE approved_at is not null GROUP BY delivery_inbox;
|
||||
|
||||
|
||||
+97
-2
@@ -306,9 +306,23 @@ const getFollowerByIRI = `-- name: GetFollowerByIRI :one
|
||||
SELECT iri, inbox, shared_inbox, name, username, image, request, request_object, created_at, approved_at, disabled_at FROM ap_followers WHERE iri = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetFollowerByIRI(ctx context.Context, iri string) (ApFollower, error) {
|
||||
type GetFollowerByIRIRow struct {
|
||||
Iri string
|
||||
Inbox string
|
||||
SharedInbox sql.NullString
|
||||
Name sql.NullString
|
||||
Username string
|
||||
Image sql.NullString
|
||||
Request string
|
||||
RequestObject []byte
|
||||
CreatedAt sql.NullTime
|
||||
ApprovedAt sql.NullTime
|
||||
DisabledAt sql.NullTime
|
||||
}
|
||||
|
||||
func (q *Queries) GetFollowerByIRI(ctx context.Context, iri string) (GetFollowerByIRIRow, error) {
|
||||
row := q.db.QueryRowContext(ctx, getFollowerByIRI, iri)
|
||||
var i ApFollower
|
||||
var i GetFollowerByIRIRow
|
||||
err := row.Scan(
|
||||
&i.Iri,
|
||||
&i.Inbox,
|
||||
@@ -340,6 +354,55 @@ func (q *Queries) GetFollowerCount(ctx context.Context) (int64, error) {
|
||||
return count, err
|
||||
}
|
||||
|
||||
const getFollowersToValidate = `-- name: GetFollowersToValidate :many
|
||||
SELECT iri, inbox, shared_inbox, name, username, image, first_validation_failure_at
|
||||
FROM ap_followers
|
||||
WHERE approved_at IS NOT NULL AND disabled_at IS NULL
|
||||
ORDER BY last_validated_at ASC NULLS FIRST
|
||||
LIMIT $1
|
||||
`
|
||||
|
||||
type GetFollowersToValidateRow struct {
|
||||
Iri string
|
||||
Inbox string
|
||||
SharedInbox sql.NullString
|
||||
Name sql.NullString
|
||||
Username string
|
||||
Image sql.NullString
|
||||
FirstValidationFailureAt sql.NullTime
|
||||
}
|
||||
|
||||
func (q *Queries) GetFollowersToValidate(ctx context.Context, limit int32) ([]GetFollowersToValidateRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getFollowersToValidate, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetFollowersToValidateRow
|
||||
for rows.Next() {
|
||||
var i GetFollowersToValidateRow
|
||||
if err := rows.Scan(
|
||||
&i.Iri,
|
||||
&i.Inbox,
|
||||
&i.SharedInbox,
|
||||
&i.Name,
|
||||
&i.Username,
|
||||
&i.Image,
|
||||
&i.FirstValidationFailureAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getIPAddressBans = `-- name: GetIPAddressBans :many
|
||||
SELECT ip_address, notes, created_at FROM ip_bans
|
||||
`
|
||||
@@ -815,3 +878,35 @@ func (q *Queries) UpdateFollowerByIRI(ctx context.Context, arg UpdateFollowerByI
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const updateFollowerValidationFailure = `-- name: UpdateFollowerValidationFailure :exec
|
||||
UPDATE ap_followers
|
||||
SET last_validated_at = $1, first_validation_failure_at = COALESCE(first_validation_failure_at, $1)
|
||||
WHERE iri = $2
|
||||
`
|
||||
|
||||
type UpdateFollowerValidationFailureParams struct {
|
||||
LastValidatedAt sql.NullTime
|
||||
Iri string
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateFollowerValidationFailure(ctx context.Context, arg UpdateFollowerValidationFailureParams) error {
|
||||
_, err := q.db.ExecContext(ctx, updateFollowerValidationFailure, arg.LastValidatedAt, arg.Iri)
|
||||
return err
|
||||
}
|
||||
|
||||
const updateFollowerValidationSuccess = `-- name: UpdateFollowerValidationSuccess :exec
|
||||
UPDATE ap_followers
|
||||
SET last_validated_at = $1, first_validation_failure_at = NULL
|
||||
WHERE iri = $2
|
||||
`
|
||||
|
||||
type UpdateFollowerValidationSuccessParams struct {
|
||||
LastValidatedAt sql.NullTime
|
||||
Iri string
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateFollowerValidationSuccess(ctx context.Context, arg UpdateFollowerValidationSuccessParams) error {
|
||||
_, err := q.db.ExecContext(ctx, updateFollowerValidationSuccess, arg.LastValidatedAt, arg.Iri)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ CREATE TABLE IF NOT EXISTS ap_followers (
|
||||
"created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
"approved_at" TIMESTAMP,
|
||||
"disabled_at" TIMESTAMP,
|
||||
"last_validated_at" TIMESTAMP,
|
||||
"first_validation_failure_at" TIMESTAMP,
|
||||
PRIMARY KEY (iri));
|
||||
CREATE INDEX iri_index ON ap_followers (iri);
|
||||
CREATE INDEX approved_at_index ON ap_followers (approved_at);
|
||||
|
||||
Reference in New Issue
Block a user