1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
-module(styx_web).
-export([render/3, render_form/1, reply_html/3, reply_html/4, temporary_redirect/2, req_param/2, identity_name/1]).
identity_name(#{<<"identity">> := Identity}) ->
identity_name(Identity);
identity_name(#{<<"traits">> := #{<<"name">> := #{<<"first">> := F, <<"last">> := L}}}) when is_binary(F), is_binary(L) ->
[F, " ", L];
identity_name(#{<<"traits">> := #{<<"name">> := N}}) when is_binary(N) ->
N;
identity_name(#{<<"traits">> := #{<<"username">> := U}}) when is_binary(U) ->
U;
identity_name(#{<<"traits">> := #{<<"email">> := E}}) when is_binary(E) ->
E;
identity_name(#{<<"id">> := Id}) ->
Id.
render(Req, InnerModule, Assigns) ->
{ok, InnerHtml} = InnerModule:render(Assigns),
render_layout(Req, InnerHtml, Assigns).
render_form(UI = #{<<"action">> := Action, <<"nodes">> := Nodes}) ->
Inputs = render_node(Nodes, []),
Msgs = maps:get(<<"messages">>, UI, []),
{ok, Html} = form_dtl:render([{"action", Action}, {"inputs", Inputs}, {"messages", Msgs}]),
Html.
render_layout(_Req, InnerHtml, Assigns0) ->
Assigns = [{"site_title", application:get_env(?MODULE, site_title, <<"Styx SSO">>)},
{"background_image_url", application:get_env(?MODULE, background_image_url, <<"https://images.unsplash.com/photo-1505904267569-f02eaeb45a4c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1908&q=80">>)},
{"inner", InnerHtml}
| Assigns0],
{ok, Html} = layout_dtl:render(Assigns),
Html.
reply_html(Req, Code, Html) ->
reply_html(Req, Code, Html, #{}).
reply_html(Req, Code, Html, Headers0) ->
Headers = maps:put(<<"content-type">>, <<"text/html">>, Headers0),
cowboy_req:reply(Code, Headers, Html, Req).
temporary_redirect(Req0, Url) ->
cowboy_req:reply(307, #{<<"location">> => Url}, Req0).
req_param(Req, Param) ->
Qs = cowboy_req:parse_qs(Req),
case lists:keyfind(Param, 1, Qs) of
{_, Value} ->
{ok, Value};
_ ->
{error, {missing_param, Param}}
end.
render_node([#{<<"attributes">> := Attrs = #{<<"name">> := AttrName, <<"type">> := AttrType}, <<"type">> := <<"input">>, <<"messages">> := Msgs, <<"meta">> := Meta} | Rest], Acc) ->
Assigns0 = [{"input_name", AttrName},
{"input_type", AttrType},
{"input_value", maps:get(<<"value">>, Attrs, undefined)},
{"input_required", maps:get(<<"required">>, Attrs, false)},
{"input_disabled", maps:get(<<"disabled">>, Attrs, false)}],
Assigns1 = case maps:get(<<"label">>, Meta, false) of
#{<<"text">> := Text, <<"type">> := LType} -> [{"label", Text}, {"label_type", LType} | Assigns0];
_ -> Assigns0
end,
Assigns2 = case AttrName of
<<"traits.email">> -> [{"autocomplete", "email"} | Assigns1];
<<"password">> -> [{"autocomplete", "password"} | Assigns1];
_ -> Assigns1
end,
Assigns = Assigns2,
{ok, Html} = case AttrType of
<<"submit">> -> form_submit_dtl:render(Assigns);
_ -> form_input_dtl:render(Assigns)
end,
render_node(Rest, Acc ++ Html);
render_node([], Acc) ->
Acc.
|