package xrpc import ( "encoding/json" "fmt" "net/http" "github.com/bluesky-social/indigo/atproto/syntax" "tangled.org/core/api/org_tangled" "tangled.org/core/spindle/db" xrpcerr "tangled.org/core/xrpc/errors" ) type OwnerBackfill interface { Track(dids ...syntax.DID) Untrack(did syntax.DID) } func allowListInput(w http.ResponseWriter, r *http.Request) (syntax.DID, bool) { var input struct { Did string `json:"did"` } if err := json.NewDecoder(r.Body).Decode(&input); err != nil { writeError(w, invalidRequest(err), http.StatusBadRequest) return "", false } did, err := syntax.ParseDID(input.Did) if err != nil { writeError(w, invalidRequest(fmt.Errorf("This DID %q deosn't parse: %w", input.Did, err)), http.StatusBadRequest) return "", false } return did, true } func (x *Xrpc) allowListEntry(w http.ResponseWriter, r *http.Request) (syntax.DID, bool) { if _, errObj, status := x.checkSpindleOwner(r); errObj != nil { writeError(w, *errObj, status) return "", false } return allowListInput(w, r) } func (x *Xrpc) allowListChange( w http.ResponseWriter, r *http.Request, write func(q db.DBTX, did syntax.DID) error, declare func(b OwnerBackfill, did syntax.DID), change string, ) { did, ok := x.allowListEntry(w, r) if !ok { return } if err := write(x.Db, did); err != nil { writeError(w, xrpcerr.GenericError(err), http.StatusInternalServerError) return } if x.Backfill != nil { declare(x.Backfill, did) } x.Logger.InfoContext(r.Context(), "Allow-list entry "+change+".", "did", did) w.WriteHeader(http.StatusOK) } func (x *Xrpc) AllowListAdd(w http.ResponseWriter, r *http.Request) { x.allowListChange(w, r, db.AddToAllowlist, func(b OwnerBackfill, did syntax.DID) { b.Track(did) }, "added") } func (x *Xrpc) AllowListRemove(w http.ResponseWriter, r *http.Request) { x.allowListChange(w, r, db.RemoveFromAllowlist, OwnerBackfill.Untrack, "removed") } func (x *Xrpc) AllowListList(w http.ResponseWriter, r *http.Request) { if _, errObj, status := x.checkSpindleOwner(r); errObj != nil { writeError(w, *errObj, status) return } dids, err := db.ListAllowlist(x.Db) if err != nil { writeError(w, xrpcerr.GenericError(err), http.StatusInternalServerError) return } out := org_tangled.TempSpindleAllowListList_Output{Dids: make([]string, 0, len(dids))} for _, did := range dids { out.Dids = append(out.Dids, did.String()) } x.writeResponse(w, r, http.StatusOK, out) }