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}