Monorepo for Tangled
tangled.org
1package xrpc
2
3import (
4 "database/sql"
5 "encoding/json"
6 "net/http"
7
8 "github.com/bluesky-social/indigo/atproto/syntax"
9 "tangled.org/core/api/tangled"
10 "tangled.org/core/knotserver/db"
11 "tangled.org/core/rbac"
12 xrpcerr "tangled.org/core/xrpc/errors"
13)
14
15func (h *Xrpc) RemoveCollaborator(w http.ResponseWriter, r *http.Request) {
16 l := h.Logger.With("handler", "RemoveCollaborator")
17 fail := func(e xrpcerr.XrpcError, status int) {
18 l.Error("failed", "kind", e.Tag, "error", e.Message)
19 writeError(w, e, status)
20 }
21
22 actorDid, ok := r.Context().Value(ActorDid).(syntax.DID)
23 if !ok {
24 fail(xrpcerr.MissingActorDidError, http.StatusForbidden)
25 return
26 }
27
28 var data tangled.RepoRemoveCollaborator_Input
29 if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
30 fail(xrpcerr.GenericError(err), http.StatusBadRequest)
31 return
32 }
33
34 t, status, xerr := h.resolveCollabTarget(actorDid, data.Repo, data.Subject)
35 if xerr != nil {
36 fail(*xerr, status)
37 return
38 }
39 if t.ownerNoop {
40 l.Info("subject is the repo owner, no-op", "repoDid", t.repoDid, "subject", t.subject)
41 w.WriteHeader(http.StatusOK)
42 return
43 }
44
45 status, xerr = h.applyAclRevoke(r.Context(), l.With("repoDid", t.repoDid), aclRevoke{
46 role: "collaborator",
47 subject: t.subject,
48 inAcl: func() (bool, error) {
49 return h.Enforcer.IsRepoCollaborator(t.subject.String(), rbac.ThisServer, t.repoDid.String())
50 },
51 inTable: func() (bool, error) {
52 return db.IsCollaborator(h.Db, t.repoDid, t.subject)
53 },
54 removeAcl: func() (bool, error) {
55 if err := h.Enforcer.RemoveCollaborator(t.subject.String(), rbac.ThisServer, t.repoDid.String()); err != nil {
56 return false, err
57 }
58 return true, nil
59 },
60 restoreAcl: func() error {
61 return h.Enforcer.AddCollaborator(t.subject.String(), rbac.ThisServer, t.repoDid.String())
62 },
63 deleteRow: func(tx *sql.Tx) error {
64 return db.RemoveCollaborator(tx, t.repoDid, t.subject)
65 },
66 emit: func() error {
67 return h.Db.EmitCollaboratorUpdate(h.Notifier, db.AclOpRemove, t.subject, t.repoDid)
68 },
69 })
70 if xerr != nil {
71 fail(*xerr, status)
72 return
73 }
74 w.WriteHeader(status)
75}