From 760d2c823d58959a18df892ef86e98528cc500fa Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Tue, 21 Jul 2026 16:00:57 +0900 Subject: [PATCH] spindle: acl db table Signed-off-by: Seongmin Lee --- spindle/db/db.go | 17 ++++++++++++ spindle/db/known_dids.go | 44 ------------------------------- spindle/db/users.go | 57 ++++++++++++++++++++++++++++++++++++++++ spindle/server.go | 4 +-- spindle/user.go | 15 +++++++++++ 5 files changed, 91 insertions(+), 46 deletions(-) delete mode 100644 spindle/db/known_dids.go create mode 100644 spindle/db/users.go create mode 100644 spindle/user.go diff --git a/spindle/db/db.go b/spindle/db/db.go index eb7484cc..8e845fea 100644 --- a/spindle/db/db.go +++ b/spindle/db/db.go @@ -270,6 +270,23 @@ func runMigrations(_ context.Context, conn *sql.Conn, logger *slog.Logger) error return err } + if err := orm.RunMigration(conn, logger, "user-acl-table", func(tx *sql.Tx) error { + _, err := tx.Exec(` + CREATE TABLE users ( + did TEXT PRIMARY KEY, + blocked INTEGER DEFAULT 0 + ); + + insert or ignore into users (did) + select did from known_dids; + + drop table known_dids; + `) + return err + }); err != nil { + return err + } + return nil } diff --git a/spindle/db/known_dids.go b/spindle/db/known_dids.go deleted file mode 100644 index 2192e069..00000000 --- a/spindle/db/known_dids.go +++ /dev/null @@ -1,44 +0,0 @@ -package db - -func AddDid(q DBTX, did string) error { - _, err := q.Exec(`insert or ignore into known_dids (did) values (?)`, did) - return err -} - -func RemoveDid(q DBTX, did string) error { - _, err := q.Exec(`delete from known_dids where did = ?`, did) - return err -} - -func (d *DB) GetAllDids() ([]string, error) { - var dids []string - - rows, err := d.Query(`select did from known_dids`) - if err != nil { - return nil, err - } - defer rows.Close() - - for rows.Next() { - var did string - if err := rows.Scan(&did); err != nil { - return nil, err - } - dids = append(dids, did) - } - - if err := rows.Err(); err != nil { - return nil, err - } - - return dids, nil -} - -func (d *DB) HasKnownDids() bool { - var count int - err := d.QueryRow(`select count(*) from known_dids`).Scan(&count) - if err != nil { - return false - } - return count > 0 -} diff --git a/spindle/db/users.go b/spindle/db/users.go new file mode 100644 index 00000000..a400074c --- /dev/null +++ b/spindle/db/users.go @@ -0,0 +1,57 @@ +package db + +import ( + "context" + "database/sql" + "errors" + + "github.com/bluesky-social/indigo/atproto/syntax" +) + +func (d *DB) ListAllowedMembers() ([]syntax.DID, error) { + rows, err := d.Query(`select did from users where blocked = 0`) + if err != nil { + return nil, err + } + defer rows.Close() + + var dids []syntax.DID + for rows.Next() { + var did syntax.DID + if err := rows.Scan(&did); err != nil { + return nil, err + } + dids = append(dids, did) + } + + return dids, rows.Err() +} + +// IsAllowedUser reports whether did is known and unblocked. Unknown DIDs get fallback. +func (d *DB) IsAllowedUser(ctx context.Context, did syntax.DID, fallback bool) (bool, error) { + var blocked bool + err := d.QueryRowContext(ctx, `select blocked from users where did = ?`, did).Scan(&blocked) + if errors.Is(err, sql.ErrNoRows) { + return fallback, nil + } + if err != nil { + return false, err + } + return !blocked, nil +} + +func (d *DB) AllowUser(ctx context.Context, did syntax.DID) error { + return d.UpsertUser(ctx, did, false) +} + +func (d *DB) BlockUser(ctx context.Context, did syntax.DID) error { + return d.UpsertUser(ctx, did, true) +} + +func (d *DB) UpsertUser(ctx context.Context, did syntax.DID, block bool) error { + _, err := d.ExecContext(ctx, ` + insert into users (did, blocked) values (?, ?) + on conflict(did) do update set blocked = excluded.blocked + `, did, block) + return err +} diff --git a/spindle/server.go b/spindle/server.go index c1e6b080..d1ed0009 100644 --- a/spindle/server.go +++ b/spindle/server.go @@ -125,12 +125,12 @@ func New(ctx context.Context, cfg *config.Config, d *db.DB, engines map[string]m jc.ExemptCollection(tangled.RepoPullNSID) // Check if the spindle knows about any Dids; - dids, err := d.GetAllDids() + dids, err := d.ListAllowedMembers() if err != nil { return nil, fmt.Errorf("failed to get all dids: %w", err) } for _, d := range dids { - jc.AddDid(d) + jc.AddDid(d.String()) } knownRepos, err := d.AllRepos() diff --git a/spindle/user.go b/spindle/user.go new file mode 100644 index 00000000..d14a6700 --- /dev/null +++ b/spindle/user.go @@ -0,0 +1,15 @@ +package spindle + +import ( + "context" + + "github.com/bluesky-social/indigo/atproto/syntax" +) + +func (s *Spindle) AllowUser(ctx context.Context, did syntax.DID) error { + return s.db.UpsertUser(ctx, did, false) +} + +func (s *Spindle) BlockUser(ctx context.Context, did syntax.DID) error { + return s.db.UpsertUser(ctx, did, true) +} -- 2.51.2