]> granicus.if.org Git - ejabberd/commitdiff
Don't expose internal FSM API of mod_muc_room
authorEvgeny Khramtsov <ekhramtsov@process-one.net>
Mon, 8 Jul 2019 21:47:54 +0000 (00:47 +0300)
committerEvgeny Khramtsov <ekhramtsov@process-one.net>
Mon, 8 Jul 2019 21:47:54 +0000 (00:47 +0300)
src/mod_muc.erl
src/mod_muc_admin.erl
src/mod_muc_log.erl
src/mod_muc_room.erl

index 34b8a7ba179e81a1b1ba62d6f2364c8b488c8bde..8ecdda0e8582f3908834b88fc428ec89515eae04 100644 (file)
@@ -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()}].
index 422dc075be0290d6a7694dab20c4ee889519676c..beef3bc04f1b42fbc73a4df3d3c0f470bb8cf50e 100644 (file)
@@ -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"})
index 79d31c360e0874e8c046ce109feec17c63aa8eb6..8c5af42c3f4d3483c24625bc23c9b46fb09a36be 100644 (file)
@@ -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) ->
index f832106068cd487a3e45ed38d8ee93a2f2429b78..718038470b9112bc7fe23587e621914ab8bf2890 100644 (file)
         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;