aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Khramtsov <ekhramtsov@process-one.net>2019-07-09 00:47:54 +0300
committerEvgeny Khramtsov <ekhramtsov@process-one.net>2019-07-09 00:47:54 +0300
commit9cbc0685db892cc22c090b28e357d1fa83a370a0 (patch)
tree2aceb859c556d82e3f38898b365d8f182430f186
parentCheck virtual host before running the command (diff)
Don't expose internal FSM API of mod_muc_room
Diffstat (limited to '')
-rw-r--r--src/mod_muc.erl43
-rw-r--r--src/mod_muc_admin.erl29
-rw-r--r--src/mod_muc_log.erl5
-rw-r--r--src/mod_muc_room.erl132
4 files changed, 159 insertions, 50 deletions
diff --git a/src/mod_muc.erl b/src/mod_muc.erl
index 34b8a7ba1..8ecdda0e8 100644
--- a/src/mod_muc.erl
+++ b/src/mod_muc.erl
@@ -164,7 +164,7 @@ reload(ServerHost, NewOpts, OldOpts) ->
fun(Host) ->
lists:foreach(
fun({_, _, Pid}) when node(Pid) == node() ->
- Pid ! config_reloaded;
+ mod_muc_room:config_reloaded(Pid);
(_) ->
ok
end, get_online_rooms(ServerHost, Host))
@@ -271,7 +271,7 @@ shutdown_rooms(ServerHost, Hosts, RMod) ->
|| Host <- Hosts],
lists:flatmap(
fun({_, _, Pid}) when node(Pid) == node() ->
- Pid ! shutdown,
+ mod_muc_room:shutdown(Pid),
[Pid];
(_) ->
[]
@@ -840,13 +840,13 @@ iq_disco_items(ServerHost, Host, From, Lang, MaxRoomsDiscoItems, Node, RSM)
when Node == <<"">>; Node == <<"nonemptyrooms">>; Node == <<"emptyrooms">> ->
Count = count_online_rooms(ServerHost, Host),
Query = if Node == <<"">>, RSM == undefined, Count > MaxRoomsDiscoItems ->
- {get_disco_item, only_non_empty, From, Lang};
+ {only_non_empty, From, Lang};
Node == <<"nonemptyrooms">> ->
- {get_disco_item, only_non_empty, From, Lang};
+ {only_non_empty, From, Lang};
Node == <<"emptyrooms">> ->
- {get_disco_item, 0, From, Lang};
+ {0, From, Lang};
true ->
- {get_disco_item, all, From, Lang}
+ {all, From, Lang}
end,
MaxItems = case RSM of
undefined ->
@@ -884,23 +884,16 @@ iq_disco_items(_ServerHost, _Host, _From, Lang, _MaxRoomsDiscoItems, _Node, _RSM
{error, xmpp:err_item_not_found(?T("Node not found"), Lang)}.
-spec get_room_disco_item({binary(), binary(), pid()},
- term()) -> {ok, disco_item()} |
- {error, timeout | notfound}.
-get_room_disco_item({Name, Host, Pid},
- {get_disco_item, Filter, JID, Lang}) ->
- RoomJID = jid:make(Name, Host),
- Timeout = 100,
- Time = erlang:system_time(millisecond),
- Query1 = {get_disco_item, Filter, JID, Lang, Time+Timeout},
- try p1_fsm:sync_send_all_state_event(Pid, Query1, Timeout) of
- {item, Desc} ->
+ {mod_muc_room:disco_item_filter(),
+ jid(), binary()}) -> {ok, disco_item()} |
+ {error, timeout | notfound}.
+get_room_disco_item({Name, Host, Pid}, {Filter, JID, Lang}) ->
+ case mod_muc_room:get_disco_item(Pid, Filter, JID, Lang) of
+ {ok, Desc} ->
+ RoomJID = jid:make(Name, Host),
{ok, #disco_item{jid = RoomJID, name = Desc}};
- false ->
- {error, notfound}
- catch _:{timeout, {p1_fsm, _, _}} ->
- {error, timeout};
- _:{_, {p1_fsm, _, _}} ->
- {error, notfound}
+ {error, _} = Err ->
+ Err
end.
-spec get_subscribed_rooms(binary(), jid()) -> {ok, [{jid(), [binary()]}]} | {error, any()}.
@@ -931,8 +924,7 @@ get_subscribed_rooms(ServerHost, Host, From) ->
[]
end;
({Name, _, Pid}) ->
- case p1_fsm:sync_send_all_state_event(
- Pid, {is_subscribed, BareFrom}) of
+ case mod_muc_room:is_subscribed(Pid, BareFrom) of
{true, Nodes} ->
[{jid:make(Name, Host), Nodes}];
false -> []
@@ -1017,8 +1009,7 @@ process_iq_register_set(ServerHost, Host, From,
broadcast_service_message(ServerHost, Host, Msg) ->
lists:foreach(
fun({_, _, Pid}) ->
- p1_fsm:send_all_state_event(
- Pid, {service_message, Msg})
+ mod_muc_room:service_message(Pid, Msg)
end, get_online_rooms(ServerHost, Host)).
-spec get_online_rooms(binary(), binary()) -> [{binary(), binary(), pid()}].
diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl
index 422dc075b..beef3bc04 100644
--- a/src/mod_muc_admin.erl
+++ b/src/mod_muc_admin.erl
@@ -673,8 +673,7 @@ muc_create_room(ServerHost, {Name, Host, _}, DefRoomOpts) ->
destroy_room(Name, Service) ->
case mod_muc:find_online_room(Name, Service) of
{ok, Pid} ->
- p1_fsm:send_all_state_event(Pid, destroy),
- ok;
+ mod_muc_room:destroy(Pid);
error ->
error
end.
@@ -793,11 +792,11 @@ get_rooms(ServerHost) ->
end, Hosts).
get_room_config(Room_pid) ->
- {ok, R} = p1_fsm:sync_send_all_state_event(Room_pid, get_config),
+ {ok, R} = mod_muc_room:get_config(Room_pid),
R.
get_room_state(Room_pid) ->
- {ok, R} = p1_fsm:sync_send_all_state_event(Room_pid, get_state),
+ {ok, R} = mod_muc_room:get_state(Room_pid),
R.
%%---------------
@@ -882,8 +881,7 @@ find_serverhost(Host, ServerHosts) ->
act_on_room(Method, destroy, {N, H, Pid}, SH) ->
Message = iolist_to_binary(io_lib:format(
<<"Room destroyed by rooms_~s_destroy.">>, [Method])),
- p1_fsm:send_all_state_event(
- Pid, {destroy, Message}),
+ mod_muc_room:destroy(Pid, Message),
mod_muc:room_destroyed(H, N, Pid, SH),
mod_muc:forget_room(SH, H, N);
@@ -991,7 +989,7 @@ change_room_option(Name, Service, OptionString, ValueString) ->
{Option, Value} = format_room_option(OptionString, ValueString),
Config = get_room_config(Pid),
Config2 = change_option(Option, Value, Config),
- {ok, _} = p1_fsm:sync_send_all_state_event(Pid, {change_config, Config2}),
+ {ok, _} = mod_muc_room:set_config(Pid, Config2),
ok
end.
@@ -1093,7 +1091,7 @@ get_room_affiliations(Name, Service) ->
case mod_muc:find_online_room(Name, Service) of
{ok, Pid} ->
%% Get the PID of the online room, then request its state
- {ok, StateData} = p1_fsm:sync_send_all_state_event(Pid, get_state),
+ {ok, StateData} = mod_muc_room:get_state(Pid),
Affiliations = maps:to_list(StateData#state.affiliations),
lists:map(
fun({{Uname, Domain, _Res}, {Aff, Reason}}) when is_atom(Aff)->
@@ -1117,7 +1115,7 @@ get_room_affiliation(Name, Service, JID) ->
case mod_muc:find_online_room(Name, Service) of
{ok, Pid} ->
%% Get the PID of the online room, then request its state
- {ok, StateData} = p1_fsm:sync_send_all_state_event(Pid, get_state),
+ {ok, StateData} = mod_muc_room:get_state(Pid),
UserJID = jid:decode(JID),
mod_muc_room:get_affiliation(UserJID, StateData);
error ->
@@ -1141,7 +1139,7 @@ set_room_affiliation(Name, Service, JID, AffiliationString) ->
case mod_muc:find_online_room(Name, Service) of
{ok, Pid} ->
%% Get the PID for the online room so we can get the state of the room
- {ok, StateData} = p1_fsm:sync_send_all_state_event(Pid, {process_item_change, {jid:decode(JID), affiliation, Affiliation, <<"">>}, undefined}),
+ {ok, StateData} = mod_muc_room:change_item(Pid, jid:decode(JID), affiliation, Affiliation, <<"">>),
mod_muc:store_room(StateData#state.server_host, StateData#state.host, StateData#state.room, make_opts(StateData)),
ok;
error ->
@@ -1163,9 +1161,8 @@ subscribe_room(User, Nick, Room, Nodes) ->
UserJID = jid:replace_resource(UserJID1, <<"modmucadmin">>),
case get_room_pid(Name, Host) of
Pid when is_pid(Pid) ->
- case p1_fsm:sync_send_all_state_event(
- Pid,
- {muc_subscribe, UserJID, Nick, NodeList}) of
+ case mod_muc_room:subscribe(
+ Pid, UserJID, Nick, NodeList) of
{ok, SubscribedNodes} ->
SubscribedNodes;
{error, Reason} ->
@@ -1190,9 +1187,7 @@ unsubscribe_room(User, Room) ->
UserJID ->
case get_room_pid(Name, Host) of
Pid when is_pid(Pid) ->
- case p1_fsm:sync_send_all_state_event(
- Pid,
- {muc_unsubscribe, UserJID}) of
+ case mod_muc_room:unsubscribe(Pid, UserJID) of
ok ->
ok;
{error, Reason} ->
@@ -1213,7 +1208,7 @@ unsubscribe_room(User, Room) ->
get_subscribers(Name, Host) ->
case get_room_pid(Name, Host) of
Pid when is_pid(Pid) ->
- {ok, JIDList} = p1_fsm:sync_send_all_state_event(Pid, get_subscribers),
+ {ok, JIDList} = mod_muc_room:get_subscribers(Pid),
[jid:encode(jid:remove_resource(J)) || J <- JIDList];
_ ->
throw({error, "The room does not exist"})
diff --git a/src/mod_muc_log.erl b/src/mod_muc_log.erl
index 79d31c360..8c5af42c3 100644
--- a/src/mod_muc_log.erl
+++ b/src/mod_muc_log.erl
@@ -896,8 +896,9 @@ get_room_state(RoomName, MucService) ->
-spec get_room_state(pid()) -> {ok, mod_muc_room:state()} | error.
get_room_state(RoomPid) ->
- try p1_fsm:sync_send_all_state_event(RoomPid, get_state)
- catch _:_ -> error
+ case mod_muc_room:get_state(RoomPid) of
+ {ok, State} -> {ok, State};
+ {error, _} -> error
end.
get_proc_name(Host) ->
diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl
index f83210606..718038470 100644
--- a/src/mod_muc_room.erl
+++ b/src/mod_muc_room.erl
@@ -39,7 +39,21 @@
is_occupant_or_admin/2,
route/2,
expand_opts/1,
- config_fields/0]).
+ config_fields/0,
+ destroy/1,
+ destroy/2,
+ shutdown/1,
+ get_config/1,
+ set_config/2,
+ get_state/1,
+ change_item/5,
+ config_reloaded/1,
+ subscribe/4,
+ unsubscribe/2,
+ is_subscribed/2,
+ get_subscribers/1,
+ service_message/2,
+ get_disco_item/4]).
%% gen_fsm callbacks
-export([init/1,
@@ -77,8 +91,8 @@
-type fsm_stop() :: {stop, normal, state()}.
-type fsm_next() :: {next_state, normal_state, state()}.
-type fsm_transition() :: fsm_stop() | fsm_next().
-
--export_type([state/0]).
+-type disco_item_filter() :: only_non_empty | all | non_neg_integer().
+-export_type([state/0, disco_item_filter/0]).
-callback set_affiliation(binary(), binary(), binary(), jid(), affiliation(),
binary()) -> ok | {error, any()}.
@@ -127,6 +141,114 @@ start_link(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts, QueueT
RoomShaper, Opts, QueueType],
?FSMOPTS).
+-spec destroy(pid()) -> ok.
+destroy(Pid) ->
+ p1_fsm:send_all_state_event(Pid, destroy).
+
+-spec destroy(pid(), binary()) -> ok.
+destroy(Pid, Reason) ->
+ p1_fsm:send_all_state_event(Pid, {destroy, Reason}).
+
+-spec shutdown(pid()) -> boolean().
+shutdown(Pid) ->
+ ejabberd_cluster:send(Pid, shutdown).
+
+-spec config_reloaded(pid()) -> boolean().
+config_reloaded(Pid) ->
+ ejabberd_cluster:send(Pid, config_reloaded).
+
+-spec get_config(pid()) -> {ok, config()} | {error, notfound | timeout}.
+get_config(Pid) ->
+ try p1_fsm:sync_send_all_state_event(Pid, get_config)
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, timeout};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, notfound}
+ end.
+
+-spec set_config(pid(), config()) -> {ok, config()} | {error, notfound | timeout}.
+set_config(Pid, Config) ->
+ try p1_fsm:sync_send_all_state_event(Pid, {change_config, Config})
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, timeout};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, notfound}
+ end.
+
+-spec change_item(pid(), jid(), affiliation | role, affiliation() | role(), binary()) ->
+ {ok, state()} | {error, notfound | timeout}.
+change_item(Pid, JID, Type, AffiliationOrRole, Reason) ->
+ try p1_fsm:sync_send_all_state_event(
+ Pid, {process_item_change, {JID, Type, AffiliationOrRole, Reason}, undefined})
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, timeout};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, notfound}
+ end.
+
+-spec get_state(pid()) -> {ok, state()} | {error, notfound | timeout}.
+get_state(Pid) ->
+ try p1_fsm:sync_send_all_state_event(Pid, get_state)
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, timeout};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, notfound}
+ end.
+
+-spec subscribe(pid(), jid(), binary(), [binary()]) -> {ok, [binary()]} | {error, binary()}.
+subscribe(Pid, JID, Nick, Nodes) ->
+ try p1_fsm:sync_send_all_state_event(Pid, {muc_subscribe, JID, Nick, Nodes})
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, ?T("Request has timed out")};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, ?T("Conference room does not exist")}
+ end.
+
+-spec unsubscribe(pid(), jid()) -> ok | {error, binary()}.
+unsubscribe(Pid, JID) ->
+ try p1_fsm:sync_send_all_state_event(Pid, {muc_unsubscribe, JID})
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, ?T("Request has timed out")};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, ?T("Conference room does not exist")}
+ end.
+
+-spec is_subscribed(pid(), jid()) -> {true, [binary()]} | false.
+is_subscribed(Pid, JID) ->
+ try p1_fsm:sync_send_all_state_event(Pid, {is_subscribed, JID})
+ catch _:{_, {p1_fsm, _, _}} -> false
+ end.
+
+-spec get_subscribers(pid()) -> {ok, [jid()]} | {error, notfound | timeout}.
+get_subscribers(Pid) ->
+ try p1_fsm:sync_send_all_state_event(Pid, get_subscribers)
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, timeout};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, notfound}
+ end.
+
+-spec service_message(pid(), binary()) -> ok.
+service_message(Pid, Text) ->
+ p1_fsm:send_all_state_event(Pid, {service_message, Text}).
+
+-spec get_disco_item(pid(), disco_item_filter(), jid(), binary()) ->
+ {ok, binary()} | {error, notfound | timeout}.
+get_disco_item(Pid, Filter, JID, Lang) ->
+ Timeout = 100,
+ Time = erlang:system_time(millisecond),
+ Query = {get_disco_item, Filter, JID, Lang, Time+Timeout},
+ try p1_fsm:sync_send_all_state_event(Pid, Query, Timeout) of
+ {item, Desc} ->
+ {ok, Desc};
+ false ->
+ {error, notfound}
+ catch _:{timeout, {p1_fsm, _, _}} ->
+ {error, timeout};
+ _:{_, {p1_fsm, _, _}} ->
+ {error, notfound}
+ end.
+
%%%----------------------------------------------------------------------
%%% Callback functions from gen_fsm
%%%----------------------------------------------------------------------
@@ -593,7 +715,7 @@ handle_sync_event({muc_subscribe, From, Nick, Nodes}, _From,
NewConfig = (NewState#state.config)#config{
captcha_protected = CaptchaRequired,
password_protected = PasswordProtected},
- {reply, {error, <<"Request is ignored">>},
+ {reply, {error, ?T("Request is ignored")},
NewState#state{config = NewConfig}};
{error, Err} ->
{reply, {error, get_error_text(Err)}, StateName, StateData}
@@ -605,7 +727,7 @@ handle_sync_event({muc_unsubscribe, From}, _From, StateName, StateData) ->
{result, _, NewState} ->
{reply, ok, StateName, NewState};
{ignore, NewState} ->
- {reply, {error, <<"Request is ignored">>}, NewState};
+ {reply, {error, ?T("Request is ignored")}, NewState};
{error, Err} ->
{reply, {error, get_error_text(Err)}, StateName, StateData}
end;