Current section

Files

Jump to
fun_with_flags_ui lib fun_with_flags ui router.ex
Raw

lib/fun_with_flags/ui/router.ex

defmodule FunWithFlags.UI.Router do
use Plug.Router
alias FunWithFlags.UI.{Templates, Utils}
alias FunWithFlags.UI.SimpleActor
if Mix.env == :dev do
use Plug.Debugger, otp_app: :fun_with_flags
end
plug Plug.Logger, log: :debug
plug Plug.Static,
gzip: true,
at: Utils.prefix("/assets"),
from: Path.expand("./assets/", __DIR__)
plug Plug.Parsers, parsers: [:urlencoded]
plug Plug.MethodOverride
plug :match
plug :dispatch
get "/" do
conn
|> redirect_to("/flags")
end
# form to create a new flag
#
get "/new" do
conn
|> html_resp(200, Templates.new(%{}))
end
# endpoint to create a new flag
#
post "/flags" do
name = Utils.sanitize(conn.params["flag_name"])
case Utils.validate_flag_name(name) do
:ok ->
case Utils.create_flag_with_name(name) do
{:ok, _} -> redirect_to conn, "/flags/#{name}"
_ -> html_resp(conn, 400, Templates.new(%{error_message: "Something went wrong!"}))
end
{:fail, reason} ->
html_resp(conn, 400, Templates.new(%{error_message: reason}))
end
end
# get a list of the flags
#
get "/flags" do
{:ok, flags} = FunWithFlags.all_flags
flags = Utils.sort_flags(flags)
body = Templates.index(flags: flags)
conn
|> html_resp(200, body)
end
# flag details
#
get "/flags/:name" do
flag = Utils.get_flag(name)
body = Templates.details(flag: flag)
html_resp(conn, 200, body)
end
# to clear an entire flag
#
delete "/flags/:name" do
name
|> String.to_atom()
|> FunWithFlags.clear()
redirect_to conn, "/flags"
end
# to toggle the default state of a flag
#
patch "/flags/:name/boolean" do
enabled = Utils.parse_bool(conn.params["enabled"])
flag_name = String.to_atom(name)
if enabled do
FunWithFlags.enable(flag_name)
else
FunWithFlags.disable(flag_name)
end
redirect_to conn, "/flags/#{name}"
end
# to toggle an actor gate
#
patch "/flags/:name/actors/:actor_id" do
enabled = Utils.parse_bool(conn.params["enabled"])
flag_name = String.to_atom(name)
actor = %SimpleActor{id: actor_id}
if enabled do
FunWithFlags.enable(flag_name, for_actor: actor)
else
FunWithFlags.disable(flag_name, for_actor: actor)
end
redirect_to conn, "/flags/#{name}#actor_#{actor_id}"
end
# to clear an actor gate
#
delete "/flags/:name/actors/:actor_id" do
flag_name = String.to_atom(name)
actor = %SimpleActor{id: actor_id}
FunWithFlags.clear(flag_name, for_actor: actor)
redirect_to conn, "/flags/#{name}#actor_gates"
end
# to toggle a group gate
#
patch "/flags/:name/groups/:group_name" do
enabled = Utils.parse_bool(conn.params["enabled"])
flag_name = String.to_atom(name)
group_name = String.to_atom(group_name)
if enabled do
FunWithFlags.enable(flag_name, for_group: group_name)
else
FunWithFlags.disable(flag_name, for_group: group_name)
end
redirect_to conn, "/flags/#{name}#group_#{group_name}"
end
# to clear a group gate
#
delete "/flags/:name/groups/:group_name" do
flag_name = String.to_atom(name)
group_name = String.to_atom(group_name)
FunWithFlags.clear(flag_name, for_group: group_name)
redirect_to conn, "/flags/#{name}#group_gates"
end
# to add a new actor to a flag
#
post "/flags/:name/actors" do
flag_name = String.to_atom(name)
actor_id = Utils.sanitize(conn.params["actor_id"])
case Utils.validate(actor_id) do
:ok ->
enabled = Utils.parse_bool(conn.params["enabled"])
actor = %SimpleActor{id: actor_id}
if enabled do
FunWithFlags.enable(flag_name, for_actor: actor)
else
FunWithFlags.disable(flag_name, for_actor: actor)
end
redirect_to conn, "/flags/#{name}#actor_#{actor_id}"
{:fail, reason} ->
flag = Utils.get_flag(name)
body = Templates.details(flag: flag, actor_error_message: "The actor ID #{reason}.")
html_resp(conn, 400, body)
end
end
# to add a new group to a flag
#
post "/flags/:name/groups" do
flag_name = String.to_atom(name)
group_name = Utils.sanitize(conn.params["group_name"])
case Utils.validate(group_name) do
:ok ->
enabled = Utils.parse_bool(conn.params["enabled"])
group_name = String.to_atom(group_name)
if enabled do
FunWithFlags.enable(flag_name, for_group: group_name)
else
FunWithFlags.disable(flag_name, for_group: group_name)
end
redirect_to conn, "/flags/#{name}#group_#{group_name}"
{:fail, reason} ->
flag = Utils.get_flag(name)
body = Templates.details(flag: flag, group_error_message: "The group name #{reason}.")
html_resp(conn, 400, body)
end
end
match _ do
send_resp(conn, 404, "")
end
defp html_resp(conn, status, body) do
conn
|> put_resp_content_type("text/html")
|> send_resp(status, body)
end
defp redirect_to(conn, uri) do
path = Utils.prefix(uri)
conn
|> put_resp_header("location", path)
|> put_resp_content_type("text/html")
|> send_resp(302, "<html><body>You are being <a href=\"#{path}\">redirected</a>.</body></html>")
end
end