Current section

Files

Jump to
step_flow lib step_flow web_controllers workflow_definition.ex
Raw

lib/step_flow/web_controllers/workflow_definition.ex

defmodule StepFlow.WebController.WorkflowDefinition do
use StepFlow, :controller
use OpenApiSpex.ControllerSpecs
import Plug.Conn
alias OpenApiSpex.Schema
alias StepFlow.WebController.Helpers
alias StepFlow.WebController.OpenApiSchemas
alias StepFlow.WorkflowDefinitions
require Logger
@moduledoc false
tags(["Workflow Definitions"])
security([%{"authorization" => %OpenApiSpex.SecurityScheme{type: "http", scheme: "bearer"}}])
action_fallback(StepFlow.WebController.Fallback)
operation(:index,
summary: "List workflow definitions",
description: "List workflow definitions",
type: :object,
parameters: [
versions: [
in: :query,
description: "List of versions to match",
schema: %Schema{
type: :array,
items: %Schema{
type: :string
}
},
example: ["1.2.3", "1.2.4"]
],
mode: [
in: :query,
description: "Output mode",
schema: %Schema{
type: :array,
items: %Schema{
type: :string,
enum: [:full, :simple]
}
},
example: ["full"]
]
],
responses: [
ok:
{"WorkflowDefinitions", "application/json", OpenApiSchemas.Workflows.WorkflowDefinitions},
forbidden: "Forbidden"
]
)
def index(%Plug.Conn{assigns: %{current_user: user}} = conn, params) do
params =
params
|> Map.put("roles", StepFlow.Map.get_by_key_or_atom(user, :roles, []))
|> Map.put("versions", StepFlow.Map.get_by_key_or_atom(params, :versions, []))
|> Map.put("mode", StepFlow.Map.get_by_key_or_atom(params, :mode, "full"))
workflow_definitions = WorkflowDefinitions.list_workflow_definitions(params)
conn
|> put_view(StepFlow.WorkflowDefinitionView)
|> render("index.json", workflow_definitions: workflow_definitions)
end
def index(conn, _) do
conn
|> put_status(403)
|> put_view(StepFlow.WorkflowDefinitionView)
|> render("error.json",
errors: %{reason: "Forbidden to view workflows"}
)
end
operation(:show,
summary: "Get workflow definition (identifier)",
description: "Get a workflow definition by identifier",
type: :object,
parameters: [
id: [
in: :path,
description: "Workflow identifier",
type: :string,
example: "my_workflow"
]
],
responses: [
ok: {"WorkflowDefinition", "application/json", OpenApiSchemas.Workflows.WorkflowDefinition},
forbidden: "Forbidden",
not_found: "Not Found"
]
)
def show(%Plug.Conn{assigns: %{current_user: user}} = conn, %{"id" => identifier}) do
case WorkflowDefinitions.get_workflow_definition(identifier) do
nil ->
conn
|> put_status(:unprocessable_entity)
|> put_view(StepFlow.WorkflowDefinitionView)
|> render("error.json",
errors: %{reason: "Unable to locate workflow with this identifier"}
)
workflow_definition ->
if Helpers.has_right?("workflow::" <> identifier, user, "view") do
conn
|> put_view(StepFlow.WorkflowDefinitionView)
|> render("show.json", workflow_definition: workflow_definition)
else
conn
|> put_status(:forbidden)
|> put_view(StepFlow.WorkflowDefinitionView)
|> render("error.json",
errors: %{reason: "Forbidden to access workflow definition with this identifier"}
)
end
end
end
def show(conn, _) do
conn
|> put_status(403)
|> put_view(StepFlow.WorkflowDefinitionView)
|> render("error.json",
errors: %{reason: "Forbidden to view workflow with this identifier"}
)
end
operation(:create,
summary: "Post workflow definition",
description: "Create or update a workflow definition",
type: :object,
parameters: [
workflow_definition: [
in: :query,
description: "Definition of the workflow to create or update",
type: :object
]
],
responses: [
created: "Created",
forbidden: "Forbidden",
unprocessable_entity: "Unprocessable entity"
]
)
def(create(conn, %{"workflow_definition" => workflow_definition})) do
case WorkflowDefinitions.load_workflow_in_database(workflow_definition) do
{:ok, msg} ->
conn
|> put_status(201)
|> json(%{message: msg})
{:error, msg} ->
conn
|> put_status(:unprocessable_entity)
|> put_view(StepFlow.WorkflowDefinitionView)
|> render("error.json",
errors: %{reason: msg}
)
end
end
operation(:delete,
summary: "Delete workflow definition",
description: "Mark a workflow definition as deleted, based on the given ID",
type: :object,
parameters: [
id: [
in: :path,
description: "ID of the workflow definition",
type: :integer,
example: 2
]
],
responses: [
ok: "Deleted",
forbidden: "Forbidden",
unprocessable_entity: "Unprocessable entity"
]
)
def delete(%Plug.Conn{assigns: %{current_user: user}} = conn, %{"id" => id}) do
if Helpers.has_right?("workflow::*", user, "delete") do
case WorkflowDefinitions.delete_by_id(id) do
{:ok, msg} ->
conn
|> put_status(200)
|> json(%{message: msg})
{:error, msg} ->
conn
|> put_status(:unprocessable_entity)
|> put_view(StepFlow.WorkflowDefinitionView)
|> render("error.json",
errors: %{reason: msg}
)
end
else
conn
|> put_status(:forbidden)
|> put_view(StepFlow.WorkflowDefinitionView)
|> render("error.json",
errors: %{reason: "Forbidden to delete workflow definition"}
)
end
end
operation(:delete_by_version_and_identifier,
summary: "Delete workflow definition",
description:
"Mark a workflow definition as deleted, based on the given version and identifier",
type: :object,
parameters: [
workflow_definition: [
in: :query,
description: "Identifier and version of the workflow definition ",
type: :object,
example:
"{workflow_definition: {identifier: 'sleeper', version_major: 2, version_minor: 0, version_micro: 1}}"
]
],
responses: [
ok: "Deleted",
forbidden: "Forbidden",
unprocessable_entity: "Unprocessable entity"
]
)
def delete_by_version_and_identifier(conn, %{
"workflow_definition" => workflow_definition
}) do
case WorkflowDefinitions.get_workflow_definition(
StepFlow.Map.get_by_key_or_atom(workflow_definition, :identifier),
StepFlow.Map.get_by_key_or_atom(workflow_definition, :version_major),
StepFlow.Map.get_by_key_or_atom(workflow_definition, :version_minor),
StepFlow.Map.get_by_key_or_atom(workflow_definition, :version_micro)
) do
nil ->
conn
|> put_status(:unprocessable_entity)
|> put_view(StepFlow.WorkflowDefinitionView)
|> render("error.json",
errors: %{
reason: "Unable to locate workflow definition with these version and identifier"
}
)
workflow_definition ->
delete(conn, %{"id" => workflow_definition.id})
end
end
end