Monorepo for Tangled
Something went wrong. Try again.
3.7 kB · 141 lines
Go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142package knotserver
import ( "context" "fmt" "log/slog" "maps" "slices"
"github.com/bluesky-social/indigo/atproto/syntax"
"tangled.org/core/knotserver/db" "tangled.org/core/rbac")
const ( collaboratorBackfillMigration = "backfill-collaborators-from-casbin-v1" knotMemberBackfillMigration = "backfill-knot-members-from-casbin-v1")
func BackfillKnotMembers( ctx context.Context, d *db.DB, e *rbac.Enforcer, ownerDid string, logger *slog.Logger,) error { l := logger.With("migration", knotMemberBackfillMigration)
applied, err := d.IsMigrationApplied(knotMemberBackfillMigration) if err != nil { return fmt.Errorf("check migration applied: %w", err) } if applied { return nil }
owner, err := syntax.ParseDID(ownerDid) if err != nil { return fmt.Errorf("invalid knot owner DID %q: %w", ownerDid, err) }
members, err := e.GetKnotUsersByRole("server:member", rbac.ThisServer) if err != nil { return fmt.Errorf("list members: %w", err) } owners, err := e.GetKnotUsersByRole("server:owner", rbac.ThisServer) if err != nil { return fmt.Errorf("list owners: %w", err) }
var rows []db.KnotMember for _, candidate := range members { if slices.Contains(owners, candidate) { continue } subject, err := syntax.ParseDID(candidate) if err != nil { l.Warn("skipping member with invalid DID", "candidate", candidate, "err", err) continue } rows = append(rows, db.KnotMember{Did: owner, Subject: subject}) }
if err := d.ApplyKnotMemberBackfill(ctx, rows, knotMemberBackfillMigration); err != nil { return fmt.Errorf("apply backfill: %w", err) }
l.Info("backfilled knot members from casbin", "count", len(rows)) return nil}
func BackfillCollaborators( ctx context.Context, d *db.DB, e *rbac.Enforcer, logger *slog.Logger, markApplied bool,) error { l := logger.With("migration", collaboratorBackfillMigration)
applied, err := d.IsMigrationApplied(collaboratorBackfillMigration) if err != nil { return fmt.Errorf("check migration applied: %w", err) } if applied { return nil }
byRepo, err := e.GetCollaboratorsByRepo(rbac.ThisServer) if err != nil { return fmt.Errorf("list collaborators: %w", err) }
var rows []db.Collaborator var skipped int for _, repoDid := range slices.Sorted(maps.Keys(byRepo)) { candidates := byRepo[repoDid]
ownerDid, _, err := d.GetRepoKeyOwner(repoDid) if err != nil { l.Warn("skipping collaborators for unresolvable repo", "repoDid", repoDid, "collaborators", len(candidates), "err", err) skipped += len(candidates) continue }
repo, err := syntax.ParseDID(repoDid) if err != nil { l.Warn("skipping collaborators for repo with invalid DID", "repoDid", repoDid, "collaborators", len(candidates), "err", err) skipped += len(candidates) continue } owner, err := syntax.ParseDID(ownerDid) if err != nil { l.Warn("skipping collaborators for repo with invalid owner DID", "repoDid", repoDid, "owner", ownerDid, "collaborators", len(candidates), "err", err) skipped += len(candidates) continue }
for _, candidate := range candidates { subject, err := syntax.ParseDID(candidate) if err != nil { l.Warn("skipping collaborator with invalid DID", "repoDid", repoDid, "candidate", candidate, "err", err) skipped++ continue } rows = append(rows, db.Collaborator{ RepoDid: repo, Subject: subject, AddedBy: owner, }) } }
if err := d.ApplyCollaboratorBackfill(ctx, rows, collaboratorBackfillMigration, markApplied); err != nil { return fmt.Errorf("apply backfill: %w", err) }
l.Info("backfilled collaborators from casbin", "count", len(rows), "repos", len(byRepo), "skipped", skipped, "marked", markApplied) return nil}