diff --git a/ejabberd.yml.example b/ejabberd.yml.example index 2508f3fb0..0a38a2b7f 100644 --- a/ejabberd.yml.example +++ b/ejabberd.yml.example @@ -195,6 +195,8 @@ modules: - allow: admin access_create: muc_create access_persistent: muc_create + access_mam: + - allow default_room_options: mam: true mod_muc_admin: {} diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 8a80e3012..e39a64ce8 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -354,6 +354,7 @@ init_state(Host, Opts) -> AccessCreate = gen_mod:get_opt(access_create, Opts), AccessAdmin = gen_mod:get_opt(access_admin, Opts), AccessPersistent = gen_mod:get_opt(access_persistent, Opts), + AccessMam = gen_mod:get_opt(access_mam, Opts), HistorySize = gen_mod:get_opt(history_size, Opts), MaxRoomsDiscoItems = gen_mod:get_opt(max_rooms_discoitems, Opts), DefRoomOpts = gen_mod:get_opt(default_room_options, Opts), @@ -361,7 +362,7 @@ init_state(Host, Opts) -> RoomShaper = gen_mod:get_opt(room_shaper, Opts), #state{hosts = MyHosts, server_host = Host, - access = {Access, AccessCreate, AccessAdmin, AccessPersistent}, + access = {Access, AccessCreate, AccessAdmin, AccessPersistent, AccessMam}, default_room_opts = DefRoomOpts, queue_type = QueueType, history_size = HistorySize, @@ -392,7 +393,7 @@ unregister_iq_handlers(Host) -> do_route(Host, ServerHost, Access, HistorySize, RoomShaper, From, To, Packet, DefRoomOpts, _MaxRoomsDiscoItems, QueueType) -> - {AccessRoute, _AccessCreate, _AccessAdmin, _AccessPersistent} = Access, + {AccessRoute, _AccessCreate, _AccessAdmin, _AccessPersistent, _AccessMam} = Access, case acl:match_rule(ServerHost, AccessRoute, From) of allow -> do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, @@ -411,7 +412,7 @@ do_route1(_Host, _ServerHost, _Access, _HistorySize, _RoomShaper, do_route1(Host, ServerHost, Access, _HistorySize, _RoomShaper, From, #jid{luser = <<"">>, lresource = <<"">>} = _To, #message{lang = Lang, body = Body, type = Type} = Packet, _, _) -> - {_AccessRoute, _AccessCreate, AccessAdmin, _AccessPersistent} = Access, + {_AccessRoute, _AccessCreate, AccessAdmin, _AccessPersistent, _AccessMam} = Access, if Type == error -> ok; true -> @@ -432,7 +433,7 @@ do_route1(_Host, _ServerHost, _Access, _HistorySize, _RoomShaper, ejabberd_router:route_error(Packet, Err); do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, From, To, Packet, DefRoomOpts, QueueType) -> - {_AccessRoute, AccessCreate, _AccessAdmin, _AccessPersistent} = Access, + {_AccessRoute, AccessCreate, _AccessAdmin, _AccessPersistent, _AccessMam} = Access, {Room, _, Nick} = jid:tolower(To), RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE), case RMod:find_online_room(ServerHost, Room, Host) of @@ -884,6 +885,8 @@ mod_opt_type(access_create) -> fun acl:access_rules_validator/1; mod_opt_type(access_persistent) -> fun acl:access_rules_validator/1; +mod_opt_type(access_mam) -> + fun acl:access_rules_validator/1; mod_opt_type(access_register) -> fun acl:access_rules_validator/1; mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; @@ -992,6 +995,7 @@ mod_options(Host) -> {access_admin, none}, {access_create, all}, {access_persistent, all}, + {access_mam, all}, {access_register, all}, {db_type, ejabberd_config:default_db(Host, ?MODULE)}, {ram_db_type, ejabberd_config:default_ram_db(Host, ?MODULE)}, diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl index 23d821642..c483228c4 100644 --- a/src/mod_muc_admin.erl +++ b/src/mod_muc_admin.erl @@ -604,6 +604,7 @@ create_room_with_opts(Name1, Host1, ServerHost, CustomRoomOpts) -> AcCreate = gen_mod:get_module_opt(ServerHost, mod_muc, access_create), AcAdmin = gen_mod:get_module_opt(ServerHost, mod_muc, access_admin), AcPer = gen_mod:get_module_opt(ServerHost, mod_muc, access_persistent), + AcMam = gen_mod:get_module_opt(ServerHost, mod_muc, access_mam), HistorySize = gen_mod:get_module_opt(ServerHost, mod_muc, history_size), RoomShaper = gen_mod:get_module_opt(ServerHost, mod_muc, room_shaper), QueueType = gen_mod:get_module_opt(ServerHost, mod_muc, queue_type), @@ -615,7 +616,7 @@ create_room_with_opts(Name1, Host1, ServerHost, CustomRoomOpts) -> {ok, Pid} = mod_muc_room:start( Host, ServerHost, - {Access, AcCreate, AcAdmin, AcPer}, + {Access, AcCreate, AcAdmin, AcPer, AcMam}, Name, HistorySize, RoomShaper, diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index a52b3d55a..3e3214815 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -1409,7 +1409,7 @@ get_affiliations_callback(StateData) -> -spec get_service_affiliation(jid(), state()) -> owner | none. get_service_affiliation(JID, StateData) -> {_AccessRoute, _AccessCreate, AccessAdmin, - _AccessPersistent} = + _AccessPersistent, _AccessMam} = StateData#state.access, case acl:match_rule(StateData#state.server_host, AccessAdmin, JID) @@ -3170,6 +3170,7 @@ process_iq_owner(From, #iq{type = set, lang = Lang, Options -> case is_allowed_log_change(Options, StateData, From) andalso is_allowed_persistent_change(Options, StateData, From) andalso + is_allowed_mam_change(Options, StateData, From) andalso is_allowed_room_name_desc_limits(Options, StateData) andalso is_password_settings_correct(Options, StateData) of true -> @@ -3234,13 +3235,26 @@ is_allowed_persistent_change(Options, StateData, From) -> false -> true; true -> {_AccessRoute, _AccessCreate, _AccessAdmin, - AccessPersistent} = + AccessPersistent, _AccessMam} = StateData#state.access, allow == acl:match_rule(StateData#state.server_host, AccessPersistent, From) end. +-spec is_allowed_mam_change(muc_roomconfig:result(), state(), jid()) -> boolean(). +is_allowed_mam_change(Options, StateData, From) -> + case proplists:is_defined(mam, Options) of + false -> true; + true -> + {_AccessRoute, _AccessCreate, _AccessAdmin, + _AccessPersistent, AccessMam} = + StateData#state.access, + allow == + acl:match_rule(StateData#state.server_host, + AccessMam, From) + end. + %% Check if the Room Name and Room Description defined in the Data Form %% are conformant to the configured limits -spec is_allowed_room_name_desc_limits(muc_roomconfig:result(), state()) -> boolean(). @@ -3283,7 +3297,7 @@ get_default_room_maxusers(RoomState) -> -spec get_config(binary(), state(), jid()) -> xdata(). get_config(Lang, StateData, From) -> - {_AccessRoute, _AccessCreate, _AccessAdmin, AccessPersistent} = + {_AccessRoute, _AccessCreate, _AccessAdmin, AccessPersistent, _AccessMam} = StateData#state.access, ServiceMaxUsers = get_service_max_users(StateData), DefaultRoomMaxUsers = get_default_room_maxusers(StateData),