25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-22 16:20:52 +01:00

Allow passing affiliations and subscribers to create_room_with_opts command

This commit is contained in:
Paweł Chmielowski 2023-02-20 13:03:46 +01:00
parent f10f6d176f
commit dfe4884d16
2 changed files with 72 additions and 11 deletions

View File

@ -162,9 +162,14 @@ get_commands_spec() ->
result = {res, rescode}}, result = {res, rescode}},
#ejabberd_commands{name = create_room_with_opts, tags = [muc_room], #ejabberd_commands{name = create_room_with_opts, tags = [muc_room],
desc = "Create a MUC room name@service in host with given options", desc = "Create a MUC room name@service in host with given options",
longdesc = "To set affilitions string value must have format 'Type:JID,Type:JID' "
"for example 'owner:bob@example.com,member:peter@example.com'. Subscribers can be "
"define with string 'JID:Nick:Node1:Node2,JID:Nick:Node3' for example "
"'bob@example.com:Bob:messages:subject,anne@example.com:Anne:messages'.",
module = ?MODULE, function = create_room_with_opts, module = ?MODULE, function = create_room_with_opts,
args_desc = ["Room name", "MUC service", "Server host", "List of options"], args_desc = ["Room name", "MUC service", "Server host", "List of options"],
args_example = ["room1", "muc.example.com", "localhost", [{"members_only","true"}]], args_example = ["room1", "muc.example.com", "localhost",
[{"members_only","true"}, {"subscribers", "bob@example.com:Bob:messages"}]],
args = [{name, binary}, {service, binary}, args = [{name, binary}, {service, binary},
{host, binary}, {host, binary},
{options, {list, {options, {list,
@ -1166,10 +1171,66 @@ format_room_option(OptionString, ValueString) ->
ValueString; ValueString;
lang -> ValueString; lang -> ValueString;
pubsub -> ValueString; pubsub -> ValueString;
affiliations ->
[parse_affiliation_string(Opt) || Opt <- str:tokens(ValueString, <<",">>)];
subscribers ->
[parse_subscription_string(Opt) || Opt <- str:tokens(ValueString, <<",">>)];
_ -> misc:binary_to_atom(ValueString) _ -> misc:binary_to_atom(ValueString)
end, end,
{Option, Value}. {Option, Value}.
parse_affiliation_string(String) ->
{Type, JidS} = case String of
<<"owner:", Jid/binary>> -> {owner, Jid};
<<"admin:", Jid/binary>> -> {admin, Jid};
<<"member:", Jid/binary>> -> {member, Jid};
<<"outcast:", Jid/binary>> -> {outcast, Jid};
_ -> throw({error, "Invalid 'affiliation'"})
end,
try jid:decode(JidS) of
#jid{luser = U, lserver = S, lresource = R} ->
{{U, S, R}, {Type, <<>>}}
catch _:{bad_jid, _} ->
throw({error, "Malformed JID in affiliation"})
end.
parse_subscription_string(String) ->
case str:tokens(String, <<":">>) of
[_] ->
throw({error, "Invalid 'subscribers' - missing nick"});
[_, _] ->
throw({error, "Invalid 'subscribers' - missing nodes"});
[JidS, Nick | Nodes] ->
Nodes2 = parse_nodes(Nodes, []),
try jid:decode(JidS) of
Jid ->
{Jid, Nick, Nodes2}
catch _:{bad_jid, _} ->
throw({error, "Malformed JID in 'subscribers'"})
end
end.
parse_nodes([], Acc) ->
Acc;
parse_nodes([<<"presence">> | Rest], Acc) ->
parse_nodes(Rest, [?NS_MUCSUB_NODES_PRESENCE | Acc]);
parse_nodes([<<"messages">> | Rest], Acc) ->
parse_nodes(Rest, [?NS_MUCSUB_NODES_MESSAGES | Acc]);
parse_nodes([<<"participants">> | Rest], Acc) ->
parse_nodes(Rest, [?NS_MUCSUB_NODES_PARTICIPANTS | Acc]);
parse_nodes([<<"affiliations">> | Rest], Acc) ->
parse_nodes(Rest, [?NS_MUCSUB_NODES_AFFILIATIONS | Acc]);
parse_nodes([<<"subject">> | Rest], Acc) ->
parse_nodes(Rest, [?NS_MUCSUB_NODES_SUBJECT | Acc]);
parse_nodes([<<"config">> | Rest], Acc) ->
parse_nodes(Rest, [?NS_MUCSUB_NODES_CONFIG | Acc]);
parse_nodes([<<"system">> | Rest], Acc) ->
parse_nodes(Rest, [?NS_MUCSUB_NODES_SYSTEM | Acc]);
parse_nodes([<<"subscribers">> | Rest], Acc) ->
parse_nodes(Rest, [?NS_MUCSUB_NODES_SUBSCRIBERS | Acc]);
parse_nodes(_, _) ->
throw({error, "Invalid 'subscribers' - unknown node name used"}).
%% @doc Get the Pid of an existing MUC room, or 'room_not_found'. %% @doc Get the Pid of an existing MUC room, or 'room_not_found'.
-spec get_room_pid(binary(), binary()) -> pid() | room_not_found | invalid_service. -spec get_room_pid(binary(), binary()) -> pid() | room_not_found | invalid_service.
get_room_pid(Name, Service) -> get_room_pid(Name, Service) ->

View File

@ -294,15 +294,15 @@ init([Host, ServerHost, Access, Room, HistorySize,
process_flag(trap_exit, true), process_flag(trap_exit, true),
Shaper = ejabberd_shaper:new(RoomShaper), Shaper = ejabberd_shaper:new(RoomShaper),
RoomQueue = room_queue_new(ServerHost, Shaper, QueueType), RoomQueue = room_queue_new(ServerHost, Shaper, QueueType),
State = set_affiliation(Creator, owner, State = set_opts(DefRoomOpts,
#state{host = Host, server_host = ServerHost, #state{host = Host, server_host = ServerHost,
access = Access, room = Room, access = Access, room = Room,
history = lqueue_new(HistorySize, QueueType), history = lqueue_new(HistorySize, QueueType),
jid = jid:make(Room, Host), jid = jid:make(Room, Host),
just_created = true, just_created = true,
room_queue = RoomQueue, room_queue = RoomQueue,
room_shaper = Shaper}), room_shaper = Shaper}),
State1 = set_opts(DefRoomOpts, State), State1 = set_affiliation(Creator, owner, State),
store_room(State1), store_room(State1),
?INFO_MSG("Created MUC room ~ts@~ts by ~ts", ?INFO_MSG("Created MUC room ~ts@~ts by ~ts",
[Room, Host, jid:encode(Creator)]), [Room, Host, jid:encode(Creator)]),
@ -4038,7 +4038,7 @@ set_opts([{Opt, Val} | Opts], StateData) ->
end, muc_subscribers_new(), Val), end, muc_subscribers_new(), Val),
StateData#state{muc_subscribers = MUCSubscribers}; StateData#state{muc_subscribers = MUCSubscribers};
affiliations -> affiliations ->
StateData#state{affiliations = maps:from_list(Val)}; set_affiliations(maps:from_list(Val), StateData);
roles -> roles ->
StateData#state{roles = maps:from_list(Val)}; StateData#state{roles = maps:from_list(Val)};
subject -> subject ->