:realm,
:name,
:goodbye,
- :peer_information,
+ :peer,
:challenge,
:authentication_module,
:authorization_module,
data
| challenge: challenge,
hello_received: true,
- realm: realm,
- peer_information: options
+ realm: realm
}
}, [{:next_event, :internal, :transition}] ++ actions}
end
) do
info = auth.parse_challenge(challenge)
- {actions, proxy} = maybe_welcome({auth, session_id, sig, realm, name, challenge, info, tt, t})
+ {actions, proxy, peer} = maybe_welcome({auth, session_id, sig, realm, name, challenge, info, tt, t})
- {:ok, %SL{sl | data: %Sess{sl.data | proxy: proxy}}, actions}
+ {:ok, %SL{sl | data: %Sess{sl.data | peer: peer, proxy: proxy}}, actions}
end
@impl true
transport_pid: t,
subscriptions: subs,
realm: realm,
+ authorization_module: am,
+ peer: peer,
subscribe: %Subscribe{request_id: ri, options: opts, topic: topic},
db: db
} = data
} = sl
) do
- id = RealmSession.get_id()
+ {data, actions} =
+ case is_authorized?(am, peer, :subscribe, topic) do
+ true ->
+ id = RealmSession.get_id()
+ wc = RealmSession.subscribe(db, realm, topic, {id, {self(), Node.self()}}, opts)
+ send_to_peer(Broker.subscribed(%Subscribed{request_id: ri, subscription_id: id}), tt, t)
- wc = RealmSession.subscribe(db, realm, topic, {id, {self(), Node.self()}}, opts)
+ {%SL{sl | data: %Sess{data | subscriptions: [{id, topic, wc} | subs]}},
+ [{:next_event, :internal, :transition}]}
- send_to_peer(Broker.subscribed(%Subscribed{request_id: ri, subscription_id: id}), tt, t)
+ false ->
+ {%SL{sl | data: %Sess{data | error: "wamp.error.not_authorized"}}, [{:next_event, :internal, :transition}]}
+ end
- {:ok, %SL{sl | data: %Sess{data | subscriptions: [{id, topic, wc} | subs]}},
- [{:next_event, :internal, :transition}]}
+ {:ok, data, actions}
end
@impl true
subs = RealmSession.unsubscribe(db, realm, {subscription_id, {self(), Node.self()}}, subs)
send_to_peer(Broker.unsubscribed(%Unsubscribed{request_id: rid}), tt, t)
-
{:ok, %SL{sl | data: %Sess{sl.data | subscriptions: subs}}, [{:next_event, :internal, :transition}]}
end
_,
@publish,
%SL{
- data: %Sess{
- proxy: proxy,
- realm: realm,
- transport: tt,
- transport_pid: t,
- db: db,
- publish: %Publish{request_id: rid, options: opts, topic: topic, arg_list: arg_l, arg_kw: arg_kw}
- }
+ data:
+ %Sess{
+ proxy: proxy,
+ realm: realm,
+ transport: tt,
+ transport_pid: t,
+ db: db,
+ authorization_module: am,
+ peer: peer,
+ publish: %Publish{request_id: rid, options: opts, topic: topic, arg_list: arg_l, arg_kw: arg_kw}
+ } = data
} = sl
) do
- pub_id = RealmSession.get_id()
-
- subs = RealmSession.subscriptions(db, realm, topic)
-
- Enum.each(subs, fn {id, {pid, node}} ->
- send(
- {proxy, node},
- {%Event{
- subscription_id: id,
- publication_id: pub_id,
- arg_list: arg_l,
- arg_kw: arg_kw,
- details: opts
- }, pid}
- )
- end)
+ {data, actions} =
+ case is_authorized?(am, peer, :publish, topic) do
+ true ->
+ pub_id = RealmSession.get_id()
+
+ subs = RealmSession.subscriptions(db, realm, topic)
+
+ Enum.each(subs, fn {id, {pid, node}} ->
+ send(
+ {proxy, node},
+ {%Event{
+ subscription_id: id,
+ publication_id: pub_id,
+ arg_list: arg_l,
+ arg_kw: arg_kw,
+ details: opts
+ }, pid}
+ )
+ end)
- case opts do
- %{acknowledge: true} ->
- send_to_peer(Broker.published(%Published{request_id: rid, publication_id: pub_id}), tt, t)
+ case opts do
+ %{acknowledge: true} ->
+ send_to_peer(Broker.published(%Published{request_id: rid, publication_id: pub_id}), tt, t)
- %{} ->
- :noop
- end
+ %{} ->
+ :noop
+ end
+
+ {sl, [{:next_event, :internal, :transition}]}
+
+ false ->
+ {%SL{sl | data: %Sess{data | error: "wamp.error.not_authorized"}}, [{:next_event, :internal, :transition}]}
+ end
- {:ok, sl, [{:next_event, :internal, :transition}]}
+ {:ok, data, actions}
end
@impl true
registrations: regs,
db: db,
realm: realm,
+ authorization_module: am,
+ peer: peer,
register: %Register{request_id: rid, procedure: procedure}
} = data
} = sl
) do
- id = RealmSession.get_id()
- RealmSession.register(db, realm, procedure, {id, {self(), Node.self()}})
- regd = %Registered{request_id: rid, registration_id: id}
- send_to_peer(Dealer.registered(regd), tt, t)
+ {data, actions} =
+ case is_authorized?(am, peer, :register, procedure) do
+ true ->
+ id = RealmSession.get_id()
+ RealmSession.register(db, realm, procedure, {id, {self(), Node.self()}})
+ regd = %Registered{request_id: rid, registration_id: id}
+ send_to_peer(Dealer.registered(regd), tt, t)
+
+ {%SL{sl | data: %Sess{data | registrations: [{id, procedure} | regs]}},
+ [{:next_event, :internal, :transition}]}
+
+ false ->
+ {%SL{sl | data: %Sess{data | error: "wamp.error.not_authorized"}}, [{:next_event, :internal, :transition}]}
+ end
- {:ok, %SL{sl | data: %Sess{data | registrations: [{id, procedure} | regs]}},
- [{:next_event, :internal, :transition}]}
+ {:ok, data, actions}
end
@impl true
transport_pid: t,
realm: realm,
request_id: ri,
+ authorization_module: am,
+ peer: peer,
call: %Call{request_id: call_id, options: opts, procedure: proc, arg_list: al, arg_kw: akw}
} = data
} = sl
) do
- data =
- with {callees, index} <- RealmSession.callees(db, realm, proc),
- {id, {pid, node}} <- get_live_callee(proxy, callees, index, 3) do
- req_id = RealmSession.get_request_id(ri)
- opts = Map.put(opts, "procedure", proc)
-
- send(
- {proxy, node},
- {
- {
- call_id,
- %Invocation{
- request_id: req_id,
- registration_id: id,
- details: opts,
- arg_list: al,
- arg_kw: akw
- },
- {self(), Node.self()}
- },
- pid
- }
- )
+ {data, actions} =
+ case is_authorized?(am, peer, :call, proc) do
+ true ->
+ with {callees, index} <- RealmSession.callees(db, realm, proc),
+ {id, {pid, node}} <- get_live_callee(proxy, callees, index, 3) do
+ req_id = RealmSession.get_request_id(ri)
+ opts = Map.put(opts, "procedure", proc)
+
+ send(
+ {proxy, node},
+ {
+ {
+ call_id,
+ %Invocation{
+ request_id: req_id,
+ registration_id: id,
+ details: opts,
+ arg_list: al,
+ arg_kw: akw
+ },
+ {self(), Node.self()}
+ },
+ pid
+ }
+ )
+
+ RealmSession.round_robin(db, realm, proc, length(callees))
+
+ {%SL{sl | data: %Sess{data | request_id: req_id}}, [{:next_event, :internal, :transition}]}
+ else
+ {:error, :no_live_callees} ->
+ send_to_peer(
+ Caller.call_error(%Error{
+ request_id: call_id,
+ error: "wamp.error.no_callees",
+ details: %{procedure: proc}
+ }),
+ tt,
+ t
+ )
+
+ {sl, [{:next_event, :internal, :transition}]}
+
+ :not_found ->
+ send_to_peer(
+ Caller.call_error(%Error{
+ request_id: call_id,
+ error: "wamp.error.no_registration",
+ details: %{procedure: proc}
+ }),
+ tt,
+ t
+ )
+
+ {sl, [{:next_event, :internal, :transition}]}
+ end
- RealmSession.round_robin(db, realm, proc, length(callees))
-
- %SL{sl | data: %Sess{data | request_id: req_id}}
- else
- {:error, :no_live_callees} ->
- send_to_peer(
- Caller.call_error(%Error{
- request_id: call_id,
- error: "wamp.error.no_callees",
- details: %{procedure: proc}
- }),
- tt,
- t
- )
-
- sl
-
- :not_found ->
- send_to_peer(
- Caller.call_error(%Error{
- request_id: call_id,
- error: "wamp.error.no_registration",
- details: %{procedure: proc}
- }),
- tt,
- t
- )
-
- sl
+ false ->
+ {%SL{sl | data: %Sess{data | error: "wamp.error.not_authorized"}}, [{:next_event, :internal, :transition}]}
end
- {:ok, data, [{:next_event, :internal, :transition}]}
+ {:ok, data, actions}
end
@impl true
{auth, session_id, sig, realm, name, challenge, {authid, authrole, authmethod, authprovider}, tt, t}
) do
case auth.authenticate(sig, realm, authid, challenge) do
- true ->
+ {true, peer} ->
proxy = Realms.start_realm(Router.realms_name(name), realm)
send_to_peer(
t
)
- {[{:next_event, :internal, :transition}], proxy}
+ {[{:next_event, :internal, :transition}], proxy, peer}
- false ->
- {[{:next_event, :internal, :transition}, {:next_event, :internal, :abort}], nil}
+ {false, peer} ->
+ {[{:next_event, :internal, :transition}, {:next_event, :internal, :abort}], nil, peer}
end
end
defp maybe_update_response(data, resp), do: {data, resp}
+ def is_authorized?(am, peer, type, uri) do
+ am.authorized?(type, uri, peer)
+ end
+
defp remove_nil_values(message) do
message =
case Enum.reverse(message) do