Monorepo for Tangled tangled.org
1package xrpc 2 3import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "strings" 8 9 "github.com/bluesky-social/indigo/atproto/syntax" 10 "tangled.org/core/api/tangled" 11 "tangled.org/core/spindle/models" 12 xrpcerr "tangled.org/core/xrpc/errors" 13) 14 15func (x *Xrpc) CancelPipeline(w http.ResponseWriter, r *http.Request) { 16 l := x.Logger 17 fail := func(e xrpcerr.XrpcError) { 18 l.Error("failed", "kind", e.Tag, "error", e.Message) 19 writeError(w, e, http.StatusBadRequest) 20 } 21 l.Debug("cancel pipeline") 22 23 actorDid, ok := r.Context().Value(ActorDid).(syntax.DID) 24 if !ok { 25 fail(xrpcerr.MissingActorDidError) 26 return 27 } 28 29 var input tangled.PipelineCancelPipeline_Input 30 if err := json.NewDecoder(r.Body).Decode(&input); err != nil { 31 fail(xrpcerr.GenericError(err)) 32 return 33 } 34 35 aturi := syntax.ATURI(input.Pipeline) 36 wid := models.WorkflowId{ 37 PipelineId: models.PipelineId{ 38 Knot: strings.TrimPrefix(aturi.Authority().String(), "did:web:"), 39 Rkey: aturi.RecordKey().String(), 40 }, 41 Name: input.Workflow, 42 } 43 l.Debug("cancel pipeline", "wid", wid) 44 45 // unfortunately we have to resolve repo-at here 46 repoAt, err := syntax.ParseATURI(input.Repo) 47 if err != nil { 48 fail(xrpcerr.InvalidRepoError(input.Repo)) 49 return 50 } 51 52 isRepoOwner, err := x.Enforcer.IsRepoOwner(actorDid, repoAt) 53 if err != nil || !isRepoOwner { 54 fail(xrpcerr.AccessControlError(actorDid.String())) 55 return 56 } 57 for _, engine := range x.Engines { 58 l.Debug("destorying workflow", "wid", wid) 59 err = engine.DestroyWorkflow(r.Context(), wid) 60 if err != nil { 61 fail(xrpcerr.GenericError(fmt.Errorf("dailed to destroy workflow: %w", err))) 62 return 63 } 64 err = x.Db.StatusCancelled(wid, "User canceled the workflow", -1, x.Notifier) 65 if err != nil { 66 fail(xrpcerr.GenericError(fmt.Errorf("dailed to emit status failed: %w", err))) 67 return 68 } 69 } 70 71 w.WriteHeader(http.StatusOK) 72}