aboutsummaryrefslogtreecommitdiff
path: root/apps/dreki_web/src/dreki_web_auth.erl
blob: 48b0609943334420c010ae1290b46b337e7b4628 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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}.