diff options
Diffstat (limited to 'apps/dreki_web/src/dreki_web_auth.erl')
-rw-r--r-- | apps/dreki_web/src/dreki_web_auth.erl | 45 |
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}. |