diff --git a/appview/repo/repo.go b/appview/repo/repo.go --- a/appview/repo/repo.go +++ b/appview/repo/repo.go @@ -1227,6 +1227,140 @@ rp.pages.HxRefresh(w) } +func (rp *Repo) SubscribeLabel(w http.ResponseWriter, r *http.Request) { + user := rp.oauth.GetUser(r) + l := rp.logger.With("handler", "DeleteLabel") + l = l.With("did", user.Did) + l = l.With("handle", user.Handle) + + f, err := rp.repoResolver.Resolve(r) + if err != nil { + l.Error("failed to get repo and knot", "err", err) + return + } + + errorId := "label-operation" + fail := func(msg string, err error) { + l.Error(msg, "err", err) + rp.pages.Notice(w, errorId, msg) + } + + labelAt := r.FormValue("label") + _, err = db.GetLabelDefinition(rp.db, db.FilterEq("at_uri", labelAt)) + if err != nil { + fail("Failed to subscribe to label.", err) + return + } + + newRepo := f.Repo + newRepo.Labels = append(newRepo.Labels, labelAt) + repoRecord := newRepo.AsRecord() + + client, err := rp.oauth.AuthorizedClient(r) + if err != nil { + fail(err.Error(), err) + return + } + + ex, err := client.RepoGetRecord(r.Context(), "", tangled.RepoNSID, f.Repo.Did, f.Repo.Rkey) + if err != nil { + fail("Failed to update labels, no record found on PDS.", err) + return + } + _, err = client.RepoPutRecord(r.Context(), &comatproto.RepoPutRecord_Input{ + Collection: tangled.RepoNSID, + Repo: newRepo.Did, + Rkey: newRepo.Rkey, + SwapRecord: ex.Cid, + Record: &lexutil.LexiconTypeDecoder{ + Val: &repoRecord, + }, + }) + + err = db.SubscribeLabel(rp.db, &db.RepoLabel{ + RepoAt: f.RepoAt(), + LabelAt: syntax.ATURI(labelAt), + }) + if err != nil { + fail("Failed to subscribe to label.", err) + return + } + + // everything succeeded + rp.pages.HxRefresh(w) +} + +func (rp *Repo) UnsubscribeLabel(w http.ResponseWriter, r *http.Request) { + user := rp.oauth.GetUser(r) + l := rp.logger.With("handler", "DeleteLabel") + l = l.With("did", user.Did) + l = l.With("handle", user.Handle) + + f, err := rp.repoResolver.Resolve(r) + if err != nil { + l.Error("failed to get repo and knot", "err", err) + return + } + + errorId := "label-operation" + fail := func(msg string, err error) { + l.Error(msg, "err", err) + rp.pages.Notice(w, errorId, msg) + } + + labelAt := r.FormValue("label") + _, err = db.GetLabelDefinition(rp.db, db.FilterEq("at_uri", labelAt)) + if err != nil { + fail("Failed to unsubscribe to label.", err) + return + } + + // update repo record to remove the label reference + newRepo := f.Repo + var updated []string + for _, l := range newRepo.Labels { + if l != labelAt { + updated = append(updated, l) + } + } + newRepo.Labels = updated + repoRecord := newRepo.AsRecord() + + client, err := rp.oauth.AuthorizedClient(r) + if err != nil { + fail(err.Error(), err) + return + } + + ex, err := client.RepoGetRecord(r.Context(), "", tangled.RepoNSID, f.Repo.Did, f.Repo.Rkey) + if err != nil { + fail("Failed to update labels, no record found on PDS.", err) + return + } + _, err = client.RepoPutRecord(r.Context(), &comatproto.RepoPutRecord_Input{ + Collection: tangled.RepoNSID, + Repo: newRepo.Did, + Rkey: newRepo.Rkey, + SwapRecord: ex.Cid, + Record: &lexutil.LexiconTypeDecoder{ + Val: &repoRecord, + }, + }) + + err = db.UnsubscribeLabel( + rp.db, + db.FilterEq("repo_at", f.RepoAt()), + db.FilterEq("label_at", labelAt), + ) + if err != nil { + fail("Failed to unsubscribe label.", err) + return + } + + // everything succeeded + rp.pages.HxRefresh(w) +} + func (rp *Repo) AddCollaborator(w http.ResponseWriter, r *http.Request) { user := rp.oauth.GetUser(r) l := rp.logger.With("handler", "AddCollaborator") diff --git a/appview/repo/router.go b/appview/repo/router.go --- a/appview/repo/router.go +++ b/appview/repo/router.go @@ -78,6 +78,8 @@ r.With(mw.RepoPermissionMiddleware("repo:owner")).Post("/spindle", rp.EditSpindle) r.With(mw.RepoPermissionMiddleware("repo:owner")).Put("/label", rp.AddLabel) r.With(mw.RepoPermissionMiddleware("repo:owner")).Delete("/label", rp.DeleteLabel) + r.With(mw.RepoPermissionMiddleware("repo:owner")).Put("/label/subscribe", rp.SubscribeLabel) + r.With(mw.RepoPermissionMiddleware("repo:owner")).Delete("/label/subscribe", rp.UnsubscribeLabel) r.With(mw.RepoPermissionMiddleware("repo:invite")).Put("/collaborator", rp.AddCollaborator) r.With(mw.RepoPermissionMiddleware("repo:delete")).Delete("/delete", rp.DeleteRepo) r.Put("/branches/default", rp.SetDefaultBranch) diff --git a/appview/state/router.go b/appview/state/router.go --- a/appview/state/router.go +++ b/appview/state/router.go @@ -253,7 +253,7 @@ } func (s *State) LabelsRouter(mw *middleware.Middleware) http.Handler { - ls := labels.New(s.oauth, s.repoResolver, s.pages, s.spindlestream, s.idResolver, s.db, s.config, s.enforcer) + ls := labels.New(s.oauth, s.pages, s.db, s.validator) return ls.Router(mw) }