-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}.