aboutsummaryrefslogtreecommitdiff
path: root/apps/styx_web/src/styx_web.erl
blob: cf565bdd1fdd71519cbb00206b07d79fee8a466d (plain) (blame)
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.