aboutsummaryrefslogtreecommitdiff
path: root/apps/dreki_web/src/dreki_web_auth.erl
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dreki_web/src/dreki_web_auth.erl')
-rw-r--r--apps/dreki_web/src/dreki_web_auth.erl45
1 files changed, 45 insertions, 0 deletions
diff --git a/apps/dreki_web/src/dreki_web_auth.erl b/apps/dreki_web/src/dreki_web_auth.erl
new file mode 100644
index 0000000..48b0609
--- /dev/null
+++ b/apps/dreki_web/src/dreki_web_auth.erl
@@ -0,0 +1,45 @@
+-module(dreki_web_auth).
+-behaviour(cowboy_middleware).
+-export([execute/2]).
+
+execute(Req0, Env) ->
+ Header = cowboy_req:header(<<"authorization">>, Req0),
+ Cookie = cowboy_req:header(<<"cookie">>, Req0),
+ case {Header, Cookie} of
+ {<<"Basic ", Basic/binary>>, _} -> basic_oauth2_client_credentials(Basic, Req0, Env);
+ {_, Cookie} when is_binary(Cookie) -> cookie(Cookie, Req0, Env);
+ _ -> error(Req0, 401, <<"Unauthorized">>, <<"Unauthorized">>, Env)
+ end.
+
+basic_oauth2_client_credentials(Base64, Req0, Env) ->
+ Binary = base64:decode(Base64),
+ [User, Pass] = binary:split(Binary, <<":">>),
+ oauth2_client_credentials(User, Pass, Req0, Env).
+
+oauth2_client_credentials(User, Pass, Req0, Env) ->
+ logger:debug("Trying with oauth2 ~p ~p", [User, Pass]),
+ Url = [ory_hydra:url(), "/oauth2/token"],
+ case oauth2c:retrieve_access_token(<<"client_credentials">>, Url, User, Pass) of
+ {ok, Headers, Client} ->
+ logger:debug("Headers ~p Client ~p", [Headers, Client]),
+ identity(Req0, Headers, Env)
+ end.
+
+cookie(Cookie, Req0, Env) ->
+ case ory_kratos:whoami(Cookie) of
+ {ok, Session = #{<<"active">> := true, <<"identity">> := Identity}} ->
+ identity(Req0, Session, Env);
+ {error, #{<<"code">> := Code, <<"status">> := Status, <<"message">> := Msg}} ->
+ error(Req0, Code, Status, Msg, Env)
+ end.
+
+identity(Req0, Identity, Env0) ->
+ IdentityId = maps:get(<<"id">>, Identity),
+ Env1 = maps:put(<<"identity">>, Identity, Env0),
+ Env2 = maps:put(<<"identity_id">>, IdentityId, Env1),
+ {ok, Req0#{identity => Identity, identity_id => IdentityId}, Env2}.
+
+error(Req0, Code, Status, Msg, _Env) ->
+ Json = #{<<"error">> => #{<<"code">> => Code, <<"status">> => Status, <<"message">> => Msg}},
+ Req = dreki_web:reply_json(Req0, Code, Json),
+ {stop, Req}.