From f771724b16a281a6b7196a2da8eee6a78eca7dd8 Mon Sep 17 00:00:00 2001 From: Arkadiusz Gil Date: Tue, 2 Jan 2018 13:00:43 +0100 Subject: [PATCH] Allow JIDs from all MUC light domains in HTTP room API --- doc/rest-api/Client-frontend_swagger.yml | 2 +- src/ejabberd_router.erl | 6 +++++ src/mongoose_client_api_rooms.erl | 34 +++++++++++++++++------- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/doc/rest-api/Client-frontend_swagger.yml b/doc/rest-api/Client-frontend_swagger.yml index c929f4f754b..2a92628400a 100644 --- a/doc/rest-api/Client-frontend_swagger.yml +++ b/doc/rest-api/Client-frontend_swagger.yml @@ -10,7 +10,7 @@ info: This is to ensure integration between the **REST API** users and regular **XMPP** users. * All requests requiring a room ID (i.e. most of the requests fired at `/room` endpoint) accept either a bare room ID (e.g. `656c6f656c6f`) or a room JID (e.g. `656c6f656c6f@muclight.somedomain.com`). - The host part of the room JID must be the host name of a MUC light service running in user's domain. + The host part of the room JID must be the host name of a registered MUC light service. * All requests require authentication. This is to make sure the server can identify who sent the request and if it comes from an authorized user. Currently the only supported method is **Basic Auth**. diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index fde8d516925..1809f3e386d 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -39,6 +39,7 @@ unregister_routes/1, dirty_get_all_routes/0, dirty_get_all_domains/0, + dirty_get_routes_to_module/1, register_components/2, register_components/3, register_component/2, @@ -322,6 +323,11 @@ dirty_get_all_routes() -> dirty_get_all_domains() -> lists:usort(all_routes()). +-spec dirty_get_routes_to_module(atom()) -> [binary()]. +dirty_get_routes_to_module(Mod) -> + Routes = mnesia:dirty_match_object(#route{domain = '_', handler = {packet_handler, Mod, '_'}}), + lists:map(fun(#route{domain = Domain}) -> Domain end, Routes). + all_routes() -> mnesia:dirty_all_keys(route) ++ mnesia:dirty_all_keys(external_component_global). diff --git a/src/mongoose_client_api_rooms.erl b/src/mongoose_client_api_rooms.erl index 8c9d013ea07..edd3f45c238 100644 --- a/src/mongoose_client_api_rooms.erl +++ b/src/mongoose_client_api_rooms.erl @@ -41,7 +41,6 @@ allowed_methods(Req, State) -> resource_exists(Req, #{jid := #jid{lserver = Server}} = State) -> {RoomIDOrJID, Req2} = cowboy_req:binding(id, Req), - MUCLightDomain = muc_light_domain(Server), case RoomIDOrJID of undefined -> {Method, Req3} = cowboy_req:method(Req2), @@ -53,8 +52,8 @@ resource_exists(Req, #{jid := #jid{lserver = Server}} = State) -> end; _ -> case validate_room_id(RoomIDOrJID, Server) of - {ok, RoomID} -> - does_room_exist(RoomID, MUCLightDomain, Req2, State); + {ok, RoomID, RoomHost} -> + does_room_exist(RoomID, RoomHost, Req2, State); _ -> bad_request(Req2, State) end @@ -150,15 +149,30 @@ determine_role(US, Users) -> Role end. --spec validate_room_id(RoomIDOrJID :: binary(), Server :: binary()) -> - {ok, RoomID :: binary()} | error. -validate_room_id(RoomIDOrJID, Server) -> - MUCLightDomain = muc_light_domain(Server), +-spec validate_room_id(RoomIDOrJID :: binary() | term(), Server :: binary()) -> + {ok, RoomID :: binary(), RoomHost :: binary()} | error. +validate_room_id(RoomIDOrJID, Server) when is_binary(RoomIDOrJID) -> case jid:from_binary(RoomIDOrJID) of #jid{luser = <<>>, lserver = RoomID, lresource = <<>>} -> - {ok, RoomID}; - #jid{luser = RoomID, lserver = MUCLightDomain, lresource = <<>>} -> - {ok, RoomID}; + DefaultMucLightDomain = muc_light_domain(Server), + {ok, RoomID, DefaultMucLightDomain}; + #jid{luser = RoomID, lserver = RoomHost, lresource = <<>>} -> + case validate_room_host(RoomHost) of + ok -> + {ok, RoomID, RoomHost}; + error -> + error + end; _ -> error end. + +-spec validate_room_host(binary()) -> ok | error. +validate_room_host(RoomHost) -> + MucLightDomains = ejabberd_router:dirty_get_routes_to_module(mod_muc_light), + case lists:member(RoomHost, MucLightDomains) of + true -> + ok; + false -> + error + end.