defmodule GitLabPushTriggerer.Router do @moduledoc """ Router dispatching requests to the correct handlers. """ use Plug.Router use Plug.ErrorHandler require Logger plug(Plug.Logger) plug(:match) plug( Plug.Parsers, parsers: [:urlencoded, :multipart, :json], pass: ["*/*"], json_decoder: Jason ) plug(:dispatch) paths = quote do GitLabPushTriggerer.get_envs() end post "/:path" do with {branch, script} <- Map.get(unquote(paths), path), :ok <- check_branch(branch, conn.body_params), :ok <- GitLabPushTriggerer.run(script) do send_resp(conn, 200, "OK") else # Nil returned by Map.get nil -> route_not_found(conn) {:error, :file_not_found} -> send_resp(conn, 404, "File not found.") {:error, :wrong_branch} -> send_resp(conn, 400, "Branch not matching.") error -> Logger.error("Unknown error: #{inspect(error)}") send_resp(conn, 500, "Unknown error.") end end match _ do route_not_found(conn) end defp route_not_found(conn), do: send_resp(conn, 404, "Route not found.") defp handle_errors(conn, data) do Logger.error(inspect(data)) send_resp(conn, conn.status, "Something went wrong.") end # Check that branch in data matches branch in configuration defp check_branch(branch, data) when is_binary(branch) and is_map(data) do with "refs/heads/" <> data_branch <- Map.get(data, "ref"), ^branch <- data_branch do :ok else _ -> {:error, :wrong_branch} end end end