mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
* src/mod_muc/: Support for more configuration options and
persistent rooms SVN Revision: 91
This commit is contained in:
parent
bc756c3737
commit
6d89957e06
@ -1,3 +1,8 @@
|
|||||||
|
2003-03-25 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
|
* src/mod_muc/: Support for more configuration options and
|
||||||
|
persistent rooms
|
||||||
|
|
||||||
2003-03-23 Alexey Shchepin <alexey@sevcom.net>
|
2003-03-23 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
* src/mod_muc/: MUC support (not completed yet)
|
* src/mod_muc/: MUC support (not completed yet)
|
||||||
|
@ -15,7 +15,10 @@
|
|||||||
-export([start/1,
|
-export([start/1,
|
||||||
init/1,
|
init/1,
|
||||||
stop/0,
|
stop/0,
|
||||||
room_destroyed/1]).
|
room_destroyed/1,
|
||||||
|
store_room/2,
|
||||||
|
restore_room/1,
|
||||||
|
forget_room/1]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
@ -38,7 +41,7 @@ init(Host) ->
|
|||||||
public,
|
public,
|
||||||
{keypos, #muc_online_room.name}]),
|
{keypos, #muc_online_room.name}]),
|
||||||
ejabberd_router:register_route(Host),
|
ejabberd_router:register_route(Host),
|
||||||
% TODO: load permanent groups
|
load_permanent_rooms(Host),
|
||||||
loop(Host).
|
loop(Host).
|
||||||
|
|
||||||
loop(Host) ->
|
loop(Host) ->
|
||||||
@ -136,7 +139,44 @@ iq_disco() ->
|
|||||||
[{"var", ?NS_MUC}], []}].
|
[{"var", ?NS_MUC}], []}].
|
||||||
|
|
||||||
|
|
||||||
|
store_room(Name, Opts) ->
|
||||||
|
F = fun() ->
|
||||||
|
mnesia:write(#muc_room{name = Name,
|
||||||
|
opts = Opts})
|
||||||
|
end,
|
||||||
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
restore_room(Name) ->
|
||||||
|
case catch mnesia:dirty_read(muc_room, Name) of
|
||||||
|
[#muc_room{opts = Opts}] ->
|
||||||
|
Opts;
|
||||||
|
_ ->
|
||||||
|
error
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
forget_room(Name) ->
|
||||||
|
F = fun() ->
|
||||||
|
mnesia:delete({muc_room, Name})
|
||||||
|
end,
|
||||||
|
mnesia:transaction(F).
|
||||||
|
|
||||||
|
|
||||||
|
load_permanent_rooms(Host) ->
|
||||||
|
case catch mnesia:dirty_select(muc_room, [{'_', [], ['$_']}]) of
|
||||||
|
{'EXIT', Reason} ->
|
||||||
|
?ERROR_MSG("~p", [Reason]),
|
||||||
|
ok;
|
||||||
|
Rs ->
|
||||||
|
lists:foreach(fun(R) ->
|
||||||
|
Room = R#muc_room.name,
|
||||||
|
{ok, Pid} = mod_muc_room:start(
|
||||||
|
Host,
|
||||||
|
Room,
|
||||||
|
R#muc_room.opts),
|
||||||
|
ets:insert(
|
||||||
|
muc_online_room,
|
||||||
|
#muc_online_room{name = Room, pid = Pid})
|
||||||
|
end, Rs)
|
||||||
|
end.
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
%% External exports
|
%% External exports
|
||||||
-export([start/4,
|
-export([start/4,
|
||||||
init/1,
|
start/3,
|
||||||
route/4]).
|
route/4]).
|
||||||
|
|
||||||
%% gen_fsm callbacks
|
%% gen_fsm callbacks
|
||||||
@ -35,6 +35,20 @@
|
|||||||
|
|
||||||
-record(lqueue, {queue, len, max}).
|
-record(lqueue, {queue, len, max}).
|
||||||
|
|
||||||
|
-record(config, {allow_change_subj = true, % TODO
|
||||||
|
allow_query_users = true,
|
||||||
|
allow_private_messages = true,
|
||||||
|
public = true, % TODO
|
||||||
|
persistent = false, % TODO
|
||||||
|
moderated = false, % TODO
|
||||||
|
members_by_default = true, % TODO
|
||||||
|
members_only = false, % TODO
|
||||||
|
allow_user_invites = false, % TODO
|
||||||
|
password_protected = false, % TODO
|
||||||
|
anonymous = true, % TODO
|
||||||
|
logging = false % TODO
|
||||||
|
}).
|
||||||
|
|
||||||
-record(user, {jid,
|
-record(user, {jid,
|
||||||
nick,
|
nick,
|
||||||
role,
|
role,
|
||||||
@ -42,7 +56,7 @@
|
|||||||
|
|
||||||
-record(state, {room,
|
-record(state, {room,
|
||||||
host,
|
host,
|
||||||
config,
|
config = #config{},
|
||||||
users = ?DICT:new(),
|
users = ?DICT:new(),
|
||||||
affiliations = ?DICT:new(),
|
affiliations = ?DICT:new(),
|
||||||
history = lqueue_new(10),
|
history = lqueue_new(10),
|
||||||
@ -78,6 +92,9 @@
|
|||||||
start(Host, Room, Creator, Nick) ->
|
start(Host, Room, Creator, Nick) ->
|
||||||
gen_fsm:start(?MODULE, [Host, Room, Creator, Nick], ?FSMOPTS).
|
gen_fsm:start(?MODULE, [Host, Room, Creator, Nick], ?FSMOPTS).
|
||||||
|
|
||||||
|
start(Host, Room, Opts) ->
|
||||||
|
gen_fsm:start(?MODULE, [Host, Room, Opts], ?FSMOPTS).
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% Callback functions from gen_fsm
|
%%% Callback functions from gen_fsm
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
@ -94,6 +111,10 @@ init([Host, Room, Creator, Nick]) ->
|
|||||||
State = set_affiliation(Creator, owner,
|
State = set_affiliation(Creator, owner,
|
||||||
#state{host = Host,
|
#state{host = Host,
|
||||||
room = Room}),
|
room = Room}),
|
||||||
|
{ok, normal_state, State};
|
||||||
|
init([Host, Room, Opts]) ->
|
||||||
|
State = set_opts(Opts, #state{host = Host,
|
||||||
|
room = Room}),
|
||||||
{ok, normal_state, State}.
|
{ok, normal_state, State}.
|
||||||
|
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
@ -186,14 +207,21 @@ normal_state({route, From, "",
|
|||||||
{xmlelement, "iq", Attrs, Els} = Packet},
|
{xmlelement, "iq", Attrs, Els} = Packet},
|
||||||
StateData) ->
|
StateData) ->
|
||||||
case jlib:iq_query_info(Packet) of
|
case jlib:iq_query_info(Packet) of
|
||||||
{iq, ID, Type, ?NS_MUC_ADMIN = XMLNS, SubEl} ->
|
{iq, ID, Type, XMLNS, SubEl} when
|
||||||
|
(XMLNS == ?NS_MUC_ADMIN) or (XMLNS == ?NS_MUC_OWNER) ->
|
||||||
|
Res1 = case XMLNS of
|
||||||
|
?NS_MUC_ADMIN ->
|
||||||
|
process_iq_admin(From, Type, SubEl, StateData);
|
||||||
|
?NS_MUC_OWNER ->
|
||||||
|
process_iq_owner(From, Type, SubEl, StateData)
|
||||||
|
end,
|
||||||
{IQRes, NewStateData} =
|
{IQRes, NewStateData} =
|
||||||
case process_iq_admin(From, Type, SubEl, StateData) of
|
case Res1 of
|
||||||
{result, Res, SD} ->
|
{result, Res, SD} ->
|
||||||
{{iq, ID, result, XMLNS,
|
{{iq, ID, result, XMLNS,
|
||||||
[{xmlelement, "query", [{"xmlns", XMLNS}],
|
[{xmlelement, "query", [{"xmlns", XMLNS}],
|
||||||
Res
|
Res
|
||||||
}]},
|
}]},
|
||||||
SD};
|
SD};
|
||||||
{error, Error} ->
|
{error, Error} ->
|
||||||
{{iq, ID, error, XMLNS,
|
{{iq, ID, error, XMLNS,
|
||||||
@ -314,7 +342,8 @@ normal_state({route, From, Nick,
|
|||||||
normal_state({route, From, ToNick,
|
normal_state({route, From, ToNick,
|
||||||
{xmlelement, "message", Attrs, Els} = Packet},
|
{xmlelement, "message", Attrs, Els} = Packet},
|
||||||
StateData) ->
|
StateData) ->
|
||||||
case is_user_online(From, StateData) of
|
case (StateData#state.config)#config.allow_private_messages
|
||||||
|
andalso is_user_online(From, StateData) of
|
||||||
true ->
|
true ->
|
||||||
case find_jid_by_nick(ToNick, StateData) of
|
case find_jid_by_nick(ToNick, StateData) of
|
||||||
false ->
|
false ->
|
||||||
@ -342,10 +371,30 @@ normal_state({route, From, ToNick,
|
|||||||
normal_state({route, From, ToNick,
|
normal_state({route, From, ToNick,
|
||||||
{xmlelement, "iq", Attrs, Els} = Packet},
|
{xmlelement, "iq", Attrs, Els} = Packet},
|
||||||
StateData) ->
|
StateData) ->
|
||||||
Err = jlib:make_error_reply(
|
case (StateData#state.config)#config.allow_query_users
|
||||||
Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
|
andalso is_user_online(From, StateData) of
|
||||||
ejabberd_router:route(
|
true ->
|
||||||
{StateData#state.room, StateData#state.host, ToNick}, From, Err),
|
case find_jid_by_nick(ToNick, StateData) of
|
||||||
|
false ->
|
||||||
|
Err = jlib:make_error_reply(
|
||||||
|
Packet, ?ERR_JID_NOT_FOUND),
|
||||||
|
ejabberd_router:route(
|
||||||
|
{StateData#state.room, StateData#state.host, ToNick},
|
||||||
|
From, Err);
|
||||||
|
ToJID ->
|
||||||
|
{ok, #user{nick = FromNick}} =
|
||||||
|
?DICT:find(jlib:jid_tolower(From),
|
||||||
|
StateData#state.users),
|
||||||
|
ejabberd_router:route(
|
||||||
|
{StateData#state.room, StateData#state.host, FromNick},
|
||||||
|
ToJID, Packet)
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
Err = jlib:make_error_reply(
|
||||||
|
Packet, ?ERR_NOT_ALLOWED),
|
||||||
|
ejabberd_router:route(
|
||||||
|
{StateData#state.room, StateData#state.host, ToNick}, From, Err)
|
||||||
|
end,
|
||||||
{next_state, normal_state, StateData};
|
{next_state, normal_state, StateData};
|
||||||
|
|
||||||
normal_state(Event, StateData) ->
|
normal_state(Event, StateData) ->
|
||||||
@ -501,7 +550,13 @@ get_default_role(Affiliation, StateData) ->
|
|||||||
admin -> moderator;
|
admin -> moderator;
|
||||||
member -> participant;
|
member -> participant;
|
||||||
outcast -> none;
|
outcast -> none;
|
||||||
none -> participant
|
none ->
|
||||||
|
case (StateData#state.config)#config.members_by_default of
|
||||||
|
true ->
|
||||||
|
participant;
|
||||||
|
_ ->
|
||||||
|
visitor
|
||||||
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
@ -1184,4 +1239,265 @@ send_kickban_presence(UJID, Code, StateData) ->
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
% Owner stuff
|
||||||
|
|
||||||
|
process_iq_owner(From, set, SubEl, StateData) ->
|
||||||
|
FAffiliation = get_affiliation(From, StateData),
|
||||||
|
case FAffiliation of
|
||||||
|
owner ->
|
||||||
|
{xmlelement, Name, Attrs, Els} = SubEl,
|
||||||
|
Lang = xml:get_tag_attr_s("xml:lang", SubEl),
|
||||||
|
case xml:remove_cdata(Els) of
|
||||||
|
[{xmlelement, "x", Attrs1, Els1} = XEl] ->
|
||||||
|
case {xml:get_tag_attr_s("xmlns", XEl),
|
||||||
|
xml:get_tag_attr_s("type", XEl)} of
|
||||||
|
{?NS_XDATA, "cancel"} ->
|
||||||
|
{error, ?ERR_FEATURE_NOT_IMPLEMENTED};
|
||||||
|
{?NS_XDATA, "submit"} ->
|
||||||
|
set_config(XEl, StateData);
|
||||||
|
_ ->
|
||||||
|
{error, ?ERR_BAD_REQUEST}
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
{error, ?ERR_FEATURE_NOT_IMPLEMENTED}
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
{error, ?ERR_NOT_ALLOWED}
|
||||||
|
end;
|
||||||
|
% {xmlelement, _, _, Items} = SubEl,
|
||||||
|
% process_admin_items_set(From, Items, StateData);
|
||||||
|
% {error, ?ERR_FEATURE_NOT_IMPLEMENTED};
|
||||||
|
|
||||||
|
process_iq_owner(From, get, SubEl, StateData) ->
|
||||||
|
FAffiliation = get_affiliation(From, StateData),
|
||||||
|
case FAffiliation of
|
||||||
|
owner ->
|
||||||
|
{xmlelement, Name, Attrs, Els} = SubEl,
|
||||||
|
Lang = xml:get_tag_attr_s("xml:lang", SubEl),
|
||||||
|
case xml:remove_cdata(Els) of
|
||||||
|
[] ->
|
||||||
|
get_config(Lang, StateData);
|
||||||
|
_ ->
|
||||||
|
{error, ?ERR_FEATURE_NOT_IMPLEMENTED}
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
{error, ?ERR_NOT_ALLOWED}
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
% case xml:get_subtag(SubEl, "item") of
|
||||||
|
% false ->
|
||||||
|
% {error, ?ERR_BAD_REQUEST};
|
||||||
|
% Item ->
|
||||||
|
% FAffiliation = get_affiliation(From, StateData),
|
||||||
|
% FRole = get_role(From, StateData),
|
||||||
|
% case xml:get_tag_attr("role", Item) of
|
||||||
|
% false ->
|
||||||
|
% case xml:get_tag_attr("affiliation", Item) of
|
||||||
|
% false ->
|
||||||
|
% {error, ?ERR_BAD_REQUEST};
|
||||||
|
% {value, StrAffiliation} ->
|
||||||
|
% case catch list_to_affiliation(StrAffiliation) of
|
||||||
|
% {'EXIT', _} ->
|
||||||
|
% {error, ?ERR_BAD_REQUEST};
|
||||||
|
% SAffiliation ->
|
||||||
|
% if
|
||||||
|
% FAffiliation == owner ->
|
||||||
|
% Items = items_with_affiliation(
|
||||||
|
% SAffiliation, StateData),
|
||||||
|
% {result, Items, StateData};
|
||||||
|
% true ->
|
||||||
|
% {error, ?ERR_NOT_ALLOWED}
|
||||||
|
% end
|
||||||
|
% end
|
||||||
|
% end;
|
||||||
|
% {value, StrRole} ->
|
||||||
|
% case catch list_to_role(StrRole) of
|
||||||
|
% {'EXIT', _} ->
|
||||||
|
% {error, ?ERR_BAD_REQUEST};
|
||||||
|
% SRole ->
|
||||||
|
% if
|
||||||
|
% FAffiliation == owner ->
|
||||||
|
% Items = items_with_role(SRole, StateData),
|
||||||
|
% {result, Items, StateData};
|
||||||
|
% true ->
|
||||||
|
% {error, ?ERR_NOT_ALLOWED}
|
||||||
|
% end
|
||||||
|
% end
|
||||||
|
% end
|
||||||
|
% end.
|
||||||
|
|
||||||
|
|
||||||
|
-define(XFIELD(Type, Label, Var, Val),
|
||||||
|
{xmlelement, "field", [{"type", Type},
|
||||||
|
{"label", translate:translate(Lang, Label)},
|
||||||
|
{"var", Var}],
|
||||||
|
[{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
|
||||||
|
|
||||||
|
-define(BOOLXFIELD(Label, Var, Val),
|
||||||
|
?XFIELD("boolean", Label, Var,
|
||||||
|
case Val of
|
||||||
|
true -> "1";
|
||||||
|
_ -> "0"
|
||||||
|
end)).
|
||||||
|
|
||||||
|
|
||||||
|
get_config(Lang, StateData) ->
|
||||||
|
Config = StateData#state.config,
|
||||||
|
Res =
|
||||||
|
[?BOOLXFIELD("Allow users to change subject?",
|
||||||
|
"allow_change_subj",
|
||||||
|
Config#config.allow_change_subj),
|
||||||
|
?BOOLXFIELD("Allow users to query other users?",
|
||||||
|
"allow_query_users",
|
||||||
|
Config#config.allow_query_users),
|
||||||
|
?BOOLXFIELD("Allow users to send private messages?",
|
||||||
|
"allow_private_messages",
|
||||||
|
Config#config.allow_private_messages),
|
||||||
|
?BOOLXFIELD("Make room public searchable?",
|
||||||
|
"public",
|
||||||
|
Config#config.public),
|
||||||
|
?BOOLXFIELD("Make room persistent?",
|
||||||
|
"persistent",
|
||||||
|
Config#config.persistent),
|
||||||
|
?BOOLXFIELD("Make room moderated?",
|
||||||
|
"moderated",
|
||||||
|
Config#config.moderated),
|
||||||
|
?BOOLXFIELD("Default users as members?",
|
||||||
|
"members_by_default",
|
||||||
|
Config#config.members_by_default),
|
||||||
|
?BOOLXFIELD("Make room members only?",
|
||||||
|
"members_only",
|
||||||
|
Config#config.members_only),
|
||||||
|
?BOOLXFIELD("Allow users to send invites?",
|
||||||
|
"allow_user_invites",
|
||||||
|
Config#config.allow_user_invites),
|
||||||
|
?BOOLXFIELD("Make room password protected?",
|
||||||
|
"password_protected",
|
||||||
|
Config#config.password_protected),
|
||||||
|
?BOOLXFIELD("Make room anonymous?",
|
||||||
|
"anonymous",
|
||||||
|
Config#config.anonymous),
|
||||||
|
?BOOLXFIELD("Enable logging?",
|
||||||
|
"logging",
|
||||||
|
Config#config.logging)
|
||||||
|
],
|
||||||
|
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], Res}], StateData}.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
set_config(XEl, StateData) ->
|
||||||
|
XData = jlib:parse_xdata_submit(XEl),
|
||||||
|
case XData of
|
||||||
|
invalid ->
|
||||||
|
{error, ?ERR_BAD_REQUEST};
|
||||||
|
_ ->
|
||||||
|
case set_xoption(XData, StateData#state.config) of
|
||||||
|
#config{} = Config ->
|
||||||
|
change_config(Config, StateData);
|
||||||
|
Err ->
|
||||||
|
Err
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
-define(SET_BOOL_XOPT(Opt, Val),
|
||||||
|
case Val of
|
||||||
|
"0" -> set_xoption(Opts, Config#config{Opt = false});
|
||||||
|
"1" -> set_xoption(Opts, Config#config{Opt = true});
|
||||||
|
_ -> {error, ?ERR_BAD_REQUEST}
|
||||||
|
end).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
set_xoption([], Config) ->
|
||||||
|
Config;
|
||||||
|
set_xoption([{"allow_change_subj", [Val]} | Opts], Config) ->
|
||||||
|
?SET_BOOL_XOPT(allow_change_subj, Val);
|
||||||
|
set_xoption([{"allow_query_users", [Val]} | Opts], Config) ->
|
||||||
|
?SET_BOOL_XOPT(allow_query_users, Val);
|
||||||
|
set_xoption([{"allow_private_messages", [Val]} | Opts], Config) ->
|
||||||
|
?SET_BOOL_XOPT(allow_private_messages, Val);
|
||||||
|
set_xoption([{"public", [Val]} | Opts], Config) ->
|
||||||
|
?SET_BOOL_XOPT(public, Val);
|
||||||
|
set_xoption([{"persistent", [Val]} | Opts], Config) ->
|
||||||
|
?SET_BOOL_XOPT(persistent, Val);
|
||||||
|
set_xoption([{"moderated", [Val]} | Opts], Config) ->
|
||||||
|
?SET_BOOL_XOPT(moderated, Val);
|
||||||
|
set_xoption([{"members_by_default", [Val]} | Opts], Config) ->
|
||||||
|
?SET_BOOL_XOPT(members_by_default, Val);
|
||||||
|
set_xoption([{"members_only", [Val]} | Opts], Config) ->
|
||||||
|
?SET_BOOL_XOPT(members_only, Val);
|
||||||
|
set_xoption([{"allow_user_invites", [Val]} | Opts], Config) ->
|
||||||
|
?SET_BOOL_XOPT(allow_user_invites, Val);
|
||||||
|
set_xoption([{"password_protected", [Val]} | Opts], Config) ->
|
||||||
|
?SET_BOOL_XOPT(password_protected, Val);
|
||||||
|
set_xoption([{"anonymous", [Val]} | Opts], Config) ->
|
||||||
|
?SET_BOOL_XOPT(anonymous, Val);
|
||||||
|
set_xoption([{"logging", [Val]} | Opts], Config) ->
|
||||||
|
?SET_BOOL_XOPT(logging, Val);
|
||||||
|
set_xoption([_ | Opts], Config) ->
|
||||||
|
{error, ?ERR_BAD_REQUEST}.
|
||||||
|
|
||||||
|
|
||||||
|
change_config(Config, StateData) ->
|
||||||
|
NSD = StateData#state{config = Config},
|
||||||
|
case {(StateData#state.config)#config.persistent,
|
||||||
|
Config#config.persistent} of
|
||||||
|
{_, true} ->
|
||||||
|
mod_muc:store_room(NSD#state.room, make_opts(NSD));
|
||||||
|
{true, false} ->
|
||||||
|
mod_muc:forget_room(NSD#state.room);
|
||||||
|
{false, false} ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
{result, [], NSD}.
|
||||||
|
|
||||||
|
|
||||||
|
-define(CASE_CONFIG_OPT(Opt),
|
||||||
|
Opt -> StateData#state{
|
||||||
|
config = (StateData#state.config)#config{Opt = Val}}).
|
||||||
|
|
||||||
|
set_opts([], StateData) ->
|
||||||
|
StateData;
|
||||||
|
set_opts([{Opt, Val} | Opts], StateData) ->
|
||||||
|
NSD = case Opt of
|
||||||
|
?CASE_CONFIG_OPT(allow_change_subj);
|
||||||
|
?CASE_CONFIG_OPT(allow_query_users);
|
||||||
|
?CASE_CONFIG_OPT(allow_private_messages);
|
||||||
|
?CASE_CONFIG_OPT(public);
|
||||||
|
?CASE_CONFIG_OPT(persistent);
|
||||||
|
?CASE_CONFIG_OPT(moderated);
|
||||||
|
?CASE_CONFIG_OPT(members_by_default);
|
||||||
|
?CASE_CONFIG_OPT(members_only);
|
||||||
|
?CASE_CONFIG_OPT(allow_user_invites);
|
||||||
|
?CASE_CONFIG_OPT(password_protected);
|
||||||
|
?CASE_CONFIG_OPT(anonymous);
|
||||||
|
?CASE_CONFIG_OPT(logging);
|
||||||
|
affiliations ->
|
||||||
|
StateData#state{affiliations = ?DICT:from_list(Val)};
|
||||||
|
_ -> StateData
|
||||||
|
end,
|
||||||
|
set_opts(Opts, NSD).
|
||||||
|
|
||||||
|
-define(MAKE_CONFIG_OPT(Opt), {Opt, Config#config.Opt}).
|
||||||
|
|
||||||
|
make_opts(StateData) ->
|
||||||
|
Config = StateData#state.config,
|
||||||
|
[
|
||||||
|
?MAKE_CONFIG_OPT(allow_change_subj),
|
||||||
|
?MAKE_CONFIG_OPT(allow_query_users),
|
||||||
|
?MAKE_CONFIG_OPT(allow_private_messages),
|
||||||
|
?MAKE_CONFIG_OPT(public),
|
||||||
|
?MAKE_CONFIG_OPT(persistent),
|
||||||
|
?MAKE_CONFIG_OPT(moderated),
|
||||||
|
?MAKE_CONFIG_OPT(members_by_default),
|
||||||
|
?MAKE_CONFIG_OPT(members_only),
|
||||||
|
?MAKE_CONFIG_OPT(allow_user_invites),
|
||||||
|
?MAKE_CONFIG_OPT(password_protected),
|
||||||
|
?MAKE_CONFIG_OPT(anonymous),
|
||||||
|
?MAKE_CONFIG_OPT(logging),
|
||||||
|
{affiliations, ?DICT:to_list(StateData#state.affiliations)}
|
||||||
|
].
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user