forked from tangled.org/core
this repo has no description
at master 2.5 kB view raw
1package xrpc 2 3import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "os" 8 "path/filepath" 9 10 comatproto "github.com/bluesky-social/indigo/api/atproto" 11 "github.com/bluesky-social/indigo/atproto/syntax" 12 "github.com/bluesky-social/indigo/xrpc" 13 securejoin "github.com/cyphar/filepath-securejoin" 14 "tangled.sh/tangled.sh/core/api/tangled" 15 "tangled.sh/tangled.sh/core/rbac" 16 xrpcerr "tangled.sh/tangled.sh/core/xrpc/errors" 17) 18 19func (x *Xrpc) DeleteRepo(w http.ResponseWriter, r *http.Request) { 20 l := x.Logger.With("handler", "DeleteRepo") 21 fail := func(e xrpcerr.XrpcError) { 22 l.Error("failed", "kind", e.Tag, "error", e.Message) 23 writeError(w, e, http.StatusBadRequest) 24 } 25 26 actorDid, ok := r.Context().Value(ActorDid).(syntax.DID) 27 if !ok { 28 fail(xrpcerr.MissingActorDidError) 29 return 30 } 31 32 var data tangled.RepoDelete_Input 33 if err := json.NewDecoder(r.Body).Decode(&data); err != nil { 34 fail(xrpcerr.GenericError(err)) 35 return 36 } 37 38 did := data.Did 39 name := data.Name 40 rkey := data.Rkey 41 42 if did == "" || name == "" { 43 fail(xrpcerr.GenericError(fmt.Errorf("did and name are required"))) 44 return 45 } 46 47 ident, err := x.Resolver.ResolveIdent(r.Context(), actorDid.String()) 48 if err != nil || ident.Handle.IsInvalidHandle() { 49 fail(xrpcerr.GenericError(err)) 50 return 51 } 52 53 xrpcc := xrpc.Client{ 54 Host: ident.PDSEndpoint(), 55 } 56 57 // ensure that the record does not exists 58 _, err = comatproto.RepoGetRecord(r.Context(), &xrpcc, "", tangled.RepoNSID, actorDid.String(), rkey) 59 if err == nil { 60 fail(xrpcerr.RecordExistsError(rkey)) 61 return 62 } 63 64 relativeRepoPath := filepath.Join(did, name) 65 isDeleteAllowed, err := x.Enforcer.IsRepoDeleteAllowed(actorDid.String(), rbac.ThisServer, relativeRepoPath) 66 if err != nil { 67 fail(xrpcerr.GenericError(err)) 68 return 69 } 70 if !isDeleteAllowed { 71 fail(xrpcerr.AccessControlError(actorDid.String())) 72 return 73 } 74 75 repoPath, err := securejoin.SecureJoin(x.Config.Repo.ScanPath, relativeRepoPath) 76 if err != nil { 77 fail(xrpcerr.GenericError(err)) 78 return 79 } 80 81 err = os.RemoveAll(repoPath) 82 if err != nil { 83 l.Error("deleting repo", "error", err.Error()) 84 writeError(w, xrpcerr.GenericError(err), http.StatusInternalServerError) 85 return 86 } 87 88 err = x.Enforcer.RemoveRepo(did, rbac.ThisServer, relativeRepoPath) 89 if err != nil { 90 l.Error("failed to delete repo from enforcer", "error", err.Error()) 91 writeError(w, xrpcerr.GenericError(err), http.StatusInternalServerError) 92 return 93 } 94 95 w.WriteHeader(http.StatusOK) 96}