diff options
author | Evgeniy Khramtsov <ekhramtsov@process-one.net> | 2017-01-13 12:03:39 +0300 |
---|---|---|
committer | Evgeniy Khramtsov <ekhramtsov@process-one.net> | 2017-01-13 12:03:39 +0300 |
commit | 0baaad30b176aa8b1d1d485fb8e113eb13d2bdf3 (patch) | |
tree | b5186d78d598e9b94f26646ef11e8c24ac1edd7c /src/mod_muc_admin.erl | |
parent | Fix some corner cases while re-reading RFC6120 (diff) |
Implement database backend interface for MUC, BOSH and auth_anonyous
Diffstat (limited to 'src/mod_muc_admin.erl')
-rw-r--r-- | src/mod_muc_admin.erl | 136 |
1 files changed, 70 insertions, 66 deletions
diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl index 91ccce55..48835c01 100644 --- a/src/mod_muc_admin.erl +++ b/src/mod_muc_admin.erl @@ -28,7 +28,6 @@ -include("logger.hrl"). -include("xmpp.hrl"). -include("mod_muc_room.hrl"). --include("mod_muc.hrl"). -include("ejabberd_http.hrl"). -include("ejabberd_web_admin.hrl"). -include("ejabberd_commands.hrl"). @@ -207,22 +206,12 @@ get_commands_spec() -> %%% muc_online_rooms(ServerHost) -> - MUCHost = find_host(ServerHost), - Rooms = ets:tab2list(muc_online_room), - lists:foldl( - fun(Room, Results) -> - {Roomname, Host} = Room#muc_online_room.name_host, - case MUCHost of - global -> - [<<Roomname/binary, "@", Host/binary>> | Results]; - Host -> - [<<Roomname/binary, "@", Host/binary>> | Results]; - _ -> - Results - end - end, - [], - Rooms). + Hosts = find_hosts(ServerHost), + lists:flatmap( + fun(Host) -> + [{<<Name/binary, "@", Host/binary>>} + || {Name, _, _} <- mod_muc:get_online_rooms(Host)] + end, Hosts). muc_unregister_nick(Nick) -> F2 = fun(N) -> @@ -237,14 +226,18 @@ muc_unregister_nick(Nick) -> end. get_user_rooms(LUser, LServer) -> - US = {LUser, LServer}, - case catch ets:select(muc_online_users, - [{#muc_online_users{us = US, room='$1', host='$2', _ = '_'}, [], [{{'$1', '$2'}}]}]) - of - Res when is_list(Res) -> - [<<R/binary, "@", H/binary>> || {R, H} <- Res]; - _ -> [] - end. + lists:flatmap( + fun(ServerHost) -> + case gen_mod:is_loaded(ServerHost, mod_muc) of + true -> + Rooms = mod_muc:get_online_rooms_by_user( + ServerHost, LUser, LServer), + [<<Name/binary, "@", Host/binary>> + || {Name, Host} <- Rooms]; + false -> + [] + end + end, ?MYHOSTS). %%---------------------------- %% Ad-hoc commands @@ -274,10 +267,14 @@ web_menu_host(Acc, _Host, Lang) -> ])). web_page_main(_, #request{path=[<<"muc">>], lang = Lang} = _Request) -> + OnlineRoomsNumber = lists:foldl( + fun(Host, Acc) -> + Acc ++ mod_muc:count_online_rooms(Host) + end, 0, find_hosts(global)), Res = [?XCT(<<"h1">>, <<"Multi-User Chat">>), ?XCT(<<"h3">>, <<"Statistics">>), ?XAE(<<"table">>, [], - [?XE(<<"tbody">>, [?TDTD(<<"Total rooms">>, ets:info(muc_online_room, size)), + [?XE(<<"tbody">>, [?TDTD(<<"Total rooms">>, OnlineRoomsNumber), ?TDTD(<<"Permanent rooms">>, mnesia:table_info(muc_room, size)), ?TDTD(<<"Registered nicknames">>, mnesia:table_info(muc_registered, size)) ]) @@ -456,8 +453,8 @@ create_room_with_opts(Name1, Host1, ServerHost, CustomRoomOpts) -> RoomShaper = gen_mod:get_module_opt(ServerHost, mod_muc, room_shaper, fun(X) -> X end, none), %% If the room does not exist yet in the muc_online_room - case mnesia:dirty_read(muc_online_room, {Name, Host}) of - [] -> + case mod_muc:find_online_room(Name, Host) of + error -> %% Start the room {ok, Pid} = mod_muc_room:start( Host, @@ -467,19 +464,12 @@ create_room_with_opts(Name1, Host1, ServerHost, CustomRoomOpts) -> HistorySize, RoomShaper, RoomOpts), - {atomic, ok} = register_room(Host, Name, Pid), + mod_muc:register_online_room(Host, Name, Pid), ok; - _ -> + {ok, _} -> error end. -register_room(Host, Name, Pid) -> - F = fun() -> - mnesia:write(#muc_online_room{name_host = {Name, Host}, - pid = Pid}) - end, - mnesia:transaction(F). - %% Create the room only in the database. %% It is required to restart the MUC service for the room to appear. muc_create_room(ServerHost, {Name, Host, _}, DefRoomOpts) -> @@ -492,12 +482,11 @@ muc_create_room(ServerHost, {Name, Host, _}, DefRoomOpts) -> %% If the room has participants, they are not notified that the room was destroyed; %% they will notice when they try to chat and receive an error that the room doesn't exist. destroy_room(Name, Service) -> - case mnesia:dirty_read(muc_online_room, {Name, Service}) of - [R] -> - Pid = R#muc_online_room.pid, + case mod_muc:find_online_room(Name, Service) of + {ok, Pid} -> gen_fsm:send_all_state_event(Pid, destroy), ok; - [] -> + error -> error end. @@ -602,19 +591,12 @@ muc_unused2(Action, ServerHost, Host, Last_allowed) -> %%--------------- %% Get info -get_rooms(Host) -> - Get_room_names = fun(Room_reg, Names) -> - Pid = Room_reg#muc_online_room.pid, - case {Host, Room_reg#muc_online_room.name_host} of - {Host, {Name1, Host}} -> - [{Name1, Host, Pid} | Names]; - {global, {Name1, Host1}} -> - [{Name1, Host1, Pid} | Names]; - _ -> - Names - end - end, - ets:foldr(Get_room_names, [], muc_online_room). +get_rooms(ServerHost) -> + Hosts = find_hosts(ServerHost), + lists:flatmap( + fun(Host) -> + mod_muc:get_online_rooms(Host) + end, Hosts). get_room_config(Room_pid) -> {ok, R} = gen_fsm:sync_send_all_state_event(Room_pid, get_config), @@ -813,11 +795,11 @@ format_room_option(OptionString, ValueString) -> %% @doc Get the Pid of an existing MUC room, or 'room_not_found'. get_room_pid(Name, Service) -> - case mnesia:dirty_read(muc_online_room, {Name, Service}) of - [] -> + case mod_muc:find_online_room(Name, Service) of + error -> room_not_found; - [Room] -> - Room#muc_online_room.pid + {ok, Pid} -> + Pid end. %% It is required to put explicitely all the options because @@ -884,10 +866,9 @@ get_options(Config) -> %% [{JID::string(), Domain::string(), Role::string(), Reason::string()}] %% @doc Get the affiliations of the room Name@Service. get_room_affiliations(Name, Service) -> - case mnesia:dirty_read(muc_online_room, {Name, Service}) of - [R] -> + case mod_muc:find_online_room(Name, Service) of + {ok, Pid} -> %% Get the PID of the online room, then request its state - Pid = R#muc_online_room.pid, {ok, StateData} = gen_fsm:sync_send_all_state_event(Pid, get_state), Affiliations = ?DICT:to_list(StateData#state.affiliations), lists:map( @@ -896,7 +877,7 @@ get_room_affiliations(Name, Service) -> ({{Uname, Domain, _Res}, Aff}) when is_atom(Aff)-> {Uname, Domain, Aff, <<>>} end, Affiliations); - [] -> + error -> throw({error, "The room does not exist."}) end. @@ -914,14 +895,13 @@ get_room_affiliations(Name, Service) -> %% In any other case the action will be to create the affiliation. set_room_affiliation(Name, Service, JID, AffiliationString) -> Affiliation = jlib:binary_to_atom(AffiliationString), - case mnesia:dirty_read(muc_online_room, {Name, Service}) of - [R] -> + 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 - Pid = R#muc_online_room.pid, {ok, StateData} = gen_fsm:sync_send_all_state_event(Pid, {process_item_change, {jid:from_string(JID), affiliation, Affiliation, <<"">>}, <<"">>}), mod_muc:store_room(StateData#state.server_host, StateData#state.host, StateData#state.room, make_opts(StateData)), ok; - [] -> + error -> error end. @@ -1045,4 +1025,28 @@ find_host(ServerHost) when is_list(ServerHost) -> find_host(ServerHost) -> gen_mod:get_module_opt_host(ServerHost, mod_muc, <<"conference.@HOST@">>). +find_hosts(Global) when Global == global; + Global == "global"; + Global == <<"global">> -> + lists:flatmap( + fun(ServerHost) -> + case gen_mod:is_loaded(ServerHost, mod_muc) of + true -> + [gen_mod:get_module_opt_host( + ServerHost, mod_muc, <<"conference.@HOST@">>)]; + false -> + [] + end + end, ?MYHOSTS); +find_hosts(ServerHost) when is_list(ServerHost) -> + find_hosts(list_to_binary(ServerHost)); +find_hosts(ServerHost) -> + case gen_mod:is_loaded(ServerHost, mod_muc) of + true -> + [gen_mod:get_module_opt_host( + ServerHost, mod_muc, <<"conference.@HOST@">>)]; + false -> + [] + end. + mod_opt_type(_) -> []. |