Skip to content

Commit

Permalink
Merge pull request #179 from getkimball/api-auth
Browse files Browse the repository at this point in the history
auth: Exclude ok handler
  • Loading branch information
philipcristiano committed May 13, 2021
2 parents 0a090ab + bcd5d72 commit 2842df8
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 27 deletions.
39 changes: 29 additions & 10 deletions src/cb_auth_simple_header.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,41 @@

-export([execute/2]).

execute(Req, Env=#{cb_auth := #{auth_tokens := Tokens,
unauth_handler := UnauthHandler}}) ->
execute(
Req,
Env = #{
cb_auth := #{
auth_tokens := Tokens,
unauth_handler := UnauthHandler
},
handler := Handler
}
) ->
#{cb_auth := CBAuth} = Env,

ExcludedHandlers = maps:get(exclude_handlers, CBAuth, []),
AuthHeader = cowboy_req:header(<<"Authorization">>, Req),
ErrorEnv = Env#{handler => UnauthHandler},

NewEnv = case token_for_authheader(AuthHeader) of
undefined -> ErrorEnv;
TokenValue -> case lists:member(TokenValue, Tokens) of
true -> Env;
false -> ErrorEnv
end
end,
NewEnv =
case lists:member(Handler, ExcludedHandlers) of
true ->
Env;
false ->
case token_for_authheader(AuthHeader) of
undefined ->
ErrorEnv;
TokenValue ->
case lists:member(TokenValue, Tokens) of
true -> Env;
false -> ErrorEnv
end
end
end,
{ok, Req, NewEnv}.

token_for_authheader(undefined) ->
undefined;
token_for_authheader(<< _Bearer:7/binary, Token/binary >>) ->
token_for_authheader(<<_Bearer:7/binary, Token/binary>>) ->
% 7 bytes for "bearer "
Token.
16 changes: 10 additions & 6 deletions src/features_app.erl
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,23 @@ start(_Type, _Args) ->

Dispatch = trails:single_host_compile(AllRoutes),

Middlewares = case application:get_env(features, api_auth, enable) of
enable -> [cowboy_router, cb_auth_simple_header, cowboy_handler];
disable -> [cowboy_router, cowboy_handler]
end,
Middlewares =
case application:get_env(features, api_auth, enable) of
enable -> [cowboy_router, cb_auth_simple_header, cowboy_handler];
disable -> [cowboy_router, cowboy_handler]
end,

CBAuthOpts = #{
auth_tokens => application:get_env(features, api_auth_tokens, []),
exclude_handlers => [features_handler_ok],
unauth_handler => features_handler_unauthorized
},

HTTPOpts = #{
env => #{dispatch => Dispatch,
cb_auth => CBAuthOpts},
env => #{
dispatch => Dispatch,
cb_auth => CBAuthOpts
},
metrics_callback => fun prometheus_cowboy2_instrumenter:observe/1,
middlewares => Middlewares,
stream_handlers => [cowboy_metrics_h, cowboy_stream_h]
Expand Down
57 changes: 46 additions & 11 deletions tests/cb_auth_simple_header_test.erl
Original file line number Diff line number Diff line change
Expand Up @@ -15,51 +15,86 @@ bearer_auth_test_() ->
{foreach, fun load/0, fun unload/1, [
fun bearer/0,
fun bearer_no_header/0,
fun bearer_no_tokens/0
fun bearer_no_tokens/0,
fun exclude_handler/0
]}.

bearer() ->
Token = <<"foo">>,
Headers = #{
<<"Authorization">> => << <<"Bearer ">>/binary, Token/binary >>
<<"Authorization">> => <<<<"Bearer ">>/binary, Token/binary>>
},
Req = ?CTH:req(<<"GET">>, #{headers => Headers}),

Env = #{cb_auth => #{auth_tokens => [Token],
unauth_handler => unauth_handler}},
Env = #{
cb_auth => #{
auth_tokens => [Token],
unauth_handler => unauth_handler
},
handler => test_handler
},

MiddlewareResp = ?MUT:execute(Req, Env),


?assertEqual({ok, Req, Env}, MiddlewareResp).

bearer_no_header() ->
Token = <<"foo">>,
Headers = #{},
Req = ?CTH:req(<<"GET">>, #{headers => Headers}),

Env = #{cb_auth => #{auth_tokens => [Token],
unauth_handler => unauth_handler}},
Env = #{
cb_auth => #{
auth_tokens => [Token],
unauth_handler => unauth_handler
},
handler => test_handler
},

MiddlewareResp = ?MUT:execute(Req, Env),

ExpectedEnv = Env#{handler => unauth_handler},


?assertEqual({ok, Req, ExpectedEnv}, MiddlewareResp).

bearer_no_tokens() ->
Token = <<"foo">>,
Headers = #{
<<"Authorization">> => << <<"Bearer ">>/binary, Token/binary >>
<<"Authorization">> => <<<<"Bearer ">>/binary, Token/binary>>
},
Req = ?CTH:req(<<"GET">>, #{headers => Headers}),

Env = #{cb_auth => #{auth_tokens => [],
unauth_handler => unauth_handler}},
Env = #{
cb_auth => #{
auth_tokens => [],
unauth_handler => unauth_handler
},
handler => test_handler
},

MiddlewareResp = ?MUT:execute(Req, Env),

ExpectedEnv = Env#{handler => unauth_handler},

?assertEqual({ok, Req, ExpectedEnv}, MiddlewareResp).

exclude_handler() ->
Token = <<"foo">>,
Headers = #{},
Req = ?CTH:req(<<"GET">>, #{headers => Headers}),
Handler = test_handler,

Env = #{
cb_auth => #{
auth_tokens => [Token],
exclude_handlers => [Handler],
unauth_handler => unauth_handler
},
handler => Handler
},

MiddlewareResp = ?MUT:execute(Req, Env),

ExpectedEnv = Env#{handler => Handler},

?assertEqual({ok, Req, ExpectedEnv}, MiddlewareResp).

0 comments on commit 2842df8

Please sign in to comment.