Packages
nova
0.10.1
0.15.1
0.14.3
0.14.1
0.13.7
0.13.1
0.13.0
0.12.1
0.12.0
0.11.0
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.24
0.9.23
0.9.22
0.9.21
0.9.20
0.9.19
0.9.18
0.9.17
0.9.16
0.9.15
0.9.11
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.4.4
0.4.3
0.4.2
0.4.1
0.2.2
0.1.0
0.0.1
0.0.0
Nova is a web application framework
Current section
Files
Jump to
Current section
Files
src/nova_security_handler.erl
-module(nova_security_handler).
-behaviour(cowboy_middleware).
-export([
execute/2
]).
-include_lib("kernel/include/logger.hrl").
-include("../include/nova.hrl").
execute(Req, Env = #{secure := false}) ->
{ok, Req, Env};
execute(Req = #{host := Host}, Env = #{secure := Callback}) ->
UseStacktrace = persistent_term:get(nova_use_stacktrace, false),
try Callback(Req) of
Result ->
handle_response(Result, Req, Env)
catch
Class:Reason:Stacktrace when UseStacktrace == true ->
?LOG_ERROR(#{msg => <<"Security handler crashed">>,
class => Class,
reason => Reason,
stacktrace => Stacktrace}),
Payload = #{status_code => 500,
stacktrace => Stacktrace,
class => Class,
reason => Reason},
{ok, Req0, _Env} = nova_router:render_status_page(Host, 500, #{}, Req#{crash_info => Payload}, Env),
Req1 = cowboy_req:reply(500, Req0),
{stop, Req1};
Class:Reason ->
?LOG_ERROR(#{msg => <<"Security handler crashed">>,
class => Class,
reason => Reason}),
Payload = #{status_code => 500,
class => Class,
reason => Reason},
{ok, Req0, _Env} = nova_router:render_status_page(Host, 500, #{}, Req#{crash_info => Payload}, Env),
Req1 = cowboy_req:reply(500, Req0),
{stop, Req1}
end.
handle_response({true, AuthData}, Req, Env) ->
case maps:get(cowboy_handler, Env, undefined) of
nova_ws_handler ->
Args = maps:get(arguments, Env, #{}),
{ok, Req, Env#{arguments => Args#{controller_data => #{auth_data => AuthData}}}};
_ ->
{ok, Req#{auth_data => AuthData}, Env}
end;
handle_response(true, Req, Env) ->
{ok, Req, Env};
handle_response({false, Headers}, Req, Env) ->
handle_response({false, 401, Headers, false}, Req, Env);
handle_response({false, StatusCode, Headers}, Req, Env) ->
handle_response({false, StatusCode, Headers, false}, Req, Env);
handle_response({false, StatusCode, Headers, Body}, Req = #{host := Host}, Env) ->
{ok, Req1, _Env1} =
case Body of
false ->
{ok, _Req0, _Env0} = nova_router:render_status_page(Host, StatusCode, #{}, Req, Env);
_ ->
Req0 = cowboy_req:set_resp_body(Body, Req),
{ok, Req0, Env}
end,
Req2 = cowboy_req:set_resp_headers(Headers, Req1),
Req3 = cowboy_req:reply(StatusCode, Req2),
{stop, Req3};
handle_response({redirect, Route}, Req, _Env) ->
Req0 = cowboy_req:set_resp_headers(#{<<"Location">> => list_to_binary(Route)}, Req),
{stop, Req0};
handle_response(_, Req = #{host := Host}, Env) ->
{ok, Req0, _Env0} = nova_router:render_status_page(Host, 401, #{}, Req, Env),
Req1 = cowboy_req:reply(401, Req0),
{stop, Req1}.