realm: String.t() | nil,
name: module() | nil,
challenge: Challenge.t() | nil,
- authentication_module: module(),
- authorization_module: module(),
+ authentication_module: module() | map(),
+ authorization_module: module() | map(),
roles: [module()],
registrations: [],
subscriptions: [],
} = data
} = sl
) do
- {actions, challenge} = maybe_challenge(auth, realm, options, session_id, tt, t)
+ {actions, challenge, module} = maybe_challenge(auth, realm, options, session_id, tt, t)
{:ok,
%SL{
data
| challenge: challenge,
hello_received: true,
- realm: realm
+ realm: realm,
+ authentication_module: module
}
}, [{:next_event, :internal, :transition}] ++ actions}
end
transport: tt,
transport_pid: t,
subscriptions: subs,
+ challenge: %Challenge{auth_method: method},
realm: realm,
authorization_module: am,
peer: peer,
} = sl
) do
{data, actions} =
- case is_authorized?(am, peer, :subscribe, topic) do
+ case is_authorized?(am, peer, :subscribe, topic, method) do
true ->
id = RealmSession.get_id()
wc = RealmSession.subscribe(db, realm, topic, {id, {self(), Node.self()}}, opts)
transport: tt,
transport_pid: t,
db: db,
+ challenge: %Challenge{auth_method: method},
authorization_module: am,
peer: peer,
id: session_id,
} = sl
) do
{data, actions} =
- case is_authorized?(am, peer, :publish, topic) do
+ case is_authorized?(am, peer, :publish, topic, method) do
true ->
pub_id = RealmSession.get_id()
registrations: regs,
db: db,
realm: realm,
+ challenge: %Challenge{auth_method: method},
authorization_module: am,
peer: peer,
register: %Register{request_id: rid, procedure: procedure}
} = sl
) do
{data, actions} =
- case is_authorized?(am, peer, :register, procedure) do
+ case is_authorized?(am, peer, :register, procedure, method) do
true ->
id = RealmSession.get_id()
RealmSession.register(db, realm, procedure, {id, {self(), Node.self()}})
transport_pid: t,
realm: realm,
request_id: ri,
+ challenge: %Challenge{auth_method: method},
authorization_module: am,
id: session_id,
peer: peer,
} = sl
) do
{data, actions} =
- case is_authorized?(am, peer, :call, proc) do
+ case is_authorized?(am, peer, :call, proc, method) do
true ->
with {callees, index} <- RealmSession.callees(db, realm, proc),
{id, {pid, node}} <- get_live_callee(proxy, callees, index, 3) do
defp maybe_challenge(auth, realm, details, session_id, tt, t) do
case details do
%{"authid" => ai, "authmethods" => am} ->
+ auth = get_auth_module(auth, am)
+
case auth.authenticate?(am) do
true ->
ch = auth.challenge(realm, ai, session_id)
t
)
- {[], ch}
+ {[], ch, auth}
false ->
- Logger.error("Not a supported authentication method: #{am}")
+ Logger.error("Not a supported authentication method: #{inspect(am)}")
{[{:next_event, :internal, :abort}], nil}
end
end
end
+ defp get_auth_module(auth, methods) when is_map(auth) do
+ case Enum.find(auth, fn {k, _v} -> k in methods end) do
+ {_, mod} -> mod
+ nil -> Logger.error("Unsupported authentication methods #{inspect(methods)}: Supported #{inspect(auth)}")
+ end
+ end
+
+ defp get_auth_module(auth, _methods), do: auth
+
defp get_live_callee(_proxy, [], _index, 0) do
Logger.error("No live callees, tried all replicas")
{:error, :no_live_callees}
defp maybe_update_response(data, resp), do: {data, resp}
- def is_authorized?(am, peer, type, uri) do
+ def is_authorized?(am, peer, type, uri, method) do
+ am = get_auth_module(am, [method])
am.authorized?(type, uri, peer)
end