diff options
Diffstat (limited to 'src')
109 files changed, 1397 insertions, 2229 deletions
diff --git a/src/acl.erl b/src/acl.erl index 0cdd7daa6..3e0617f55 100644 --- a/src/acl.erl +++ b/src/acl.erl @@ -199,13 +199,13 @@ load_from_config() -> lists:foreach( fun(Host) -> ACLs = ejabberd_config:get_option( - {acl, Host}, fun(V) -> V end, []), + {acl, Host}, []), AccessRules = ejabberd_config:get_option( - {access, Host}, fun(V) -> V end, []), + {access, Host}, []), AccessRulesNew = ejabberd_config:get_option( - {access_rules, Host}, fun(V) -> V end, []), + {access_rules, Host}, []), ShaperRules = ejabberd_config:get_option( - {shaper_rules, Host}, fun(V) -> V end, []), + {shaper_rules, Host}, []), lists:foreach( fun({ACLName, SpecList}) -> lists:foreach( @@ -605,7 +605,7 @@ access_rules_validator(Rules0) -> (deny) -> true; (_) -> false end), - throw({replace_with, Rules}). + Rules. shaper_rules_validator(Name) when is_atom(Name) -> @@ -616,7 +616,7 @@ shaper_rules_validator(Rules0) -> (V2) when is_integer(V2) -> true; (_) -> false end), - throw({replace_with, Rules}). + Rules. access_shaper_rules_validator([{Type, Acls} = Rule | Rest], RuleTypeCheck) -> case RuleTypeCheck(Type) of diff --git a/src/cyrsasl_digest.erl b/src/cyrsasl_digest.erl index eedb5366c..9d23271d1 100644 --- a/src/cyrsasl_digest.erl +++ b/src/cyrsasl_digest.erl @@ -55,7 +55,7 @@ check_password :: check_password_fun(), auth_module :: atom(), host = <<"">> :: binary(), - hostfqdn = <<"">> :: binary() | [binary()]}). + hostfqdn = [] :: [binary()]}). start(_Opts) -> Fqdn = get_local_fqdn(), @@ -204,8 +204,6 @@ is_digesturi_valid(DigestURICase, JabberDomain, false end. -is_host_fqdn(Host, Fqdn) when is_binary(Fqdn) -> - Host == Fqdn; is_host_fqdn(_Host, []) -> false; is_host_fqdn(Host, [Fqdn | _FqdnTail]) when Host == Fqdn -> @@ -214,26 +212,13 @@ is_host_fqdn(Host, [Fqdn | FqdnTail]) when Host /= Fqdn -> is_host_fqdn(Host, FqdnTail). get_local_fqdn() -> - case catch get_local_fqdn2() of - Str when is_binary(Str) -> Str; - List when is_list(List) -> List; - _ -> - <<"unknown-fqdn, please configure fqdn " - "option in ejabberd.yml!">> - end. - -get_local_fqdn2() -> - case ejabberd_config:get_option( - fqdn, fun(X) -> X end) of - ConfiguredFqdn when is_binary(ConfiguredFqdn) -> - ConfiguredFqdn; - [A | _] = ConfiguredFqdns when is_binary(A) -> - ConfiguredFqdns; - undefined -> - {ok, Hostname} = inet:gethostname(), - {ok, {hostent, Fqdn, _, _, _, _}} = - inet:gethostbyname(Hostname), - list_to_binary(Fqdn) + case ejabberd_config:get_option(fqdn) of + undefined -> + {ok, Hostname} = inet:gethostname(), + {ok, {hostent, Fqdn, _, _, _, _}} = inet:gethostbyname(Hostname), + [list_to_binary(Fqdn)]; + Fqdn -> + Fqdn end. hex(S) -> @@ -275,5 +260,10 @@ response(KeyVals, User, Passwd, Nonce, AuthzId, ":", (hex((erlang:md5(A2))))/binary>>, hex((erlang:md5(T))). -opt_type(fqdn) -> fun iolist_to_binary/1; +opt_type(fqdn) -> + fun(FQDN) when is_binary(FQDN) -> + [FQDN]; + (FQDNs) when is_list(FQDNs) -> + [iolist_to_binary(FQDN) || FQDN <- FQDNs] + end; opt_type(_) -> [fqdn]. diff --git a/src/ejabberd_access_permissions.erl b/src/ejabberd_access_permissions.erl index 244b2c121..b27d17683 100644 --- a/src/ejabberd_access_permissions.erl +++ b/src/ejabberd_access_permissions.erl @@ -239,8 +239,7 @@ get_definitions(#state{definitions = none, fragments_generators = Gens} = State) [{acl,{acl,admin}}, {oauth,[<<"ejabberd:admin">>],[{acl,{acl,admin}}]}], {all, [start, stop]}}}], - ApiPerms = ejabberd_config:get_option(api_permissions, fun(A) -> A end, - DefaultOptions), + ApiPerms = ejabberd_config:get_option(api_permissions, DefaultOptions), AllCommands = ejabberd_commands:get_commands_definition(), Frags = lists:foldl( fun({_Name, Generator}, Acc) -> @@ -334,7 +333,7 @@ command_matches_patterns(C, [_ | Tail]) -> %%%=================================================================== parse_api_permissions(Data) when is_list(Data) -> - throw({replace_with, [parse_api_permission(Name, Args) || {Name, Args} <- Data]}). + [parse_api_permission(Name, Args) || {Name, Args} <- Data]. parse_api_permission(Name, Args0) -> Args = lists:flatten(Args0), @@ -374,8 +373,6 @@ parse_who(Name, Defs, ParseOauth) when is_list(Defs) -> throw:{invalid_syntax, Msg} -> report_error(<<"Invalid access rule: '~s' used inside 'who' section for api_permission '~s'">>, [Msg, Name]); - throw:{replace_with, NVal} -> - {access, NVal}; error:_ -> report_error(<<"Invalid access rule '~p' used inside 'who' section for api_permission '~s'">>, [Val, Name]) diff --git a/src/ejabberd_admin.erl b/src/ejabberd_admin.erl index 15cd78c02..a615b2fee 100644 --- a/src/ejabberd_admin.erl +++ b/src/ejabberd_admin.erl @@ -616,7 +616,7 @@ restore(Path) -> %% Obsolete tables or tables created by module who are no longer used are not %% restored and are ignored. keep_tables() -> - lists:flatten([acl, passwd, config, local_config, + lists:flatten([acl, passwd, config, keep_modules_tables()]). %% Returns the list of modules tables in use, according to the list of actually diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl index 214c38b21..b23249aa0 100644 --- a/src/ejabberd_app.erl +++ b/src/ejabberd_app.erl @@ -46,9 +46,9 @@ start(normal, _Args) -> start_apps(), start_elixir_application(), ejabberd:check_app(ejabberd), - ejabberd_mnesia:start(), setup_if_elixir_conf_used(), ejabberd_config:start(), + ejabberd_mnesia:start(), set_settings_from_config(), file_queue_init(), maybe_add_nameservers(), @@ -59,6 +59,7 @@ start(normal, _Args) -> {T2, _} = statistics(wall_clock), ?INFO_MSG("ejabberd ~s is started in the node ~p in ~.2fs", [?VERSION, node(), (T2-T1)/1000]), + lists:foreach(fun erlang:garbage_collect/1, processes()), {ok, SupPid}; Err -> Err @@ -88,12 +89,7 @@ stop(_State) -> %%% connect_nodes() -> - Nodes = ejabberd_config:get_option( - cluster_nodes, - fun(Ns) -> - true = lists:all(fun is_atom/1, Ns), - Ns - end, []), + Nodes = ejabberd_config:get_option(cluster_nodes, []), lists:foreach(fun(Node) -> net_kernel:connect_node(Node) end, Nodes). @@ -141,10 +137,7 @@ delete_pid_file() -> end. set_settings_from_config() -> - Ticktime = ejabberd_config:get_option( - net_ticktime, - opt_type(net_ticktime), - 60), + Ticktime = ejabberd_config:get_option(net_ticktime, 60), net_kernel:set_net_ticktime(Ticktime). file_queue_init() -> @@ -161,6 +154,7 @@ start_apps() -> crypto:start(), ejabberd:start_app(sasl), ejabberd:start_app(ssl), + ejabberd:start_app(p1_utils), ejabberd:start_app(fast_yaml), ejabberd:start_app(fast_tls), ejabberd:start_app(xmpp), diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl index 10acb8157..756fafcf6 100644 --- a/src/ejabberd_auth.erl +++ b/src/ejabberd_auth.erl @@ -44,7 +44,7 @@ get_password_s/2, get_password_with_authmodule/2, is_user_exists/2, is_user_exists_in_other_modules/3, remove_user/2, remove_user/3, plain_password_required/1, - store_type/1, entropy/1, backend_type/1]). + store_type/1, entropy/1, backend_type/1, password_format/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). @@ -497,6 +497,9 @@ backend_type(Mod) -> _ -> Mod end. +password_format(LServer) -> + ejabberd_config:get_option({auth_password_format, LServer}, plain). + %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- @@ -508,8 +511,7 @@ auth_modules() -> auth_modules(Server) -> LServer = jid:nameprep(Server), Default = ejabberd_config:default_db(LServer, ?MODULE), - Methods = ejabberd_config:get_option( - {auth_method, LServer}, opt_type(auth_method), [Default]), + Methods = ejabberd_config:get_option({auth_method, LServer}, [Default]), [misc:binary_to_atom(<<"ejabberd_auth_", (misc:atom_to_binary(M))/binary>>) || M <- Methods]. @@ -537,4 +539,8 @@ opt_type(auth_method) -> lists:map(fun(M) -> ejabberd_config:v_db(?MODULE, M) end, V); (V) -> [ejabberd_config:v_db(?MODULE, V)] end; -opt_type(_) -> [auth_method]. +opt_type(auth_password_format) -> + fun (plain) -> plain; + (scram) -> scram + end; +opt_type(_) -> [auth_method, auth_password_format]. diff --git a/src/ejabberd_auth_anonymous.erl b/src/ejabberd_auth_anonymous.erl index 51eab74b7..a75af709e 100644 --- a/src/ejabberd_auth_anonymous.erl +++ b/src/ejabberd_auth_anonymous.erl @@ -26,9 +26,11 @@ -module(ejabberd_auth_anonymous). -behaviour(ejabberd_config). +-behaviour(ejabberd_auth). -author('mickael.remond@process-one.net'). -export([start/1, + stop/1, allow_anonymous/1, is_sasl_anonymous_enabled/1, is_login_anonymous_enabled/1, @@ -59,6 +61,12 @@ start(Host) -> ?MODULE, unregister_connection, 100), ok. +stop(Host) -> + ejabberd_hooks:delete(sm_register_connection_hook, Host, + ?MODULE, register_connection, 100), + ejabberd_hooks:delete(sm_remove_connection_hook, Host, + ?MODULE, unregister_connection, 100). + %% Return true if anonymous is allowed for host or false otherwise allow_anonymous(Host) -> lists:member(?MODULE, ejabberd_auth:auth_modules(Host)). @@ -93,21 +101,12 @@ is_login_anonymous_enabled(Host) -> %% Return the anonymous protocol to use: sasl_anon|login_anon|both %% defaults to login_anon anonymous_protocol(Host) -> - ejabberd_config:get_option( - {anonymous_protocol, Host}, - fun(sasl_anon) -> sasl_anon; - (login_anon) -> login_anon; - (both) -> both - end, - sasl_anon). + ejabberd_config:get_option({anonymous_protocol, Host}, sasl_anon). %% Return true if multiple connections have been allowed in the config file %% defaults to false allow_multiple_connections(Host) -> - ejabberd_config:get_option( - {allow_multiple_connections, Host}, - fun(V) when is_boolean(V) -> V end, - false). + ejabberd_config:get_option({allow_multiple_connections, Host}, false). anonymous_user_exist(User, Server) -> lists:any( diff --git a/src/ejabberd_auth_external.erl b/src/ejabberd_auth_external.erl index 4ba76cd99..8ba2e2b22 100644 --- a/src/ejabberd_auth_external.erl +++ b/src/ejabberd_auth_external.erl @@ -48,12 +48,7 @@ %%% API %%%---------------------------------------------------------------------- start(Host) -> - Cmd = ejabberd_config:get_option( - {extauth_program, Host}, - fun(V) -> - binary_to_list(iolist_to_binary(V)) - end, - "extauth"), + Cmd = ejabberd_config:get_option({extauth_program, Host}, "extauth"), extauth:start(Host, Cmd), check_cache_last_options(Host), ejabberd_auth_mnesia:start(Host). @@ -179,12 +174,8 @@ remove_user(User, Server, Password) -> %% @spec (Host::string()) -> false | {true, CacheTime::integer()} get_cache_option(Host) -> - case ejabberd_config:get_option( - {extauth_cache, Host}, - fun(false) -> undefined; - (I) when is_integer(I), I >= 0 -> I - end) of - undefined -> false; + case ejabberd_config:get_option({extauth_cache, Host}, false) of + false -> false; CacheTime -> {true, CacheTime} end. @@ -319,12 +310,11 @@ get_mod_last_configured(Server) -> end. is_configured(Host, Module) -> - Os = ejabberd_config:get_option({modules, Host}, - fun(M) when is_list(M) -> M end), + Os = ejabberd_config:get_option({modules, Host}, []), lists:keymember(Module, 1, Os). opt_type(extauth_cache) -> - fun (false) -> undefined; + fun (false) -> false; (I) when is_integer(I), I >= 0 -> I end; opt_type(extauth_program) -> diff --git a/src/ejabberd_auth_ldap.erl b/src/ejabberd_auth_ldap.erl index 7d4626a9f..53c256490 100644 --- a/src/ejabberd_auth_ldap.erl +++ b/src/ejabberd_auth_ldap.erl @@ -364,24 +364,11 @@ parse_options(Host) -> Eldap_ID = misc:atom_to_binary(gen_mod:get_module_proc(Host, ?MODULE)), Bind_Eldap_ID = misc:atom_to_binary( gen_mod:get_module_proc(Host, bind_ejabberd_auth_ldap)), - UIDsTemp = gen_mod:get_opt( - {ldap_uids, Host}, [], - fun(Us) -> - lists:map( - fun({U, P}) -> - {iolist_to_binary(U), - iolist_to_binary(P)}; - ({U}) -> - {iolist_to_binary(U)}; - (U) -> - {iolist_to_binary(U)} - end, lists:flatten(Us)) - end, [{<<"uid">>, <<"%u">>}]), + UIDsTemp = ejabberd_config:get_option( + {ldap_uids, Host}, [{<<"uid">>, <<"%u">>}]), UIDs = eldap_utils:uids_domain_subst(Host, UIDsTemp), SubFilter = eldap_utils:generate_subfilter(UIDs), - UserFilter = case gen_mod:get_opt( - {ldap_filter, Host}, [], - fun check_filter/1, <<"">>) of + UserFilter = case ejabberd_config:get_option({ldap_filter, Host}, <<"">>) of <<"">> -> SubFilter; F -> @@ -390,20 +377,8 @@ parse_options(Host) -> SearchFilter = eldap_filter:do_sub(UserFilter, [{<<"%u">>, <<"*">>}]), {DNFilter, DNFilterAttrs} = - gen_mod:get_opt({ldap_dn_filter, Host}, [], - fun([{DNF, DNFA}]) -> - NewDNFA = case DNFA of - undefined -> - []; - _ -> - [iolist_to_binary(A) - || A <- DNFA] - end, - NewDNF = check_filter(DNF), - {NewDNF, NewDNFA} - end, {undefined, []}), - LocalFilter = gen_mod:get_opt( - {ldap_local_filter, Host}, [], fun(V) -> V end), + ejabberd_config:get_option({ldap_dn_filter, Host}, {undefined, []}), + LocalFilter = ejabberd_config:get_option({ldap_local_filter, Host}), #state{host = Host, eldap_id = Eldap_ID, bind_eldap_id = Bind_Eldap_ID, servers = Cfg#eldap_config.servers, @@ -418,31 +393,15 @@ parse_options(Host) -> sfilter = SearchFilter, lfilter = LocalFilter, dn_filter = DNFilter, dn_filter_attrs = DNFilterAttrs}. -check_filter(F) -> - NewF = iolist_to_binary(F), - {ok, _} = eldap_filter:parse(NewF), - NewF. - opt_type(ldap_dn_filter) -> fun ([{DNF, DNFA}]) -> NewDNFA = case DNFA of undefined -> []; _ -> [iolist_to_binary(A) || A <- DNFA] end, - NewDNF = check_filter(DNF), + NewDNF = eldap_utils:check_filter(DNF), {NewDNF, NewDNFA} end; -opt_type(ldap_filter) -> fun check_filter/1; opt_type(ldap_local_filter) -> fun (V) -> V end; -opt_type(ldap_uids) -> - fun (Us) -> - lists:map(fun ({U, P}) -> - {iolist_to_binary(U), iolist_to_binary(P)}; - ({U}) -> {iolist_to_binary(U)}; - (U) -> {iolist_to_binary(U)} - end, - lists:flatten(Us)) - end; opt_type(_) -> - [ldap_dn_filter, ldap_filter, ldap_local_filter, - ldap_uids]. + [ldap_dn_filter, ldap_local_filter]. diff --git a/src/ejabberd_auth_mnesia.erl b/src/ejabberd_auth_mnesia.erl index f856c8a9c..592b9c566 100644 --- a/src/ejabberd_auth_mnesia.erl +++ b/src/ejabberd_auth_mnesia.erl @@ -27,8 +27,6 @@ -compile([{parse_transform, ejabberd_sql_pt}]). --behaviour(ejabberd_config). - -author('alexey@process-one.net'). -behaviour(ejabberd_auth). @@ -41,7 +39,7 @@ get_vh_registered_users_number/2, get_password/2, get_password_s/2, is_user_exists/2, remove_user/2, remove_user/3, store_type/0, export/1, import/2, - plain_password_required/0, opt_type/1]). + plain_password_required/0]). -export([need_transform/1, transform/1]). -include("ejabberd.hrl"). @@ -89,8 +87,7 @@ plain_password_required() -> is_scrammed(). store_type() -> - ejabberd_config:get_option({auth_password_format, ?MYNAME}, - opt_type(auth_password_format), plain). + ejabberd_auth:password_format(?MYNAME). check_password(User, AuthzId, Server, Password) -> if AuthzId /= <<>> andalso AuthzId /= User -> @@ -494,9 +491,3 @@ export(_Server) -> import(LServer, [LUser, Password, _TimeStamp]) -> mnesia:dirty_write( #passwd{us = {LUser, LServer}, password = Password}). - -opt_type(auth_password_format) -> - fun (plain) -> plain; - (scram) -> scram - end; -opt_type(_) -> [auth_password_format]. diff --git a/src/ejabberd_auth_pam.erl b/src/ejabberd_auth_pam.erl index 51ad3a881..974cc8e43 100644 --- a/src/ejabberd_auth_pam.erl +++ b/src/ejabberd_auth_pam.erl @@ -112,18 +112,10 @@ store_type() -> external. %% Internal functions %%==================================================================== get_pam_service(Host) -> - ejabberd_config:get_option( - {pam_service, Host}, - fun iolist_to_binary/1, - <<"ejabberd">>). + ejabberd_config:get_option({pam_service, Host}, <<"ejabberd">>). get_pam_userinfotype(Host) -> - ejabberd_config:get_option( - {pam_userinfotype, Host}, - fun(username) -> username; - (jid) -> jid - end, - username). + ejabberd_config:get_option({pam_userinfotype, Host}, username). opt_type(pam_service) -> fun iolist_to_binary/1; opt_type(pam_userinfotype) -> diff --git a/src/ejabberd_auth_riak.erl b/src/ejabberd_auth_riak.erl index 9555fcad8..74f0f73ca 100644 --- a/src/ejabberd_auth_riak.erl +++ b/src/ejabberd_auth_riak.erl @@ -27,8 +27,6 @@ -compile([{parse_transform, ejabberd_sql_pt}]). --behaviour(ejabberd_config). - -author('alexey@process-one.net'). -behaviour(ejabberd_auth). @@ -42,7 +40,7 @@ get_vh_registered_users_number/2, get_password/2, get_password_s/2, is_user_exists/2, remove_user/2, remove_user/3, store_type/0, export/1, import/2, - plain_password_required/0, opt_type/1]). + plain_password_required/0]). -export([passwd_schema/0]). -include("ejabberd.hrl"). @@ -272,9 +270,7 @@ remove_user(User, Server, Password) -> %%% is_scrammed() -> - scram == - ejabberd_config:get_option({auth_password_format, ?MYNAME}, - opt_type(auth_password_format), plain). + scram == ejabberd_auth:password_format(?MYNAME). password_to_scram(Password) -> password_to_scram(Password, @@ -320,9 +316,3 @@ export(_Server) -> import(LServer, [LUser, Password, _TimeStamp]) -> Passwd = #passwd{us = {LUser, LServer}, password = Password}, ejabberd_riak:put(Passwd, passwd_schema(), [{'2i', [{<<"host">>, LServer}]}]). - -opt_type(auth_password_format) -> - fun (plain) -> plain; - (scram) -> scram - end; -opt_type(_) -> [auth_password_format]. diff --git a/src/ejabberd_auth_sql.erl b/src/ejabberd_auth_sql.erl index 0d9665afc..8514b9cf1 100644 --- a/src/ejabberd_auth_sql.erl +++ b/src/ejabberd_auth_sql.erl @@ -27,8 +27,6 @@ -compile([{parse_transform, ejabberd_sql_pt}]). --behaviour(ejabberd_config). - -author('alexey@process-one.net'). -behaviour(ejabberd_auth). @@ -41,7 +39,7 @@ get_vh_registered_users_number/2, get_password/2, get_password_s/2, is_user_exists/2, remove_user/2, remove_user/3, store_type/0, plain_password_required/0, - convert_to_scram/1, opt_type/1]). + convert_to_scram/1]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -408,9 +406,7 @@ remove_user(User, Server, Password) -> %%% is_scrammed() -> - scram == - ejabberd_config:get_option({auth_password_format, ?MYNAME}, - opt_type(auth_password_format), plain). + scram == ejabberd_auth:password_format(?MYNAME). password_to_scram(Password) -> password_to_scram(Password, @@ -509,9 +505,3 @@ convert_to_scram(Server) -> Error -> Error end end. - -opt_type(auth_password_format) -> - fun (plain) -> plain; - (scram) -> scram - end; -opt_type(_) -> [auth_password_format]. diff --git a/src/ejabberd_bosh.erl b/src/ejabberd_bosh.erl index d050eb091..0755067e7 100644 --- a/src/ejabberd_bosh.erl +++ b/src/ejabberd_bosh.erl @@ -299,10 +299,7 @@ init([#body{attrs = Attrs}, IP, SID]) -> XMPPVer = get_attr('xmpp:version', Attrs), XMPPDomain = get_attr(to, Attrs), {InBuf, Opts} = case gen_mod:get_module_opt( - XMPPDomain, - mod_bosh, prebind, - fun(B) when is_boolean(B) -> B end, - false) of + XMPPDomain, mod_bosh, prebind, false) of true -> JID = make_random_jid(XMPPDomain), {buf_new(XMPPDomain), [{jid, JID} | Opts2]}; @@ -315,12 +312,9 @@ init([#body{attrs = Attrs}, IP, SID]) -> Opts), Inactivity = gen_mod:get_module_opt(XMPPDomain, mod_bosh, max_inactivity, - fun(I) when is_integer(I), I>0 -> I end, ?DEFAULT_INACTIVITY), MaxConcat = gen_mod:get_module_opt(XMPPDomain, mod_bosh, max_concat, - fun(unlimited) -> unlimited; - (N) when is_integer(N), N>0 -> N - end, unlimited), + unlimited), ShapedReceivers = buf_new(XMPPDomain, ?MAX_SHAPED_REQUESTS_QUEUE_LEN), State = #state{host = XMPPDomain, sid = SID, ip = IP, xmpp_ver = XMPPVer, el_ibuf = InBuf, @@ -366,7 +360,6 @@ wait_for_session(#body{attrs = Attrs} = Req, From, end, MaxPause = gen_mod:get_module_opt(State#state.host, mod_bosh, max_pause, - fun(I) when is_integer(I), I>0 -> I end, ?DEFAULT_MAXPAUSE), Resp = #body{attrs = [{sid, State#state.sid}, {wait, Wait}, @@ -1039,12 +1032,9 @@ buf_new(Host) -> buf_new(Host, unlimited). buf_new(Host, Limit) -> - QueueType = case gen_mod:get_module_opt( - Host, mod_bosh, queue_type, - mod_bosh:mod_opt_type(queue_type)) of - undefined -> ejabberd_config:default_queue_type(Host); - T -> T - end, + QueueType = gen_mod:get_module_opt( + Host, mod_bosh, queue_type, + ejabberd_config:default_queue_type(Host)), p1_queue:new(QueueType, Limit). buf_in(Xs, Buf) -> diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index b6bd1c59f..24db8c1ea 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -29,7 +29,7 @@ %% ejabberd_socket callbacks -export([start/2, start_link/2, socket_type/0]). %% ejabberd_config callbacks --export([opt_type/1, transform_listen_option/2]). +-export([opt_type/1, listen_opt_type/1, transform_listen_option/2]). %% xmpp_stream_in callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). @@ -293,45 +293,37 @@ process_terminated(State, _Reason) -> tls_options(#{lserver := LServer, tls_options := DefaultOpts}) -> TLSOpts1 = case ejabberd_config:get_option( {c2s_certfile, LServer}, - fun iolist_to_binary/1, ejabberd_config:get_option( - {domain_certfile, LServer}, - fun iolist_to_binary/1)) of + {domain_certfile, LServer})) of undefined -> DefaultOpts; CertFile -> lists:keystore(certfile, 1, DefaultOpts, {certfile, CertFile}) end, TLSOpts2 = case ejabberd_config:get_option( - {c2s_ciphers, LServer}, - fun iolist_to_binary/1) of + {c2s_ciphers, LServer}) of undefined -> TLSOpts1; Ciphers -> lists:keystore(ciphers, 1, TLSOpts1, {ciphers, Ciphers}) end, TLSOpts3 = case ejabberd_config:get_option( - {c2s_protocol_options, LServer}, - fun (Options) -> str:join(Options, <<$|>>) end) of + {c2s_protocol_options, LServer}) of undefined -> TLSOpts2; ProtoOpts -> lists:keystore(protocol_options, 1, TLSOpts2, {protocol_options, ProtoOpts}) end, TLSOpts4 = case ejabberd_config:get_option( - {c2s_dhfile, LServer}, - fun iolist_to_binary/1) of + {c2s_dhfile, LServer}) of undefined -> TLSOpts3; DHFile -> lists:keystore(dhfile, 1, TLSOpts3, {dhfile, DHFile}) end, TLSOpts5 = case ejabberd_config:get_option( - {c2s_cafile, LServer}, - fun iolist_to_binary/1) of + {c2s_cafile, LServer}) of undefined -> TLSOpts4; CAFile -> lists:keystore(cafile, 1, TLSOpts4, {cafile, CAFile}) end, - case ejabberd_config:get_option( - {c2s_tls_compression, LServer}, - fun(B) when is_boolean(B) -> B end) of + case ejabberd_config:get_option({c2s_tls_compression, LServer}) of undefined -> TLSOpts5; false -> [compression_none | TLSOpts5]; true -> lists:delete(compression_none, TLSOpts5) @@ -360,13 +352,7 @@ authenticated_stream_features(#{lserver := LServer}) -> ejabberd_hooks:run_fold(c2s_post_auth_features, LServer, [], [LServer]). sasl_mechanisms(Mechs, #{lserver := LServer}) -> - Mechs1 = ejabberd_config:get_option( - {disable_sasl_mechanisms, LServer}, - fun(V) when is_list(V) -> - lists:map(fun(M) -> str:to_upper(M) end, V); - (V) -> - [str:to_upper(V)] - end, []), + Mechs1 = ejabberd_config:get_option({disable_sasl_mechanisms, LServer}, []), Mechs2 = case ejabberd_auth_anonymous:is_sasl_anonymous_enabled(LServer) of true -> Mechs1; false -> [<<"ANONYMOUS">>|Mechs1] @@ -504,30 +490,25 @@ handle_send(Pkt, Result, #{lserver := LServer} = State) -> ejabberd_hooks:run_fold(c2s_handle_send, LServer, State, [Pkt, Result]). init([State, Opts]) -> - Access = gen_mod:get_opt(access, Opts, fun acl:access_rules_validator/1, all), - Shaper = gen_mod:get_opt(shaper, Opts, fun acl:shaper_rules_validator/1, none), + Access = gen_mod:get_opt(access, Opts, all), + Shaper = gen_mod:get_opt(shaper, Opts, none), TLSOpts1 = lists:filter( fun({certfile, _}) -> true; ({ciphers, _}) -> true; ({dhfile, _}) -> true; ({cafile, _}) -> true; + ({protocol_options, _}) -> true; (_) -> false end, Opts), - TLSOpts2 = case lists:keyfind(protocol_options, 1, Opts) of - false -> TLSOpts1; - {_, OptString} -> - ProtoOpts = str:join(OptString, <<$|>>), - [{protocol_options, ProtoOpts}|TLSOpts1] - end, - TLSOpts3 = case proplists:get_bool(tls_compression, Opts) of - false -> [compression_none | TLSOpts2]; - true -> TLSOpts2 + TLSOpts2 = case proplists:get_bool(tls_compression, Opts) of + false -> [compression_none | TLSOpts1]; + true -> TLSOpts1 end, TLSEnabled = proplists:get_bool(starttls, Opts), TLSRequired = proplists:get_bool(starttls_required, Opts), TLSVerify = proplists:get_bool(tls_verify, Opts), Zlib = proplists:get_bool(zlib, Opts), - State1 = State#{tls_options => TLSOpts3, + State1 = State#{tls_options => TLSOpts2, tls_required => TLSRequired, tls_enabled => TLSEnabled, tls_verify => TLSVerify, @@ -674,9 +655,7 @@ process_presence_out(#{user := User, server := Server, lserver := LServer, send_error(State, Pres, Err); allow when Type == subscribe; Type == subscribed; Type == unsubscribe; Type == unsubscribed -> - Access = gen_mod:get_module_opt(LServer, mod_roster, access, - fun(A) when is_atom(A) -> A end, - all), + Access = gen_mod:get_module_opt(LServer, mod_roster, access, all), MyBareJID = jid:remove_resource(JID), case acl:match_rule(LServer, Access, MyBareJID) of deny -> @@ -805,22 +784,15 @@ resource_conflict_action(U, S, R) -> OptionRaw = case ejabberd_sm:is_existing_resource(U, S, R) of true -> ejabberd_config:get_option( - {resource_conflict, S}, - fun(setresource) -> setresource; - (closeold) -> closeold; - (closenew) -> closenew; - (acceptnew) -> acceptnew - end); + {resource_conflict, S}, acceptnew); false -> acceptnew end, Option = case OptionRaw of setresource -> setresource; - closeold -> - acceptnew; %% ejabberd_sm will close old session + closeold -> acceptnew; %% ejabberd_sm will close old session closenew -> closenew; - acceptnew -> acceptnew; - _ -> acceptnew %% default ejabberd behavior + acceptnew -> acceptnew end, case Option of acceptnew -> {accept_resource, R}; @@ -922,7 +894,6 @@ format_reason(_, _) -> transform_listen_option(Opt, Opts) -> [Opt|Opts]. -opt_type(domain_certfile) -> fun iolist_to_binary/1; opt_type(c2s_certfile) -> fun iolist_to_binary/1; opt_type(c2s_ciphers) -> fun iolist_to_binary/1; opt_type(c2s_dhfile) -> fun iolist_to_binary/1; @@ -945,6 +916,39 @@ opt_type(disable_sasl_mechanisms) -> (V) -> [str:to_upper(V)] end; opt_type(_) -> - [domain_certfile, c2s_certfile, c2s_ciphers, c2s_cafile, + [c2s_certfile, c2s_ciphers, c2s_cafile, c2s_protocol_options, c2s_tls_compression, resource_conflict, disable_sasl_mechanisms]. + +listen_opt_type(access) -> fun acl:access_rules_validator/1; +listen_opt_type(shaper) -> fun acl:shaper_rules_validator/1; +listen_opt_type(certfile) -> opt_type(c2s_certfile); +listen_opt_type(ciphers) -> opt_type(c2s_ciphers); +listen_opt_type(dhfile) -> opt_type(c2s_dhfile); +listen_opt_type(cafile) -> opt_type(c2s_cafile); +listen_opt_type(protocol_options) -> opt_type(c2s_protocol_options); +listen_opt_type(tls_compression) -> opt_type(c2s_tls_compression); +listen_opt_type(tls) -> fun(B) when is_boolean(B) -> B end; +listen_opt_type(starttls) -> fun(B) when is_boolean(B) -> B end; +listen_opt_type(starttls_required) -> fun(B) when is_boolean(B) -> B end; +listen_opt_type(tls_verify) -> fun(B) when is_boolean(B) -> B end; +listen_opt_type(zlib) -> fun(B) when is_boolean(B) -> B end; +listen_opt_type(supervisor) -> fun(B) when is_boolean(B) -> B end; +listen_opt_type(max_stanza_size) -> + fun(I) when is_integer(I) -> I; + (unlimited) -> infinity; + (infinity) -> infinity + end; +listen_opt_type(max_fsm_queue) -> + fun(I) when is_integer(I), I>0 -> I end; +listen_opt_type(O) -> + %% This hack should be removed in future releases: it is intended + %% for backward compatibility with ejabberd 17.01 or older + case mod_stream_mgmt:mod_opt_type(O) of + L when is_list(L) -> + [access, shaper, certfile, ciphers, dhfile, cafile, + protocol_options, tls, tls_compression, starttls, + starttls_required, tls_verify, zlib, max_fsm_queue] ++ L; + VFun -> + VFun + end. diff --git a/src/ejabberd_c2s_config.erl b/src/ejabberd_c2s_config.erl index 5db740777..b94bbdc52 100644 --- a/src/ejabberd_c2s_config.erl +++ b/src/ejabberd_c2s_config.erl @@ -26,24 +26,20 @@ -module(ejabberd_c2s_config). --behaviour(ejabberd_config). - -author('mremond@process-one.net'). --export([get_c2s_limits/0, opt_type/1]). +-export([get_c2s_limits/0]). %% Get first c2s configuration limitations to apply it to other c2s %% connectors. get_c2s_limits() -> - case ejabberd_config:get_option(listen, fun(V) -> V end) of - undefined -> []; - C2SFirstListen -> - case lists:keysearch(ejabberd_c2s, 2, C2SFirstListen) of - false -> []; - {value, {_Port, ejabberd_c2s, Opts}} -> - select_opts_values(Opts) - end + C2SFirstListen = ejabberd_config:get_option(listen, []), + case lists:keysearch(ejabberd_c2s, 2, C2SFirstListen) of + false -> []; + {value, {_Port, ejabberd_c2s, Opts}} -> + select_opts_values(Opts) end. + %% Only get access, shaper and max_stanza_size values select_opts_values(Opts) -> @@ -65,6 +61,3 @@ select_opts_values([{max_stanza_size, Value} | Opts], [{max_stanza_size, Value} | SelectedValues]); select_opts_values([_Opt | Opts], SelectedValues) -> select_opts_values(Opts, SelectedValues). - -opt_type(listen) -> fun (V) -> V end; -opt_type(_) -> [listen]. diff --git a/src/ejabberd_captcha.erl b/src/ejabberd_captcha.erl index 0a1e1a9eb..0a8dc0261 100644 --- a/src/ejabberd_captcha.erl +++ b/src/ejabberd_captcha.erl @@ -350,12 +350,7 @@ do_create_image(Key) -> end. get_prog_name() -> - case ejabberd_config:get_option( - captcha_cmd, - fun(FileName) -> - F = iolist_to_binary(FileName), - if F /= <<"">> -> F end - end) of + case ejabberd_config:get_option(captcha_cmd) of undefined -> ?DEBUG("The option captcha_cmd is not configured, " "but some module wants to use the CAPTCHA " @@ -367,10 +362,7 @@ get_prog_name() -> end. get_url(Str) -> - CaptchaHost = ejabberd_config:get_option( - captcha_host, - fun iolist_to_binary/1, - <<"">>), + CaptchaHost = ejabberd_config:get_option(captcha_host, <<"">>), case str:tokens(CaptchaHost, <<":">>) of [Host] -> <<"http://", Host/binary, "/captcha/", Str/binary>>; @@ -395,7 +387,7 @@ get_transfer_protocol(PortString) -> get_captcha_transfer_protocol(PortListeners). get_port_listeners(PortNumber) -> - AllListeners = ejabberd_config:get_option(listen, fun(V) -> V end), + AllListeners = ejabberd_config:get_option(listen, []), lists:filter(fun (Listener) when is_list(Listener) -> case proplists:get_value(port, Listener) of PortNumber -> true; @@ -425,9 +417,7 @@ get_captcha_transfer_protocol([_ | Listeners]) -> is_limited(undefined) -> false; is_limited(Limiter) -> - case ejabberd_config:get_option( - captcha_limit, - fun(I) when is_integer(I), I > 0 -> I end) of + case ejabberd_config:get_option(captcha_limit) of undefined -> false; Int -> case catch gen_server:call(?MODULE, @@ -545,6 +535,5 @@ opt_type(captcha_cmd) -> opt_type(captcha_host) -> fun iolist_to_binary/1; opt_type(captcha_limit) -> fun (I) when is_integer(I), I > 0 -> I end; -opt_type(listen) -> fun (V) -> V end; opt_type(_) -> - [captcha_cmd, captcha_host, captcha_limit, listen]. + [captcha_cmd, captcha_host, captcha_limit]. diff --git a/src/ejabberd_commands.erl b/src/ejabberd_commands.erl index df0ce9123..c8822032c 100644 --- a/src/ejabberd_commands.erl +++ b/src/ejabberd_commands.erl @@ -211,6 +211,7 @@ -author('badlop@process-one.net'). -behaviour(gen_server). +-behaviour(ejabberd_config). -define(DEFAULT_VERSION, 1000000). @@ -613,12 +614,12 @@ execute_check_access(undefined, _Command, _Arguments) -> execute_check_access(FromJID, #ejabberd_commands{access = AccessRefs} = Command, Arguments) -> %% TODO Review: Do we have smarter / better way to check rule on other Host than global ? Host = global, - Rules = lists:map(fun({Mod, AccessName, Default}) -> - gen_mod:get_module_opt(Host, Mod, - AccessName, fun(A) -> A end, Default); - (Default) -> - Default - end, AccessRefs), + Rules = lists:map( + fun({Mod, AccessName, Default}) -> + gen_mod:get_module_opt(Host, Mod, AccessName, Default); + (Default) -> + Default + end, AccessRefs), case acl:any_rules_allowed(Host, Rules, FromJID) of true -> do_execute_command(Command, Arguments); @@ -822,10 +823,7 @@ get_access_commands(AccessCommands, _Version) -> get_exposed_commands() -> get_exposed_commands(?DEFAULT_VERSION). get_exposed_commands(Version) -> - Opts0 = ejabberd_config:get_option( - commands, - fun(V) when is_list(V) -> V end, - []), + Opts0 = ejabberd_config:get_option(commands, []), Opts = lists:map(fun(V) when is_tuple(V) -> [V]; (V) -> V end, Opts0), CommandsList = list_commands_policy(Version), OpenCmds = [N || {N, _, _, open} <- CommandsList], @@ -876,10 +874,7 @@ is_admin(Name, Auth, Extra) -> _ -> {Extra, global} end, - AdminAccess = ejabberd_config:get_option( - commands_admin_access, - fun(V) -> V end, - none), + AdminAccess = ejabberd_config:get_option(commands_admin_access, none), case acl:access_matches(AdminAccess, ACLInfo, Server) of allow -> case catch check_auth(get_command_definition(Name), Auth) of @@ -893,9 +888,7 @@ is_admin(Name, Auth, Extra) -> permission_addon() -> [{<<"'commands' option compatibility shim">>, {[], - [{access, ejabberd_config:get_option(commands_admin_access, - fun(V) -> V end, - none)}], + [{access, ejabberd_config:get_option(commands_admin_access, none)}], {get_exposed_commands(), []}}}]. opt_type(commands_admin_access) -> fun acl:access_rules_validator/1; diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl index 139549413..1ad76caf7 100644 --- a/src/ejabberd_config.erl +++ b/src/ejabberd_config.erl @@ -27,9 +27,9 @@ -author('alexey@process-one.net'). -export([start/0, load_file/1, reload_file/0, read_file/1, - get_option/2, get_option/3, add_option/2, has_option/1, + get_option/1, get_option/2, add_option/2, has_option/1, get_vh_by_auth_method/1, is_file_readable/1, - get_version/0, get_myhosts/0, get_mylang/0, + get_version/0, get_myhosts/0, get_mylang/0, get_lang/1, get_ejabberd_config_path/0, is_using_elixir_config/0, prepare_opt_val/4, transform_options/1, collect_options/1, convert_to_yaml/1, convert_to_yaml/2, v_db/2, @@ -37,24 +37,26 @@ is_elixir_enabled/0, v_dbs/1, v_dbs_mods/1, default_db/1, default_db/2, default_ram_db/1, default_ram_db/2, default_queue_type/1, queue_dir/0, fsm_limit_opts/1, - use_cache/1, cache_size/1, cache_missed/1, cache_life_time/1, - dump/0]). + use_cache/1, cache_size/1, cache_missed/1, cache_life_time/1]). -export([start/2]). %% The following functions are deprecated. -export([add_global_option/2, add_local_option/2, get_global_option/2, get_local_option/2, - get_global_option/3, get_local_option/3]). + get_global_option/3, get_local_option/3, + get_option/3]). -deprecated([{add_global_option, 2}, {add_local_option, 2}, {get_global_option, 2}, {get_local_option, 2}, - {get_global_option, 3}, {get_local_option, 3}]). + {get_global_option, 3}, {get_local_option, 3}, + {get_option, 3}]). -include("ejabberd.hrl"). -include("logger.hrl"). -include("ejabberd_config.hrl"). -include_lib("kernel/include/file.hrl"). +-include_lib("stdlib/include/ms_transform.hrl"). -callback opt_type(atom()) -> function() | [atom()]. @@ -68,7 +70,8 @@ start() -> ConfigFile = get_ejabberd_config_path(), ?INFO_MSG("Loading configuration from ~s", [ConfigFile]), - mnesia_init(), + p1_options:start_link(ejabberd_options), + p1_options:start_link(ejabberd_db_modules), State1 = load_file(ConfigFile), UnixTime = p1_time_compat:system_time(seconds), SharedKey = case erlang:get_cookie() of @@ -101,22 +104,11 @@ hosts_to_start(State) -> %% At the moment, these functions are mainly used to setup unit tests. -spec start(Hosts :: [binary()], Opts :: [acl:acl() | local_config()]) -> ok. start(Hosts, Opts) -> - mnesia_init(), + p1_options:start_link(ejabberd_options), + p1_options:start_link(ejabberd_db_modules), set_opts(set_hosts_in_options(Hosts, #state{opts = Opts})), ok. -mnesia_init() -> - case catch mnesia:table_info(local_config, storage_type) of - disc_copies -> - mnesia:delete_table(local_config); - _ -> - ok - end, - ejabberd_mnesia:create(?MODULE, local_config, - [{ram_copies, [node()]}, - {local_content, true}, - {attributes, record_info(fields, local_config)}]). - %% @doc Get the filename of the ejabberd configuration file. %% The filename can be specified with: erl -config "/path/to/ejabberd.yml". %% It can also be specified with the environtment variable EJABBERD_CONFIG_PATH. @@ -762,36 +754,21 @@ append_option({Opt, Host}, Val, State) -> set_opts(State) -> Opts = State#state.opts, - F = fun() -> - lists:foreach( - fun({node_start, _}) -> ok; - ({shared_key, _}) -> ok; - (Key) -> mnesia:delete({local_config, Key}) - end, mnesia:all_keys(local_config)), - lists:foreach(fun mnesia:write/1, Opts) - end, - case mnesia:transaction(F) of - {atomic, _} -> - recompile_options(), - set_log_level(); - {aborted,{no_exists,Table}} -> - MnesiaDirectory = mnesia:system_info(directory), - ?CRITICAL_MSG("Error reading Mnesia database spool files:~n" - "The Mnesia database couldn't read the spool file for the table '~p'.~n" - "ejabberd needs read and write access in the directory:~n ~s~n" - "Maybe the problem is a change in the computer hostname,~n" - "or a change in the Erlang node name, which is currently:~n ~p~n" - "Check the ejabberd guide for details about changing the~n" - "computer hostname or Erlang node name.~n", - [Table, MnesiaDirectory, node()]), - exit("Error reading Mnesia database") - end. + ets:select_delete(ejabberd_options, + ets:fun2ms( + fun({{node_start, _}, _}) -> false; + ({{shared_key, _}, _}) -> false; + (_) -> true + end)), + lists:foreach( + fun(#local_config{key = {Opt, Host}, value = Val}) -> + p1_options:insert(ejabberd_options, Opt, Host, Val) + end, Opts), + p1_options:compile(ejabberd_options), + set_log_level(). set_log_level() -> - Level = get_option( - loglevel, - fun(P) when P>=0, P=<5 -> P end, - 4), + Level = get_option(loglevel, 4), ejabberd_logger:set(Level). add_global_option(Opt, Val) -> @@ -802,12 +779,9 @@ add_local_option(Opt, Val) -> add_option(Opt, Val) when is_atom(Opt) -> add_option({Opt, global}, Val); -add_option(Opt, Val) -> - mnesia:transaction(fun() -> - mnesia:write(#local_config{key = Opt, - value = Val}) - end), - recompile_options(). +add_option({Opt, Host}, Val) -> + p1_options:insert(ejabberd_options, Opt, Host, Val), + p1_options:compile(ejabberd_options). -spec prepare_opt_val(any(), any(), check_fun(), any()) -> any(). @@ -844,34 +818,38 @@ prepare_opt_val(Opt, Val, F, Default) -> -spec get_global_option(any(), check_fun()) -> any(). -get_global_option(Opt, F) -> - get_option(Opt, F, undefined). +get_global_option(Opt, _) -> + get_option(Opt, undefined). -spec get_global_option(any(), check_fun(), any()) -> any(). -get_global_option(Opt, F, Default) -> - get_option(Opt, F, Default). +get_global_option(Opt, _, Default) -> + get_option(Opt, Default). -spec get_local_option(any(), check_fun()) -> any(). -get_local_option(Opt, F) -> - get_option(Opt, F, undefined). +get_local_option(Opt, _) -> + get_option(Opt, undefined). -spec get_local_option(any(), check_fun(), any()) -> any(). -get_local_option(Opt, F, Default) -> - get_option(Opt, F, Default). +get_local_option(Opt, _, Default) -> + get_option(Opt, Default). --spec get_option(any(), check_fun()) -> any(). - -get_option(Opt, F) -> - get_option(Opt, F, undefined). +-spec get_option(any()) -> any(). +get_option(Opt) -> + get_option(Opt, undefined). -spec get_option(any(), check_fun(), any()) -> any(). - -get_option(Opt, F, Default) when is_atom(Opt) -> - get_option({Opt, global}, F, Default); -get_option(Opt, F, Default) -> +get_option(Opt, _, Default) -> + get_option(Opt, Default). + +-spec get_option(any(), check_fun() | any()) -> any(). +get_option(Opt, F) when is_function(F) -> + get_option(Opt, undefined); +get_option(Opt, Default) when is_atom(Opt) -> + get_option({Opt, global}, Default); +get_option(Opt, Default) -> {Key, Host} = case Opt of {O, global} when is_atom(O) -> Opt; {O, H} when is_atom(O), is_binary(H) -> Opt; @@ -882,10 +860,9 @@ get_option(Opt, F, Default) -> end, case ejabberd_options:is_known(Key) of true -> - try ejabberd_options:Key(Host) of - Val -> prepare_opt_val(Opt, Val, F, Default) - catch _:function_clause -> - Default + case ejabberd_options:Key(Host) of + {ok, Val} -> Val; + undefined -> Default end; false -> Default @@ -893,49 +870,74 @@ get_option(Opt, F, Default) -> -spec has_option(atom() | {atom(), global | binary()}) -> any(). has_option(Opt) -> - get_option(Opt, fun(_) -> true end, false). + get_option(Opt) /= undefined. init_module_db_table(Modules) -> - catch ets:new(module_db, [named_table, public, bag, - {read_concurrency, true}]), %% Dirty hack for mod_pubsub - ets:insert(module_db, {mod_pubsub, mnesia}), - ets:insert(module_db, {mod_pubsub, sql}), + p1_options:insert(ejabberd_db_modules, mod_pubsub, mnesia, true), + p1_options:insert(ejabberd_db_modules, mod_pubsub, sql, true), lists:foreach( fun(M) -> case re:split(atom_to_list(M), "_", [{return, list}]) of [_] -> ok; Parts -> - [Suffix|T] = lists:reverse(Parts), - BareMod = string:join(lists:reverse(T), "_"), - ets:insert(module_db, {list_to_atom(BareMod), - list_to_atom(Suffix)}) + [H|T] = lists:reverse(Parts), + Suffix = list_to_atom(H), + BareMod = list_to_atom(string:join(lists:reverse(T), "_")), + case is_behaviour(BareMod, M) of + true -> + p1_options:insert(ejabberd_db_modules, + BareMod, Suffix, true); + false -> + ok + end end - end, Modules). + end, Modules), + p1_options:compile(ejabberd_db_modules). + +is_behaviour(Behav, Mod) -> + try Mod:module_info(attributes) of + [] -> + %% Stripped module? + true; + Attrs -> + lists:any( + fun({behaviour, L}) -> lists:member(Behav, L); + ({behavior, L}) -> lists:member(Behav, L); + (_) -> false + end, Attrs) + catch _:_ -> + true + end. -spec v_db(module(), atom()) -> atom(). v_db(Mod, internal) -> v_db(Mod, mnesia); v_db(Mod, odbc) -> v_db(Mod, sql); v_db(Mod, Type) -> - case ets:match_object(module_db, {Mod, Type}) of - [_|_] -> Type; - [] -> erlang:error(badarg) + case ejabberd_db_modules:is_known(Mod) of + true -> + case ejabberd_db_modules:Mod(Type) of + {ok, _} -> Type; + _ -> erlang:error(badarg) + end; + false -> + erlang:error(badarg) end. -spec v_dbs(module()) -> [atom()]. v_dbs(Mod) -> - lists:flatten(ets:match(module_db, {Mod, '$1'})). + ejabberd_db_modules:get_scope(Mod). -spec v_dbs_mods(module()) -> [module()]. v_dbs_mods(Mod) -> - lists:map(fun([M]) -> + lists:map(fun(M) -> binary_to_atom(<<(atom_to_binary(Mod, utf8))/binary, "_", (atom_to_binary(M, utf8))/binary>>, utf8) - end, ets:match(module_db, {Mod, '$1'})). + end, v_dbs(Mod)). -spec default_db(module()) -> atom(). default_db(Module) -> @@ -955,7 +957,7 @@ default_ram_db(Host, Module) -> -spec default_db(default_db | default_ram_db, binary() | global, module()) -> atom(). default_db(Opt, Host, Module) -> - case get_option({Opt, Host}, fun(T) when is_atom(T) -> T end) of + case get_option({Opt, Host}) of undefined -> mnesia; DBType -> @@ -976,13 +978,18 @@ get_modules_with_options() -> init_module_db_table(AllMods), lists:foldl( fun(Mod, D) -> - case catch Mod:opt_type('') of - Opts when is_list(Opts) -> - lists:foldl( - fun(Opt, Acc) -> - dict:append(Opt, Mod, Acc) - end, D, Opts); - {'EXIT', {undef, _}} -> + case is_behaviour(?MODULE, Mod) orelse Mod == ?MODULE of + true -> + try Mod:opt_type('') of + Opts when is_list(Opts) -> + lists:foldl( + fun(Opt, Acc) -> + dict:append(Opt, Mod, Acc) + end, D, Opts) + catch _:undef -> + D + end; + false -> D end end, dict:new(), AllMods). @@ -995,11 +1002,9 @@ validate_opts(#state{opts = Opts} = State) -> {ok, [Mod|_]} -> VFun = Mod:opt_type(Opt), try VFun(Val) of - _ -> - true - catch {replace_with, NewVal} -> - {true, In#local_config{value = NewVal}}; - {invalid_syntax, Error} -> + NewVal -> + {true, In#local_config{value = NewVal}} + catch {invalid_syntax, Error} -> ?ERROR_MSG("ignoring option '~s' with " "invalid value: ~p: ~s", [Opt, Val, Error]), @@ -1022,23 +1027,21 @@ validate_opts(#state{opts = Opts} = State) -> %% Return the list of hosts with a given auth method get_vh_by_auth_method(AuthMethod) -> - Cfgs = mnesia:dirty_match_object(local_config, - #local_config{key = {auth_method, '_'}, - _ = '_'}), - lists:flatmap( - fun(#local_config{key = {auth_method, Host}, value = M}) -> - Methods = if not is_list(M) -> [M]; - true -> M - end, - case lists:member(AuthMethod, Methods) of - true when Host == global -> - get_myhosts(); - true -> - [Host]; - false -> - [] - end - end, Cfgs). + Hosts = ejabberd_options:get_scope(auth_method), + get_vh_by_auth_method(AuthMethod, Hosts, []). + +get_vh_by_auth_method(Method, [Host|Hosts], Result) -> + Methods = get_option({auth_method, Host}, []), + case lists:member(Method, Methods) of + true when Host == global -> + get_myhosts(); + true -> + get_vh_by_auth_method(Method, Hosts, [Host|Result]); + false -> + get_vh_by_auth_method(Method, Hosts, Result) + end; +get_vh_by_auth_method(_, [], Result) -> + Result. %% @spec (Path::string()) -> true | false is_file_readable(Path) -> @@ -1062,15 +1065,16 @@ get_version() -> -spec get_myhosts() -> [binary()]. get_myhosts() -> - get_option(hosts, fun(V) -> V end). + get_option(hosts). -spec get_mylang() -> binary(). get_mylang() -> - get_option( - language, - fun iolist_to_binary/1, - <<"en">>). + get_lang(global). + +-spec get_lang(global | binary()) -> binary(). +get_lang(Host) -> + get_option({language, Host}, <<"en">>). replace_module(mod_announce_odbc) -> {mod_announce, sql}; replace_module(mod_blocking_odbc) -> {mod_blocking, sql}; @@ -1206,7 +1210,6 @@ transform_terms(Terms) -> %% We could check all ejabberd beams, but this %% slows down start-up procedure :( Mods = [mod_register, - mod_last, ejabberd_s2s, ejabberd_listener, ejabberd_sql_sup, @@ -1315,6 +1318,10 @@ transform_options(Opt, Opts) when Opt == override_global; Opt == override_acls -> ?WARNING_MSG("Ignoring '~s' option which has no effect anymore", [Opt]), Opts; +transform_options({node_start, {_, _, _} = Now}, Opts) -> + ?WARNING_MSG("Old 'node_start' format detected. This is still supported " + "but it is better to fix your config.", []), + [{node_start, now_to_seconds(Now)}|Opts]; transform_options({host_config, Host, HOpts}, Opts) -> {AddOpts, HOpts1} = lists:mapfoldl( @@ -1351,14 +1358,15 @@ emit_deprecation_warning(Module, NewModule) -> [Module, NewModule]) end. +-spec now_to_seconds(erlang:timestamp()) -> non_neg_integer(). +now_to_seconds({MegaSecs, Secs, _MicroSecs}) -> + MegaSecs * 1000000 + Secs. + opt_type(hide_sensitive_log_data) -> fun (H) when is_boolean(H) -> H end; opt_type(hosts) -> - fun(L) when is_list(L) -> - lists:map( - fun(H) -> - iolist_to_binary(H) - end, L) + fun(L) -> + [iolist_to_binary(H) || H <- L] end; opt_type(language) -> fun iolist_to_binary/1; @@ -1388,19 +1396,21 @@ opt_type(cache_life_time) -> (infinity) -> infinity; (unlimited) -> infinity end; +opt_type(domain_certfile) -> + fun iolist_to_binary/1; +opt_type(shared_key) -> + fun iolist_to_binary/1; +opt_type(node_start) -> + fun(I) when is_integer(I), I>=0 -> I end; opt_type(_) -> [hide_sensitive_log_data, hosts, language, max_fsm_queue, default_db, default_ram_db, queue_type, queue_dir, loglevel, - use_cache, cache_size, cache_missed, cache_life_time]. + use_cache, cache_size, cache_missed, cache_life_time, + domain_certfile, shared_key, node_start]. -spec may_hide_data(any()) -> any(). may_hide_data(Data) -> - case get_option( - hide_sensitive_log_data, - fun(false) -> false; - (true) -> true - end, - false) of + case get_option(hide_sensitive_log_data, false) of false -> Data; true -> @@ -1413,9 +1423,7 @@ fsm_limit_opts(Opts) -> {_, I} when is_integer(I), I>0 -> [{max_queue, I}]; false -> - case get_option( - max_fsm_queue, - fun(I) when is_integer(I), I>0 -> I end) of + case get_option(max_fsm_queue) of undefined -> []; N -> [{max_queue, N}] end @@ -1423,86 +1431,25 @@ fsm_limit_opts(Opts) -> -spec queue_dir() -> binary() | undefined. queue_dir() -> - get_option(queue_dir, opt_type(queue_dir)). + get_option(queue_dir). -spec default_queue_type(binary()) -> ram | file. default_queue_type(Host) -> - get_option({queue_type, Host}, opt_type(queue_type), ram). + get_option({queue_type, Host}, ram). -spec use_cache(binary() | global) -> boolean(). use_cache(Host) -> - get_option({use_cache, Host}, opt_type(use_cache), true). + get_option({use_cache, Host}, true). -spec cache_size(binary() | global) -> pos_integer() | infinity. cache_size(Host) -> - get_option({cache_size, Host}, opt_type(cache_size), 1000). + get_option({cache_size, Host}, 1000). -spec cache_missed(binary() | global) -> boolean(). cache_missed(Host) -> - get_option({cache_missed, Host}, opt_type(cache_missed), true). + get_option({cache_missed, Host}, true). -spec cache_life_time(binary() | global) -> pos_integer() | infinity. %% NOTE: the integer value returned is in *seconds* cache_life_time(Host) -> - get_option({cache_life_time, Host}, opt_type(cache_life_time), 3600). - -%%%=================================================================== -%%% Dynamic config compilation -%%%=================================================================== --spec recompile_options() -> ok. -recompile_options() -> - Exprs = get_exprs(), - case misc:compile_exprs(ejabberd_options, Exprs) of - ok -> ok; - {error, _} = Err -> - ?CRITICAL_MSG("Failed to compile ejabberd_options:~n~s", - [string:join(Exprs, io_lib:nl())]), - erlang:error(Err) - end. - --spec get_exprs() -> [string()]. -get_exprs() -> - Opts = lists:foldl( - fun(#local_config{key = {Opt, Host}, value = Val}, D) -> - Hosts = maps:get(Opt, D, #{}), - maps:put(Opt, maps:put(Host, Val, Hosts), D) - end, #{}, ets:tab2list(local_config)), - Funs = maps:fold( - fun(Opt, Vals, Acc) -> - HostVals = lists:reverse(lists:keysort(1, maps:to_list(Vals))), - [string:join( - lists:map( - fun({global, Val}) -> - io_lib:format("'~s'(_) -> ~p", [Opt, Val]); - ({Host, Val}) -> - io_lib:format("'~s'(~p) -> ~p", [Opt, Host, Val]) - end, HostVals), - ";" ++ io_lib:nl()) ++ "."|Acc] - end, [], Opts), - Module = "-module(ejabberd_options).", - Export = "-compile(export_all).", - Knowns = maps:fold( - fun(Opt, _, Acc) -> - io_lib:format("is_known('~s') -> true;~n", [Opt]) ++ Acc - end, "", Opts) ++ "is_known(_) -> false.", - [Module, Export, Knowns|Funs]. - -%% @doc This is only for debugging purposes, likely to report a bug --spec dump() -> ok. -dump() -> - ETSFile = filename:join("/tmp", "ejabberd_options.ets"), - ErlFile = filename:join("/tmp", "ejabberd_options.erl"), - ETSData = io_lib:format("~p~n", [ets:tab2list(local_config)]), - ErlData = io_lib:format("~s~n", [str:join(get_exprs(), io_lib:nl())]), - case file:write_file(ETSFile, ETSData) of - ok -> io:format("ETS data written to ~s~n", [ETSFile]); - {error, Reason1} -> - io:format("Failed to write to ~s: ~s", - [ETSFile, file:format_error(Reason1)]) - end, - case file:write_file(ErlFile, ErlData) of - ok -> io:format("Dynamic module written to ~s~n", [ErlFile]); - {error, Reason2} -> - io:format("Failed to write to ~s: ~s", - [ErlFile, file:format_error(Reason2)]) - end. + get_option({cache_life_time, Host}, 3600). diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl index f006ad5c1..a9643386d 100644 --- a/src/ejabberd_ctl.erl +++ b/src/ejabberd_ctl.erl @@ -289,8 +289,7 @@ process2(Args, AccessCommands, Auth, Version) -> end. get_accesscommands() -> - ejabberd_config:get_option(ejabberdctl_access_commands, - fun(V) when is_list(V) -> V end, []). + ejabberd_config:get_option(ejabberdctl_access_commands, []). %%----------------------------- %% Command calling diff --git a/src/ejabberd_db_modules.erl b/src/ejabberd_db_modules.erl new file mode 100644 index 000000000..2a92f3ae0 --- /dev/null +++ b/src/ejabberd_db_modules.erl @@ -0,0 +1,44 @@ +%%%------------------------------------------------------------------- +%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net> +%%% @doc +%%% This is a stub module which will be replaced during +%%% configuration load via p1_options:compile/1 +%%% The only purpose of this file is to shut up xref/dialyzer +%%% @end +%%% Created : 27 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net> +%%% +%%% +%%% ejabberd, Copyright (C) 2002-2017 ProcessOne +%%% +%%% This program is free software; you can redistribute it and/or +%%% modify it under the terms of the GNU General Public License as +%%% published by the Free Software Foundation; either version 2 of the +%%% License, or (at your option) any later version. +%%% +%%% This program is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%%% General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License along +%%% with this program; if not, write to the Free Software Foundation, Inc., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +%%% +%%%------------------------------------------------------------------- +-module(ejabberd_db_modules). + +%% API +-export([is_known/1, get_scope/1]). + +%%%=================================================================== +%%% API +%%%=================================================================== +is_known(_) -> + false. + +get_scope(_) -> + []. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== diff --git a/src/ejabberd_http.erl b/src/ejabberd_http.erl index 5c591386d..b706215a9 100644 --- a/src/ejabberd_http.erl +++ b/src/ejabberd_http.erl @@ -32,7 +32,7 @@ %% External exports -export([start/2, start_link/2, become_controller/1, socket_type/0, receive_headers/1, url_encode/1, - transform_listen_option/2]). + transform_listen_option/2, listen_opt_type/1]). -export([init/2, opt_type/1]). @@ -100,23 +100,15 @@ init({SockMod, Socket}, Opts) -> TLSOpts1 = lists:filter(fun ({certfile, _}) -> true; ({ciphers, _}) -> true; ({dhfile, _}) -> true; + ({protocol_options, _}) -> true; (_) -> false end, Opts), - TLSOpts2 = case lists:keysearch(protocol_options, 1, Opts) of - {value, {_, O}} -> - [_|ProtocolOptions] = lists:foldl( - fun(X, Acc) -> X ++ Acc end, [], - [["|" | binary_to_list(Opt)] || Opt <- O, is_binary(Opt)] - ), - [{protocol_options, iolist_to_binary(ProtocolOptions)} | TLSOpts1]; - _ -> TLSOpts1 + TLSOpts2 = case proplists:get_bool(tls_compression, Opts) of + false -> [compression_none | TLSOpts1]; + true -> TLSOpts1 end, - TLSOpts3 = case proplists:get_bool(tls_compression, Opts) of - false -> [compression_none | TLSOpts2]; - true -> TLSOpts2 - end, - TLSOpts = [verify_none | TLSOpts3], + TLSOpts = [verify_none | TLSOpts2], {SockMod1, Socket1} = if TLSEnabled -> inet:setopts(Socket, [{recbuf, 8192}]), {ok, TLSSocket} = fast_tls:tcp_to_tls(Socket, @@ -144,33 +136,15 @@ init({SockMod, Socket}, Opts) -> true -> [{[], ejabberd_xmlrpc}]; false -> [] end, - DefinedHandlers = gen_mod:get_opt( - request_handlers, Opts, - fun(Hs) -> - Hs1 = lists:map(fun - ({Mod, Path}) when is_atom(Mod) -> {Path, Mod}; - ({Path, Mod}) -> {Path, Mod} - end, Hs), - - Hs2 = [{str:tokens( - iolist_to_binary(Path), <<"/">>), - Mod} || {Path, Mod} <- Hs1], - [{Path, - case Mod of - mod_http_bind -> mod_bosh; - _ -> Mod - end} || {Path, Mod} <- Hs2] - end, []), + DefinedHandlers = gen_mod:get_opt(request_handlers, Opts, []), RequestHandlers = DefinedHandlers ++ Captcha ++ Register ++ Admin ++ Bind ++ XMLRPC, ?DEBUG("S: ~p~n", [RequestHandlers]), - DefaultHost = gen_mod:get_opt(default_host, Opts, fun(A) -> A end, undefined), + DefaultHost = gen_mod:get_opt(default_host, Opts, undefined), {ok, RE} = re:compile(<<"^(?:\\[(.*?)\\]|(.*?))(?::(\\d+))?$">>), - CustomHeaders = gen_mod:get_opt(custom_headers, Opts, - fun expand_custom_headers/1, - []), + CustomHeaders = gen_mod:get_opt(custom_headers, Opts, []), ?INFO_MSG("started: ~p", [{SockMod1, Socket1}]), State = #state{sockmod = SockMod1, @@ -521,12 +495,7 @@ analyze_ip_xff(IP, [], _Host) -> IP; analyze_ip_xff({IPLast, Port}, XFF, Host) -> [ClientIP | ProxiesIPs] = str:tokens(XFF, <<", ">>) ++ [misc:ip_to_list(IPLast)], - TrustedProxies = ejabberd_config:get_option( - {trusted_proxies, Host}, - fun(all) -> all; - (TPs) -> - [iolist_to_binary(TP) || TP <- TPs] - end, []), + TrustedProxies = ejabberd_config:get_option({trusted_proxies, Host}, []), IPClient = case is_ipchain_trusted(ProxiesIPs, TrustedProxies) of @@ -934,3 +903,48 @@ opt_type(trusted_proxies) -> fun (all) -> all; (TPs) -> [iolist_to_binary(TP) || TP <- TPs] end; opt_type(_) -> [trusted_proxies]. + +listen_opt_type(tls) -> + fun(B) when is_boolean(B) -> B end; +listen_opt_type(certfile) -> + fun iolist_to_binary/1; +listen_opt_type(ciphers) -> + fun iolist_to_binary/1; +listen_opt_type(dhfile) -> + fun iolist_to_binary/1; +listen_opt_type(protocol_options) -> + fun(Options) -> str:join(Options, <<"|">>) end; +listen_opt_type(tls_compression) -> + fun(B) when is_boolean(B) -> B end; +listen_opt_type(captcha) -> + fun(B) when is_boolean(B) -> B end; +listen_opt_type(register) -> + fun(B) when is_boolean(B) -> B end; +listen_opt_type(web_admin) -> + fun(B) when is_boolean(B) -> B end; +listen_opt_type(http_bind) -> + fun(B) when is_boolean(B) -> B end; +listen_opt_type(xmlrpc) -> + fun(B) when is_boolean(B) -> B end; +listen_opt_type(request_handlers) -> + fun(Hs) -> + Hs1 = lists:map(fun + ({Mod, Path}) when is_atom(Mod) -> {Path, Mod}; + ({Path, Mod}) -> {Path, Mod} + end, Hs), + Hs2 = [{str:tokens( + iolist_to_binary(Path), <<"/">>), + Mod} || {Path, Mod} <- Hs1], + [{Path, + case Mod of + mod_http_bind -> mod_bosh; + _ -> Mod + end} || {Path, Mod} <- Hs2] + end; +listen_opt_type(default_host) -> + fun(A) -> A end; +listen_opt_type(custom_headers) -> + fun expand_custom_headers/1; +listen_opt_type(_) -> + %% TODO + fun(A) -> A end. diff --git a/src/ejabberd_http_ws.erl b/src/ejabberd_http_ws.erl index 5231d7ab1..18ba071dd 100644 --- a/src/ejabberd_http_ws.erl +++ b/src/ejabberd_http_ws.erl @@ -123,11 +123,9 @@ init([{#ws{ip = IP, http_opts = HOpts}, _} = WS]) -> Opts = ejabberd_c2s_config:get_c2s_limits() ++ SOpts, PingInterval = ejabberd_config:get_option( {websocket_ping_interval, ?MYNAME}, - fun(I) when is_integer(I), I>=0 -> I end, ?PING_INTERVAL) * 1000, WSTimeout = ejabberd_config:get_option( {websocket_timeout, ?MYNAME}, - fun(I) when is_integer(I), I>0 -> I end, ?WEBSOCKET_TIMEOUT) * 1000, Socket = {http_ws, self(), IP}, ?DEBUG("Client connected through websocket ~p", diff --git a/src/ejabberd_listener.erl b/src/ejabberd_listener.erl index 7d3c53574..653ad931a 100644 --- a/src/ejabberd_listener.erl +++ b/src/ejabberd_listener.erl @@ -49,24 +49,19 @@ init(_) -> {ok, {{one_for_one, 10, 1}, listeners_childspec()}}. listeners_childspec() -> - case ejabberd_config:get_option(listen, fun validate_cfg/1) of - undefined -> - []; - Ls -> - Specs = lists:map( - fun({Port, Module, Opts}) -> - maybe_start_sip(Module), - ets:insert(?MODULE, {Port, Module, Opts}), - {Port, - {?MODULE, start, [Port, Module, Opts]}, - transient, - brutal_kill, - worker, - [?MODULE]} - end, Ls), - report_duplicated_portips(Ls), - Specs - end. + Ls = ejabberd_config:get_option(listen, []), + Specs = lists:map( + fun({Port, Module, Opts}) -> + ets:insert(?MODULE, {Port, Module, Opts}), + {Port, + {?MODULE, start, [Port, Module, Opts]}, + transient, + brutal_kill, + worker, + [?MODULE]} + end, Ls), + report_duplicated_portips(Ls), + Specs. start_listeners() -> lists:foreach( @@ -86,10 +81,11 @@ report_duplicated_portips(L) -> end. start(Port, Module, Opts) -> + NewOpts = validate_module_options(Module, Opts), %% Check if the module is an ejabberd listener or an independent listener case Module:socket_type() of - independent -> Module:start_listener(Port, Opts); - _ -> start_dependent(Port, Module, Opts) + independent -> Module:start_listener(Port, NewOpts); + _ -> start_dependent(Port, Module, NewOpts) end. %% @spec(Port, Module, Opts) -> {ok, Pid} | {error, ErrorMessage} @@ -360,7 +356,6 @@ start_listener2(Port, Module, Opts) -> %% It is only required to start the supervisor in some cases. %% But it doesn't hurt to attempt to start it for any listener. %% So, it's normal (and harmless) that in most cases this call returns: {error, {already_started, pid()}} - maybe_start_sip(Module), start_listener_sup(Port, Module, Opts). start_module_sup(_Port, Module) -> @@ -384,7 +379,7 @@ start_listener_sup(Port, Module, Opts) -> supervisor:start_child(?MODULE, ChildSpec). stop_listeners() -> - Ports = ejabberd_config:get_option(listen, fun validate_cfg/1), + Ports = ejabberd_config:get_option(listen, []), lists:foreach( fun({PortIpNetp, Module, _Opts}) -> delete_listener(PortIpNetp, Module) @@ -431,17 +426,8 @@ delete_listener(PortIP, Module, Opts) -> PortIP1 = {Port, IPT, Proto}, stop_listener(PortIP1, Module). - -maybe_start_sip(esip_socket) -> - ejabberd:start_app(esip); -maybe_start_sip(_) -> - ok. - config_reloaded() -> - New = case ejabberd_config:get_option(listen, fun validate_cfg/1) of - undefined -> []; - Ls -> Ls - end, + New = ejabberd_config:get_option(listen, []), Old = ets:tab2list(?MODULE), lists:foreach( fun({PortIP, Module, _Opts}) -> @@ -633,6 +619,47 @@ transform_options({listen, LOpts}, Opts) -> transform_options(Opt, Opts) -> [Opt|Opts]. +-spec validate_module_options(module(), [{atom(), any()}]) -> [{atom(), any()}]. +validate_module_options(Module, Opts) -> + try Module:listen_opt_type('') of + _ -> + lists:filtermap( + fun({Opt, Val}) -> + case validate_module_option(Module, Opt, Val) of + {ok, NewVal} -> {true, {Opt, NewVal}}; + error -> false + end + end, Opts) + catch _:undef -> + ?WARNING_MSG("module '~s' doesn't export listen_opt_type/1", + [Module]), + Opts + end. + +-spec validate_module_option(module(), atom(), any()) -> {ok, any()} | error. +validate_module_option(Module, Opt, Val) -> + case Module:listen_opt_type(Opt) of + VFun when is_function(VFun) -> + try VFun(Val) of + NewVal -> {ok, NewVal} + catch {invalid_syntax, Error} -> + ?ERROR_MSG("ignoring listen option '~s' with " + "invalid value: ~p: ~s", + [Opt, Val, Error]), + error; + _:_ -> + ?ERROR_MSG("ignoring listen option '~s' with " + "invalid value: ~p", + [Opt, Val]), + error + end; + KnownOpts when is_list(KnownOpts) -> + ?ERROR_MSG("unknown listen option '~s' for '~s' will be likely " + "ignored, available options are: ~s", + [Opt, Module, misc:join_atoms(KnownOpts, <<", ">>)]), + {ok, Val} + end. + -type transport() :: udp | tcp. -type port_ip_transport() :: inet:port_number() | {inet:port_number(), transport()} | @@ -654,7 +681,7 @@ validate_cfg(L) -> true = ?IS_TRANSPORT(T), {{Port, IP, T}, Mod, Opts}; ({module, Mod}, {Port, _, Opts}) -> - {Port, prepare_mod(Mod), Opts}; + {Port, Mod, Opts}; (Opt, {Port, Mod, Opts}) -> {Port, Mod, [Opt|Opts]} end, {{5222, all_zero_ip(LOpts), tcp}, ejabberd_c2s, []}, LOpts) @@ -673,13 +700,6 @@ prepare_ip(IP) when is_list(IP) -> prepare_ip(IP) when is_binary(IP) -> prepare_ip(binary_to_list(IP)). -prepare_mod(ejabberd_sip) -> - prepare_mod(sip); -prepare_mod(sip) -> - esip_socket; -prepare_mod(Mod) when is_atom(Mod) -> - Mod. - all_zero_ip(Opts) -> case proplists:get_bool(inet6, Opts) of true -> {0,0,0,0,0,0,0,0}; diff --git a/src/ejabberd_oauth.erl b/src/ejabberd_oauth.erl index 8527c9271..455db85a5 100644 --- a/src/ejabberd_oauth.erl +++ b/src/ejabberd_oauth.erl @@ -27,6 +27,7 @@ -module(ejabberd_oauth). -behaviour(gen_server). +-behaviour(ejabberd_config). -compile(export_all). @@ -199,7 +200,6 @@ authenticate_user({User, Server}, Ctx) -> Access = ejabberd_config:get_option( {oauth_access, JID#jid.lserver}, - fun(A) -> A end, none), case acl:match_rule(JID#jid.lserver, Access, JID) of allow -> @@ -402,22 +402,19 @@ use_cache(DBMod) -> true -> DBMod:use_cache(); false -> ejabberd_config:get_option( - oauth_use_cache, opt_type(oauth_use_cache), + oauth_use_cache, ejabberd_config:use_cache(global)) end. cache_opts() -> MaxSize = ejabberd_config:get_option( oauth_cache_size, - opt_type(oauth_cache_size), ejabberd_config:cache_size(global)), CacheMissed = ejabberd_config:get_option( oauth_cache_missed, - opt_type(oauth_cache_missed), ejabberd_config:cache_missed(global)), LifeTime = case ejabberd_config:get_option( oauth_cache_life_time, - opt_type(oauth_cache_life_time), ejabberd_config:cache_life_time(global)) of infinity -> infinity; I -> timer:seconds(I) @@ -425,10 +422,7 @@ cache_opts() -> [{max_size, MaxSize}, {life_time, LifeTime}, {cache_missed, CacheMissed}]. expire() -> - ejabberd_config:get_option( - oauth_expire, - fun(I) when is_integer(I) -> I end, - ?EXPIRE). + ejabberd_config:get_option(oauth_expire, ?EXPIRE). -define(DIV(Class, Els), ?XAE(<<"div">>, [{<<"class">>, Class}], Els)). @@ -623,9 +617,8 @@ process(_Handlers, _Request) -> get_db_backend() -> DBType = ejabberd_config:get_option( - oauth_db_type, - fun(T) -> ejabberd_config:v_db(?MODULE, T) end, - mnesia), + oauth_db_type, + ejabberd_config:default_db(?MODULE)), list_to_atom("ejabberd_oauth_" ++ atom_to_list(DBType)). diff --git a/src/ejabberd_oauth_rest.erl b/src/ejabberd_oauth_rest.erl index 15e118a0b..6c5b30523 100644 --- a/src/ejabberd_oauth_rest.erl +++ b/src/ejabberd_oauth_rest.erl @@ -26,6 +26,8 @@ -module(ejabberd_oauth_rest). +-behaviour(ejabberd_config). + -export([init/0, store/1, lookup/1, @@ -87,9 +89,7 @@ clean(_TS) -> ok. path(Path) -> - Base = ejabberd_config:get_option(ext_api_path_oauth, - fun(X) -> iolist_to_binary(X) end, - <<"/oauth">>), + Base = ejabberd_config:get_option(ext_api_path_oauth, <<"/oauth">>), <<Base/binary, "/", Path/binary>>. diff --git a/src/ejabberd_options.erl b/src/ejabberd_options.erl index bcde437eb..228b891c3 100644 --- a/src/ejabberd_options.erl +++ b/src/ejabberd_options.erl @@ -2,7 +2,7 @@ %%% @author Evgeny Khramtsov <ekhramtsov@process-one.net> %%% @doc %%% This is a stub module which will be replaced during -%%% configuration load, see ejabberd_config:recompile_options/0. +%%% configuration load via p1_options:compile/1 %%% The only purpose of this file is to shut up xref/dialyzer %%% @end %%% Created : 16 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net> @@ -28,7 +28,7 @@ -module(ejabberd_options). %% API --export([is_known/1]). +-export([is_known/1, get_scope/1]). %%%=================================================================== %%% API @@ -36,6 +36,9 @@ is_known(_) -> false. +get_scope(_) -> + []. + %%%=================================================================== %%% Internal functions %%%=================================================================== diff --git a/src/ejabberd_piefxis.erl b/src/ejabberd_piefxis.erl index d16f826c7..aea280591 100644 --- a/src/ejabberd_piefxis.erl +++ b/src/ejabberd_piefxis.erl @@ -34,12 +34,9 @@ -module(ejabberd_piefxis). --behaviour(ejabberd_config). - -protocol({xep, 227, '1.0'}). --export([import_file/1, export_server/1, export_host/2, - opt_type/1]). +-export([import_file/1, export_server/1, export_host/2]). -define(CHUNK_SIZE, 1024*20). %20k @@ -169,7 +166,7 @@ export_users([], _Server, _Fd) -> export_user(User, Server, Fd) -> Password = ejabberd_auth:get_password_s(User, Server), LServer = jid:nameprep(Server), - PasswordFormat = ejabberd_config:get_option({auth_password_format, LServer}, fun(X) -> X end, plain), + PasswordFormat = ejabberd_auth:password_format(LServer), Pass = case Password of {_,_,_,_} -> case PasswordFormat of @@ -389,7 +386,7 @@ process_user(#xmlel{name = <<"user">>, attrs = Attrs, children = Els}, #state{server = LServer} = State) -> Name = fxml:get_attr_s(<<"name">>, Attrs), Password = fxml:get_attr_s(<<"password">>, Attrs), - PasswordFormat = ejabberd_config:get_option({auth_password_format, LServer}, fun(X) -> X end, plain), + PasswordFormat = ejabberd_auth:password_format(LServer), Pass = case PasswordFormat of scram -> case Password of @@ -596,7 +593,3 @@ make_xinclude(Fn) -> print(Fd, String) -> file:write(Fd, String). - -opt_type(auth_password_format) -> fun (X) -> X end; -opt_type(_) -> [auth_password_format]. - diff --git a/src/ejabberd_rdbms.erl b/src/ejabberd_rdbms.erl index 0f89e333e..7021c10b7 100644 --- a/src/ejabberd_rdbms.erl +++ b/src/ejabberd_rdbms.erl @@ -100,13 +100,7 @@ stop_host(Host) -> %% Returns {true, App} if we have configured sql for the given host needs_sql(Host) -> LHost = jid:nameprep(Host), - case ejabberd_config:get_option({sql_type, LHost}, - fun(mysql) -> mysql; - (pgsql) -> pgsql; - (sqlite) -> sqlite; - (mssql) -> mssql; - (odbc) -> odbc - end, undefined) of + case ejabberd_config:get_option({sql_type, LHost}, undefined) of mysql -> {true, p1_mysql}; pgsql -> {true, p1_pgsql}; sqlite -> {true, sqlite3}; diff --git a/src/ejabberd_receiver.erl b/src/ejabberd_receiver.erl index 5ec26171d..38ad70eb3 100644 --- a/src/ejabberd_receiver.erl +++ b/src/ejabberd_receiver.erl @@ -31,6 +31,7 @@ -define(GEN_SERVER, gen_server). -endif. -behaviour(?GEN_SERVER). +-behaviour(ejabberd_config). %% API -export([start_link/4, @@ -41,7 +42,8 @@ starttls/2, compress/2, become_controller/2, - close/1]). + close/1, + opt_type/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, @@ -59,9 +61,6 @@ xml_stream_state :: fxml_stream:xml_stream_state() | undefined, timeout = infinity:: timeout()}). --define(HIBERNATE_TIMEOUT, ejabberd_config:get_option(receiver_hibernate, fun(X) when is_integer(X); X == hibernate-> X end, 90000)). - - -spec start_link(inet:socket(), atom(), shaper:shaper(), non_neg_integer() | infinity) -> ignore | {error, any()} | @@ -137,7 +136,7 @@ handle_call({starttls, TLSSocket}, _From, State) -> case fast_tls:recv_data(TLSSocket, <<"">>) of {ok, TLSData} -> {reply, ok, - process_data(TLSData, NewState), ?HIBERNATE_TIMEOUT}; + process_data(TLSData, NewState), hibernate_timeout()}; {error, _} = Err -> {stop, normal, Err, NewState} end; @@ -156,31 +155,31 @@ handle_call({compress, Data}, _From, case ezlib:recv_data(ZlibSocket, <<"">>) of {ok, ZlibData} -> {reply, {ok, ZlibSocket}, - process_data(ZlibData, NewState), ?HIBERNATE_TIMEOUT}; + process_data(ZlibData, NewState), hibernate_timeout()}; {error, _} = Err -> {stop, normal, Err, NewState} end; handle_call(reset_stream, _From, State) -> NewState = reset_parser(State), Reply = ok, - {reply, Reply, NewState, ?HIBERNATE_TIMEOUT}; + {reply, Reply, NewState, hibernate_timeout()}; handle_call({become_controller, C2SPid}, _From, State) -> XMLStreamState = fxml_stream:new(C2SPid, State#state.max_stanza_size), NewState = State#state{c2s_pid = C2SPid, xml_stream_state = XMLStreamState}, activate_socket(NewState), Reply = ok, - {reply, Reply, NewState, ?HIBERNATE_TIMEOUT}; + {reply, Reply, NewState, hibernate_timeout()}; handle_call(_Request, _From, State) -> - Reply = ok, {reply, Reply, State, ?HIBERNATE_TIMEOUT}. + Reply = ok, {reply, Reply, State, hibernate_timeout()}. handle_cast({change_shaper, Shaper}, State) -> NewShaperState = shaper:new(Shaper), {noreply, State#state{shaper_state = NewShaperState}, - ?HIBERNATE_TIMEOUT}; + hibernate_timeout()}; handle_cast(close, State) -> {stop, normal, State}; handle_cast(_Msg, State) -> - {noreply, State, ?HIBERNATE_TIMEOUT}. + {noreply, State, hibernate_timeout()}. handle_info({Tag, _TCPSocket, Data}, #state{socket = Socket, sock_mod = SockMod} = State) @@ -191,7 +190,7 @@ handle_info({Tag, _TCPSocket, Data}, case fast_tls:recv_data(Socket, Data) of {ok, TLSData} -> {noreply, process_data(TLSData, State), - ?HIBERNATE_TIMEOUT}; + hibernate_timeout()}; {error, Reason} -> if is_binary(Reason) -> ?DEBUG("TLS error = ~s", [Reason]); @@ -204,11 +203,11 @@ handle_info({Tag, _TCPSocket, Data}, case ezlib:recv_data(Socket, Data) of {ok, ZlibData} -> {noreply, process_data(ZlibData, State), - ?HIBERNATE_TIMEOUT}; + hibernate_timeout()}; {error, _Reason} -> {stop, normal, State} end; _ -> - {noreply, process_data(Data, State), ?HIBERNATE_TIMEOUT} + {noreply, process_data(Data, State), hibernate_timeout()} end; handle_info({Tag, _TCPSocket}, State) when (Tag == tcp_closed) or (Tag == ssl_closed) -> @@ -216,18 +215,18 @@ handle_info({Tag, _TCPSocket}, State) handle_info({Tag, _TCPSocket, Reason}, State) when (Tag == tcp_error) or (Tag == ssl_error) -> case Reason of - timeout -> {noreply, State, ?HIBERNATE_TIMEOUT}; + timeout -> {noreply, State, hibernate_timeout()}; _ -> {stop, normal, State} end; handle_info({timeout, _Ref, activate}, State) -> activate_socket(State), - {noreply, State, ?HIBERNATE_TIMEOUT}; + {noreply, State, hibernate_timeout()}; handle_info(timeout, State) -> proc_lib:hibernate(?GEN_SERVER, enter_loop, [?MODULE, [], State]), - {noreply, State, ?HIBERNATE_TIMEOUT}; + {noreply, State, hibernate_timeout()}; handle_info(_Info, State) -> - {noreply, State, ?HIBERNATE_TIMEOUT}. + {noreply, State, hibernate_timeout()}. terminate(_Reason, #state{xml_stream_state = XMLStreamState, @@ -345,3 +344,13 @@ do_call(Pid, Msg) -> _:_ -> {error, einval} end. + +hibernate_timeout() -> + ejabberd_config:get_option(receiver_hibernate, timer:seconds(90)). + +opt_type(receiver_hibernate) -> + fun(I) when is_integer(I), I>0 -> I; + (hibernate) -> hibernate + end; +opt_type(_) -> + [receiver_hibernate]. diff --git a/src/ejabberd_redis.erl b/src/ejabberd_redis.erl index 7757c6df3..56948ec83 100644 --- a/src/ejabberd_redis.erl +++ b/src/ejabberd_redis.erl @@ -421,26 +421,13 @@ code_change(_OldVsn, State, _Extra) -> %%%=================================================================== -spec connect(state()) -> {ok, pid()} | {error, any()}. connect(#state{num = Num}) -> - Server = ejabberd_config:get_option(redis_server, - fun iolist_to_list/1, - "localhost"), - Port = ejabberd_config:get_option(redis_port, - fun(P) when is_integer(P), - P>0, P<65536 -> - P - end, 6379), - DB = ejabberd_config:get_option(redis_db, - fun(I) when is_integer(I), I >= 0 -> - I - end, 0), - Pass = ejabberd_config:get_option(redis_password, - fun iolist_to_list/1, - ""), + Server = ejabberd_config:get_option(redis_server, "localhost"), + Port = ejabberd_config:get_option(redis_port, 6379), + DB = ejabberd_config:get_option(redis_db, 0), + Pass = ejabberd_config:get_option(redis_password, ""), ConnTimeout = timer:seconds( ejabberd_config:get_option( - redis_connect_timeout, - fun(I) when is_integer(I), I>0 -> I end, - 1)), + redis_connect_timeout, 1)), try case do_connect(Num, Server, Port, Pass, DB, ConnTimeout) of {ok, Client} -> ?DEBUG("Connection #~p established to Redis at ~s:~p", @@ -552,10 +539,6 @@ reply(Val) -> _ -> queued end. --spec iolist_to_list(iodata()) -> string(). -iolist_to_list(IOList) -> - binary_to_list(iolist_to_binary(IOList)). - -spec max_fsm_queue() -> pos_integer(). max_fsm_queue() -> proplists:get_value(max_queue, fsm_limit_opts(), ?DEFAULT_MAX_QUEUE). @@ -564,14 +547,9 @@ fsm_limit_opts() -> ejabberd_config:fsm_limit_opts([]). get_queue_type() -> - case ejabberd_config:get_option( - redis_queue_type, - ejabberd_redis_sup:opt_type(redis_queue_type)) of - undefined -> - ejabberd_config:default_queue_type(global); - Type -> - Type - end. + ejabberd_config:get_option( + redis_queue_type, + ejabberd_config:default_queue_type(global)). -spec flush_queue(p1_queue:queue()) -> p1_queue:queue(). flush_queue(Q) -> diff --git a/src/ejabberd_redis_sup.erl b/src/ejabberd_redis_sup.erl index 7e2953c11..85cfd7abb 100644 --- a/src/ejabberd_redis_sup.erl +++ b/src/ejabberd_redis_sup.erl @@ -23,6 +23,7 @@ -module(ejabberd_redis_sup). -behaviour(supervisor). +-behaviour(ejabberd_config). %% API -export([start_link/0, get_pool_size/0, @@ -107,15 +108,9 @@ is_redis_configured(Host) -> PoolSize = ejabberd_config:has_option({redis_pool_size, Host}), ConnTimeoutConfigured = ejabberd_config:has_option( {redis_connect_timeout, Host}), - Modules = ejabberd_config:get_option( - {modules, Host}, - fun(L) when is_list(L) -> L end, []), - SMConfigured = ejabberd_config:get_option( - {sm_db_type, Host}, - fun(V) -> V end) == redis, - RouterConfigured = ejabberd_config:get_option( - {router_db_type, Host}, - fun(V) -> V end) == redis, + Modules = ejabberd_config:get_option({modules, Host}, []), + SMConfigured = ejabberd_config:get_option({sm_db_type, Host}) == redis, + RouterConfigured = ejabberd_config:get_option({router_db_type, Host}) == redis, ModuleWithRedisDBConfigured = lists:any( fun({Module, Opts}) -> @@ -133,10 +128,7 @@ get_specs() -> end, lists:seq(1, get_pool_size())). get_pool_size() -> - ejabberd_config:get_option( - redis_pool_size, - fun(N) when is_integer(N), N >= 1 -> N end, - ?DEFAULT_POOL_SIZE) + 1. + ejabberd_config:get_option(redis_pool_size, ?DEFAULT_POOL_SIZE) + 1. iolist_to_list(IOList) -> binary_to_list(iolist_to_binary(IOList)). diff --git a/src/ejabberd_riak_sup.erl b/src/ejabberd_riak_sup.erl index a01f3538a..3d754f6d6 100644 --- a/src/ejabberd_riak_sup.erl +++ b/src/ejabberd_riak_sup.erl @@ -87,15 +87,9 @@ is_riak_configured(Host) -> AuthConfigured = lists:member( ejabberd_auth_riak, ejabberd_auth:auth_modules(Host)), - SMConfigured = ejabberd_config:get_option( - {sm_db_type, Host}, - ejabberd_sm:opt_type(sm_db_type)) == riak, - RouterConfigured = ejabberd_config:get_option( - {router_db_type, Host}, - ejabberd_router:opt_type(router_db_type)) == riak, - Modules = ejabberd_config:get_option( - {modules, Host}, - fun(L) when is_list(L) -> L end, []), + SMConfigured = ejabberd_config:get_option({sm_db_type, Host}) == riak, + RouterConfigured = ejabberd_config:get_option({router_db_type, Host}) == riak, + Modules = ejabberd_config:get_option({modules, Host}, []), ModuleWithRiakDBConfigured = lists:any( fun({Module, Opts}) -> gen_mod:db_type(Host, Opts, Module) == riak @@ -150,50 +144,25 @@ get_specs() -> end, lists:seq(1, PoolSize)). get_start_interval() -> - ejabberd_config:get_option( - riak_start_interval, - fun(N) when is_integer(N), N >= 1 -> N end, - ?DEFAULT_RIAK_START_INTERVAL). + ejabberd_config:get_option(riak_start_interval, ?DEFAULT_RIAK_START_INTERVAL). get_pool_size() -> - ejabberd_config:get_option( - riak_pool_size, - fun(N) when is_integer(N), N >= 1 -> N end, - ?DEFAULT_POOL_SIZE). + ejabberd_config:get_option(riak_pool_size, ?DEFAULT_POOL_SIZE). get_riak_server() -> - ejabberd_config:get_option( - riak_server, - fun(S) -> - binary_to_list(iolist_to_binary(S)) - end, ?DEFAULT_RIAK_HOST). + ejabberd_config:get_option(riak_server, ?DEFAULT_RIAK_HOST). get_riak_cacertfile() -> - ejabberd_config:get_option( - riak_cacertfile, - fun(S) -> - binary_to_list(iolist_to_binary(S)) - end, nil). + ejabberd_config:get_option(riak_cacertfile, nil). get_riak_username() -> - ejabberd_config:get_option( - riak_username, - fun(S) -> - binary_to_list(iolist_to_binary(S)) - end, nil). + ejabberd_config:get_option(riak_username, nil). get_riak_password() -> - ejabberd_config:get_option( - riak_password, - fun(S) -> - binary_to_list(iolist_to_binary(S)) - end, nil). + ejabberd_config:get_option(riak_password, nil). get_riak_port() -> - ejabberd_config:get_option( - riak_port, - fun(P) when is_integer(P), P > 0, P < 65536 -> P end, - ?DEFAULT_RIAK_PORT). + ejabberd_config:get_option(riak_port, ?DEFAULT_RIAK_PORT). get_pids() -> [ejabberd_riak:get_proc(I) || I <- lists:seq(1, get_pool_size())]. @@ -210,16 +179,20 @@ transform_options({riak_server, {S, P}}, Opts) -> transform_options(Opt, Opts) -> [Opt|Opts]. -opt_type(modules) -> fun (L) when is_list(L) -> L end; opt_type(riak_pool_size) -> fun (N) when is_integer(N), N >= 1 -> N end; -opt_type(riak_port) -> fun (_) -> true end; -opt_type(riak_server) -> fun (_) -> true end; +opt_type(riak_port) -> + fun(P) when is_integer(P), P > 0, P < 65536 -> P end; +opt_type(riak_server) -> + fun(S) -> binary_to_list(iolist_to_binary(S)) end; opt_type(riak_start_interval) -> fun (N) when is_integer(N), N >= 1 -> N end; -opt_type(riak_cacertfile) -> fun iolist_to_binary/1; -opt_type(riak_username) -> fun iolist_to_binary/1; -opt_type(riak_password) -> fun iolist_to_binary/1; +opt_type(riak_cacertfile) -> + fun(S) -> binary_to_list(iolist_to_binary(S)) end; +opt_type(riak_username) -> + fun(S) -> binary_to_list(iolist_to_binary(S)) end; +opt_type(riak_password) -> + fun(S) -> binary_to_list(iolist_to_binary(S)) end; opt_type(_) -> - [modules, riak_pool_size, riak_port, riak_server, + [riak_pool_size, riak_port, riak_server, riak_start_interval, riak_cacertfile, riak_username, riak_password]. diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index 5951cbeca..490133d79 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -385,15 +385,11 @@ balancing_route(From, To, Packet, Rs) -> -spec get_component_number(binary()) -> pos_integer() | undefined. get_component_number(LDomain) -> - ejabberd_config:get_option( - {domain_balancing_component_number, LDomain}, - fun(N) when is_integer(N), N > 1 -> N end, - undefined). + ejabberd_config:get_option({domain_balancing_component_number, LDomain}). -spec get_domain_balancing(jid(), jid(), binary()) -> any(). get_domain_balancing(From, To, LDomain) -> - case ejabberd_config:get_option( - {domain_balancing, LDomain}, fun(D) when is_atom(D) -> D end) of + case ejabberd_config:get_option({domain_balancing, LDomain}) of undefined -> p1_time_compat:system_time(); random -> p1_time_compat:system_time(); source -> jid:tolower(From); @@ -404,14 +400,9 @@ get_domain_balancing(From, To, LDomain) -> -spec get_backend() -> module(). get_backend() -> - DBType = case ejabberd_config:get_option( - router_db_type, - fun(T) -> ejabberd_config:v_db(?MODULE, T) end) of - undefined -> - ejabberd_config:default_ram_db(?MODULE); - T -> - T - end, + DBType = ejabberd_config:get_option( + router_db_type, + ejabberd_config:default_ram_db(?MODULE)), list_to_atom("ejabberd_router_" ++ atom_to_list(DBType)). -spec cache_nodes(module()) -> [node()]. @@ -427,7 +418,7 @@ use_cache(Mod) -> true -> Mod:use_cache(); false -> ejabberd_config:get_option( - router_use_cache, opt_type(router_use_cache), + router_use_cache, ejabberd_config:use_cache(global)) end. @@ -454,15 +445,12 @@ init_cache(Mod) -> cache_opts() -> MaxSize = ejabberd_config:get_option( router_cache_size, - opt_type(router_cache_size), ejabberd_config:cache_size(global)), CacheMissed = ejabberd_config:get_option( router_cache_missed, - opt_type(router_cache_missed), ejabberd_config:cache_missed(global)), LifeTime = case ejabberd_config:get_option( router_cache_life_time, - opt_type(router_cache_life_time), ejabberd_config:cache_life_time(global)) of infinity -> infinity; I -> timer:seconds(I) diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl index 61d3b021b..b6685c12e 100644 --- a/src/ejabberd_s2s.erl +++ b/src/ejabberd_s2s.erl @@ -200,45 +200,37 @@ dirty_get_connections() -> tls_options(LServer, DefaultOpts) -> TLSOpts1 = case ejabberd_config:get_option( {s2s_certfile, LServer}, - fun iolist_to_binary/1, ejabberd_config:get_option( - {domain_certfile, LServer}, - fun iolist_to_binary/1)) of + {domain_certfile, LServer})) of undefined -> DefaultOpts; CertFile -> lists:keystore(certfile, 1, DefaultOpts, {certfile, CertFile}) end, TLSOpts2 = case ejabberd_config:get_option( - {s2s_ciphers, LServer}, - fun iolist_to_binary/1) of + {s2s_ciphers, LServer}) of undefined -> TLSOpts1; Ciphers -> lists:keystore(ciphers, 1, TLSOpts1, {ciphers, Ciphers}) end, TLSOpts3 = case ejabberd_config:get_option( - {s2s_protocol_options, LServer}, - fun (Options) -> str:join(Options, <<$|>>) end) of + {s2s_protocol_options, LServer}) of undefined -> TLSOpts2; ProtoOpts -> lists:keystore(protocol_options, 1, TLSOpts2, {protocol_options, ProtoOpts}) end, TLSOpts4 = case ejabberd_config:get_option( - {s2s_dhfile, LServer}, - fun iolist_to_binary/1) of + {s2s_dhfile, LServer}) of undefined -> TLSOpts3; DHFile -> lists:keystore(dhfile, 1, TLSOpts3, {dhfile, DHFile}) end, TLSOpts5 = case ejabberd_config:get_option( - {s2s_cafile, LServer}, - fun iolist_to_binary/1) of + {s2s_cafile, LServer}) of undefined -> TLSOpts4; CAFile -> lists:keystore(cafile, 1, TLSOpts4, {cafile, CAFile}) end, - case ejabberd_config:get_option( - {s2s_tls_compression, LServer}, - fun(B) when is_boolean(B) -> B end) of + case ejabberd_config:get_option({s2s_tls_compression, LServer}) of undefined -> TLSOpts5; false -> [compression_none | TLSOpts5]; true -> lists:delete(compression_none, TLSOpts5) @@ -261,37 +253,21 @@ tls_enabled(LServer) -> -spec zlib_enabled(binary()) -> boolean(). zlib_enabled(LServer) -> - ejabberd_config:get_option( - {s2s_zlib, LServer}, - fun(B) when is_boolean(B) -> B end, - false). + ejabberd_config:get_option({s2s_zlib, LServer}, false). -spec use_starttls(binary()) -> boolean() | optional | required | required_trusted. use_starttls(LServer) -> - ejabberd_config:get_option( - {s2s_use_starttls, LServer}, - fun(true) -> true; - (false) -> false; - (optional) -> optional; - (required) -> required; - (required_trusted) -> required_trusted - end, false). + ejabberd_config:get_option({s2s_use_starttls, LServer}, false). -spec get_idle_timeout(binary()) -> non_neg_integer() | infinity. get_idle_timeout(LServer) -> - ejabberd_config:get_option( - {s2s_timeout, LServer}, - fun(I) when is_integer(I), I >= 0 -> timer:seconds(I); - (infinity) -> infinity - end, timer:minutes(10)). + ejabberd_config:get_option({s2s_timeout, LServer}, timer:minutes(10)). -spec queue_type(binary()) -> ram | file. queue_type(LServer) -> - case ejabberd_config:get_option( - {s2s_queue_type, LServer}, opt_type(s2s_queue_type)) of - undefined -> ejabberd_config:default_queue_type(LServer); - Type -> Type - end. + ejabberd_config:get_option( + {s2s_queue_type, LServer}, + ejabberd_config:default_queue_type(LServer)). %%==================================================================== %% gen_server callbacks @@ -543,9 +519,7 @@ needed_connections_number(Ls, MaxS2SConnectionsNumber, -spec is_service(jid(), jid()) -> boolean(). is_service(From, To) -> LFromDomain = From#jid.lserver, - case ejabberd_config:get_option( - {route_subdomains, LFromDomain}, - fun(s2s) -> s2s; (local) -> local end, local) of + case ejabberd_config:get_option({route_subdomains, LFromDomain}, local) of s2s -> % bypass RFC 3920 10.3 false; local -> @@ -645,10 +619,7 @@ allow_host(MyServer, S2SHost) -> not is_temporarly_blocked(S2SHost). allow_host1(MyHost, S2SHost) -> - Rule = ejabberd_config:get_option( - {s2s_access, MyHost}, - fun acl:access_rules_validator/1, - all), + Rule = ejabberd_config:get_option({s2s_access, MyHost}, all), JID = jid:make(S2SHost), case acl:match_rule(MyHost, Rule, JID) of deny -> false; @@ -724,7 +695,6 @@ opt_type(route_subdomains) -> end; opt_type(s2s_access) -> fun acl:access_rules_validator/1; -opt_type(domain_certfile) -> fun iolist_to_binary/1; opt_type(s2s_certfile) -> fun iolist_to_binary/1; opt_type(s2s_ciphers) -> fun iolist_to_binary/1; opt_type(s2s_dhfile) -> fun iolist_to_binary/1; @@ -742,13 +712,16 @@ opt_type(s2s_use_starttls) -> (required) -> required; (required_trusted) -> required_trusted end; +opt_type(s2s_zlib) -> + fun(B) when is_boolean(B) -> B end; opt_type(s2s_timeout) -> - fun(I) when is_integer(I), I>=0 -> I; - (infinity) -> infinity + fun(I) when is_integer(I), I >= 0 -> timer:seconds(I); + (infinity) -> infinity; + (unlimited) -> infinity end; opt_type(s2s_queue_type) -> fun(ram) -> ram; (file) -> file end; opt_type(_) -> - [route_subdomains, s2s_access, s2s_certfile, + [route_subdomains, s2s_access, s2s_certfile, s2s_zlib, s2s_ciphers, s2s_dhfile, s2s_cafile, s2s_protocol_options, s2s_tls_compression, s2s_use_starttls, s2s_timeout, s2s_queue_type]. diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index ee4e72599..b1d0ae215 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -27,7 +27,7 @@ %% ejabberd_socket callbacks -export([start/2, start_link/2, socket_type/0]). %% ejabberd_config callbacks --export([opt_type/1]). +-export([opt_type/1, listen_opt_type/1]). %% xmpp_stream_in callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). @@ -245,25 +245,20 @@ handle_send(Pkt, Result, #{server_host := LServer} = State) -> State, [Pkt, Result]). init([State, Opts]) -> - Shaper = gen_mod:get_opt(shaper, Opts, fun acl:shaper_rules_validator/1, none), + Shaper = gen_mod:get_opt(shaper, Opts, none), TLSOpts1 = lists:filter( fun({certfile, _}) -> true; ({ciphers, _}) -> true; ({dhfile, _}) -> true; ({cafile, _}) -> true; + ({protocol_options, _}) -> true; (_) -> false end, Opts), - TLSOpts2 = case lists:keyfind(protocol_options, 1, Opts) of - false -> TLSOpts1; - {_, OptString} -> - ProtoOpts = str:join(OptString, <<$|>>), - [{protocol_options, ProtoOpts}|TLSOpts1] - end, - TLSOpts3 = case proplists:get_bool(tls_compression, Opts) of - false -> [compression_none | TLSOpts2]; - true -> TLSOpts2 + TLSOpts2 = case proplists:get_bool(tls_compression, Opts) of + false -> [compression_none | TLSOpts1]; + true -> TLSOpts1 end, - State1 = State#{tls_options => TLSOpts3, + State1 = State#{tls_options => TLSOpts2, auth_domains => sets:new(), xmlns => ?NS_SERVER, lang => ?MYLANG, @@ -351,3 +346,23 @@ change_shaper(#{shaper := ShaperName, server_host := ServerHost} = State, opt_type(_) -> []. + +listen_opt_type(shaper) -> fun acl:shaper_rules_validator/1; +listen_opt_type(certfile) -> ejabberd_s2s:opt_type(s2s_certfile); +listen_opt_type(ciphers) -> ejabberd_s2s:opt_type(s2s_ciphers); +listen_opt_type(dhfile) -> ejabberd_s2s:opt_type(s2s_dhfile); +listen_opt_type(cafile) -> ejabberd_s2s:opt_type(s2s_cafile); +listen_opt_type(protocol_options) -> ejabberd_s2s:opt_type(s2s_protocol_options); +listen_opt_type(tls_compression) -> ejabberd_s2s:opt_type(s2s_tls_compression); +listen_opt_type(tls) -> fun(B) when is_boolean(B) -> B end; +listen_opt_type(supervisor) -> fun(B) when is_boolean(B) -> B end; +listen_opt_type(max_stanza_size) -> + fun(I) when is_integer(I) -> I; + (unlimited) -> infinity; + (infinity) -> infinity + end; +listen_opt_type(max_fsm_queue) -> + fun(I) when is_integer(I), I>0 -> I end; +listen_opt_type(_) -> + [shaper, certfile, ciphers, dhfile, cafile, protocol_options, + tls_compression, tls, max_fsm_queue]. diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl index 3c9e1a1c9..deff3e5b5 100644 --- a/src/ejabberd_s2s_out.erl +++ b/src/ejabberd_s2s_out.erl @@ -191,42 +191,21 @@ tls_enabled(#{server := LServer}) -> connect_timeout(#{server := LServer}) -> ejabberd_config:get_option( {outgoing_s2s_timeout, LServer}, - fun(TimeOut) when is_integer(TimeOut), TimeOut > 0 -> - timer:seconds(TimeOut); - (infinity) -> - infinity - end, timer:seconds(10)). + timer:seconds(10)). default_port(#{server := LServer}) -> - ejabberd_config:get_option( - {outgoing_s2s_port, LServer}, - fun(I) when is_integer(I), I > 0, I =< 65536 -> I end, - 5269). + ejabberd_config:get_option({outgoing_s2s_port, LServer}, 5269). address_families(#{server := LServer}) -> ejabberd_config:get_option( {outgoing_s2s_families, LServer}, - fun(Families) -> - lists:map( - fun(ipv4) -> inet; - (ipv6) -> inet6 - end, Families) - end, [inet, inet6]). + [inet, inet6]). dns_retries(#{server := LServer}) -> - ejabberd_config:get_option( - {s2s_dns_retries, LServer}, - fun(I) when is_integer(I), I>=0 -> I end, - 2). + ejabberd_config:get_option({s2s_dns_retries, LServer}, 2). dns_timeout(#{server := LServer}) -> - ejabberd_config:get_option( - {s2s_dns_timeout, LServer}, - fun(I) when is_integer(I), I>=0 -> - timer:seconds(I); - (infinity) -> - infinity - end, timer:seconds(10)). + ejabberd_config:get_option({s2s_dns_timeout, LServer}, timer:seconds(10)). handle_auth_success(Mech, #{sockmod := SockMod, socket := Socket, ip := IP, @@ -391,10 +370,7 @@ mk_bounce_error(_Lang, _State) -> -spec get_delay() -> non_neg_integer(). get_delay() -> - MaxDelay = ejabberd_config:get_option( - s2s_max_retry_delay, - fun(I) when is_integer(I), I > 0 -> I end, - 300), + MaxDelay = ejabberd_config:get_option(s2s_max_retry_delay, 300), crypto:rand_uniform(1, MaxDelay). -spec set_idle_timeout(state()) -> state(). @@ -464,26 +440,28 @@ maybe_report_huge_timeout(_, _) -> ok. opt_type(outgoing_s2s_families) -> - fun (Families) -> - true = lists:all(fun (ipv4) -> true; - (ipv6) -> true - end, - Families), - Families + fun(Families) -> + lists:map( + fun(ipv4) -> inet; + (ipv6) -> inet6 + end, Families) end; opt_type(outgoing_s2s_port) -> fun (I) when is_integer(I), I > 0, I =< 65536 -> I end; opt_type(outgoing_s2s_timeout) -> - fun (TimeOut) when is_integer(TimeOut), TimeOut > 0 -> - TimeOut; - (infinity) -> infinity + fun(TimeOut) when is_integer(TimeOut), TimeOut > 0 -> + timer:seconds(TimeOut); + (unlimited) -> + infinity; + (infinity) -> + infinity end; opt_type(s2s_dns_retries) -> fun (I) when is_integer(I), I >= 0 -> I end; opt_type(s2s_dns_timeout) -> - fun (TimeOut) when is_integer(TimeOut), TimeOut > 0 -> - TimeOut; - (infinity) -> infinity + fun(I) when is_integer(I), I>=0 -> timer:seconds(I); + (infinity) -> infinity; + (unlimited) -> infinity end; opt_type(s2s_max_retry_delay) -> fun (I) when is_integer(I), I > 0 -> I end; diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl index 8634dd122..0dcf74ab0 100644 --- a/src/ejabberd_service.erl +++ b/src/ejabberd_service.erl @@ -29,7 +29,7 @@ %% ejabberd_socket callbacks -export([start/2, start_link/2, socket_type/0, close/1, close/2]). %% ejabberd_config callbacks --export([opt_type/1, transform_listen_option/2]). +-export([opt_type/1, listen_opt_type/1, transform_listen_option/2]). %% xmpp_stream_in callbacks -export([init/1, handle_info/2, terminate/2, code_change/3]). -export([handle_stream_start/2, handle_auth_success/4, handle_auth_failure/4, @@ -80,49 +80,33 @@ tls_options(#{tls_options := TLSOptions}) -> TLSOptions. init([State, Opts]) -> - Access = gen_mod:get_opt(access, Opts, fun acl:access_rules_validator/1, all), - Shaper = gen_mod:get_opt(shaper_rule, Opts, fun acl:shaper_rules_validator/1, none), - HostOpts = case lists:keyfind(hosts, 1, Opts) of - {hosts, HOpts} -> - lists:foldl( - fun({H, Os}, D) -> - P = proplists:get_value( - password, Os, - str:sha(randoms:bytes(20))), - dict:store(H, P, D) - end, dict:new(), HOpts); - false -> - Pass = proplists:get_value( - password, Opts, - str:sha(randoms:bytes(20))), - dict:from_list([{global, Pass}]) - end, - CheckFrom = gen_mod:get_opt(check_from, Opts, - fun(Flag) when is_boolean(Flag) -> Flag end, - true), + Access = gen_mod:get_opt(access, Opts, all), + Shaper = gen_mod:get_opt(shaper_rule, Opts, none), + GlobalPassword = gen_mod:get_opt(password, Opts, random_password()), + HostOpts = gen_mod:get_opt(hosts, Opts, [{global, GlobalPassword}]), + HostOpts1 = lists:map( + fun({Host, undefined}) -> {Host, GlobalPassword}; + ({Host, Password}) -> {Host, Password} + end, HostOpts), + CheckFrom = gen_mod:get_opt(check_from, Opts, true), TLSOpts1 = lists:filter( fun({certfile, _}) -> true; ({ciphers, _}) -> true; ({dhfile, _}) -> true; ({cafile, _}) -> true; + ({protocol_options, _}) -> true; (_) -> false end, Opts), - TLSOpts2 = case lists:keyfind(protocol_options, 1, Opts) of - false -> TLSOpts1; - {_, OptString} -> - ProtoOpts = str:join(OptString, <<$|>>), - [{protocol_options, ProtoOpts}|TLSOpts1] - end, TLSOpts = case proplists:get_bool(tls_compression, Opts) of - false -> [compression_none | TLSOpts2]; - true -> TLSOpts2 + false -> [compression_none | TLSOpts1]; + true -> TLSOpts1 end, xmpp_stream_in:change_shaper(State, Shaper), State1 = State#{access => Access, xmlns => ?NS_COMPONENT, lang => ?MYLANG, server => ?MYNAME, - host_opts => HostOpts, + host_opts => dict:from_list(HostOpts1), stream_version => undefined, tls_options => TLSOpts, check_from => CheckFrom}, @@ -254,6 +238,9 @@ check_from(From, #{host_opts := HostOpts}) -> Server = From#jid.lserver, dict:is_key(Server, HostOpts). +random_password() -> + str:sha(randoms:bytes(20)). + transform_listen_option({hosts, Hosts, O}, Opts) -> case lists:keyfind(hosts, 1, Opts) of {_, PrevHostOpts} -> @@ -273,3 +260,38 @@ transform_listen_option(Opt, Opts) -> [Opt|Opts]. opt_type(_) -> []. + +listen_opt_type(access) -> fun acl:access_rules_validator/1; +listen_opt_type(shaper_rule) -> fun acl:shaper_rules_validator/1; +listen_opt_type(certfile) -> fun iolist_to_binary/1; +listen_opt_type(ciphers) -> fun iolist_to_binary/1; +listen_opt_type(dhfile) -> fun iolist_to_binary/1; +listen_opt_type(cafile) -> fun iolist_to_binary/1; +listen_opt_type(protocol_options) -> + fun(Options) -> str:join(Options, <<"|">>) end; +listen_opt_type(tls_compression) -> fun(B) when is_boolean(B) -> B end; +listen_opt_type(tls) -> fun(B) when is_boolean(B) -> B end; +listen_opt_type(check_from) -> fun(B) when is_boolean(B) -> B end; +listen_opt_type(password) -> fun iolist_to_binary/1; +listen_opt_type(hosts) -> + fun(HostOpts) -> + lists:map( + fun({Host, Opts}) -> + Password = case proplists:get_value(password, Opts) of + undefined -> undefined; + P -> iolist_to_binary(P) + end, + {iolist_to_binary(Host), Password} + end, HostOpts) + end; +listen_opt_type(max_stanza_size) -> + fun(I) when is_integer(I) -> I; + (unlimited) -> infinity; + (infinity) -> infinity + end; +listen_opt_type(max_fsm_queue) -> + fun(I) when is_integer(I), I>0 -> I end; +listen_opt_type(_) -> + [access, shaper_rule, certfile, ciphers, dhfile, cafile, tls, + protocol_options, tls_compression, password, hosts, check_from, + max_fsm_queue]. diff --git a/src/ejabberd_sip.erl b/src/ejabberd_sip.erl new file mode 100644 index 000000000..5ee81cfa1 --- /dev/null +++ b/src/ejabberd_sip.erl @@ -0,0 +1,58 @@ +%%%------------------------------------------------------------------- +%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net> +%%% Created : 30 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net> +%%% +%%% +%%% ejabberd, Copyright (C) 2013-2017 ProcessOne +%%% +%%% This program is free software; you can redistribute it and/or +%%% modify it under the terms of the GNU General Public License as +%%% published by the Free Software Foundation; either version 2 of the +%%% License, or (at your option) any later version. +%%% +%%% This program is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%%% General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License along +%%% with this program; if not, write to the Free Software Foundation, Inc., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +%%% +%%%------------------------------------------------------------------- +-module(ejabberd_sip). + +%% API +-export([tcp_init/2, udp_init/2, udp_recv/5, start/2, + socket_type/0, listen_opt_type/1]). + +%%%=================================================================== +%%% API +%%%=================================================================== +tcp_init(Socket, Opts) -> + ejabberd:start_app(esip), + esip_socket:tcp_init(Socket, Opts). + +udp_init(Socket, Opts) -> + ejabberd:start_app(esip), + esip_socket:udp_init(Socket, Opts). + +udp_recv(Sock, Addr, Port, Data, Opts) -> + esip_socket:udp_recv(Sock, Addr, Port, Data, Opts). + +start(Opaque, Opts) -> + esip_socket:start(Opaque, Opts). + +socket_type() -> + raw. + +listen_opt_type(certfile) -> + fun iolist_to_binary/1; +listen_opt_type(tls) -> + fun(B) when is_boolean(B) -> B end; +listen_opt_type(_) -> + [tls, certfile]. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 20614a58d..ce2abfff0 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -865,14 +865,9 @@ force_update_presence({LUser, LServer}) -> -spec get_sm_backend(binary()) -> module(). get_sm_backend(Host) -> - DBType = case ejabberd_config:get_option( + DBType = ejabberd_config:get_option( {sm_db_type, Host}, - fun(T) -> ejabberd_config:v_db(?MODULE, T) end) of - undefined -> - ejabberd_config:default_ram_db(Host, ?MODULE); - T -> - T - end, + ejabberd_config:default_ram_db(Host, ?MODULE)), list_to_atom("ejabberd_sm_" ++ atom_to_list(DBType)). -spec get_sm_backends() -> [module()]. @@ -904,15 +899,12 @@ init_cache() -> cache_opts() -> MaxSize = ejabberd_config:get_option( sm_cache_size, - opt_type(sm_cache_size), ejabberd_config:cache_size(global)), CacheMissed = ejabberd_config:get_option( sm_cache_missed, - opt_type(sm_cache_missed), ejabberd_config:cache_missed(global)), LifeTime = case ejabberd_config:get_option( sm_cache_life_time, - opt_type(sm_cache_life_time), ejabberd_config:cache_life_time(global)) of infinity -> infinity; I -> timer:seconds(I) @@ -943,7 +935,6 @@ use_cache(Mod, LServer) -> false -> ejabberd_config:get_option( {sm_use_cache, LServer}, - ejabberd_sm:opt_type(sm_use_cache), ejabberd_config:use_cache(LServer)) end. diff --git a/src/ejabberd_sm_redis.erl b/src/ejabberd_sm_redis.erl index cf1836c56..288ec77b6 100644 --- a/src/ejabberd_sm_redis.erl +++ b/src/ejabberd_sm_redis.erl @@ -27,13 +27,12 @@ -define(GEN_SERVER, p1_server). -endif. -behaviour(?GEN_SERVER). --behaviour(ejabberd_config). -behaviour(ejabberd_sm). -export([init/0, set_session/1, delete_session/1, get_sessions/0, get_sessions/1, get_sessions/2, - cache_nodes/1, opt_type/1]). + cache_nodes/1]). %% gen_server callbacks -export([init/1, handle_cast/2, handle_call/3, handle_info/2, terminate/2, code_change/3, start_link/0]). @@ -169,9 +168,6 @@ code_change(_OldVsn, State, _Extra) -> %%%=================================================================== %%% Internal functions %%%=================================================================== -iolist_to_list(IOList) -> - binary_to_list(iolist_to_binary(IOList)). - us_to_key({LUser, LServer}) -> <<"ejabberd:sm:", LUser/binary, "@", LServer/binary>>. @@ -214,17 +210,3 @@ clean_table() -> catch _:{badmatch, {error, _}} -> ?ERROR_MSG("failed to clean redis c2s sessions", []) end. - -opt_type(redis_connect_timeout) -> - fun (I) when is_integer(I), I > 0 -> I end; -opt_type(redis_db) -> - fun (I) when is_integer(I), I >= 0 -> I end; -opt_type(redis_password) -> fun iolist_to_list/1; -opt_type(redis_port) -> - fun (P) when is_integer(P), P > 0, P < 65536 -> P end; -opt_type(redis_reconnect_timeout) -> - fun (I) when is_integer(I), I > 0 -> I end; -opt_type(redis_server) -> fun iolist_to_list/1; -opt_type(_) -> - [redis_connect_timeout, redis_db, redis_password, - redis_port, redis_reconnect_timeout, redis_server]. diff --git a/src/ejabberd_sql.erl b/src/ejabberd_sql.erl index 8b9f81233..0dddcb03e 100644 --- a/src/ejabberd_sql.erl +++ b/src/ejabberd_sql.erl @@ -252,8 +252,7 @@ sqlite_db(Host) -> -spec sqlite_file(binary()) -> string(). sqlite_file(Host) -> - case ejabberd_config:get_option({sql_database, Host}, - fun iolist_to_binary/1) of + case ejabberd_config:get_option({sql_database, Host}) of undefined -> {ok, Cwd} = file:get_cwd(), filename:join([Cwd, "sqlite", atom_to_list(node()), @@ -266,9 +265,7 @@ sqlite_file(Host) -> %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- init([Host, StartInterval]) -> - case ejabberd_config:get_option( - {sql_keepalive_interval, Host}, - fun(I) when is_integer(I), I>0 -> I end) of + case ejabberd_config:get_option({sql_keepalive_interval, Host}) of undefined -> ok; KeepaliveInterval -> @@ -278,8 +275,7 @@ init([Host, StartInterval]) -> [DBType | _] = db_opts(Host), (?GEN_FSM):send_event(self(), connect), ejabberd_sql_sup:add_pid(Host, self()), - QueueType = case ejabberd_config:get_option( - {sql_queue_type, Host}, opt_type(sql_queue_type)) of + QueueType = case ejabberd_config:get_option({sql_queue_type, Host}) of undefined -> ejabberd_config:default_queue_type(Host); Type -> @@ -927,20 +923,9 @@ log(Level, Format, Args) -> end. db_opts(Host) -> - Type = ejabberd_config:get_option({sql_type, Host}, - fun(mysql) -> mysql; - (pgsql) -> pgsql; - (sqlite) -> sqlite; - (mssql) -> mssql; - (odbc) -> odbc - end, odbc), - Server = ejabberd_config:get_option({sql_server, Host}, - fun iolist_to_binary/1, - <<"localhost">>), - Transport = case ejabberd_config:get_option( - {sql_ssl, Host}, - fun(B) when is_boolean(B) -> B end, - false) of + Type = ejabberd_config:get_option({sql_type, Host}, odbc), + Server = ejabberd_config:get_option({sql_server, Host}, <<"localhost">>), + Transport = case ejabberd_config:get_option({sql_ssl, Host}, false) of false -> tcp; true -> ssl end, @@ -953,20 +938,16 @@ db_opts(Host) -> _ -> Port = ejabberd_config:get_option( {sql_port, Host}, - fun(P) when is_integer(P), P > 0, P < 65536 -> P end, case Type of mssql -> ?MSSQL_PORT; mysql -> ?MYSQL_PORT; pgsql -> ?PGSQL_PORT end), DB = ejabberd_config:get_option({sql_database, Host}, - fun iolist_to_binary/1, <<"ejabberd">>), User = ejabberd_config:get_option({sql_username, Host}, - fun iolist_to_binary/1, <<"ejabberd">>), Pass = ejabberd_config:get_option({sql_password, Host}, - fun iolist_to_binary/1, <<"">>), SSLOpts = get_ssl_opts(Transport, Host), case Type of @@ -986,19 +967,15 @@ warn_if_ssl_unsupported(ssl, Type) -> ?WARNING_MSG("SSL connection is not supported for ~s", [Type]). get_ssl_opts(ssl, Host) -> - Opts1 = case ejabberd_config:get_option({sql_ssl_certfile, Host}, - fun iolist_to_binary/1) of + Opts1 = case ejabberd_config:get_option({sql_ssl_certfile, Host}) of undefined -> []; CertFile -> [{certfile, CertFile}] end, - Opts2 = case ejabberd_config:get_option({sql_ssl_cafile, Host}, - fun iolist_to_binary/1) of + Opts2 = case ejabberd_config:get_option({sql_ssl_cafile, Host}) of undefined -> Opts1; CAFile -> [{cacertfile, CAFile}|Opts1] end, - case ejabberd_config:get_option({sql_ssl_verify, Host}, - fun(B) when is_boolean(B) -> B end, - false) of + case ejabberd_config:get_option({sql_ssl_verify, Host}, false) of true -> case lists:keymember(cacertfile, 1, Opts2) of true -> @@ -1017,16 +994,9 @@ get_ssl_opts(tcp, _) -> []. init_mssql(Host) -> - Server = ejabberd_config:get_option({sql_server, Host}, - fun iolist_to_binary/1, - <<"localhost">>), - Port = ejabberd_config:get_option( - {sql_port, Host}, - fun(P) when is_integer(P), P > 0, P < 65536 -> P end, - ?MSSQL_PORT), - DB = ejabberd_config:get_option({sql_database, Host}, - fun iolist_to_binary/1, - <<"ejabberd">>), + Server = ejabberd_config:get_option({sql_server, Host}, <<"localhost">>), + Port = ejabberd_config:get_option({sql_port, Host}, ?MSSQL_PORT), + DB = ejabberd_config:get_option({sql_database, Host}, <<"ejabberd">>), FreeTDS = io_lib:fwrite("[~s]~n" "\thost = ~s~n" "\tport = ~p~n" @@ -1109,13 +1079,6 @@ opt_type(sql_password) -> fun iolist_to_binary/1; opt_type(sql_port) -> fun (P) when is_integer(P), P > 0, P < 65536 -> P end; opt_type(sql_server) -> fun iolist_to_binary/1; -opt_type(sql_type) -> - fun (mysql) -> mysql; - (pgsql) -> pgsql; - (sqlite) -> sqlite; - (mssql) -> mssql; - (odbc) -> odbc - end; opt_type(sql_username) -> fun iolist_to_binary/1; opt_type(sql_ssl) -> fun(B) when is_boolean(B) -> B end; opt_type(sql_ssl_verify) -> fun(B) when is_boolean(B) -> B end; @@ -1125,6 +1088,6 @@ opt_type(sql_queue_type) -> fun(ram) -> ram; (file) -> file end; opt_type(_) -> [sql_database, sql_keepalive_interval, - sql_password, sql_port, sql_server, sql_type, + sql_password, sql_port, sql_server, sql_username, sql_ssl, sql_ssl_verify, sql_ssl_cerfile, sql_ssl_cafile, sql_queue_type]. diff --git a/src/ejabberd_sql_sup.erl b/src/ejabberd_sql_sup.erl index d778e32b7..7526aedbe 100644 --- a/src/ejabberd_sql_sup.erl +++ b/src/ejabberd_sql_sup.erl @@ -62,15 +62,8 @@ start_link(Host) -> init([Host]) -> StartInterval = ejabberd_config:get_option( {sql_start_interval, Host}, - fun(I) when is_integer(I), I>0 -> I end, ?DEFAULT_SQL_START_INTERVAL), - Type = ejabberd_config:get_option({sql_type, Host}, - fun(mysql) -> mysql; - (pgsql) -> pgsql; - (sqlite) -> sqlite; - (mssql) -> mssql; - (odbc) -> odbc - end, odbc), + Type = ejabberd_config:get_option({sql_type, Host}, odbc), PoolSize = get_pool_size(Type, Host), case Type of sqlite -> @@ -119,7 +112,6 @@ remove_pid(Host, Pid) -> get_pool_size(SQLType, Host) -> PoolSize = ejabberd_config:get_option( {sql_pool_size, Host}, - fun(I) when is_integer(I), I>0 -> I end, case SQLType of sqlite -> 1; _ -> ?DEFAULT_POOL_SIZE @@ -230,12 +222,5 @@ opt_type(sql_pool_size) -> fun (I) when is_integer(I), I > 0 -> I end; opt_type(sql_start_interval) -> fun (I) when is_integer(I), I > 0 -> I end; -opt_type(sql_type) -> - fun (mysql) -> mysql; - (pgsql) -> pgsql; - (sqlite) -> sqlite; - (mssql) -> mssql; - (odbc) -> odbc - end; opt_type(_) -> - [sql_pool_size, sql_start_interval, sql_type]. + [sql_pool_size, sql_start_interval]. diff --git a/src/ejabberd_stun.erl b/src/ejabberd_stun.erl index ebe98f476..c45caf686 100644 --- a/src/ejabberd_stun.erl +++ b/src/ejabberd_stun.erl @@ -28,7 +28,7 @@ -protocol({xep, 176, '1.0'}). -export([tcp_init/2, udp_init/2, udp_recv/5, start/2, - socket_type/0]). + socket_type/0, listen_opt_type/1]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -73,14 +73,9 @@ prepare_turn_opts(Opts, _UseTurn = true) -> ok end, AuthFun = fun ejabberd_auth:get_password_s/2, - Shaper = gen_mod:get_opt(shaper, Opts, - fun(S) when is_atom(S) -> S end, - none), - AuthType = gen_mod:get_opt(auth_type, Opts, - fun(anonymous) -> anonymous; - (user) -> user - end, user), - Realm = case gen_mod:get_opt(auth_realm, Opts, fun iolist_to_binary/1) of + Shaper = gen_mod:get_opt(shaper, Opts, none), + AuthType = gen_mod:get_opt(auth_type, Opts, user), + Realm = case gen_mod:get_opt(auth_realm, Opts) of undefined when AuthType == user -> if NumberOfMyHosts > 1 -> ?WARNING_MSG("you have several virtual " @@ -100,3 +95,43 @@ prepare_turn_opts(Opts, _UseTurn = true) -> MaxRate = shaper:get_max_rate(Shaper), Realm ++ [{auth_fun, AuthFun},{shaper, MaxRate} | lists:keydelete(shaper, 1, Opts)]. + +listen_opt_type(use_turn) -> + fun(B) when is_boolean(B) -> B end; +listen_opt_type(turn_ip) -> + fun(S) -> + {ok, Addr} = inet_parse:ipv4_address(binary_to_list(S)), + Addr + end; +listen_opt_type(shaper) -> + fun acl:shaper_rules_validator/1; +listen_opt_type(auth_type) -> + fun(anonymous) -> anonymous; + (user) -> user + end; +listen_opt_type(auth_realm) -> + fun iolist_to_binary/1; +listen_opt_type(tls) -> + fun(B) when is_boolean(B) -> B end; +listen_opt_type(certfile) -> + fun iolist_to_binary/1; +listen_opt_type(turn_min_port) -> + fun(P) when is_integer(P), P > 0, P =< 65535 -> P end; +listen_opt_type(turn_max_port) -> + fun(P) when is_integer(P), P > 0, P =< 65535 -> P end; +listen_opt_type(turn_max_allocations) -> + fun(I) when is_integer(I), I>0 -> I; + (unlimited) -> infinity; + (infinity) -> infinity + end; +listen_opt_type(turn_max_permissions) -> + fun(I) when is_integer(I), I>0 -> I; + (unlimited) -> infinity; + (infinity) -> infinity + end; +listen_opt_type(server_name) -> + fun iolist_to_binary/1; +listen_opt_type(_) -> + [shaper, auth_type, auth_realm, tls, certfile, turn_min_port, + turn_max_port, turn_max_allocations, turn_max_permissions, + server_name]. diff --git a/src/ejabberd_system_monitor.erl b/src/ejabberd_system_monitor.erl index e5b924c1e..881bfa635 100644 --- a/src/ejabberd_system_monitor.erl +++ b/src/ejabberd_system_monitor.erl @@ -53,10 +53,7 @@ %% Description: Starts the server %%-------------------------------------------------------------------- start_link() -> - LH = ejabberd_config:get_option( - watchdog_large_heap, - fun(I) when is_integer(I), I > 0 -> I end, - 1000000), + LH = ejabberd_config:get_option(watchdog_large_heap, 1000000), Opts = [{large_heap, LH}], gen_server:start_link({local, ?MODULE}, ?MODULE, Opts, []). @@ -205,13 +202,7 @@ send_message(From, To, Body, ExtraEls) -> sub_els = ExtraEls}). get_admin_jids() -> - ejabberd_config:get_option( - watchdog_admins, - fun(JIDs) -> - [jid:tolower( - jid:decode( - iolist_to_binary(S))) || S <- JIDs] - end, []). + ejabberd_config:get_option(watchdog_admins, []). detailed_info(Pid) -> case process_info(Pid, dictionary) of diff --git a/src/ejabberd_web_admin.erl b/src/ejabberd_web_admin.erl index 1ef5c510f..f4186b3e5 100644 --- a/src/ejabberd_web_admin.erl +++ b/src/ejabberd_web_admin.erl @@ -75,25 +75,25 @@ get_acl_rule([<<"vhosts">>], _) -> get_acl_rule([<<"server">>, VHost | _RPath], Method) when Method =:= 'GET' orelse Method =:= 'HEAD' -> AC = gen_mod:get_module_opt(VHost, ejabberd_web_admin, - access, fun(A) -> A end, configure), + access, configure), ACR = gen_mod:get_module_opt(VHost, ejabberd_web_admin, - access_readonly, fun(A) -> A end, webadmin_view), + access_readonly, webadmin_view), {VHost, [AC, ACR]}; get_acl_rule([<<"server">>, VHost | _RPath], 'POST') -> AC = gen_mod:get_module_opt(VHost, ejabberd_web_admin, - access, fun(A) -> A end, configure), + access, configure), {VHost, [AC]}; %% Default rule: only global admins can access any other random page get_acl_rule(_RPath, Method) when Method =:= 'GET' orelse Method =:= 'HEAD' -> AC = gen_mod:get_module_opt(global, ejabberd_web_admin, - access, fun(A) -> A end, configure), + access, configure), ACR = gen_mod:get_module_opt(global, ejabberd_web_admin, - access_readonly, fun(A) -> A end, webadmin_view), + access_readonly, webadmin_view), {global, [AC, ACR]}; get_acl_rule(_RPath, 'POST') -> AC = gen_mod:get_module_opt(global, ejabberd_web_admin, - access, fun(A) -> A end, configure), + access, configure), {global, [AC]}. %%%================================== @@ -920,12 +920,7 @@ process_admin(Host, end; _ -> nothing end, - Rules = case ejabberd_config:get_option( - {access, Name, Host}, fun(V) -> V end) - of - undefined -> []; - Rs1 -> Rs1 - end, + Rules = ejabberd_config:get_option({access, Name, Host}, []), make_xhtml([?XC(<<"h1">>, (str:format( ?T(<<"~s access rule configuration">>), @@ -2980,8 +2975,7 @@ make_menu_item(item, 3, URI, Name, Lang) -> %%%================================== -opt_type(access) -> fun acl:access_rules_validator/1; opt_type(access_readonly) -> fun acl:access_rules_validator/1; -opt_type(_) -> [access, access_readonly]. +opt_type(_) -> [access_readonly]. %%% vim: set foldmethod=marker foldmarker=%%%%,%%%=: diff --git a/src/ejabberd_xmlrpc.erl b/src/ejabberd_xmlrpc.erl index 17fe75621..41695cb10 100644 --- a/src/ejabberd_xmlrpc.erl +++ b/src/ejabberd_xmlrpc.erl @@ -35,7 +35,7 @@ -author('badlop@process-one.net'). -export([start/2, handler/2, process/2, socket_type/0, - transform_listen_option/2]). + transform_listen_option/2, listen_opt_type/1]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -197,36 +197,7 @@ socket_type() -> raw. %% HTTP interface %% ----------------------------- process(_, #request{method = 'POST', data = Data, opts = Opts, ip = {IP, _}}) -> - AccessCommandsOpts = gen_mod:get_opt(access_commands, Opts, - fun(L) when is_list(L) -> L end, - undefined), - AccessCommands = - case AccessCommandsOpts of - undefined -> undefined; - _ -> - lists:flatmap( - fun({Ac, AcOpts}) -> - Commands = gen_mod:get_opt( - commands, lists:flatten(AcOpts), - fun(A) when is_atom(A) -> - A; - (L) when is_list(L) -> - true = lists:all( - fun is_atom/1, - L), - L - end, all), - %% CommOpts = gen_mod:get_opt( - %% options, AcOpts, - %% fun(L) when is_list(L) -> L end, - %% []), - [{<<"ejabberd_xmlrpc compatibility shim">>, {[?MODULE], [{access, Ac}], Commands}}]; - (Wrong) -> - ?WARNING_MSG("wrong options format for ~p: ~p", - [?MODULE, Wrong]), - [] - end, lists:flatten(AccessCommandsOpts)) - end, + AccessCommands = gen_mod:get_opt(access_commands, Opts), GetAuth = true, State = #state{access_commands = AccessCommands, get_auth = GetAuth, ip = IP}, case fxml_stream:parse_element(Data) of @@ -590,3 +561,25 @@ transform_listen_option({access_commands, ACOpts}, Opts) -> [{access_commands, NewACOpts}|Opts]; transform_listen_option(Opt, Opts) -> [Opt|Opts]. + +listen_opt_type(access_commands) -> + fun(Opts) -> + lists:map( + fun({Ac, AcOpts}) -> + Commands = case proplists:get_value( + commands, lists:flatten(AcOpts), all) of + Cmd when is_atom(Cmd) -> Cmd; + Cmds when is_list(Cmds) -> + true = lists:all(fun is_atom/1, Cmds), + Cmds + end, + {<<"ejabberd_xmlrpc compatibility shim">>, + {[?MODULE], [{access, Ac}], Commands}} + end, lists:flatten(Opts)) + end; +listen_opt_type(maxsessions) -> + fun(I) when is_integer(I), I>0 -> I end; +listen_opt_type(timeout) -> + fun(I) when is_integer(I), I>0 -> I end; +listen_opt_type(_) -> + [access_commands, maxsessions, timeout]. diff --git a/src/eldap.erl b/src/eldap.erl index 5f8c6f722..9763e2a79 100644 --- a/src/eldap.erl +++ b/src/eldap.erl @@ -565,11 +565,7 @@ get_handle(Name) when is_binary(Name) -> %% process. %%---------------------------------------------------------------------- init([Hosts, Port, Rootdn, Passwd, Opts]) -> - Encrypt = case gen_mod:get_opt(encrypt, Opts, - fun(tls) -> tls; - (starttls) -> starttls; - (none) -> none - end) of + Encrypt = case gen_mod:get_opt(encrypt, Opts) of tls -> tls; _ -> none end, @@ -581,35 +577,19 @@ init([Hosts, Port, Rootdn, Passwd, Opts]) -> end; PT -> PT end, - CacertOpts = case gen_mod:get_opt( - tls_cacertfile, Opts, - fun(S) when is_binary(S) -> - binary_to_list(S); - (undefined) -> - undefined - end) of + CacertOpts = case gen_mod:get_opt(tls_cacertfile, Opts) of undefined -> []; Path -> [{cacertfile, Path}] end, - DepthOpts = case gen_mod:get_opt( - tls_depth, Opts, - fun(I) when is_integer(I), I>=0 -> - I; - (undefined) -> - undefined - end) of + DepthOpts = case gen_mod:get_opt(tls_depth, Opts) of undefined -> []; Depth -> [{depth, Depth}] end, - Verify = gen_mod:get_opt(tls_verify, Opts, - fun(hard) -> hard; - (soft) -> soft; - (false) -> false - end, false), + Verify = gen_mod:get_opt(tls_verify, Opts, false), TLSOpts = if (Verify == hard orelse Verify == soft) andalso CacertOpts == [] -> ?WARNING_MSG("TLS verification is enabled but no CA " diff --git a/src/eldap_utils.erl b/src/eldap_utils.erl index 8c071c6dd..d15e5bc9c 100644 --- a/src/eldap_utils.erl +++ b/src/eldap_utils.erl @@ -28,7 +28,7 @@ -behaviour(ejabberd_config). -author('mremond@process-one.net'). --export([generate_subfilter/1, find_ldap_attrs/2, +-export([generate_subfilter/1, find_ldap_attrs/2, check_filter/1, get_ldap_attr/2, get_user_part/2, make_filter/2, get_state/2, case_insensitive_match/2, get_config/2, decode_octet_string/3, uids_domain_subst/2, opt_type/1]). @@ -137,6 +137,11 @@ make_filter(Data, UIDs) -> eldap:'and'(Filter) end. +check_filter(F) -> + NewF = iolist_to_binary(F), + {ok, _} = eldap_filter:parse(NewF), + NewF. + -spec case_insensitive_match(binary(), binary()) -> boolean(). case_insensitive_match(X, Y) -> @@ -168,58 +173,25 @@ uids_domain_subst(Host, UIDs) -> -spec get_config(binary(), list()) -> eldap_config(). get_config(Host, Opts) -> - Servers = gen_mod:get_opt({ldap_servers, Host}, Opts, - fun(L) -> - [iolist_to_binary(H) || H <- L] - end, [<<"localhost">>]), - Backups = gen_mod:get_opt({ldap_backups, Host}, Opts, - fun(L) -> - [iolist_to_binary(H) || H <- L] - end, []), - Encrypt = gen_mod:get_opt({ldap_encrypt, Host}, Opts, - fun(tls) -> tls; - (starttls) -> starttls; - (none) -> none - end, none), - TLSVerify = gen_mod:get_opt({ldap_tls_verify, Host}, Opts, - fun(hard) -> hard; - (soft) -> soft; - (false) -> false - end, false), - TLSCAFile = gen_mod:get_opt({ldap_tls_cacertfile, Host}, Opts, - fun iolist_to_binary/1), - TLSDepth = gen_mod:get_opt({ldap_tls_depth, Host}, Opts, - fun(I) when is_integer(I), I>=0 -> I end), + Servers = gen_mod:get_opt({ldap_servers, Host}, Opts, [<<"localhost">>]), + Backups = gen_mod:get_opt({ldap_backups, Host}, Opts, []), + Encrypt = gen_mod:get_opt({ldap_encrypt, Host}, Opts, none), + TLSVerify = gen_mod:get_opt({ldap_tls_verify, Host}, Opts, false), + TLSCAFile = gen_mod:get_opt({ldap_tls_cacertfile, Host}, Opts), + TLSDepth = gen_mod:get_opt({ldap_tls_depth, Host}, Opts), Port = gen_mod:get_opt({ldap_port, Host}, Opts, - fun(I) when is_integer(I), I>0 -> I end, - case Encrypt of - tls -> ?LDAPS_PORT; - starttls -> ?LDAP_PORT; - _ -> ?LDAP_PORT - end), - RootDN = gen_mod:get_opt({ldap_rootdn, Host}, Opts, - fun iolist_to_binary/1, - <<"">>), - Password = gen_mod:get_opt({ldap_password, Host}, Opts, - fun iolist_to_binary/1, - <<"">>), - Base = gen_mod:get_opt({ldap_base, Host}, Opts, - fun iolist_to_binary/1, - <<"">>), - OldDerefAliases = gen_mod:get_opt({deref_aliases, Host}, Opts, - fun(never) -> never; - (searching) -> searching; - (finding) -> finding; - (always) -> always - end, unspecified), + case Encrypt of + tls -> ?LDAPS_PORT; + starttls -> ?LDAP_PORT; + _ -> ?LDAP_PORT + end), + RootDN = gen_mod:get_opt({ldap_rootdn, Host}, Opts, <<"">>), + Password = gen_mod:get_opt({ldap_password, Host}, Opts, <<"">>), + Base = gen_mod:get_opt({ldap_base, Host}, Opts, <<"">>), + OldDerefAliases = gen_mod:get_opt({deref_aliases, Host}, Opts, unspecified), DerefAliases = if OldDerefAliases == unspecified -> - gen_mod:get_opt({ldap_deref_aliases, Host}, Opts, - fun(never) -> never; - (searching) -> searching; - (finding) -> finding; - (always) -> always - end, never); + gen_mod:get_opt({ldap_deref_aliases, Host}, Opts, never); true -> ?WARNING_MSG("Option 'deref_aliases' is deprecated. " "The option is still supported " @@ -372,7 +344,8 @@ opt_type(ldap_port) -> opt_type(ldap_rootdn) -> fun iolist_to_binary/1; opt_type(ldap_servers) -> fun (L) -> [iolist_to_binary(H) || H <- L] end; -opt_type(ldap_tls_cacertfile) -> fun iolist_to_binary/1; +opt_type(ldap_tls_cacertfile) -> + fun(S) -> binary_to_list(iolist_to_binary(S)) end; opt_type(ldap_tls_depth) -> fun (I) when is_integer(I), I >= 0 -> I end; opt_type(ldap_tls_verify) -> @@ -380,8 +353,19 @@ opt_type(ldap_tls_verify) -> (soft) -> soft; (false) -> false end; +opt_type(ldap_filter) -> + fun check_filter/1; +opt_type(ldap_uids) -> + fun (Us) -> + lists:map(fun ({U, P}) -> + {iolist_to_binary(U), iolist_to_binary(P)}; + ({U}) -> {iolist_to_binary(U)}; + (U) -> {iolist_to_binary(U)} + end, + lists:flatten(Us)) + end; opt_type(_) -> - [deref_aliases, ldap_backups, ldap_base, + [deref_aliases, ldap_backups, ldap_base, ldap_uids, ldap_deref_aliases, ldap_encrypt, ldap_password, - ldap_port, ldap_rootdn, ldap_servers, + ldap_port, ldap_rootdn, ldap_servers, ldap_filter, ldap_tls_cacertfile, ldap_tls_depth, ldap_tls_verify]. diff --git a/src/ext_mod.erl b/src/ext_mod.erl index 6ca218c2a..15fe8e17f 100644 --- a/src/ext_mod.erl +++ b/src/ext_mod.erl @@ -439,11 +439,7 @@ short_spec({Module, Attrs}) when is_atom(Module), is_list(Attrs) -> {Module, proplists:get_value(summary, Attrs, "")}. is_contrib_allowed() -> - ejabberd_config:get_option(allow_contrib_modules, - fun(false) -> false; - (no) -> false; - (_) -> true - end, true). + ejabberd_config:get_option(allow_contrib_modules, true). %% -- build functions diff --git a/src/extauth.erl b/src/extauth.erl index 6ec7e7760..c6f25102c 100644 --- a/src/extauth.erl +++ b/src/extauth.erl @@ -105,11 +105,7 @@ random_instance(MaxNum) -> randoms:uniform(MaxNum) - 1. get_instances(Server) -> - ejabberd_config:get_option( - {extauth_instances, Server}, - fun(V) when is_integer(V), V > 0 -> - V - end, 1). + ejabberd_config:get_option({extauth_instances, Server}, 1). loop(Port, Timeout, ProcessName, ExtPrg) -> receive diff --git a/src/gen_mod.erl b/src/gen_mod.erl index 4b845a386..44093950b 100644 --- a/src/gen_mod.erl +++ b/src/gen_mod.erl @@ -33,16 +33,18 @@ -export([init/1, start_link/0, start_child/3, start_child/4, stop_child/1, stop_child/2, config_reloaded/0]). -export([start_module/2, start_module/3, - stop_module/2, stop_module_keep_config/2, get_opt/3, - get_opt/4, get_opt_host/3, opt_type/1, is_equal_opt/5, - get_module_opt/4, get_module_opt/5, get_module_opt_host/3, + stop_module/2, stop_module_keep_config/2, + get_opt/2, get_opt/3, get_opt_host/3, opt_type/1, is_equal_opt/4, + get_module_opt/3, get_module_opt/4, get_module_opt_host/3, loaded_modules/1, loaded_modules_with_opts/1, get_hosts/2, get_module_proc/2, is_loaded/2, is_loaded_elsewhere/2, start_modules/0, start_modules/1, stop_modules/0, stop_modules/1, db_mod/2, db_mod/3, ram_db_mod/2, ram_db_mod/3, db_type/2, db_type/3, ram_db_type/2, ram_db_type/3]). -%%-export([behaviour_info/1]). +%% Deprecated functions +-export([get_opt/4, get_module_opt/5]). +-deprecated([{get_opt, 4}, {get_module_opt, 5}]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -73,7 +75,7 @@ start_link() -> case supervisor:start_link({local, ejabberd_gen_mod_sup}, ?MODULE, []) of {ok, Pid} -> - gen_mod:start_modules(), + start_modules(), {ok, Pid}; Err -> Err @@ -119,14 +121,7 @@ start_modules() -> end, ?MYHOSTS). get_modules_options(Host) -> - ejabberd_config:get_option( - {modules, Host}, - fun(Mods) -> - lists:map( - fun({M, A}) when is_atom(M), is_list(A) -> - {M, A} - end, Mods) - end, []). + ejabberd_config:get_option({modules, Host}, []). sort_modules(Host, ModOpts) -> G = digraph:new([acyclic]), @@ -164,7 +159,9 @@ sort_modules(Host, ModOpts) -> end end, Deps) end, ModOpts), - [digraph:vertex(G, V) || V <- digraph_utils:topsort(G)]. + Result = [digraph:vertex(G, V) || V <- digraph_utils:topsort(G)], + digraph:delete(G), + Result. -spec start_modules(binary()) -> ok. @@ -181,16 +178,23 @@ start_module(Host, Module) -> Modules = get_modules_options(Host), case lists:keyfind(Module, 1, Modules) of {_, Opts} -> - start_module(Host, Module, Opts); + start_module(Host, Module, Opts, false); false -> {error, not_found_in_config} end. -spec start_module(binary(), atom(), opts()) -> ok | {ok, pid()}. +start_module(Host, Module, Opts) -> + start_module(Host, Module, Opts, true). -start_module(Host, Module, Opts0) -> +-spec start_module(binary(), atom(), opts(), boolean()) -> ok | {ok, pid()}. +start_module(Host, Module, Opts0, NeedValidation) -> ?DEBUG("loading ~s at ~s", [Module, Host]), - Opts = validate_opts(Module, Opts0), + Opts = if NeedValidation -> + validate_opts(Module, Opts0); + true -> + Opts0 + end, store_options(Host, Module, Opts), try case Module:start(Host, Opts) of ok -> ok; @@ -211,8 +215,7 @@ start_module(Host, Module, Opts0) -> -spec reload_modules(binary()) -> ok. reload_modules(Host) -> - NewMods = ejabberd_config:get_option( - {modules, Host}, opt_type(modules), []), + NewMods = ejabberd_config:get_option({modules, Host}, []), OldMods = ets:select( ejabberd_modules, ets:fun2ms( @@ -240,19 +243,23 @@ reload_modules(Host) -> lists:foreach( fun({Mod, OldOpts}) -> case lists:keyfind(Mod, 1, NewMods) of - {_, NewOpts} when NewOpts /= OldOpts -> - reload_module(Host, Mod, NewOpts, OldOpts); + {_, NewOpts0} -> + case validate_opts(Mod, NewOpts0) of + OldOpts -> + ok; + NewOpts -> + reload_module(Host, Mod, NewOpts, OldOpts) + end; _ -> ok end end, OldMods). -spec reload_module(binary(), module(), opts(), opts()) -> ok | {ok, pid()}. -reload_module(Host, Module, NewOpts0, OldOpts) -> +reload_module(Host, Module, NewOpts, OldOpts) -> case erlang:function_exported(Module, reload, 3) of true -> ?DEBUG("reloading ~s at ~s", [Module, Host]), - NewOpts = validate_opts(Module, NewOpts0), store_options(Host, Module, NewOpts), try case Module:reload(Host, NewOpts, OldOpts) of ok -> ok; @@ -271,7 +278,7 @@ reload_module(Host, Module, NewOpts0, OldOpts) -> ?WARNING_MSG("module ~s doesn't support reloading " "and will be restarted", [Module]), stop_module(Host, Module), - start_module(Host, Module, NewOpts0) + start_module(Host, Module, NewOpts, false) end. -spec store_options(binary(), module(), opts()) -> true. @@ -311,7 +318,7 @@ stop_modules(Host) -> Modules = get_modules_options(Host), lists:foreach( fun({Module, _Args}) -> - gen_mod:stop_module_keep_config(Host, Module) + stop_module_keep_config(Host, Module) end, Modules). -spec stop_module(binary(), atom()) -> error | {aborted, any()} | {atomic, any()}. @@ -359,40 +366,47 @@ wait_for_stop1(MonitorReference) -> -type check_fun() :: fun((any()) -> any()) | {module(), atom()}. --spec get_opt(atom() | {atom(), binary()|global}, opts(), check_fun()) -> any(). - -get_opt(Opt, Opts, F) -> - get_opt(Opt, Opts, F, undefined). +-spec get_opt(atom() | {atom(), binary() | global}, opts()) -> any(). +get_opt(Opt, Opts) -> + get_opt(Opt, Opts, undefined). --spec get_opt(atom() | {atom(), binary()|global}, opts(), check_fun(), any()) -> any(). +-spec get_opt(atom() | {atom(), binary()|global}, opts(), check_fun() | any()) -> any(). -get_opt({Opt, Host}, Opts, F, Default) -> - case lists:keysearch(Opt, 1, Opts) of +get_opt(Opt, Opts, F) when is_function(F) -> + get_opt(Opt, Opts, undefined); +get_opt({Opt, Host}, Opts, Default) -> + case lists:keyfind(Opt, 1, Opts) of false -> - ejabberd_config:get_option({Opt, Host}, F, Default); - {value, {_, Val}} -> - ejabberd_config:prepare_opt_val(Opt, Val, F, Default) + ejabberd_config:get_option({Opt, Host}, Default); + {_, Val} -> + Val end; -get_opt(Opt, Opts, F, Default) -> - case lists:keysearch(Opt, 1, Opts) of +get_opt(Opt, Opts, Default) -> + case lists:keyfind(Opt, 1, Opts) of false -> Default; - {value, {_, Val}} -> - ejabberd_config:prepare_opt_val(Opt, Val, F, Default) + {_, Val} -> + Val end. --spec get_module_opt(global | binary(), atom(), atom(), check_fun()) -> any(). +-spec get_opt(atom() | {atom(), binary()}, opts(), check_fun(), any()) -> any(). +get_opt(Opt, Opts, _, Default) -> + get_opt(Opt, Opts, Default). -get_module_opt(Host, Module, Opt, F) -> - get_module_opt(Host, Module, Opt, F, undefined). +-spec get_module_opt(global | binary(), atom(), atom()) -> any(). --spec get_module_opt(global | binary(), atom(), atom(), check_fun(), any()) -> any(). +get_module_opt(Host, Module, Opt) -> + get_module_opt(Host, Module, Opt, undefined). -get_module_opt(global, Module, Opt, F, Default) -> +-spec get_module_opt(global | binary(), atom(), atom(), any()) -> any(). + +get_module_opt(Host, Module, Opt, F) when is_function(F) -> + get_module_opt(Host, Module, Opt, undefined); +get_module_opt(global, Module, Opt, Default) -> Hosts = (?MYHOSTS), [Value | Values] = lists:map(fun (Host) -> get_module_opt(Host, Module, Opt, - F, Default) + Default) end, Hosts), Same_all = lists:all(fun (Other_value) -> @@ -403,26 +417,28 @@ get_module_opt(global, Module, Opt, F, Default) -> true -> Value; false -> Default end; -get_module_opt(Host, Module, Opt, F, Default) -> +get_module_opt(Host, Module, Opt, Default) -> OptsList = ets:lookup(ejabberd_modules, {Module, Host}), case OptsList of [] -> Default; [#ejabberd_module{opts = Opts} | _] -> - get_opt(Opt, Opts, F, Default) + get_opt(Opt, Opts, Default) end. +-spec get_module_opt(global | binary(), atom(), atom(), check_fun(), any()) -> any(). +get_module_opt(Host, Module, Opt, _, Default) -> + get_module_opt(Host, Module, Opt, Default). + -spec get_module_opt_host(global | binary(), atom(), binary()) -> binary(). get_module_opt_host(Host, Module, Default) -> - Val = get_module_opt(Host, Module, host, - fun iolist_to_binary/1, - Default), + Val = get_module_opt(Host, Module, host, Default), ejabberd_regexp:greplace(Val, <<"@HOST@">>, Host). -spec get_opt_host(binary(), opts(), binary()) -> binary(). get_opt_host(Host, Opts, Default) -> - Val = get_opt(host, Opts, fun iolist_to_binary/1, Default), + Val = get_opt(host, Opts, Default), ejabberd_regexp:greplace(Val, <<"@HOST@">>, Host). @@ -444,23 +460,19 @@ get_module_mod_opt_type_fun(Module) -> throw({'EXIT', {undef, mod_opt_type}}); {[], Args, _} -> Args; {Funs, _, _} -> - fun(Val) -> - lists:any(fun(F) -> - try F(Val) of - _ -> - true - catch {replace_with, _NewVal} = E -> - throw(E); - {invalid_syntax, _Error} = E2 -> - throw(E2); - _:_ -> - false - end - end, Funs) - end + fun(Val) -> try_mod_opt_type(Funs, Val) end end end. +try_mod_opt_type([Fun|Funs], Val) -> + try Fun(Val) of + NewVal -> NewVal + catch {invalid_syntax, _Error} = E2 -> + throw(E2); + _:_ -> + try_mod_opt_type(Funs, Val) + end. + validate_opts(Module, Opts) -> ModOptFun = get_module_mod_opt_type_fun(Module), lists:filtermap( @@ -468,11 +480,9 @@ validate_opts(Module, Opts) -> case catch ModOptFun(Opt) of VFun when is_function(VFun) -> try VFun(Val) of - _ -> - true - catch {replace_with, NewVal} -> - {true, {Opt, NewVal}}; - {invalid_syntax, Error} -> + NewVal -> + {true, {Opt, NewVal}} + catch {invalid_syntax, Error} -> ?ERROR_MSG("ignoring invalid value '~p' for " "option '~s' of module '~s': ~s", [Val, Opt, Module, Error]), @@ -506,27 +516,21 @@ validate_opts(Module, Opts) -> db_type(Opts, Module) when is_list(Opts) -> db_type(global, Opts, Module); db_type(Host, Module) when is_atom(Module) -> - case catch Module:mod_opt_type(db_type) of - F when is_function(F) -> - case get_module_opt(Host, Module, db_type, F) of - undefined -> ejabberd_config:default_db(Host, Module); - Type -> Type - end; - _ -> - undefined + case get_module_opt(Host, Module, db_type) of + undefined -> + ejabberd_config:default_db(Host, Module); + Type -> + Type end. -spec db_type(binary() | global, opts(), module()) -> db_type(). db_type(Host, Opts, Module) -> - case catch Module:mod_opt_type(db_type) of - F when is_function(F) -> - case get_opt(db_type, Opts, F) of - undefined -> ejabberd_config:default_db(Host, Module); - Type -> Type - end; - _ -> - undefined + case get_opt(db_type, Opts) of + undefined -> + ejabberd_config:default_db(Host, Module); + Type -> + Type end. -spec db_mod(binary() | global | db_type(), module()) -> module(). @@ -546,26 +550,20 @@ db_mod(Host, Opts, Module) when is_list(Opts) -> ram_db_type(Opts, Module) when is_list(Opts) -> ram_db_type(global, Opts, Module); ram_db_type(Host, Module) when is_atom(Module) -> - case catch Module:mod_opt_type(ram_db_type) of - F when is_function(F) -> - case get_module_opt(Host, Module, ram_db_type, F) of - undefined -> ejabberd_config:default_ram_db(Host, Module); - Type -> Type - end; - _ -> - undefined + case get_module_opt(Host, Module, ram_db_type) of + undefined -> + ejabberd_config:default_ram_db(Host, Module); + Type -> + Type end. -spec ram_db_type(binary() | global, opts(), module()) -> db_type(). ram_db_type(Host, Opts, Module) -> - case catch Module:mod_opt_type(ram_db_type) of - F when is_function(F) -> - case get_opt(ram_db_type, Opts, F) of - undefined -> ejabberd_config:default_ram_db(Host, Module); - Type -> Type - end; - _ -> - undefined + case get_opt(ram_db_type, Opts) of + undefined -> + ejabberd_config:default_ram_db(Host, Module); + Type -> + Type end. -spec ram_db_mod(binary() | global | db_type(), module()) -> module(). @@ -596,11 +594,9 @@ loaded_modules_with_opts(Host) -> -spec get_hosts(opts(), binary()) -> [binary()]. get_hosts(Opts, Prefix) -> - case get_opt(hosts, Opts, - fun(Hs) -> [iolist_to_binary(H) || H <- Hs] end) of + case get_opt(hosts, Opts) of undefined -> - case get_opt(host, Opts, - fun iolist_to_binary/1) of + case get_opt(host, Opts) of undefined -> [<<Prefix/binary, Host/binary>> || Host <- ?MYHOSTS]; Host -> @@ -639,11 +635,11 @@ config_reloaded() -> reload_modules(Host) end, ?MYHOSTS). --spec is_equal_opt(atom(), opts(), opts(), check_fun(), any()) -> +-spec is_equal_opt(atom(), opts(), opts(), any()) -> true | {false, any(), any()}. -is_equal_opt(Opt, NewOpts, OldOpts, VFun, Default) -> - NewVal = get_opt(Opt, NewOpts, VFun, Default), - OldVal = get_opt(Opt, OldOpts, VFun, Default), +is_equal_opt(Opt, NewOpts, OldOpts, Default) -> + NewVal = get_opt(Opt, NewOpts, Default), + OldVal = get_opt(Opt, OldOpts, Default), if NewVal /= OldVal -> {false, NewVal, OldVal}; true -> diff --git a/src/misc.erl b/src/misc.erl index 99612b77d..dae95c6d5 100644 --- a/src/misc.erl +++ b/src/misc.erl @@ -33,7 +33,7 @@ hex_to_bin/1, hex_to_base64/1, expand_keyword/3, atom_to_binary/1, binary_to_atom/1, tuple_to_binary/1, l2i/1, i2l/1, i2l/2, expr_to_term/1, term_to_expr/1, - encode_pid/1, decode_pid/2, compile_exprs/2]). + encode_pid/1, decode_pid/2, compile_exprs/2, join_atoms/2]). %%%=================================================================== %%% API @@ -237,6 +237,10 @@ compile_exprs(Mod, Exprs) -> {error, compile_failed} end. +-spec join_atoms([atom()], binary()) -> binary(). +join_atoms(Atoms, Sep) -> + str:join([io_lib:format("~p", [A]) || A <- Atoms], Sep). + %%%=================================================================== %%% Internal functions %%%=================================================================== diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl index a0090aba9..46fed2867 100644 --- a/src/mod_adhoc.erl +++ b/src/mod_adhoc.erl @@ -42,8 +42,7 @@ -include("xmpp.hrl"). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS, ?MODULE, process_local_iq, IQDisc), @@ -89,9 +88,7 @@ stop(Host) -> ?NS_COMMANDS). reload(Host, NewOpts, OldOpts) -> - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS, ?MODULE, process_local_iq, IQDisc), @@ -108,7 +105,6 @@ get_local_commands(Acc, _From, Lang) -> Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, - fun(B) when is_boolean(B) -> B end, false), case Display of false -> Acc; @@ -138,7 +134,6 @@ get_sm_commands(Acc, _From, #jid{lserver = LServer} = To, <<"">>, Lang) -> Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, - fun(B) when is_boolean(B) -> B end, false), case Display of false -> Acc; diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl index 141f5f5db..133b2fd29 100644 --- a/src/mod_admin_extra.erl +++ b/src/mod_admin_extra.erl @@ -1363,7 +1363,7 @@ get_last(User, Server) -> %% <aa xmlns='bb'>Cluth</aa> private_get(Username, Host, Element, Ns) -> - ElementXml = [{Ns, #xmlel{name = Element, attrs = [{<<"xmlns">>, Ns}]}}], + ElementXml = #xmlel{name = Element, attrs = [{<<"xmlns">>, Ns}]}, Els = mod_private:get_data(jid:nodeprep(Username), jid:nameprep(Host), [{Ns, ElementXml}]), binary_to_list(fxml:element_to_binary(xmpp:encode(#private{xml_els = Els}))). diff --git a/src/mod_announce.erl b/src/mod_announce.erl index 522be8936..35d179c0c 100644 --- a/src/mod_announce.erl +++ b/src/mod_announce.erl @@ -763,9 +763,7 @@ send_announcement_to_all(Host, SubjectS, BodyS) -> -spec get_access(global | binary()) -> atom(). get_access(Host) -> - gen_mod:get_module_opt(Host, ?MODULE, access, - fun(A) -> A end, - none). + gen_mod:get_module_opt(Host, ?MODULE, access, none). -spec add_store_hint(stanza()) -> stanza(). add_store_hint(El) -> diff --git a/src/mod_block_strangers.erl b/src/mod_block_strangers.erl index 8072fa874..6a4a96bf9 100644 --- a/src/mod_block_strangers.erl +++ b/src/mod_block_strangers.erl @@ -74,14 +74,8 @@ filter_packet({#message{} = Msg, State} = Acc) -> Acc; false -> #{lserver := LServer} = State, - Drop = - gen_mod:get_module_opt(LServer, ?MODULE, drop, - fun(B) when is_boolean(B) -> B end, - true), - Log = - gen_mod:get_module_opt(LServer, ?MODULE, log, - fun(B) when is_boolean(B) -> B end, - false), + Drop = gen_mod:get_module_opt(LServer, ?MODULE, drop, true), + Log = gen_mod:get_module_opt(LServer, ?MODULE, log, false), if Log -> ?INFO_MSG("Drop packet: ~s", diff --git a/src/mod_blocking.erl b/src/mod_blocking.erl index 97c2e8b16..6da7b4358 100644 --- a/src/mod_blocking.erl +++ b/src/mod_blocking.erl @@ -46,8 +46,7 @@ -type block_event() :: {block, [jid()]} | {unblock, [jid()]} | unblock_all. start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 50), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING, ?MODULE, process_iq, IQDisc). @@ -57,9 +56,7 @@ stop(Host) -> gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING). reload(Host, NewOpts, OldOpts) -> - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING, ?MODULE, process_iq, IQDisc); diff --git a/src/mod_bosh.erl b/src/mod_bosh.erl index c2bf7600e..ed12d569c 100644 --- a/src/mod_bosh.erl +++ b/src/mod_bosh.erl @@ -144,10 +144,7 @@ reload(_Host, NewOpts, _OldOpts) -> %%% Internal functions %%%=================================================================== start_jiffy(Opts) -> - case gen_mod:get_opt(json, Opts, - fun(false) -> false; - (true) -> true - end, false) of + case gen_mod:get_opt(json, Opts, false) of false -> ok; true -> @@ -220,7 +217,7 @@ use_cache(Mod) -> true -> Mod:use_cache(); false -> gen_mod:get_module_opt( - global, ?MODULE, use_cache, mod_opt_type(use_cache), + global, ?MODULE, use_cache, ejabberd_config:use_cache(global)) end. @@ -244,15 +241,12 @@ delete_cache(Mod, SID) -> cache_opts() -> MaxSize = gen_mod:get_module_opt( global, ?MODULE, cache_size, - mod_opt_type(cache_size), ejabberd_config:cache_size(global)), CacheMissed = gen_mod:get_module_opt( global, ?MODULE, cache_missed, - mod_opt_type(cache_missed), ejabberd_config:cache_missed(global)), LifeTime = case gen_mod:get_module_opt( global, ?MODULE, cache_life_time, - mod_opt_type(cache_life_time), ejabberd_config:cache_life_time(global)) of infinity -> infinity; I -> timer:seconds(I) diff --git a/src/mod_caps.erl b/src/mod_caps.erl index 56eaf5f4f..5609030d3 100644 --- a/src/mod_caps.erl +++ b/src/mod_caps.erl @@ -247,8 +247,7 @@ reload(Host, NewOpts, OldOpts) -> ok end, case gen_mod:is_equal_opt(cache_size, NewOpts, OldOpts, - fun(I) when is_integer(I), I>0 -> I end, - 1000) of + ejabberd_config:cache_size(Host)) of {false, MaxSize, _} -> ets_cache:setopts(caps_features_cache, [{max_size, MaxSize}]), ets_cache:setopts(caps_requests_cache, [{max_size, MaxSize}]); @@ -256,9 +255,12 @@ reload(Host, NewOpts, OldOpts) -> ok end, case gen_mod:is_equal_opt(cache_life_time, NewOpts, OldOpts, - fun(I) when is_integer(I), I>0 -> I end, - timer:hours(24) div 1000) of - {false, LifeTime, _} -> + ejabberd_config:cache_life_time(Host)) of + {false, Time, _} -> + LifeTime = case Time of + infinity -> infinity; + _ -> timer:seconds(Time) + end, ets_cache:setopts(caps_features_cache, [{life_time, LifeTime}]); true -> ok @@ -483,18 +485,14 @@ init_cache(Host, Opts) -> {life_time, timer:seconds(?BAD_HASH_LIFETIME)}]). use_cache(Host, Opts) -> - gen_mod:get_opt(use_cache, Opts, mod_opt_type(use_cache), - ejabberd_config:use_cache(Host)). + gen_mod:get_opt(use_cache, Opts, ejabberd_config:use_cache(Host)). cache_opts(Host, Opts) -> MaxSize = gen_mod:get_opt(cache_size, Opts, - mod_opt_type(cache_size), ejabberd_config:cache_size(Host)), CacheMissed = gen_mod:get_opt(cache_missed, Opts, - mod_opt_type(cache_missed), ejabberd_config:cache_missed(Host)), LifeTime = case gen_mod:get_opt(cache_life_time, Opts, - mod_opt_type(cache_life_time), ejabberd_config:cache_life_time(Host)) of infinity -> infinity; I -> timer:seconds(I) diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl index 91c18aabf..0d036c8e9 100644 --- a/src/mod_carboncopy.erl +++ b/src/mod_carboncopy.erl @@ -61,7 +61,7 @@ is_carbon_copy(_) -> false. start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts,fun gen_iq_handler:check_type/1, one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 50), Mod = gen_mod:ram_db_mod(Host, ?MODULE), init_cache(Mod, Host, Opts), @@ -95,9 +95,7 @@ reload(Host, NewOpts, OldOpts) -> false -> ok end, - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_CARBONS_2, ?MODULE, iq_handler, IQDisc); @@ -331,13 +329,13 @@ init_cache(Mod, Host, Opts) -> -spec cache_opts(binary(), gen_mod:opts()) -> [proplists:property()]. cache_opts(Host, Opts) -> MaxSize = gen_mod:get_opt( - cache_size, Opts, mod_opt_type(cache_size), + cache_size, Opts, ejabberd_config:cache_size(Host)), CacheMissed = gen_mod:get_opt( - cache_missed, Opts, mod_opt_type(cache_missed), + cache_missed, Opts, ejabberd_config:cache_missed(Host)), LifeTime = case gen_mod:get_opt( - cache_life_time, Opts, mod_opt_type(cache_life_time), + cache_life_time, Opts, ejabberd_config:cache_life_time(Host)) of infinity -> infinity; I -> timer:seconds(I) @@ -350,7 +348,7 @@ use_cache(Mod, Host) -> true -> Mod:use_cache(Host); false -> gen_mod:get_module_opt( - Host, ?MODULE, use_cache, mod_opt_type(use_cache), + Host, ?MODULE, use_cache, ejabberd_config:use_cache(Host)) end. diff --git a/src/mod_client_state.erl b/src/mod_client_state.erl index be5679855..f2fcb37ee 100644 --- a/src/mod_client_state.erl +++ b/src/mod_client_state.erl @@ -59,18 +59,9 @@ %%-------------------------------------------------------------------- -spec start(binary(), gen_mod:opts()) -> ok. start(Host, Opts) -> - QueuePresence = - gen_mod:get_opt(queue_presence, Opts, - fun(B) when is_boolean(B) -> B end, - true), - QueueChatStates = - gen_mod:get_opt(queue_chat_states, Opts, - fun(B) when is_boolean(B) -> B end, - true), - QueuePEP = - gen_mod:get_opt(queue_pep, Opts, - fun(B) when is_boolean(B) -> B end, - true), + QueuePresence = gen_mod:get_opt(queue_presence, Opts, true), + QueueChatStates = gen_mod:get_opt(queue_chat_states, Opts, true), + QueuePEP = gen_mod:get_opt(queue_pep, Opts, true), if QueuePresence; QueueChatStates; QueuePEP -> register_hooks(Host), if QueuePresence -> @@ -93,18 +84,9 @@ start(Host, Opts) -> -spec stop(binary()) -> ok. stop(Host) -> - QueuePresence = - gen_mod:get_module_opt(Host, ?MODULE, queue_presence, - fun(B) when is_boolean(B) -> B end, - true), - QueueChatStates = - gen_mod:get_module_opt(Host, ?MODULE, queue_chat_states, - fun(B) when is_boolean(B) -> B end, - true), - QueuePEP = - gen_mod:get_module_opt(Host, ?MODULE, queue_pep, - fun(B) when is_boolean(B) -> B end, - true), + QueuePresence = gen_mod:get_module_opt(Host, ?MODULE, queue_presence, true), + QueueChatStates = gen_mod:get_module_opt(Host, ?MODULE, queue_chat_states, true), + QueuePEP = gen_mod:get_module_opt(Host, ?MODULE, queue_pep, true), if QueuePresence; QueueChatStates; QueuePEP -> unregister_hooks(Host), if QueuePresence -> @@ -127,15 +109,9 @@ stop(Host) -> -spec reload(binary(), gen_mod:opts(), gen_mod:opts()) -> ok. reload(Host, NewOpts, _OldOpts) -> - QueuePresence = gen_mod:get_opt(queue_presence, NewOpts, - fun(B) when is_boolean(B) -> B end, - true), - QueueChatStates = gen_mod:get_opt(queue_chat_states, NewOpts, - fun(B) when is_boolean(B) -> B end, - true), - QueuePEP = gen_mod:get_opt(queue_pep, NewOpts, - fun(B) when is_boolean(B) -> B end, - true), + QueuePresence = gen_mod:get_opt(queue_presence, NewOpts, true), + QueueChatStates = gen_mod:get_opt(queue_chat_states, NewOpts, true), + QueuePEP = gen_mod:get_opt(queue_pep, NewOpts, true), if QueuePresence; QueueChatStates; QueuePEP -> register_hooks(Host); true -> diff --git a/src/mod_delegation.erl b/src/mod_delegation.erl index baad79af3..f41c7610c 100644 --- a/src/mod_delegation.erl +++ b/src/mod_delegation.erl @@ -61,7 +61,15 @@ reload(_Host, _NewOpts, _OldOpts) -> ok. mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; -mod_opt_type(namespaces) -> validate_fun(); +mod_opt_type(namespaces) -> + fun(L) -> + lists:map( + fun({NS, Opts}) -> + Attrs = proplists:get_value(filtering, Opts, []), + Access = proplists:get_value(access, Opts, none), + {NS, Attrs, Access} + end, L) + end; mod_opt_type(_) -> [namespaces, iqdisc]. @@ -142,8 +150,7 @@ handle_cast({component_connected, Host}, State) -> ServerHost = State#state.server_host, To = jid:make(Host), NSAttrsAccessList = gen_mod:get_module_opt( - ServerHost, ?MODULE, namespaces, - validate_fun(), []), + ServerHost, ?MODULE, namespaces, []), lists:foreach( fun({NS, _Attrs, Access}) -> case acl:match_rule(ServerHost, Access, To) of @@ -342,13 +349,3 @@ disco_identity(Acc, _From, _To, _Node, _Lang, _Type) -> my_features(ejabberd_local) -> [?NS_DELEGATION]; my_features(ejabberd_sm) -> []. - -validate_fun() -> - fun(L) -> - lists:map( - fun({NS, Opts}) -> - Attrs = proplists:get_value(filtering, Opts, []), - Access = proplists:get_value(access, Opts, none), - {NS, Attrs, Access} - end, L) - end. diff --git a/src/mod_disco.erl b/src/mod_disco.erl index 88c06c543..6b8263371 100644 --- a/src/mod_disco.erl +++ b/src/mod_disco.erl @@ -50,8 +50,7 @@ -type items_acc() :: {error, stanza_error()} | {result, [disco_item()]} | empty. start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS, ?MODULE, process_local_iq_items, IQDisc), @@ -67,10 +66,7 @@ start(Host, Opts) -> catch ets:new(disco_extra_domains, [named_table, ordered_set, public, {heir, erlang:group_leader(), none}]), - ExtraDomains = gen_mod:get_opt(extra_domains, Opts, - fun(Hs) -> - [iolist_to_binary(H) || H <- Hs] - end, []), + ExtraDomains = gen_mod:get_opt(extra_domains, Opts, []), lists:foreach(fun (Domain) -> register_extra_domain(Host, Domain) end, @@ -119,10 +115,7 @@ stop(Host) -> ok. reload(Host, NewOpts, OldOpts) -> - case gen_mod:is_equal_opt(extra_domains, NewOpts, OldOpts, - fun(Hs) -> - [iolist_to_binary(H) || H <- Hs] - end, []) of + case gen_mod:is_equal_opt(extra_domains, NewOpts, OldOpts, []) of {false, NewDomains, OldDomains} -> lists:foreach( fun(Domain) -> @@ -135,9 +128,7 @@ reload(Host, NewOpts, OldOpts) -> true -> ok end, - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS, ?MODULE, @@ -447,17 +438,7 @@ get_info(Acc, _, _, _Node, _) -> Acc. -spec get_fields(binary(), module()) -> [xdata_field()]. get_fields(Host, Module) -> - Fields = gen_mod:get_module_opt( - Host, ?MODULE, server_info, - fun(L) -> - lists:map( - fun(Opts) -> - Mods = proplists:get_value(modules, Opts, all), - Name = proplists:get_value(name, Opts, <<>>), - URLs = proplists:get_value(urls, Opts, []), - {Mods, Name, URLs} - end, L) - end, []), + Fields = gen_mod:get_module_opt(Host, ?MODULE, server_info, []), Fields1 = lists:filter(fun ({Modules, _, _}) -> case Modules of all -> true; diff --git a/src/mod_fail2ban.erl b/src/mod_fail2ban.erl index ec19194c8..b49773403 100644 --- a/src/mod_fail2ban.erl +++ b/src/mod_fail2ban.erl @@ -58,11 +58,9 @@ c2s_auth_result(#{ip := {Addr, _}, lserver := LServer} = State, false, _User) -> false -> BanLifetime = gen_mod:get_module_opt( LServer, ?MODULE, c2s_auth_ban_lifetime, - fun(T) when is_integer(T), T > 0 -> T end, ?C2S_AUTH_BAN_LIFETIME), MaxFailures = gen_mod:get_module_opt( LServer, ?MODULE, c2s_max_auth_failures, - fun(I) when is_integer(I), I > 0 -> I end, ?C2S_MAX_AUTH_FAILURES), UnbanTS = p1_time_compat:system_time(seconds) + BanLifetime, Attempts = case ets:lookup(failed_auth, Addr) of @@ -179,9 +177,7 @@ log_and_disconnect(#{ip := {Addr, _}, lang := Lang} = State, Attempts, UnbanTS) {stop, ejabberd_c2s:send(State, Err)}. is_whitelisted(Host, Addr) -> - Access = gen_mod:get_module_opt(Host, ?MODULE, access, - fun(A) -> A end, - none), + Access = gen_mod:get_module_opt(Host, ?MODULE, access, none), acl:match_rule(Host, Access, Addr) == allow. seconds_to_now(Secs) -> diff --git a/src/mod_http_api.erl b/src/mod_http_api.erl index c50318ccc..7be05dbf1 100644 --- a/src/mod_http_api.erl +++ b/src/mod_http_api.erl @@ -543,9 +543,7 @@ log(Call, Args, IP) -> ?INFO_MSG("API call ~s ~p (~p)", [Call, Args, IP]). permission_addon() -> - Access = gen_mod:get_module_opt(global, ?MODULE, admin_ip_access, - fun(V) -> V end, - none), + Access = gen_mod:get_module_opt(global, ?MODULE, admin_ip_access, none), Rules = acl:resolve_access(Access, global), R = case Rules of all -> diff --git a/src/mod_http_fileserver.erl b/src/mod_http_fileserver.erl index 4aa47902a..c2144042e 100644 --- a/src/mod_http_fileserver.erl +++ b/src/mod_http_fileserver.erl @@ -118,41 +118,25 @@ init([Host, Opts]) -> end. initialize(Host, Opts) -> - DocRoot = gen_mod:get_opt(docroot, Opts, fun(A) -> A end, undefined), + DocRoot = gen_mod:get_opt(docroot, Opts), check_docroot_defined(DocRoot, Host), DRInfo = check_docroot_exists(DocRoot), check_docroot_is_dir(DRInfo, DocRoot), check_docroot_is_readable(DRInfo, DocRoot), - AccessLog = gen_mod:get_opt(accesslog, Opts, - fun iolist_to_binary/1, - undefined), + AccessLog = gen_mod:get_opt(accesslog, Opts), AccessLogFD = try_open_log(AccessLog, Host), - DirectoryIndices = gen_mod:get_opt(directory_indices, Opts, - fun(L) when is_list(L) -> L end, - []), - CustomHeaders = gen_mod:get_opt(custom_headers, Opts, - fun(L) when is_list(L) -> L end, - []), + DirectoryIndices = gen_mod:get_opt(directory_indices, Opts, []), + CustomHeaders = gen_mod:get_opt(custom_headers, Opts, []), DefaultContentType = gen_mod:get_opt(default_content_type, Opts, - fun iolist_to_binary/1, ?DEFAULT_CONTENT_TYPE), - UserAccess0 = gen_mod:get_opt(must_authenticate_with, Opts, - mod_opt_type(must_authenticate_with), - []), + UserAccess0 = gen_mod:get_opt(must_authenticate_with, Opts, []), UserAccess = case UserAccess0 of [] -> none; _ -> dict:from_list(UserAccess0) end, ContentTypes = build_list_content_types( - gen_mod:get_opt(content_types, Opts, - fun(L) when is_list(L) -> - lists:map( - fun({K, V}) -> - {iolist_to_binary(K), - iolist_to_binary(V)} - end, L) - end, []), + gen_mod:get_opt(content_types, Opts, []), ?DEFAULT_CONTENT_TYPES), ?DEBUG("known content types: ~s", [str:join([[$*, K, " -> ", V] || {K, V} <- ContentTypes], @@ -493,7 +477,13 @@ ip_to_string(Address) when size(Address) == 8 -> mod_opt_type(accesslog) -> fun iolist_to_binary/1; mod_opt_type(content_types) -> - fun (L) when is_list(L) -> L end; + fun(L) when is_list(L) -> + lists:map( + fun({K, V}) -> + {iolist_to_binary(K), + iolist_to_binary(V)} + end, L) + end; mod_opt_type(custom_headers) -> fun (L) when is_list(L) -> L end; mod_opt_type(default_content_type) -> diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl index 49893f14a..c8cd300f4 100644 --- a/src/mod_http_upload.erl +++ b/src/mod_http_upload.erl @@ -124,9 +124,7 @@ -spec start(binary(), gen_mod:opts()) -> {ok, pid()}. start(ServerHost, Opts) -> - case gen_mod:get_opt(rm_on_unregister, Opts, - fun(B) when is_boolean(B) -> B end, - true) of + case gen_mod:get_opt(rm_on_unregister, Opts, true) of true -> ejabberd_hooks:add(remove_user, ServerHost, ?MODULE, remove_user, 50); @@ -139,9 +137,7 @@ start(ServerHost, Opts) -> -spec stop(binary()) -> ok | {error, any()}. stop(ServerHost) -> - case gen_mod:get_module_opt(ServerHost, ?MODULE, rm_on_unregister, - fun(B) when is_boolean(B) -> B end, - true) of + case gen_mod:get_module_opt(ServerHost, ?MODULE, rm_on_unregister, true) of true -> ejabberd_hooks:delete(remove_user, ServerHost, ?MODULE, remove_user, 50); @@ -216,49 +212,18 @@ depends(_Host, _Opts) -> init([ServerHost, Opts]) -> process_flag(trap_exit, true), Host = gen_mod:get_opt_host(ServerHost, Opts, <<"upload.@HOST@">>), - Name = gen_mod:get_opt(name, Opts, - fun iolist_to_binary/1, - <<"HTTP File Upload">>), - Access = gen_mod:get_opt(access, Opts, - fun acl:access_rules_validator/1, - local), - MaxSize = gen_mod:get_opt(max_size, Opts, - fun(I) when is_integer(I), I > 0 -> I; - (infinity) -> infinity - end, - 104857600), - SecretLength = gen_mod:get_opt(secret_length, Opts, - fun(I) when is_integer(I), I >= 8 -> I end, - 40), - JIDinURL = gen_mod:get_opt(jid_in_url, Opts, - fun(sha1) -> sha1; - (node) -> node - end, - sha1), - DocRoot = gen_mod:get_opt(docroot, Opts, - fun iolist_to_binary/1, - <<"@HOME@/upload">>), - FileMode = gen_mod:get_opt(file_mode, Opts, - fun(Mode) -> ?STR_TO_INT(Mode, 8) end), - DirMode = gen_mod:get_opt(dir_mode, Opts, - fun(Mode) -> ?STR_TO_INT(Mode, 8) end), - PutURL = gen_mod:get_opt(put_url, Opts, - fun(<<"http://", _/binary>> = URL) -> URL; - (<<"https://", _/binary>> = URL) -> URL - end, - <<"http://@HOST@:5444">>), - GetURL = gen_mod:get_opt(get_url, Opts, - fun(<<"http://", _/binary>> = URL) -> URL; - (<<"https://", _/binary>> = URL) -> URL - end, - PutURL), - ServiceURL = gen_mod:get_opt(service_url, Opts, - fun(<<"http://", _/binary>> = URL) -> URL; - (<<"https://", _/binary>> = URL) -> URL - end), - Thumbnail = gen_mod:get_opt(thumbnail, Opts, - fun(B) when is_boolean(B) -> B end, - true), + Name = gen_mod:get_opt(name, Opts, <<"HTTP File Upload">>), + Access = gen_mod:get_opt(access, Opts, local), + MaxSize = gen_mod:get_opt(max_size, Opts, 104857600), + SecretLength = gen_mod:get_opt(secret_length, Opts, 40), + JIDinURL = gen_mod:get_opt(jid_in_url, Opts, sha1), + DocRoot = gen_mod:get_opt(docroot, Opts, <<"@HOME@/upload">>), + FileMode = gen_mod:get_opt(file_mode, Opts), + DirMode = gen_mod:get_opt(dir_mode, Opts), + PutURL = gen_mod:get_opt(put_url, Opts, <<"http://@HOST@:5444">>), + GetURL = gen_mod:get_opt(get_url, Opts, PutURL), + ServiceURL = gen_mod:get_opt(service_url, Opts), + Thumbnail = gen_mod:get_opt(thumbnail, Opts, true), DocRoot1 = expand_home(str:strip(DocRoot, right, $/)), DocRoot2 = expand_host(DocRoot1, ServerHost), case DirMode of @@ -476,10 +441,6 @@ process(_LocalPath, #request{method = Method, host = Host, ip = IP}) -> get_proc_name(ServerHost, ModuleName) -> PutURL = gen_mod:get_module_opt(ServerHost, ?MODULE, put_url, - fun(<<"http://", _/binary>> = URL) -> URL; - (<<"https://", _/binary>> = URL) -> URL; - (_) -> <<"http://@HOST@">> - end, <<"http://@HOST@">>), {ok, {_Scheme, _UserInfo, Host, _Port, Path, _Query}} = http_uri:parse(binary_to_list(expand_host(PutURL, ServerHost))), @@ -512,12 +473,31 @@ process_iq(#iq{type = get, lang = Lang, sub_els = [#disco_info{}]} = IQ, xmpp:make_iq_result(IQ, iq_disco_info(ServerHost, Lang, Name, AddInfo)); process_iq(#iq{type = get, sub_els = [#disco_items{}]} = IQ, _State) -> xmpp:make_iq_result(IQ, #disco_items{}); -process_iq(#iq{type = get, lang = Lang, from = From, - sub_els = [#upload_request{filename = File, - size = Size, - 'content-type' = CType, - xmlns = XMLNS}]} = IQ, - #state{server_host = ServerHost, access = Access} = State) -> +process_iq(#iq{type = get, sub_els = [#upload_request{filename = File, + size = Size, + 'content-type' = CType, + xmlns = XMLNS}]} = IQ, + State) -> + process_slot_request(IQ, File, Size, CType, XMLNS, State); +process_iq(#iq{type = get, sub_els = [#upload_request_0{filename = File, + size = Size, + 'content-type' = CType, + xmlns = XMLNS}]} = IQ, + State) -> + process_slot_request(IQ, File, Size, CType, XMLNS, State); +process_iq(#iq{type = T, lang = Lang} = IQ, _State) when T == get; T == set -> + Txt = <<"No module is handling this query">>, + xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)); +process_iq(#iq{}, _State) -> + not_request. + +-spec process_slot_request(iq(), binary(), pos_integer(), binary(), binary(), + state()) -> {iq(), state()} | iq(). + +process_slot_request(#iq{lang = Lang, from = From} = IQ, + File, Size, CType, XMLNS, + #state{server_host = ServerHost, + access = Access} = State) -> case acl:match_rule(ServerHost, Access, From) of allow -> ContentType = yield_content_type(CType), @@ -540,12 +520,7 @@ process_iq(#iq{type = get, lang = Lang, from = From, [jid:encode(From)]), Txt = <<"Denied by ACL">>, xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)) - end; -process_iq(#iq{type = T, lang = Lang} = IQ, _State) when T == get; T == set -> - Txt = <<"No module is handling this query">>, - xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)); -process_iq(#iq{}, _State) -> - not_request. + end. -spec create_slot(state(), jid(), binary(), pos_integer(), binary(), binary()) -> {ok, slot()} | {ok, binary(), binary()} | {error, xmlel()}. @@ -649,6 +624,8 @@ mk_slot(Slot, #state{put_url = PutPrefix, get_url = GetPrefix}, XMLNS) -> PutURL = str:join([PutPrefix | Slot], <<$/>>), GetURL = str:join([GetPrefix | Slot], <<$/>>), mk_slot(PutURL, GetURL, XMLNS); +mk_slot(PutURL, GetURL, ?NS_HTTP_UPLOAD_0) -> + #upload_slot_0{get = GetURL, put = PutURL, xmlns = ?NS_HTTP_UPLOAD_0}; mk_slot(PutURL, GetURL, XMLNS) -> #upload_slot{get = GetURL, put = PutURL, xmlns = XMLNS}. @@ -693,27 +670,32 @@ yield_content_type(Type) -> Type. -spec iq_disco_info(binary(), binary(), binary(), [xdata()]) -> disco_info(). iq_disco_info(Host, Lang, Name, AddInfo) -> - Form = case gen_mod:get_module_opt(Host, ?MODULE, max_size, - fun(I) when is_integer(I), I > 0 -> I; - (infinity) -> infinity - end, - 104857600) of + Form = case gen_mod:get_module_opt(Host, ?MODULE, max_size, 104857600) of infinity -> AddInfo; MaxSize -> MaxSizeStr = integer_to_binary(MaxSize), - Fields = [#xdata_field{type = hidden, - var = <<"FORM_TYPE">>, - values = [?NS_HTTP_UPLOAD]}, - #xdata_field{var = <<"max-file-size">>, - values = [MaxSizeStr]}], - [#xdata{type = result, fields = Fields}|AddInfo] + XData = lists:map( + fun(NS) -> + Fields = [#xdata_field{ + type = hidden, + var = <<"FORM_TYPE">>, + values = [NS]}, + #xdata_field{ + var = <<"max-file-size">>, + values = [MaxSizeStr]}], + #xdata{type = result, fields = Fields} + end, [?NS_HTTP_UPLOAD, ?NS_HTTP_UPLOAD_0]), + XData ++ AddInfo end, #disco_info{identities = [#identity{category = <<"store">>, type = <<"file">>, name = translate:translate(Lang, Name)}], - features = [?NS_HTTP_UPLOAD, ?NS_HTTP_UPLOAD_OLD, - ?NS_DISCO_INFO, ?NS_DISCO_ITEMS], + features = [?NS_HTTP_UPLOAD, + ?NS_HTTP_UPLOAD_0, + ?NS_HTTP_UPLOAD_OLD, + ?NS_DISCO_INFO, + ?NS_DISCO_ITEMS], xdata = Form}. %% HTTP request handling. @@ -821,15 +803,7 @@ http_response(Host, Code, ExtraHeaders) -> -> {pos_integer(), [{binary(), binary()}], binary()}. http_response(Host, Code, ExtraHeaders, Body) -> - CustomHeaders = - gen_mod:get_module_opt(Host, ?MODULE, custom_headers, - fun(Headers) -> - lists:map(fun({K, V}) -> - {iolist_to_binary(K), - iolist_to_binary(V)} - end, Headers) - end, - []), + CustomHeaders = gen_mod:get_module_opt(Host, ?MODULE, custom_headers, []), Headers = case proplists:is_defined(<<"Content-Type">>, ExtraHeaders) of true -> ExtraHeaders; @@ -915,13 +889,8 @@ thumb_el(Path, URI) -> remove_user(User, Server) -> ServerHost = jid:nameprep(Server), DocRoot = gen_mod:get_module_opt(ServerHost, ?MODULE, docroot, - fun iolist_to_binary/1, <<"@HOME@/upload">>), - JIDinURL = gen_mod:get_module_opt(ServerHost, ?MODULE, jid_in_url, - fun(sha1) -> sha1; - (node) -> node - end, - sha1), + JIDinURL = gen_mod:get_module_opt(ServerHost, ?MODULE, jid_in_url, sha1), DocRoot1 = expand_host(expand_home(DocRoot), ServerHost), UserStr = make_user_string(jid:make(User, Server), JIDinURL), UserDir = str:join([DocRoot1, UserStr], <<$/>>), diff --git a/src/mod_http_upload_quota.erl b/src/mod_http_upload_quota.erl index 8d79d16d6..10243ac0e 100644 --- a/src/mod_http_upload_quota.erl +++ b/src/mod_http_upload_quota.erl @@ -105,18 +105,11 @@ depends(_Host, _Opts) -> init([ServerHost, Opts]) -> process_flag(trap_exit, true), AccessSoftQuota = gen_mod:get_opt(access_soft_quota, Opts, - fun acl:shaper_rules_validator/1, soft_upload_quota), AccessHardQuota = gen_mod:get_opt(access_hard_quota, Opts, - fun acl:shaper_rules_validator/1, hard_upload_quota), - MaxDays = gen_mod:get_opt(max_days, Opts, - fun(I) when is_integer(I), I > 0 -> I; - (infinity) -> infinity - end, - infinity), + MaxDays = gen_mod:get_opt(max_days, Opts, infinity), DocRoot1 = gen_mod:get_module_opt(ServerHost, mod_http_upload, docroot, - fun iolist_to_binary/1, <<"@HOME@/upload">>), DocRoot2 = mod_http_upload:expand_home(str:strip(DocRoot1, right, $/)), DocRoot3 = mod_http_upload:expand_host(DocRoot2, ServerHost), diff --git a/src/mod_irc.erl b/src/mod_irc.erl index 091a26797..a2fa4fcd5 100644 --- a/src/mod_irc.erl +++ b/src/mod_irc.erl @@ -103,14 +103,11 @@ init([Host, Opts]) -> <<"irc.@HOST@">>), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), - Access = gen_mod:get_opt(access, Opts, - fun acl:access_rules_validator/1, - all), + Access = gen_mod:get_opt(access, Opts, all), catch ets:new(irc_connection, [named_table, public, {keypos, #irc_connection.jid_server_host}]), - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), register_hooks(MyHost, IQDisc), ejabberd_router:register_route(MyHost, Host), {ok, @@ -138,17 +135,11 @@ handle_call(stop, _From, State) -> handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) -> NewHost = gen_mod:get_opt_host(ServerHost, NewOpts, <<"irc.@HOST@">>), OldHost = gen_mod:get_opt_host(ServerHost, OldOpts, <<"irc.@HOST@">>), - NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, - fun gen_iq_handler:check_type/1, - one_queue), - OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue), + NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, one_queue), + OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, one_queue), NewMod = gen_mod:db_mod(ServerHost, NewOpts, ?MODULE), OldMod = gen_mod:db_mod(ServerHost, OldOpts, ?MODULE), - Access = gen_mod:get_opt(access, NewOpts, - fun acl:access_rules_validator/1, - all), + Access = gen_mod:get_opt(access, NewOpts, all), if NewMod /= OldMod -> NewMod:init(ServerHost, NewOpts); true -> @@ -166,9 +157,7 @@ handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) -> true -> ok end, - Access = gen_mod:get_opt(access, NewOpts, - fun acl:access_rules_validator/1, - all), + Access = gen_mod:get_opt(access, NewOpts, all), {noreply, State#state{host = NewHost, access = Access}}; handle_cast(Msg, State) -> ?WARNING_MSG("unexpected cast: ~p", [Msg]), @@ -593,7 +582,6 @@ get_connection_params(Host, From, IRCServer) -> get_default_encoding(ServerHost) -> Result = gen_mod:get_module_opt(ServerHost, ?MODULE, default_encoding, - fun iolist_to_binary/1, ?DEFAULT_IRC_ENCODING), ?INFO_MSG("The default_encoding configured for " "host ~p is: ~p~n", @@ -601,10 +589,10 @@ get_default_encoding(ServerHost) -> Result. get_realname(ServerHost) -> - gen_mod:get_module_opt(ServerHost, ?MODULE, realname, fun iolist_to_binary/1, ?DEFAULT_REALNAME). + gen_mod:get_module_opt(ServerHost, ?MODULE, realname, ?DEFAULT_REALNAME). get_webirc_password(ServerHost) -> - gen_mod:get_module_opt(ServerHost, ?MODULE, webirc_password, fun iolist_to_binary/1, ?DEFAULT_WEBIRC_PASSWORD). + gen_mod:get_module_opt(ServerHost, ?MODULE, webirc_password, ?DEFAULT_WEBIRC_PASSWORD). get_connection_params(Host, ServerHost, From, IRCServer) -> diff --git a/src/mod_last.erl b/src/mod_last.erl index e20c1524d..a2a92cbf7 100644 --- a/src/mod_last.erl +++ b/src/mod_last.erl @@ -25,8 +25,6 @@ -module(mod_last). --behaviour(ejabberd_config). - -author('alexey@process-one.net'). -protocol({xep, 12, '2.0'}). @@ -36,8 +34,8 @@ -export([start/2, stop/1, reload/3, process_local_iq/1, export/1, process_sm_iq/1, on_presence_update/4, import_info/0, import/5, import_start/2, store_last_info/4, get_last_info/2, - remove_user/2, transform_options/1, mod_opt_type/1, - opt_type/1, register_user/2, depends/2, privacy_check_packet/4]). + remove_user/2, mod_opt_type/1, + register_user/2, depends/2, privacy_check_packet/4]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -55,8 +53,7 @@ -callback remove_user(binary(), binary()) -> any(). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), gen_iq_handler:add_iq_handler(ejabberd_local, Host, @@ -94,9 +91,7 @@ reload(Host, NewOpts, OldOpts) -> true -> ok end, - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST, ?MODULE, process_local_iq, IQDisc), @@ -121,19 +116,13 @@ process_local_iq(#iq{type = get} = IQ) -> %% @doc Get the uptime of the ejabberd node, expressed in seconds. %% When ejabberd is starting, ejabberd_config:start/0 stores the datetime. get_node_uptime() -> - case ejabberd_config:get_option( - node_start, - fun(S) when is_integer(S), S >= 0 -> S end) of + case ejabberd_config:get_option(node_start) of undefined -> trunc(element(1, erlang:statistics(wall_clock)) / 1000); Now -> p1_time_compat:system_time(seconds) - Now end. --spec now_to_seconds(erlang:timestamp()) -> non_neg_integer(). -now_to_seconds({MegaSecs, Secs, _MicroSecs}) -> - MegaSecs * 1000000 + Secs. - %%% %%% Serve queries about user last online %%% @@ -273,23 +262,9 @@ export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -transform_options(Opts) -> - lists:foldl(fun transform_options/2, [], Opts). - -transform_options({node_start, {_, _, _} = Now}, Opts) -> - ?WARNING_MSG("Old 'node_start' format detected. This is still supported " - "but it is better to fix your config.", []), - [{node_start, now_to_seconds(Now)}|Opts]; -transform_options(Opt, Opts) -> - [Opt|Opts]. - depends(_Host, _Opts) -> []. mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(_) -> [db_type, iqdisc]. - -opt_type(node_start) -> - fun (S) when is_integer(S), S >= 0 -> S end; -opt_type(_) -> [node_start]. diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 5a61df327..4b94163c0 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -72,8 +72,7 @@ %%% API %%%=================================================================== start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), init_cache(Host, Opts), @@ -100,8 +99,7 @@ start(Host, Opts) -> get_room_config, 50), ejabberd_hooks:add(set_room_option, Host, ?MODULE, set_room_option, 50), - case gen_mod:get_opt(assume_mam_usage, Opts, - fun(B) when is_boolean(B) -> B end, false) of + case gen_mod:get_opt(assume_mam_usage, Opts, false) of true -> ejabberd_hooks:add(message_is_archived, Host, ?MODULE, message_is_archived, 50); @@ -117,7 +115,6 @@ use_cache(Host, Opts) -> true -> Mod:use_cache(Host, Opts); false -> gen_mod:get_opt(use_cache, Opts, - mod_opt_type(use_cache), ejabberd_config:use_cache(Host)) end. @@ -131,13 +128,10 @@ init_cache(Host, Opts) -> cache_opts(Host, Opts) -> MaxSize = gen_mod:get_opt(cache_size, Opts, - mod_opt_type(cache_size), ejabberd_config:cache_size(Host)), CacheMissed = gen_mod:get_opt(cache_missed, Opts, - mod_opt_type(cache_missed), ejabberd_config:cache_missed(Host)), LifeTime = case gen_mod:get_opt(cache_life_time, Opts, - mod_opt_type(cache_life_time), ejabberd_config:cache_life_time(Host)) of infinity -> infinity; I -> timer:seconds(I) @@ -168,8 +162,7 @@ stop(Host) -> get_room_config, 50), ejabberd_hooks:delete(set_room_option, Host, ?MODULE, set_room_option, 50), - case gen_mod:get_module_opt(Host, ?MODULE, assume_mam_usage, - fun(B) when is_boolean(B) -> B end, false) of + case gen_mod:get_module_opt(Host, ?MODULE, assume_mam_usage, false) of true -> ejabberd_hooks:delete(message_is_archived, Host, ?MODULE, message_is_archived, 50); @@ -188,16 +181,13 @@ reload(Host, NewOpts, OldOpts) -> ok end, ets_cache:setopts(archive_prefs_cache, NewOpts), - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of {false, IQDisc, _} -> register_iq_handlers(Host, IQDisc); true -> ok end, - case gen_mod:is_equal_opt(assume_mam_usage, NewOpts, OldOpts, - fun(B) when is_boolean(B) -> B end, false) of + case gen_mod:is_equal_opt(assume_mam_usage, NewOpts, OldOpts, false) of {false, true, _} -> ejabberd_hooks:add(message_is_archived, Host, ?MODULE, message_is_archived, 50); @@ -431,8 +421,7 @@ message_is_archived(true, _C2SState, _Pkt) -> message_is_archived(false, #{jid := JID} = C2SState, Pkt) -> #jid{luser = LUser, lserver = LServer} = JID, Peer = xmpp:get_from(Pkt), - case gen_mod:get_module_opt(LServer, ?MODULE, assume_mam_usage, - fun(B) when is_boolean(B) -> B end, false) of + case gen_mod:get_module_opt(LServer, ?MODULE, assume_mam_usage, false) of true -> should_archive(strip_my_archived_tag(Pkt, LServer), LServer) andalso should_archive_peer(C2SState, LUser, LServer, @@ -788,18 +777,14 @@ get_prefs(LUser, LServer) -> Prefs; error -> ActivateOpt = gen_mod:get_module_opt( - LServer, ?MODULE, request_activates_archiving, - fun(B) when is_boolean(B) -> B end, false), + LServer, ?MODULE, + request_activates_archiving, false), case ActivateOpt of true -> #archive_prefs{us = {LUser, LServer}, default = never}; false -> Default = gen_mod:get_module_opt( - LServer, ?MODULE, default, - fun(always) -> always; - (never) -> never; - (roster) -> roster - end, never), + LServer, ?MODULE, default, never), #archive_prefs{us = {LUser, LServer}, default = Default} end end. @@ -811,10 +796,8 @@ prefs_el(Default, Always, Never, NS) -> xmlns = NS}. maybe_activate_mam(LUser, LServer) -> - ActivateOpt = gen_mod:get_module_opt(LServer, ?MODULE, - request_activates_archiving, - fun(B) when is_boolean(B) -> B end, - false), + ActivateOpt = gen_mod:get_module_opt( + LServer, ?MODULE, request_activates_archiving, false), case ActivateOpt of true -> Mod = gen_mod:db_mod(LServer, ?MODULE), @@ -826,11 +809,8 @@ maybe_activate_mam(LUser, LServer) -> {ok, _Prefs} -> ok; error -> - Default = gen_mod:get_module_opt(LServer, ?MODULE, default, - fun(always) -> always; - (never) -> never; - (roster) -> roster - end, never), + Default = gen_mod:get_module_opt( + LServer, ?MODULE, default, never), write_prefs(LUser, LServer, LServer, Default, [], []) end; false -> diff --git a/src/mod_mam_sql.erl b/src/mod_mam_sql.erl index 93bf2f2f2..d2fd48a9f 100644 --- a/src/mod_mam_sql.erl +++ b/src/mod_mam_sql.erl @@ -200,9 +200,7 @@ make_sql_query(User, LServer, MAMQuery, RSM) -> With = proplists:get_value(with, MAMQuery), WithText = proplists:get_value(withtext, MAMQuery), {Max, Direction, ID} = get_max_direction_id(RSM), - ODBCType = ejabberd_config:get_option( - {sql_type, LServer}, - ejabberd_sql:opt_type(sql_type)), + ODBCType = ejabberd_config:get_option({sql_type, LServer}), Escape = case ODBCType of mssql -> fun ejabberd_sql:standard_escape/1; diff --git a/src/mod_mix.erl b/src/mod_mix.erl index 714a6b020..380ef4997 100644 --- a/src/mod_mix.erl +++ b/src/mod_mix.erl @@ -125,8 +125,7 @@ process_iq(#iq{lang = Lang} = IQ) -> init([ServerHost, Opts]) -> process_flag(trap_exit, true), Host = gen_mod:get_opt_host(ServerHost, Opts, <<"mix.@HOST@">>), - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), ConfigTab = gen_mod:get_module_proc(Host, config), ets:new(ConfigTab, [named_table]), ets:insert(ConfigTab, {plugins, [<<"mix">>]}), diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 9c8316e2e..b37f1c94d 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -224,8 +224,7 @@ get_online_rooms_by_user(ServerHost, LUser, LServer) -> init([Host, Opts]) -> process_flag(trap_exit, true), - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), #state{access = Access, host = MyHost, history_size = HistorySize, queue_type = QueueType, room_shaper = RoomShaper} = State = init_state(Host, Opts), @@ -260,12 +259,8 @@ handle_call({create, Room, From, Nick, Opts}, _From, {reply, ok, State}. handle_cast({reload, ServerHost, NewOpts, OldOpts}, #state{host = OldHost}) -> - NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, - fun gen_iq_handler:check_type/1, - one_queue), - OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue), + NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, one_queue), + OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, one_queue), NewMod = gen_mod:db_mod(ServerHost, NewOpts, ?MODULE), NewRMod = gen_mod:ram_db_mod(ServerHost, NewOpts, ?MODULE), OldMod = gen_mod:db_mod(ServerHost, OldOpts, ?MODULE), @@ -336,32 +331,15 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. init_state(Host, Opts) -> MyHost = gen_mod:get_opt_host(Host, Opts, <<"conference.@HOST@">>), - Access = gen_mod:get_opt(access, Opts, - fun acl:access_rules_validator/1, all), - AccessCreate = gen_mod:get_opt(access_create, Opts, - fun acl:access_rules_validator/1, all), - AccessAdmin = gen_mod:get_opt(access_admin, Opts, - fun acl:access_rules_validator/1, - none), - AccessPersistent = gen_mod:get_opt(access_persistent, Opts, - fun acl:access_rules_validator/1, - all), - HistorySize = gen_mod:get_opt(history_size, Opts, - fun(I) when is_integer(I), I>=0 -> I end, - 20), - MaxRoomsDiscoItems = gen_mod:get_opt(max_rooms_discoitems, Opts, - fun(I) when is_integer(I), I>=0 -> I end, - 100), - DefRoomOpts1 = gen_mod:get_opt(default_room_options, Opts, - fun(L) when is_list(L) -> L end, - []), - QueueType = case gen_mod:get_opt(queue_type, Opts, - mod_opt_type(queue_type)) of - undefined -> - ejabberd_config:default_queue_type(Host); - Type -> - Type - end, + Access = gen_mod:get_opt(access, Opts, all), + AccessCreate = gen_mod:get_opt(access_create, Opts, all), + AccessAdmin = gen_mod:get_opt(access_admin, Opts, none), + AccessPersistent = gen_mod:get_opt(access_persistent, Opts, all), + HistorySize = gen_mod:get_opt(history_size, Opts, 20), + MaxRoomsDiscoItems = gen_mod:get_opt(max_rooms_discoitems, Opts, 100), + DefRoomOpts1 = gen_mod:get_opt(default_room_options, Opts, []), + QueueType = gen_mod:get_opt(queue_type, Opts, + ejabberd_config:default_queue_type(Host)), DefRoomOpts = lists:flatmap( fun({Opt, Val}) -> @@ -407,14 +385,12 @@ init_state(Host, Opts) -> [Opt, Val]), fun(_) -> undefined end end, - case gen_mod:get_opt(Opt, [{Opt, Val}], VFun) of + case ejabberd_config:prepare_opt_val(Opt, Val, VFun, undefined) of undefined -> []; NewVal -> [{Opt, NewVal}] end end, DefRoomOpts1), - RoomShaper = gen_mod:get_opt(room_shaper, Opts, - fun(A) when is_atom(A) -> A end, - none), + RoomShaper = gen_mod:get_opt(room_shaper, Opts, none), #state{host = MyHost, server_host = Host, access = {Access, AccessCreate, AccessAdmin, AccessPersistent}, @@ -601,7 +577,6 @@ process_disco_items(#iq{type = get, from = From, to = To, lang = Lang, ServerHost = ejabberd_router:host_of_route(Host), MaxRoomsDiscoItems = gen_mod:get_module_opt( ServerHost, ?MODULE, max_rooms_discoitems, - fun(I) when is_integer(I), I>=0 -> I end, 100), case iq_disco_items(ServerHost, Host, From, Lang, MaxRoomsDiscoItems, Node, RSM) of @@ -655,12 +630,8 @@ check_user_can_create_room(ServerHost, AccessCreate, end. check_create_roomid(ServerHost, RoomID) -> - Max = gen_mod:get_module_opt(ServerHost, ?MODULE, max_room_id, - fun(infinity) -> infinity; - (I) when is_integer(I), I>0 -> I - end, infinity), - Regexp = gen_mod:get_module_opt(ServerHost, ?MODULE, regexp_room_id, - fun iolist_to_binary/1, ""), + Max = gen_mod:get_module_opt(ServerHost, ?MODULE, max_room_id, infinity), + Regexp = gen_mod:get_module_opt(ServerHost, ?MODULE, regexp_room_id, ""), (byte_size(RoomID) =< Max) and (re:run(RoomID, Regexp, [unicode, {capture, none}]) == match). @@ -956,7 +927,7 @@ mod_opt_type(max_users_admin_threshold) -> mod_opt_type(max_users_presence) -> fun (MUP) when is_integer(MUP) -> MUP end; mod_opt_type(min_message_interval) -> - fun (MMI) when is_number(MMI) -> MMI end; + fun (MMI) when is_number(MMI), MMI >= 0 -> MMI end; mod_opt_type(min_presence_interval) -> fun (I) when is_number(I), I >= 0 -> I end; mod_opt_type(room_shaper) -> diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl index 31f267879..cf42e86c7 100644 --- a/src/mod_muc_admin.erl +++ b/src/mod_muc_admin.erl @@ -476,7 +476,7 @@ create_room_with_opts(Name1, Host1, ServerHost, CustomRoomOpts) -> %% Get the default room options from the muc configuration DefRoomOpts = gen_mod:get_module_opt(ServerHost, mod_muc, - default_room_options, fun(X) -> X end, []), + default_room_options, []), %% Change default room options as required FormattedRoomOpts = [format_room_option(Opt, Val) || {Opt, Val}<-CustomRoomOpts], RoomOpts = lists:ukeymerge(1, @@ -487,13 +487,13 @@ create_room_with_opts(Name1, Host1, ServerHost, CustomRoomOpts) -> mod_muc:store_room(ServerHost, Host, Name, RoomOpts), %% Get all remaining mod_muc parameters that might be utilized - Access = gen_mod:get_module_opt(ServerHost, mod_muc, access, fun(X) -> X end, all), - AcCreate = gen_mod:get_module_opt(ServerHost, mod_muc, access_create, fun(X) -> X end, all), - AcAdmin = gen_mod:get_module_opt(ServerHost, mod_muc, access_admin, fun(X) -> X end, none), - AcPer = gen_mod:get_module_opt(ServerHost, mod_muc, access_persistent, fun(X) -> X end, all), - HistorySize = gen_mod:get_module_opt(ServerHost, mod_muc, history_size, fun(X) -> X end, 20), - RoomShaper = gen_mod:get_module_opt(ServerHost, mod_muc, room_shaper, fun(X) -> X end, none), - QueueType = gen_mod:get_module_opt(ServerHost, mod_muc, queue_type, fun(X) -> X end, + Access = gen_mod:get_module_opt(ServerHost, mod_muc, access, all), + AcCreate = gen_mod:get_module_opt(ServerHost, mod_muc, access_create, all), + AcAdmin = gen_mod:get_module_opt(ServerHost, mod_muc, access_admin, none), + AcPer = gen_mod:get_module_opt(ServerHost, mod_muc, access_persistent, all), + HistorySize = gen_mod:get_module_opt(ServerHost, mod_muc, history_size, 20), + RoomShaper = gen_mod:get_module_opt(ServerHost, mod_muc, room_shaper, none), + QueueType = gen_mod:get_module_opt(ServerHost, mod_muc, queue_type, ejabberd_config:default_queue_type(ServerHost)), %% If the room does not exist yet in the muc_online_room @@ -596,8 +596,7 @@ create_rooms_file(Filename) -> file:close(F), %% Read the default room options defined for the first virtual host DefRoomOpts = gen_mod:get_module_opt(?MYNAME, mod_muc, - default_room_options, - fun(L) when is_list(L) -> L end, []), + default_room_options, []), [muc_create_room(?MYNAME, A, DefRoomOpts) || A <- Rooms], ok. diff --git a/src/mod_muc_log.erl b/src/mod_muc_log.erl index 73c1998a6..820cbd3bd 100644 --- a/src/mod_muc_log.erl +++ b/src/mod_muc_log.erl @@ -27,8 +27,6 @@ -protocol({xep, 334, '0.2'}). --behaviour(ejabberd_config). - -author('badlop@process-one.net'). -behaviour(gen_server). @@ -41,7 +39,7 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3, - mod_opt_type/1, opt_type/1, depends/2]). + mod_opt_type/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -140,52 +138,17 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. %%% Internal functions %%-------------------------------------------------------------------- init_state(Host, Opts) -> - OutDir = gen_mod:get_opt(outdir, Opts, - fun iolist_to_binary/1, - <<"www/muc">>), - DirType = gen_mod:get_opt(dirtype, Opts, - fun(subdirs) -> subdirs; - (plain) -> plain - end, subdirs), - DirName = gen_mod:get_opt(dirname, Opts, - fun(room_jid) -> room_jid; - (room_name) -> room_name - end, room_jid), - FileFormat = gen_mod:get_opt(file_format, Opts, - fun(html) -> html; - (plaintext) -> plaintext - end, html), - FilePermissions = gen_mod:get_opt(file_permissions, Opts, - fun(SubOpts) -> - F = fun({mode, Mode}, {_M, G}) -> - {Mode, G}; - ({group, Group}, {M, _G}) -> - {M, Group} - end, - lists:foldl(F, {644, 33}, SubOpts) - end, {644, 33}), - CSSFile = gen_mod:get_opt(cssfile, Opts, - fun iolist_to_binary/1, - false), - AccessLog = gen_mod:get_opt(access_log, Opts, - fun acl:access_rules_validator/1, - muc_admin), - Timezone = gen_mod:get_opt(timezone, Opts, - fun(local) -> local; - (universal) -> universal - end, local), - Top_link = gen_mod:get_opt(top_link, Opts, - fun([{S1, S2}]) -> - {iolist_to_binary(S1), - iolist_to_binary(S2)} - end, {<<"/">>, <<"Home">>}), - NoFollow = gen_mod:get_opt(spam_prevention, Opts, - fun(B) when is_boolean(B) -> B end, - true), - Lang = ejabberd_config:get_option( - {language, Host}, - fun iolist_to_binary/1, - ?MYLANG), + OutDir = gen_mod:get_opt(outdir, Opts, <<"www/muc">>), + DirType = gen_mod:get_opt(dirtype, Opts, subdirs), + DirName = gen_mod:get_opt(dirname, Opts, room_jid), + FileFormat = gen_mod:get_opt(file_format, Opts, html), + FilePermissions = gen_mod:get_opt(file_permissions, Opts, {644, 33}), + CSSFile = gen_mod:get_opt(cssfile, Opts, false), + AccessLog = gen_mod:get_opt(access_log, Opts, muc_admin), + Timezone = gen_mod:get_opt(timezone, Opts, local), + Top_link = gen_mod:get_opt(top_link, Opts, {<<"/">>, <<"Home">>}), + NoFollow = gen_mod:get_opt(spam_prevention, Opts, true), + Lang = ejabberd_config:get_lang(Host), #logstate{host = Host, out_dir = OutDir, dir_type = DirType, dir_name = DirName, file_format = FileFormat, css_file = CSSFile, @@ -1206,7 +1169,7 @@ has_no_permanent_store_hint(Packet) -> xmpp:has_subtag(Packet, #hint{type = 'no-permanent-storage'}). mod_opt_type(access_log) -> - fun (A) when is_atom(A) -> A end; + fun acl:access_rules_validator/1; mod_opt_type(cssfile) -> fun iolist_to_binary/1; mod_opt_type(dirname) -> fun (room_jid) -> room_jid; @@ -1242,6 +1205,3 @@ mod_opt_type(_) -> [access_log, cssfile, dirname, dirtype, file_format, file_permissions, outdir, spam_prevention, timezone, top_link]. - -opt_type(language) -> fun iolist_to_binary/1; -opt_type(_) -> [language]. diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index f93828962..231b59b2a 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -165,8 +165,7 @@ normal_state({route, <<"">>, MinMessageInterval = trunc(gen_mod:get_module_opt( StateData#state.server_host, mod_muc, min_message_interval, - fun(MMI) when is_number(MMI) -> MMI end, 0) - * 1000000), + 0) * 1000000), Size = element_size(Packet), {MessageShaper, MessageShaperInterval} = shaper:update(Activity#activity.message_shaper, Size), @@ -347,10 +346,7 @@ normal_state({route, Nick, #presence{from = From} = Packet}, StateData) -> MinPresenceInterval = trunc(gen_mod:get_module_opt(StateData#state.server_host, mod_muc, min_presence_interval, - fun(I) when is_number(I), I>=0 -> - I - end, 0) - * 1000000), + 0) * 1000000), if (Now >= Activity#activity.presence_time + MinPresenceInterval) and (Activity#activity.presence == undefined) -> NewActivity = Activity#activity{presence_time = Now}, @@ -1415,14 +1411,12 @@ get_max_users(StateData) -> get_service_max_users(StateData) -> gen_mod:get_module_opt(StateData#state.server_host, mod_muc, max_users, - fun(I) when is_integer(I), I>0 -> I end, ?MAX_USERS_DEFAULT). -spec get_max_users_admin_threshold(state()) -> pos_integer(). get_max_users_admin_threshold(StateData) -> gen_mod:get_module_opt(StateData#state.server_host, mod_muc, max_users_admin_threshold, - fun(I) when is_integer(I), I>0 -> I end, 5). -spec room_queue_new(binary(), shaper:shaper(), _) -> p1_queue:queue(). @@ -1430,19 +1424,15 @@ room_queue_new(ServerHost, Shaper, QueueType) -> HaveRoomShaper = Shaper /= none, HaveMessageShaper = gen_mod:get_module_opt( ServerHost, mod_muc, user_message_shaper, - fun(A) when is_atom(A) -> A end, none) /= none, HavePresenceShaper = gen_mod:get_module_opt( ServerHost, mod_muc, user_presence_shaper, - fun(A) when is_atom(A) -> A end, none) /= none, HaveMinMessageInterval = gen_mod:get_module_opt( ServerHost, mod_muc, min_message_interval, - fun(I) when is_number(I), I>=0 -> I end, 0) /= 0, HaveMinPresenceInterval = gen_mod:get_module_opt( ServerHost, mod_muc, min_presence_interval, - fun(I) when is_number(I), I>=0 -> I end, 0) /= 0, if HaveRoomShaper or HaveMessageShaper or HavePresenceShaper or HaveMinMessageInterval or HaveMinPresenceInterval -> @@ -1461,12 +1451,10 @@ get_user_activity(JID, StateData) -> MessageShaper = shaper:new(gen_mod:get_module_opt(StateData#state.server_host, mod_muc, user_message_shaper, - fun(A) when is_atom(A) -> A end, none)), PresenceShaper = shaper:new(gen_mod:get_module_opt(StateData#state.server_host, mod_muc, user_presence_shaper, - fun(A) when is_atom(A) -> A end, none)), #activity{message_shaper = MessageShaper, presence_shaper = PresenceShaper} @@ -1477,15 +1465,11 @@ store_user_activity(JID, UserActivity, StateData) -> MinMessageInterval = trunc(gen_mod:get_module_opt(StateData#state.server_host, mod_muc, min_message_interval, - fun(I) when is_number(I), I>=0 -> I end, - 0) - * 1000), + 0) * 1000), MinPresenceInterval = trunc(gen_mod:get_module_opt(StateData#state.server_host, mod_muc, min_presence_interval, - fun(I) when is_number(I), I>=0 -> I end, - 0) - * 1000), + 0) * 1000), Key = jid:tolower(JID), Now = p1_time_compat:system_time(micro_seconds), Activity1 = clean_treap(StateData#state.activity, @@ -1788,7 +1772,6 @@ add_new_user(From, Nick, Packet, StateData) -> MaxConferences = gen_mod:get_module_opt(StateData#state.server_host, mod_muc, max_user_conferences, - fun(I) when is_integer(I), I>0 -> I end, 10), Collision = nick_collision(From, Nick, StateData), IsSubscribeRequest = not is_record(Packet, presence), @@ -2061,10 +2044,10 @@ filter_history(Queue, Now, Nick, -spec is_room_overcrowded(state()) -> boolean(). is_room_overcrowded(StateData) -> - MaxUsersPresence = gen_mod:get_module_opt(StateData#state.server_host, - mod_muc, max_users_presence, - fun(MUP) when is_integer(MUP) -> MUP end, - ?DEFAULT_MAX_USERS_PRESENCE), + MaxUsersPresence = gen_mod:get_module_opt( + StateData#state.server_host, + mod_muc, max_users_presence, + ?DEFAULT_MAX_USERS_PRESENCE), (?DICT):size(StateData#state.users) > MaxUsersPresence. -spec presence_broadcast_allowed(jid(), state()) -> boolean(). @@ -3114,18 +3097,11 @@ is_allowed_room_name_desc_limits(Options, StateData) -> MaxRoomName = gen_mod:get_module_opt( StateData#state.server_host, mod_muc, max_room_name, - fun(infinity) -> infinity; - (I) when is_integer(I), - I>0 -> I - end, infinity), + infinity), MaxRoomDesc = gen_mod:get_module_opt( StateData#state.server_host, mod_muc, max_room_desc, - fun(infinity) -> infinity; - (I) when is_integer(I), - I>0 -> - I - end, infinity), + infinity), (byte_size(RoomName) =< MaxRoomName) andalso (byte_size(RoomDesc) =< MaxRoomDesc). @@ -3151,7 +3127,6 @@ get_default_room_maxusers(RoomState) -> DefRoomOpts = gen_mod:get_module_opt(RoomState#state.server_host, mod_muc, default_room_options, - fun(L) when is_list(L) -> L end, []), RoomState2 = set_opts(DefRoomOpts, RoomState), (RoomState2#state.config)#config.max_users. @@ -3713,6 +3688,21 @@ process_iq_mucsub(_From, #iq{type = set, lang = Lang, {error, xmpp:err_not_allowed(<<"Subscriptions are not allowed">>, Lang)}; process_iq_mucsub(From, #iq{type = set, lang = Lang, + sub_els = [#muc_subscribe{jid = #jid{} = SubJid} = Mucsub]}, + StateData) -> + FAffiliation = get_affiliation(From, StateData), + FRole = get_role(From, StateData), + if FRole == moderator; FAffiliation == owner; FAffiliation == admin -> + process_iq_mucsub(SubJid, + #iq{type = set, lang = Lang, + sub_els = [Mucsub#muc_subscribe{jid = undefined}]}, + StateData); + true -> + Txt = <<"Moderator privileges required">>, + {error, xmpp:err_forbidden(Txt, Lang)} + end; +process_iq_mucsub(From, + #iq{type = set, lang = Lang, sub_els = [#muc_subscribe{nick = Nick}]} = Packet, StateData) -> LBareJID = jid:tolower(jid:remove_resource(From)), @@ -3748,7 +3738,7 @@ process_iq_mucsub(From, #iq{type = set, lang = Lang, FRole = get_role(From, StateData), if FRole == moderator; FAffiliation == owner; FAffiliation == admin -> process_iq_mucsub(UnsubJid, - #iq{type = set, + #iq{type = set, lang = Lang, sub_els = [#muc_unsubscribe{jid = undefined}]}, StateData); true -> diff --git a/src/mod_multicast.erl b/src/mod_multicast.erl index 4f4f96614..d2627c252 100644 --- a/src/mod_multicast.erl +++ b/src/mod_multicast.erl @@ -134,14 +134,8 @@ init([LServerS, Opts]) -> process_flag(trap_exit, true), LServiceS = gen_mod:get_opt_host(LServerS, Opts, <<"multicast.@HOST@">>), - Access = gen_mod:get_opt(access, Opts, - fun acl:access_rules_validator/1, all), - SLimits = - build_service_limit_record(gen_mod:get_opt(limits, Opts, - fun (A) when is_list(A) -> - A - end, - [])), + Access = gen_mod:get_opt(access, Opts, all), + SLimits = build_service_limit_record(gen_mod:get_opt(limits, Opts, [])), create_cache(), try_start_loop(), create_pool(), @@ -156,14 +150,8 @@ handle_call(stop, _From, State) -> handle_cast({reload, NewOpts, NewOpts}, #state{lserver = LServerS, lservice = OldLServiceS} = State) -> - Access = gen_mod:get_opt(access, NewOpts, - fun acl:access_rules_validator/1, all), - SLimits = - build_service_limit_record(gen_mod:get_opt(limits, NewOpts, - fun (A) when is_list(A) -> - A - end, - [])), + Access = gen_mod:get_opt(access, NewOpts, all), + SLimits = build_service_limit_record(gen_mod:get_opt(limits, NewOpts, [])), NewLServiceS = gen_mod:get_opt_host(LServerS, NewOpts, <<"multicast.@HOST@">>), if NewLServiceS /= OldLServiceS -> diff --git a/src/mod_offline.erl b/src/mod_offline.erl index db2efb040..f92090717 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -129,8 +129,7 @@ init([Host, Opts]) -> process_flag(trap_exit, true), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - no_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, no_queue), ejabberd_hooks:add(offline_message_hook, Host, ?MODULE, store_packet, 50), ejabberd_hooks:add(c2s_self_presence, Host, ?MODULE, c2s_self_presence, 50), @@ -157,7 +156,6 @@ init([Host, Opts]) -> ?MODULE, handle_offline_query, IQDisc), AccessMaxOfflineMsgs = gen_mod:get_opt(access_max_user_messages, Opts, - fun acl:shaper_rules_validator/1, max_user_offline_messages), {ok, #state{host = Host, @@ -175,9 +173,7 @@ handle_cast({reload, NewOpts, OldOpts}, #state{host = Host} = State) -> true -> ok end, - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_FLEX_OFFLINE, ?MODULE, handle_offline_query, IQDisc); @@ -185,7 +181,6 @@ handle_cast({reload, NewOpts, OldOpts}, #state{host = Host} = State) -> ok end, case gen_mod:is_equal_opt(access_max_user_messages, NewOpts, OldOpts, - fun acl:shaper_rules_validator/1, max_user_offline_messages) of {false, AccessMaxOfflineMsgs, _} -> {noreply, @@ -462,9 +457,6 @@ need_to_store(LServer, #message{type = Type} = Packet) -> none -> case gen_mod:get_module_opt( LServer, ?MODULE, store_empty_body, - fun(V) when is_boolean(V) -> V; - (unless_chat_state) -> unless_chat_state - end, unless_chat_state) of true -> true; @@ -532,15 +524,15 @@ has_no_store_hint(Packet) -> %% Check if the packet has any content about XEP-0022 -spec check_event(message()) -> boolean(). -check_event(#message{from = From, to = To, id = ID} = Msg) -> +check_event(#message{from = From, to = To, id = ID, type = Type} = Msg) -> case xmpp:get_subtag(Msg, #xevent{}) of false -> true; #xevent{id = undefined, offline = false} -> true; #xevent{id = undefined, offline = true} -> - NewMsg = Msg#message{from = To, to = From, - sub_els = [#xevent{id = ID, offline = true}]}, + NewMsg = #message{from = To, to = From, id = ID, type = Type, + sub_els = [#xevent{id = ID, offline = true}]}, ejabberd_router:route(NewMsg), true; _ -> @@ -799,7 +791,6 @@ get_queue_length(LUser, LServer) -> get_messages_subset(User, Host, MsgsAll) -> Access = gen_mod:get_module_opt(Host, ?MODULE, access_max_user_messages, - fun(A) when is_atom(A) -> A end, max_user_offline_messages), MaxOfflineMsgs = case get_max_user_messages(Access, User, Host) diff --git a/src/mod_ping.erl b/src/mod_ping.erl index a16d9b2c4..038b1bc2d 100644 --- a/src/mod_ping.erl +++ b/src/mod_ping.erl @@ -95,8 +95,7 @@ reload(Host, NewOpts, OldOpts) -> init([Host, Opts]) -> process_flag(trap_exit, true), State = init_state(Host, Opts), - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - no_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, no_queue), register_iq_handlers(Host, IQDisc), case State#state.send_pings of true -> register_hooks(Host); @@ -115,9 +114,7 @@ handle_call(_Req, _From, State) -> handle_cast({reload, Host, NewOpts, OldOpts}, #state{timers = Timers} = OldState) -> - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of {false, IQDisc, _} -> register_iq_handlers(Host, IQDisc); true -> ok end, @@ -200,19 +197,10 @@ user_send({Packet, #{jid := JID} = C2SState}) -> %% Internal functions %%==================================================================== init_state(Host, Opts) -> - SendPings = gen_mod:get_opt(send_pings, Opts, - fun(B) when is_boolean(B) -> B end, - ?DEFAULT_SEND_PINGS), - PingInterval = gen_mod:get_opt(ping_interval, Opts, - fun(I) when is_integer(I), I>0 -> I end, - ?DEFAULT_PING_INTERVAL), - PingAckTimeout = gen_mod:get_opt(ping_ack_timeout, Opts, - fun(I) when is_integer(I), I>0 -> I * 1000 end, - undefined), - TimeoutAction = gen_mod:get_opt(timeout_action, Opts, - fun(none) -> none; - (kill) -> kill - end, none), + SendPings = gen_mod:get_opt(send_pings, Opts, ?DEFAULT_SEND_PINGS), + PingInterval = gen_mod:get_opt(ping_interval, Opts, ?DEFAULT_PING_INTERVAL), + PingAckTimeout = gen_mod:get_opt(ping_ack_timeout, Opts), + TimeoutAction = gen_mod:get_opt(timeout_action, Opts, none), #state{host = Host, send_pings = SendPings, ping_interval = PingInterval, @@ -284,7 +272,7 @@ mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(ping_interval) -> fun (I) when is_integer(I), I > 0 -> I end; mod_opt_type(ping_ack_timeout) -> - fun (I) when is_integer(I), I > 0 -> I end; + fun(I) when is_integer(I), I>0 -> timer:seconds(I) end; mod_opt_type(send_pings) -> fun (B) when is_boolean(B) -> B end; mod_opt_type(timeout_action) -> diff --git a/src/mod_pres_counter.erl b/src/mod_pres_counter.erl index 8756b4f67..875aeef37 100644 --- a/src/mod_pres_counter.erl +++ b/src/mod_pres_counter.erl @@ -79,12 +79,8 @@ check_packet(Acc, _, _, _) -> Acc. update(Server, JID, Dir) -> - StormCount = gen_mod:get_module_opt(Server, ?MODULE, count, - fun(I) when is_integer(I), I>0 -> I end, - 5), - TimeInterval = gen_mod:get_module_opt(Server, ?MODULE, interval, - fun(I) when is_integer(I), I>0 -> I end, - 60), + StormCount = gen_mod:get_module_opt(Server, ?MODULE, count, 5), + TimeInterval = gen_mod:get_module_opt(Server, ?MODULE, interval, 60), TimeStamp = p1_time_compat:system_time(seconds), case read(Dir) of undefined -> diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index 7a34588e5..22cfd8243 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -60,8 +60,7 @@ -callback remove_user(binary(), binary()) -> any(). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), ejabberd_hooks:add(disco_local_features, Host, ?MODULE, @@ -107,9 +106,7 @@ reload(Host, NewOpts, OldOpts) -> true -> ok end, - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY, ?MODULE, process_iq, IQDisc); diff --git a/src/mod_private.erl b/src/mod_private.erl index dc33af7f8..16ca31491 100644 --- a/src/mod_private.erl +++ b/src/mod_private.erl @@ -49,8 +49,7 @@ -callback remove_user(binary(), binary()) -> any(). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), ejabberd_hooks:add(remove_user, Host, ?MODULE, @@ -72,9 +71,7 @@ reload(Host, NewOpts, OldOpts) -> true -> ok end, - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE, ?MODULE, process_sm_iq, IQDisc); diff --git a/src/mod_privilege.erl b/src/mod_privilege.erl index 1547d53ad..e2a62adb0 100644 --- a/src/mod_privilege.erl +++ b/src/mod_privilege.erl @@ -58,9 +58,29 @@ stop(Host) -> reload(_Host, _NewOpts, _OldOpts) -> ok. -mod_opt_type(roster) -> v_roster(); -mod_opt_type(message) -> v_message(); -mod_opt_type(presence) -> v_presence(); +mod_opt_type(roster) -> + fun(Props) -> + lists:map( + fun({both, ACL}) -> {both, acl:access_rules_validator(ACL)}; + ({get, ACL}) -> {get, acl:access_rules_validator(ACL)}; + ({set, ACL}) -> {set, acl:access_rules_validator(ACL)} + end, Props) + end; +mod_opt_type(message) -> + fun(Props) -> + lists:map( + fun({outgoing, ACL}) -> {outgoing, acl:access_rules_validator(ACL)} + end, Props) + end; +mod_opt_type(presence) -> + fun(Props) -> + lists:map( + fun({managed_entity, ACL}) -> + {managed_entity, acl:access_rules_validator(ACL)}; + ({roster, ACL}) -> + {roster, acl:access_rules_validator(ACL)} + end, Props) + end; mod_opt_type(_) -> [roster, message, presence]. @@ -302,8 +322,7 @@ forward_message(#message{to = To} = Msg) -> end. get_roster_permission(ServerHost, Host) -> - Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, roster, - v_roster(), []), + Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, roster, []), case match_rule(ServerHost, Host, Perms, both) of allow -> both; @@ -318,16 +337,14 @@ get_roster_permission(ServerHost, Host) -> end. get_message_permission(ServerHost, Host) -> - Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, message, - v_message(), []), + Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, message, []), case match_rule(ServerHost, Host, Perms, outgoing) of allow -> outgoing; deny -> none end. get_presence_permission(ServerHost, Host) -> - Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, presence, - v_presence(), []), + Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, presence, []), case match_rule(ServerHost, Host, Perms, roster) of allow -> roster; @@ -341,29 +358,3 @@ get_presence_permission(ServerHost, Host) -> match_rule(ServerHost, Host, Perms, Type) -> Access = proplists:get_value(Type, Perms, none), acl:match_rule(ServerHost, Access, jid:make(Host)). - -v_roster() -> - fun(Props) -> - lists:map( - fun({both, ACL}) -> {both, acl:access_rules_validator(ACL)}; - ({get, ACL}) -> {get, acl:access_rules_validator(ACL)}; - ({set, ACL}) -> {set, acl:access_rules_validator(ACL)} - end, Props) - end. - -v_message() -> - fun(Props) -> - lists:map( - fun({outgoing, ACL}) -> {outgoing, acl:access_rules_validator(ACL)} - end, Props) - end. - -v_presence() -> - fun(Props) -> - lists:map( - fun({managed_entity, ACL}) -> - {managed_entity, acl:access_rules_validator(ACL)}; - ({roster, ACL}) -> - {roster, acl:access_rules_validator(ACL)} - end, Props) - end. diff --git a/src/mod_proxy65.erl b/src/mod_proxy65.erl index 53f708340..aee324960 100644 --- a/src/mod_proxy65.erl +++ b/src/mod_proxy65.erl @@ -50,14 +50,21 @@ ok | {error, limit | conflict | notfound | term()}. start(Host, Opts) -> - case mod_proxy65_service:add_listener(Host, Opts) of + {ListenOpts, ModOpts} = lists:partition( + fun({auth_type, _}) -> true; + ({recbuf, _}) -> true; + ({sndbuf, _}) -> true; + ({shaper, _}) -> true; + (_) -> false + end, Opts), + case mod_proxy65_service:add_listener(Host, ListenOpts) of {error, _} = Err -> Err; _ -> Mod = gen_mod:ram_db_mod(global, ?MODULE), Mod:init(), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, + ChildSpec = {Proc, {?MODULE, start_link, [Host, ModOpts]}, transient, infinity, supervisor, [?MODULE]}, supervisor:start_child(ejabberd_gen_mod_sup, ChildSpec) end. @@ -103,15 +110,6 @@ init([Host, Opts]) -> depends(_Host, _Opts) -> []. -mod_opt_type(auth_type) -> - fun (plain) -> plain; - (anonymous) -> anonymous - end; -mod_opt_type(recbuf) -> - fun (I) when is_integer(I), I > 0 -> I end; -mod_opt_type(shaper) -> fun acl:shaper_rules_validator/1; -mod_opt_type(sndbuf) -> - fun (I) when is_integer(I), I > 0 -> I end; mod_opt_type(access) -> fun acl:access_rules_validator/1; mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(hostname) -> fun iolist_to_binary/1; @@ -130,7 +128,11 @@ mod_opt_type(max_connections) -> end; mod_opt_type(ram_db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; -mod_opt_type(_) -> - [auth_type, recbuf, shaper, sndbuf, - access, host, hostname, ip, name, port, - max_connections, ram_db_type]. +mod_opt_type(Opt) -> + case mod_proxy65_stream:listen_opt_type(Opt) of + Opts when is_list(Opts) -> + [access, host, hostname, ip, name, port, + max_connections, ram_db_type] ++ Opts; + Fun -> + Fun + end. diff --git a/src/mod_proxy65_service.erl b/src/mod_proxy65_service.erl index f2a70cd09..6a0b1fc16 100644 --- a/src/mod_proxy65_service.erl +++ b/src/mod_proxy65_service.erl @@ -60,8 +60,7 @@ reload(Host, NewOpts, OldOpts) -> init([Host, Opts]) -> process_flag(trap_exit, true), - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), MyHost = gen_mod:get_opt_host(Host, Opts, <<"proxy.@HOST@">>), gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO, ?MODULE, process_disco_info, IQDisc), @@ -92,12 +91,8 @@ handle_call(_Request, _From, State) -> handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) -> NewHost = gen_mod:get_opt_host(ServerHost, NewOpts, <<"proxy.@HOST@">>), OldHost = gen_mod:get_opt_host(ServerHost, OldOpts, <<"proxy.@HOST@">>), - NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, - fun gen_iq_handler:check_type/1, - one_queue), - OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue), + NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, one_queue), + OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, one_queue), if (NewIQDisc /= OldIQDisc) or (NewHost /= OldHost) -> gen_iq_handler:add_iq_handler(ejabberd_local, NewHost, ?NS_DISCO_INFO, ?MODULE, process_disco_info, NewIQDisc), @@ -132,7 +127,7 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. %%%------------------------ add_listener(Host, Opts) -> - NewOpts = [Host | Opts], + NewOpts = [{server_host, Host} | Opts], ejabberd_listener:add_listener(get_port_ip(Host), mod_proxy65_stream, NewOpts). @@ -150,7 +145,6 @@ process_disco_info(#iq{type = set, lang = Lang} = IQ) -> process_disco_info(#iq{type = get, to = To, lang = Lang} = IQ) -> Host = ejabberd_router:host_of_route(To#jid.lserver), Name = gen_mod:get_module_opt(Host, mod_proxy65, name, - fun iolist_to_binary/1, <<"SOCKS5 Bytestreams">>), Info = ejabberd_hooks:run_fold(disco_info, Host, [], [Host, ?MODULE, <<"">>, <<"">>]), @@ -184,9 +178,7 @@ process_vcard(#iq{type = get, lang = Lang} = IQ) -> process_bytestreams(#iq{type = get, from = JID, to = To, lang = Lang} = IQ) -> Host = To#jid.lserver, ServerHost = ejabberd_router:host_of_route(Host), - ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access, - fun acl:access_rules_validator/1, - all), + ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access, all), case acl:match_rule(ServerHost, ACL, JID) of allow -> StreamHost = get_streamhost(Host, ServerHost), @@ -209,9 +201,7 @@ process_bytestreams(#iq{type = set, lang = Lang, from = InitiatorJID, to = To, sub_els = [#bytestreams{activate = TargetJID, sid = SID}]} = IQ) -> ServerHost = ejabberd_router:host_of_route(To#jid.lserver), - ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access, - fun acl:access_rules_validator/1, - all), + ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access, all), case acl:match_rule(ServerHost, ACL, InitiatorJID) of allow -> Node = ejabberd_cluster:get_node_by_id(To#jid.lresource), @@ -264,7 +254,6 @@ transform_module_options(Opts) -> get_streamhost(Host, ServerHost) -> {Port, IP} = get_port_ip(ServerHost), HostName = gen_mod:get_module_opt(ServerHost, mod_proxy65, hostname, - fun iolist_to_binary/1, misc:ip_to_list(IP)), Resource = ejabberd_cluster:node_id(), #streamhost{jid = jid:make(<<"">>, Host, Resource), @@ -273,18 +262,8 @@ get_streamhost(Host, ServerHost) -> -spec get_port_ip(binary()) -> {pos_integer(), inet:ip_address()}. get_port_ip(Host) -> - Port = gen_mod:get_module_opt(Host, mod_proxy65, port, - fun(P) when is_integer(P), P>0, P<65536 -> - P - end, - 7777), - IP = gen_mod:get_module_opt(Host, mod_proxy65, ip, - fun(S) -> - {ok, Addr} = inet_parse:address( - binary_to_list( - iolist_to_binary(S))), - Addr - end, get_my_ip()), + Port = gen_mod:get_module_opt(Host, mod_proxy65, port, 7777), + IP = gen_mod:get_module_opt(Host, mod_proxy65, ip, get_my_ip()), {Port, IP}. -spec get_my_ip() -> inet:ip_address(). @@ -296,7 +275,4 @@ get_my_ip() -> end. max_connections(ServerHost) -> - gen_mod:get_module_opt(ServerHost, mod_proxy65, max_connections, - fun(I) when is_integer(I), I>0 -> I; - (infinity) -> infinity - end, infinity). + gen_mod:get_module_opt(ServerHost, mod_proxy65, max_connections, infinity). diff --git a/src/mod_proxy65_stream.erl b/src/mod_proxy65_stream.erl index 45ce2f44c..899b66727 100644 --- a/src/mod_proxy65_stream.erl +++ b/src/mod_proxy65_stream.erl @@ -38,7 +38,7 @@ stream_established/2]). -export([start/2, stop/1, start_link/3, activate/2, - relay/3, socket_type/0]). + relay/3, socket_type/0, listen_opt_type/1]). -include("mod_proxy65.hrl"). @@ -65,9 +65,10 @@ code_change(_OldVsn, StateName, StateData, _Extra) -> %%------------------------------- start({gen_tcp, Socket}, Opts1) -> - {[Host], Opts} = lists:partition(fun (O) -> is_binary(O) - end, - Opts1), + {[{server_host, Host}], Opts} = lists:partition( + fun({server_host, _}) -> true; + (_) -> false + end, Opts1), Supervisor = gen_mod:get_module_proc(Host, ejabberd_mod_proxy65_sup), supervisor:start_child(Supervisor, @@ -78,19 +79,10 @@ start_link(Socket, Host, Opts) -> init([Socket, Host, Opts]) -> process_flag(trap_exit, true), - AuthType = gen_mod:get_opt(auth_type, Opts, - fun(plain) -> plain; - (anonymous) -> anonymous - end, anonymous), - Shaper = gen_mod:get_opt(shaper, Opts, - fun acl:shaper_rules_validator/1, - none), - RecvBuf = gen_mod:get_opt(recbuf, Opts, - fun(I) when is_integer(I), I>0 -> I end, - 8192), - SendBuf = gen_mod:get_opt(sndbuf, Opts, - fun(I) when is_integer(I), I>0 -> I end, - 8192), + AuthType = gen_mod:get_opt(auth_type, Opts, anonymous), + Shaper = gen_mod:get_opt(shaper, Opts, none), + RecvBuf = gen_mod:get_opt(recbuf, Opts, 8192), + SendBuf = gen_mod:get_opt(sndbuf, Opts, 8192), TRef = erlang:send_after(?WAIT_TIMEOUT, self(), stop), inet:setopts(Socket, [{active, true}, {recbuf, RecvBuf}, {sndbuf, SendBuf}]), @@ -290,3 +282,17 @@ find_maxrate(Shaper, JID1, JID2, Host) -> if MaxRate1 == none; MaxRate2 == none -> none; true -> lists:max([MaxRate1, MaxRate2]) end. + +listen_opt_type(server_host) -> + fun iolist_to_binary/1; +listen_opt_type(auth_type) -> + fun (plain) -> plain; + (anonymous) -> anonymous + end; +listen_opt_type(recbuf) -> + fun (I) when is_integer(I), I > 0 -> I end; +listen_opt_type(shaper) -> fun acl:shaper_rules_validator/1; +listen_opt_type(sndbuf) -> + fun (I) when is_integer(I), I > 0 -> I end; +listen_opt_type(_) -> + [auth_type, recbuf, sndbuf, shaper]. diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index b1ca26a9c..d5a4fd9c4 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -244,18 +244,12 @@ init([ServerHost, Opts]) -> ?DEBUG("pubsub init ~p ~p", [ServerHost, Opts]), Host = gen_mod:get_opt_host(ServerHost, Opts, <<"pubsub.@HOST@">>), ejabberd_router:register_route(Host, ServerHost), - Access = gen_mod:get_opt(access_createnode, Opts, - fun acl:access_rules_validator/1, all), - PepOffline = gen_mod:get_opt(ignore_pep_from_offline, Opts, - fun(A) when is_boolean(A) -> A end, true), - IQDisc = gen_mod:get_opt(iqdisc, Opts, - fun gen_iq_handler:check_type/1, one_queue), - LastItemCache = gen_mod:get_opt(last_item_cache, Opts, - fun(A) when is_boolean(A) -> A end, false), - MaxItemsNode = gen_mod:get_opt(max_items_node, Opts, - fun(A) when is_integer(A) andalso A >= 0 -> A end, ?MAXITEMS), - MaxSubsNode = gen_mod:get_opt(max_subscriptions_node, Opts, - fun(A) when is_integer(A) andalso A >= 0 -> A end, undefined), + Access = gen_mod:get_opt(access_createnode, Opts, all), + PepOffline = gen_mod:get_opt(ignore_pep_from_offline, Opts, true), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), + LastItemCache = gen_mod:get_opt(last_item_cache, Opts, false), + MaxItemsNode = gen_mod:get_opt(max_items_node, Opts, ?MAXITEMS), + MaxSubsNode = gen_mod:get_opt(max_subscriptions_node, Opts), case gen_mod:db_type(ServerHost, ?MODULE) of mnesia -> pubsub_index:init(Host, ServerHost, Opts); _ -> ok @@ -263,8 +257,9 @@ init([ServerHost, Opts]) -> {Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts), DefaultModule = plugin(Host, hd(Plugins)), BaseOptions = DefaultModule:options(), - DefaultNodeCfg = gen_mod:get_opt(default_node_config, Opts, - fun(A) when is_list(A) -> filter_node_options(A, BaseOptions) end, []), + DefaultNodeCfg = filter_node_options( + gen_mod:get_opt(default_node_config, Opts, []), + BaseOptions), ejabberd_mnesia:create(?MODULE, pubsub_last_item, [{ram_copies, [node()]}, {attributes, record_info(fields, pubsub_last_item)}]), @@ -364,8 +359,7 @@ init_send_loop(ServerHost) -> depends(ServerHost, Opts) -> Host = gen_mod:get_opt_host(ServerHost, Opts, <<"pubsub.@HOST@">>), - Plugins = gen_mod:get_opt(plugins, Opts, - fun(A) when is_list(A) -> A end, [?STDNODE]), + Plugins = gen_mod:get_opt(plugins, Opts, [?STDNODE]), lists:flatmap( fun(Name) -> Plugin = plugin(ServerHost, Name), @@ -380,15 +374,11 @@ depends(ServerHost, Opts) -> %% <em>node_plugin</em>. The 'node_' prefix is mandatory.</p> %% <p>See {@link node_hometree:init/1} for an example implementation.</p> init_plugins(Host, ServerHost, Opts) -> - TreePlugin = tree(Host, gen_mod:get_opt(nodetree, Opts, - fun(A) when is_binary(A) -> A end, - ?STDTREE)), + TreePlugin = tree(Host, gen_mod:get_opt(nodetree, Opts, ?STDTREE)), ?DEBUG("** tree plugin is ~p", [TreePlugin]), TreePlugin:init(Host, ServerHost, Opts), - Plugins = gen_mod:get_opt(plugins, Opts, - fun(A) when is_list(A) -> A end, [?STDNODE]), - PepMapping = gen_mod:get_opt(pep_mapping, Opts, - fun(A) when is_list(A) -> A end, []), + Plugins = gen_mod:get_opt(plugins, Opts, [?STDNODE]), + PepMapping = gen_mod:get_opt(pep_mapping, Opts, []), ?DEBUG("** PEP Mapping : ~p~n", [PepMapping]), PluginsOK = lists:foldl( fun (Name, Acc) -> diff --git a/src/mod_register.erl b/src/mod_register.erl index e15165f77..2d6442ba7 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -44,8 +44,7 @@ -include("xmpp.hrl"). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_REGISTER, ?MODULE, process_iq, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, @@ -70,9 +69,7 @@ stop(Host) -> ?NS_REGISTER). reload(Host, NewOpts, OldOpts) -> - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_REGISTER, ?MODULE, process_iq, IQDisc), @@ -87,9 +84,7 @@ depends(_Host, _Opts) -> -spec stream_feature_register([xmpp_element()], binary()) -> [xmpp_element()]. stream_feature_register(Acc, Host) -> - AF = gen_mod:get_module_opt(Host, ?MODULE, access_from, - fun(A) -> A end, - all), + AF = gen_mod:get_module_opt(Host, ?MODULE, access_from, all), case (AF /= none) of true -> [#feature_register{}|Acc]; @@ -120,15 +115,12 @@ process_iq(#iq{from = From} = IQ) -> process_iq(#iq{from = From, to = To} = IQ, Source) -> IsCaptchaEnabled = case gen_mod:get_module_opt(To#jid.lserver, ?MODULE, - captcha_protected, - fun(B) when is_boolean(B) -> B end, - false) of + captcha_protected, false) of true -> true; false -> false end, Server = To#jid.lserver, - Access = gen_mod:get_module_opt(Server, ?MODULE, access, - fun(A) -> A end, all), + Access = gen_mod:get_module_opt(Server, ?MODULE, access, all), AllowRemove = allow == acl:match_rule(Server, Access, From), process_iq(IQ, Source, IsCaptchaEnabled, AllowRemove). @@ -315,9 +307,7 @@ try_register(User, Server, Password, SourceRaw, Lang) -> false -> {error, xmpp:err_bad_request(<<"Malformed username">>, Lang)}; _ -> JID = jid:make(User, Server), - Access = gen_mod:get_module_opt(Server, ?MODULE, access, - fun(A) -> A end, - all), + Access = gen_mod:get_module_opt(Server, ?MODULE, access, all), IPAccess = get_ip_access(Server), case {acl:match_rule(Server, Access, JID), check_ip_access(SourceRaw, IPAccess)} @@ -379,15 +369,7 @@ try_register(User, Server, Password, SourceRaw, Lang) -> send_welcome_message(JID) -> Host = JID#jid.lserver, case gen_mod:get_module_opt(Host, ?MODULE, welcome_message, - fun(Opts) -> - S = proplists:get_value( - subject, Opts, <<>>), - B = proplists:get_value( - body, Opts, <<>>), - {iolist_to_binary(S), - iolist_to_binary(B)} - end, {<<"">>, <<"">>}) - of + {<<"">>, <<"">>}) of {<<"">>, <<"">>} -> ok; {Subj, Body} -> ejabberd_router:route( @@ -400,11 +382,7 @@ send_welcome_message(JID) -> send_registration_notifications(Mod, UJID, Source) -> Host = UJID#jid.lserver, - case gen_mod:get_module_opt( - Host, Mod, registration_watchers, - fun(Ss) -> - [jid:decode(iolist_to_binary(S)) || S <- Ss] - end, []) of + case gen_mod:get_module_opt(Host, Mod, registration_watchers, []) of [] -> ok; JIDs when is_list(JIDs) -> Body = @@ -428,22 +406,12 @@ check_from(#jid{user = <<"">>, server = <<"">>}, _Server) -> allow; check_from(JID, Server) -> - Access = gen_mod:get_module_opt(Server, ?MODULE, access_from, - fun(A) -> A end, - none), + Access = gen_mod:get_module_opt(Server, ?MODULE, access_from, none), acl:match_rule(Server, Access, JID). check_timeout(undefined) -> true; check_timeout(Source) -> - Timeout = ejabberd_config:get_option( - registration_timeout, - fun(TO) when is_integer(TO), TO > 0 -> - TO; - (infinity) -> - infinity; - (unlimited) -> - infinity - end, 600), + Timeout = ejabberd_config:get_option(registration_timeout, 600), if is_integer(Timeout) -> Priority = -p1_time_compat:system_time(seconds), CleanPriority = Priority + Timeout, @@ -488,15 +456,7 @@ clean_treap(Treap, CleanPriority) -> remove_timeout(undefined) -> true; remove_timeout(Source) -> - Timeout = ejabberd_config:get_option( - registration_timeout, - fun(TO) when is_integer(TO), TO > 0 -> - TO; - (infinity) -> - infinity; - (unlimited) -> - infinity - end, 600), + Timeout = ejabberd_config:get_option(registration_timeout, 600), if is_integer(Timeout) -> F = fun () -> Treap = case mnesia:read(mod_register_ip, treap, write) @@ -548,9 +508,7 @@ is_strong_password(Server, Password) -> is_strong_password2(Server, Password) -> LServer = jid:nameprep(Server), - case gen_mod:get_module_opt(LServer, ?MODULE, password_strength, - fun(N) when is_number(N), N>=0 -> N end, - 0) of + case gen_mod:get_module_opt(LServer, ?MODULE, password_strength, 0) of 0 -> true; Entropy -> @@ -614,9 +572,7 @@ may_remove_resource({_, _, _} = From) -> may_remove_resource(From) -> From. get_ip_access(Host) -> - gen_mod:get_module_opt(Host, ?MODULE, ip_access, - fun(A) when is_atom(A) -> A end, - all). + gen_mod:get_module_opt(Host, ?MODULE, ip_access, all). check_ip_access({User, Server, Resource}, IPAccess) -> case ejabberd_sm:get_user_ip(User, Server, Resource) of diff --git a/src/mod_register_web.erl b/src/mod_register_web.erl index 109550475..cd19bb65a 100644 --- a/src/mod_register_web.erl +++ b/src/mod_register_web.erl @@ -496,9 +496,7 @@ form_del_get(Host, Lang) -> %% {error, not_allowed} | %% {error, invalid_jid} register_account(Username, Host, Password) -> - Access = gen_mod:get_module_opt(Host, mod_register, access, - fun(A) -> A end, - all), + Access = gen_mod:get_module_opt(Host, mod_register, access, all), case jid:make(Username, Host) of error -> {error, invalid_jid}; JID -> diff --git a/src/mod_roster.erl b/src/mod_roster.erl index cf281528a..819e6a895 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -84,8 +84,7 @@ {subscription(), [binary()]}. start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), ejabberd_hooks:add(roster_get, Host, ?MODULE, @@ -147,9 +146,7 @@ reload(Host, NewOpts, OldOpts) -> true -> ok end, - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER, ?MODULE, process_iq, IQDisc); @@ -188,8 +185,7 @@ process_local_iq(#iq{type = set, from = From, lang = Lang, xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)); false -> #jid{server = Server} = From, - Access = gen_mod:get_module_opt(Server, ?MODULE, - access, fun(A) -> A end, all), + Access = gen_mod:get_module_opt(Server, ?MODULE, access, all), case acl:match_rule(Server, Access, From) of deny -> Txt = <<"Denied by ACL">>, @@ -222,14 +218,10 @@ roster_hash(Items) -> <- Items]))). roster_versioning_enabled(Host) -> - gen_mod:get_module_opt(Host, ?MODULE, versioning, - fun(B) when is_boolean(B) -> B end, - false). + gen_mod:get_module_opt(Host, ?MODULE, versioning, false). roster_version_on_db(Host) -> - gen_mod:get_module_opt(Host, ?MODULE, store_current_id, - fun(B) when is_boolean(B) -> B end, - false). + gen_mod:get_module_opt(Host, ?MODULE, store_current_id, false). %% Returns a list that may contain an xmlelement with the XEP-237 feature if it's enabled. -spec get_versioning_feature([xmpp_element()], binary()) -> [xmpp_element()]. diff --git a/src/mod_s2s_dialback.erl b/src/mod_s2s_dialback.erl index 00730f327..ab33597a5 100644 --- a/src/mod_s2s_dialback.erl +++ b/src/mod_s2s_dialback.erl @@ -265,7 +265,7 @@ s2s_out_packet(State, _) -> %%%=================================================================== -spec make_key(binary(), binary(), binary()) -> binary(). make_key(From, To, StreamID) -> - Secret = ejabberd_config:get_option(shared_key, fun(V) -> V end), + Secret = ejabberd_config:get_option(shared_key), str:to_hexlist( crypto:hmac(sha256, str:to_hexlist(crypto:hash(sha256, Secret)), [To, " ", From, " ", StreamID])). diff --git a/src/mod_service_log.erl b/src/mod_service_log.erl index 46fae9217..1c6e5fe82 100644 --- a/src/mod_service_log.erl +++ b/src/mod_service_log.erl @@ -68,8 +68,7 @@ log_user_receive({Packet, C2SState}) -> -spec log_packet(stanza(), binary()) -> ok. log_packet(Packet, Host) -> - Loggers = gen_mod:get_module_opt(Host, ?MODULE, loggers, - mod_opt_type(loggers), []), + Loggers = gen_mod:get_module_opt(Host, ?MODULE, loggers, []), ForwardedMsg = #message{from = jid:make(Host), id = randoms:get_string(), sub_els = [#forwarded{ diff --git a/src/mod_shared_roster_ldap.erl b/src/mod_shared_roster_ldap.erl index 951ff0739..08220f7ec 100644 --- a/src/mod_shared_roster_ldap.erl +++ b/src/mod_shared_roster_ldap.erl @@ -468,44 +468,18 @@ get_user_part_re(String, Pattern) -> parse_options(Host, Opts) -> Eldap_ID = misc:atom_to_binary(gen_mod:get_module_proc(Host, ?MODULE)), Cfg = eldap_utils:get_config(Host, Opts), - GroupAttr = gen_mod:get_opt(ldap_groupattr, Opts, - fun iolist_to_binary/1, - <<"cn">>), - GroupDesc = gen_mod:get_opt(ldap_groupdesc, Opts, - fun iolist_to_binary/1, - GroupAttr), - UserDesc = gen_mod:get_opt(ldap_userdesc, Opts, - fun iolist_to_binary/1, - <<"cn">>), - UserUID = gen_mod:get_opt(ldap_useruid, Opts, - fun iolist_to_binary/1, - <<"cn">>), - UIDAttr = gen_mod:get_opt(ldap_memberattr, Opts, - fun iolist_to_binary/1, - <<"memberUid">>), - UIDAttrFormat = gen_mod:get_opt(ldap_memberattr_format, Opts, - fun iolist_to_binary/1, - <<"%u">>), - UIDAttrFormatRe = gen_mod:get_opt(ldap_memberattr_format_re, Opts, - fun(S) -> - Re = iolist_to_binary(S), - {ok, MP} = re:compile(Re), - MP - end, <<"">>), - AuthCheck = gen_mod:get_opt(ldap_auth_check, Opts, - fun(on) -> true; - (off) -> false; - (false) -> false; - (true) -> true - end, true), - ConfigFilter = gen_mod:get_opt({ldap_filter, Host}, Opts, - fun check_filter/1, <<"">>), - ConfigUserFilter = gen_mod:get_opt({ldap_ufilter, Host}, Opts, - fun check_filter/1, <<"">>), - ConfigGroupFilter = gen_mod:get_opt({ldap_gfilter, Host}, Opts, - fun check_filter/1, <<"">>), - RosterFilter = gen_mod:get_opt({ldap_rfilter, Host}, Opts, - fun check_filter/1, <<"">>), + GroupAttr = gen_mod:get_opt(ldap_groupattr, Opts, <<"cn">>), + GroupDesc = gen_mod:get_opt(ldap_groupdesc, Opts, GroupAttr), + UserDesc = gen_mod:get_opt(ldap_userdesc, Opts, <<"cn">>), + UserUID = gen_mod:get_opt(ldap_useruid, Opts, <<"cn">>), + UIDAttr = gen_mod:get_opt(ldap_memberattr, Opts, <<"memberUid">>), + UIDAttrFormat = gen_mod:get_opt(ldap_memberattr_format, Opts, <<"%u">>), + UIDAttrFormatRe = gen_mod:get_opt(ldap_memberattr_format_re, Opts, <<"">>), + AuthCheck = gen_mod:get_opt(ldap_auth_check, Opts, true), + ConfigFilter = gen_mod:get_opt({ldap_filter, Host}, Opts, <<"">>), + ConfigUserFilter = gen_mod:get_opt({ldap_ufilter, Host}, Opts, <<"">>), + ConfigGroupFilter = gen_mod:get_opt({ldap_gfilter, Host}, Opts, <<"">>), + RosterFilter = gen_mod:get_opt({ldap_rfilter, Host}, Opts, <<"">>), SubFilter = <<"(&(", UIDAttr/binary, "=", UIDAttrFormat/binary, ")(", GroupAttr/binary, "=%g))">>, UserSubFilter = case ConfigUserFilter of @@ -552,11 +526,6 @@ parse_options(Host, Opts) -> ufilter = UserFilter, rfilter = RosterFilter, gfilter = GroupFilter, auth_check = AuthCheck}. -check_filter(F) -> - NewF = iolist_to_binary(F), - {ok, _} = eldap_filter:parse(NewF), - NewF. - init_cache(Host, Opts) -> UseCache = use_cache(Host, Opts), case UseCache of @@ -571,18 +540,14 @@ init_cache(Host, Opts) -> UseCache. use_cache(Host, Opts) -> - gen_mod:get_opt(use_cache, Opts, mod_opt_type(use_cache), - ejabberd_config:use_cache(Host)). + gen_mod:get_opt(use_cache, Opts, ejabberd_config:use_cache(Host)). cache_opts(Host, Opts) -> MaxSize = gen_mod:get_opt(cache_size, Opts, - mod_opt_type(cache_size), ejabberd_config:cache_size(Host)), CacheMissed = gen_mod:get_opt(cache_missed, Opts, - mod_opt_type(cache_missed), ejabberd_config:cache_missed(Host)), LifeTime = case gen_mod:get_opt(cache_life_time, Opts, - mod_opt_type(cache_life_time), ejabberd_config:cache_life_time(Host)) of infinity -> infinity; I -> timer:seconds(I) @@ -654,8 +619,8 @@ mod_opt_type(ldap_auth_check) -> (false) -> false; (true) -> true end; -mod_opt_type(ldap_filter) -> fun check_filter/1; -mod_opt_type(ldap_gfilter) -> fun check_filter/1; +mod_opt_type(ldap_filter) -> fun eldap_utils:check_filter/1; +mod_opt_type(ldap_gfilter) -> fun eldap_utils:check_filter/1; mod_opt_type(O) when O == cache_size; O == cache_life_time -> fun (I) when is_integer(I), I > 0 -> I; @@ -672,8 +637,8 @@ mod_opt_type(ldap_memberattr_format_re) -> fun (S) -> Re = iolist_to_binary(S), {ok, MP} = re:compile(Re), MP end; -mod_opt_type(ldap_rfilter) -> fun check_filter/1; -mod_opt_type(ldap_ufilter) -> fun check_filter/1; +mod_opt_type(ldap_rfilter) -> fun eldap_utils:check_filter/1; +mod_opt_type(ldap_ufilter) -> fun eldap_utils:check_filter/1; mod_opt_type(ldap_userdesc) -> fun iolist_to_binary/1; mod_opt_type(ldap_useruid) -> fun iolist_to_binary/1; mod_opt_type(_) -> @@ -687,9 +652,8 @@ mod_opt_type(_) -> ldap_tls_cacertfile, ldap_tls_certfile, ldap_tls_depth, ldap_tls_verify, use_cache, cache_missed, cache_size, cache_life_time]. -opt_type(ldap_filter) -> fun check_filter/1; -opt_type(ldap_gfilter) -> fun check_filter/1; -opt_type(ldap_rfilter) -> fun check_filter/1; -opt_type(ldap_ufilter) -> fun check_filter/1; +opt_type(ldap_gfilter) -> fun eldap_utils:check_filter/1; +opt_type(ldap_rfilter) -> fun eldap_utils:check_filter/1; +opt_type(ldap_ufilter) -> fun eldap_utils:check_filter/1; opt_type(_) -> - [ldap_filter, ldap_gfilter, ldap_rfilter, ldap_ufilter]. + [ldap_gfilter, ldap_rfilter, ldap_ufilter]. diff --git a/src/mod_sic.erl b/src/mod_sic.erl index bca662fcd..73d4f9de2 100644 --- a/src/mod_sic.erl +++ b/src/mod_sic.erl @@ -39,8 +39,7 @@ -include("xmpp.hrl"). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_SIC_0, ?MODULE, process_local_iq, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_SIC_0, @@ -57,9 +56,7 @@ stop(Host) -> gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_SIC_1). reload(Host, NewOpts, OldOpts) -> - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_SIC_0, ?MODULE, process_local_iq, IQDisc), diff --git a/src/mod_sip_proxy.erl b/src/mod_sip_proxy.erl index b57e431d6..5e0cfa25e 100644 --- a/src/mod_sip_proxy.erl +++ b/src/mod_sip_proxy.erl @@ -24,8 +24,6 @@ %%%------------------------------------------------------------------- -module(mod_sip_proxy). --behaviour(ejabberd_config). - -define(GEN_FSM, p1_fsm). -behaviour(?GEN_FSM). @@ -35,7 +33,7 @@ -export([init/1, wait_for_request/2, wait_for_response/2, handle_event/3, handle_sync_event/4, handle_info/3, terminate/3, - code_change/4, opt_type/1]). + code_change/4]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -269,8 +267,7 @@ cancel_pending_transactions(State) -> lists:foreach(fun esip:cancel/1, State#state.tr_ids). add_certfile(LServer, Opts) -> - case ejabberd_config:get_option({domain_certfile, LServer}, - fun iolist_to_binary/1) of + case ejabberd_config:get_option({domain_certfile, LServer}) of CertFile when is_binary(CertFile), CertFile /= <<"">> -> [{certfile, CertFile}|Opts]; _ -> @@ -316,11 +313,7 @@ is_request_within_dialog(#sip{hdrs = Hdrs}) -> esip:has_param(<<"tag">>, Params). need_record_route(LServer) -> - gen_mod:get_module_opt( - LServer, mod_sip, always_record_route, - fun(true) -> true; - (false) -> false - end, true). + gen_mod:get_module_opt(LServer, mod_sip, always_record_route, true). make_sign(TS, Hdrs) -> {_, #uri{user = FUser, host = FServer}, FParams} = esip:get_hdr('from', Hdrs), @@ -331,7 +324,7 @@ make_sign(TS, Hdrs) -> LTServer = safe_nameprep(TServer), FromTag = esip:get_param(<<"tag">>, FParams), CallID = esip:get_hdr('call-id', Hdrs), - SharedKey = ejabberd_config:get_option(shared_key, fun(V) -> V end), + SharedKey = ejabberd_config:get_option(shared_key), str:sha([SharedKey, LFUser, LFServer, LTUser, LTServer, FromTag, CallID, TS]). @@ -347,41 +340,17 @@ is_signed_by_me(TS_Sign, Hdrs) -> end. get_configured_vias(LServer) -> - gen_mod:get_module_opt( - LServer, mod_sip, via, - fun(L) -> - lists:map( - fun(Opts) -> - Type = proplists:get_value(type, Opts), - Host = proplists:get_value(host, Opts), - Port = proplists:get_value(port, Opts), - true = (Type == tcp) or (Type == tls) or (Type == udp), - true = is_binary(Host) and (Host /= <<"">>), - true = (is_integer(Port) - and (Port > 0) and (Port < 65536)) - or (Port == undefined), - {Type, {Host, Port}} - end, L) - end, []). + gen_mod:get_module_opt(LServer, mod_sip, via, []). get_configured_record_route(LServer) -> gen_mod:get_module_opt( LServer, mod_sip, record_route, - fun(IOList) -> - S = iolist_to_binary(IOList), - #uri{} = esip:decode_uri(S) - end, #uri{host = LServer, params = [{<<"lr">>, <<"">>}]}). + #uri{host = LServer, params = [{<<"lr">>, <<"">>}]}). get_configured_routes(LServer) -> gen_mod:get_module_opt( LServer, mod_sip, routes, - fun(L) -> - lists:map( - fun(IOList) -> - S = iolist_to_binary(IOList), - #uri{} = esip:decode_uri(S) - end, L) - end, [#uri{host = LServer, params = [{<<"lr">>, <<"">>}]}]). + [#uri{host = LServer, params = [{<<"lr">>, <<"">>}]}]). mark_transaction_as_complete(TrID, State) -> NewTrIDs = lists:delete(TrID, State#state.tr_ids), @@ -455,7 +424,3 @@ safe_nameprep(S) -> error -> S; S1 -> S1 end. - -opt_type(domain_certfile) -> fun iolist_to_binary/1; -opt_type(shared_key) -> fun (V) -> V end; -opt_type(_) -> [domain_certfile, shared_key]. diff --git a/src/mod_sip_registrar.erl b/src/mod_sip_registrar.erl index 1cd165210..1bc819c08 100644 --- a/src/mod_sip_registrar.erl +++ b/src/mod_sip_registrar.erl @@ -494,12 +494,10 @@ get_flow_timeout(LServer, #sip_socket{type = Type}) -> udp -> gen_mod:get_module_opt( LServer, mod_sip, flow_timeout_udp, - fun(I) when is_integer(I), I>0 -> I end, ?FLOW_TIMEOUT_UDP); _ -> gen_mod:get_module_opt( LServer, mod_sip, flow_timeout_tcp, - fun(I) when is_integer(I), I>0 -> I end, ?FLOW_TIMEOUT_TCP) end. diff --git a/src/mod_stats.erl b/src/mod_stats.erl index 124b21d50..88ff7d0cb 100644 --- a/src/mod_stats.erl +++ b/src/mod_stats.erl @@ -38,8 +38,7 @@ -include("xmpp.hrl"). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_STATS, ?MODULE, process_iq, IQDisc). diff --git a/src/mod_stream_mgmt.erl b/src/mod_stream_mgmt.erl index a1d1ba2e9..3465ce779 100644 --- a/src/mod_stream_mgmt.erl +++ b/src/mod_stream_mgmt.erl @@ -522,7 +522,7 @@ route_unacked_stanzas(#{mgmt_state := MgmtState, Resend when is_boolean(Resend) -> Resend; if_offline -> - case ejabberd_sm:get_user_resources(User, Resource) of + case ejabberd_sm:get_user_resources(User, LServer) of [Resource] -> %% Same resource opened new session true; @@ -673,58 +673,36 @@ bounce_message_queue() -> %%% Configuration processing %%%=================================================================== get_max_ack_queue(Host, Opts) -> - VFun = mod_opt_type(max_ack_queue), - case gen_mod:get_module_opt(Host, ?MODULE, max_ack_queue, VFun) of - undefined -> gen_mod:get_opt(max_ack_queue, Opts, VFun, 1000); - Limit -> Limit - end. + gen_mod:get_module_opt(Host, ?MODULE, max_ack_queue, + gen_mod:get_opt(max_ack_queue, Opts, 1000)). get_resume_timeout(Host, Opts) -> - VFun = mod_opt_type(resume_timeout), - case gen_mod:get_module_opt(Host, ?MODULE, resume_timeout, VFun) of - undefined -> gen_mod:get_opt(resume_timeout, Opts, VFun, 300); - Timeout -> Timeout - end. + gen_mod:get_module_opt(Host, ?MODULE, resume_timeout, + gen_mod:get_opt(resume_timeout, Opts, 300)). get_max_resume_timeout(Host, Opts, ResumeTimeout) -> - VFun = mod_opt_type(max_resume_timeout), - case gen_mod:get_module_opt(Host, ?MODULE, max_resume_timeout, VFun) of - undefined -> - case gen_mod:get_opt(max_resume_timeout, Opts, VFun) of - undefined -> ResumeTimeout; - Max when Max >= ResumeTimeout -> Max; - _ -> ResumeTimeout - end; + case gen_mod:get_module_opt(Host, ?MODULE, max_resume_timeout, + gen_mod:get_opt(max_resume_timeout, Opts)) of + undefined -> ResumeTimeout; Max when Max >= ResumeTimeout -> Max; _ -> ResumeTimeout end. get_ack_timeout(Host, Opts) -> - VFun = mod_opt_type(ack_timeout), - T = case gen_mod:get_module_opt(Host, ?MODULE, ack_timeout, VFun) of - undefined -> gen_mod:get_opt(ack_timeout, Opts, VFun, 60); - AckTimeout -> AckTimeout - end, - case T of + case gen_mod:get_module_opt(Host, ?MODULE, ack_timeout, + gen_mod:get_opt(ack_timeout, Opts, 60)) of infinity -> infinity; - _ -> timer:seconds(T) + T -> timer:seconds(T) end. get_resend_on_timeout(Host, Opts) -> - VFun = mod_opt_type(resend_on_timeout), - case gen_mod:get_module_opt(Host, ?MODULE, resend_on_timeout, VFun) of - undefined -> gen_mod:get_opt(resend_on_timeout, Opts, VFun, false); - Resend -> Resend - end. + gen_mod:get_module_opt(Host, ?MODULE, resend_on_timeout, + gen_mod:get_opt(resend_on_timeout, Opts, false)). get_queue_type(Host, Opts) -> - VFun = mod_opt_type(queue_type), - case gen_mod:get_module_opt(Host, ?MODULE, queue_type, VFun) of - undefined -> - case gen_mod:get_opt(queue_type, Opts, VFun) of - undefined -> ejabberd_config:default_queue_type(Host); - Type -> Type - end; + case gen_mod:get_module_opt(Host, ?MODULE, queue_type, + gen_mod:get_opt(queue_type, Opts)) of + undefined -> ejabberd_config:default_queue_type(Host); Type -> Type end. @@ -744,6 +722,8 @@ mod_opt_type(resend_on_timeout) -> fun(B) when is_boolean(B) -> B; (if_offline) -> if_offline end; +mod_opt_type(stream_management) -> + fun(B) when is_boolean(B) -> B end; mod_opt_type(queue_type) -> fun(ram) -> ram; (file) -> file end; mod_opt_type(_) -> diff --git a/src/mod_time.erl b/src/mod_time.erl index 0b5264889..ba167ad80 100644 --- a/src/mod_time.erl +++ b/src/mod_time.erl @@ -41,8 +41,7 @@ -include("xmpp.hrl"). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_TIME, ?MODULE, process_local_iq, IQDisc). @@ -51,9 +50,7 @@ stop(Host) -> ?NS_TIME). reload(Host, NewOpts, OldOpts) -> - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_TIME, ?MODULE, process_local_iq, IQDisc); diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index e7677b4bf..90f270b54 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -82,8 +82,7 @@ init([Host, Opts]) -> Mod:init(Host, Opts), ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50), - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD, ?MODULE, process_local_iq, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, @@ -91,9 +90,7 @@ init([Host, Opts]) -> ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50), MyHost = gen_mod:get_opt_host(Host, Opts, <<"vjud.@HOST@">>), - Search = gen_mod:get_opt(search, Opts, - fun(B) when is_boolean(B) -> B end, - false), + Search = gen_mod:get_opt(search, Opts, false), if Search -> ejabberd_hooks:add( disco_local_items, MyHost, ?MODULE, disco_items, 100), @@ -433,14 +430,8 @@ search(LServer, XFields) -> Data = [{Var, Vals} || #xdata_field{var = Var, values = Vals} <- XFields], Mod = gen_mod:db_mod(LServer, ?MODULE), AllowReturnAll = gen_mod:get_module_opt(LServer, ?MODULE, allow_return_all, - fun(B) when is_boolean(B) -> B end, false), - MaxMatch = gen_mod:get_module_opt(LServer, ?MODULE, matches, - fun(infinity) -> infinity; - (I) when is_integer(I), - I>0 -> - I - end, ?JUD_MATCHES), + MaxMatch = gen_mod:get_module_opt(LServer, ?MODULE, matches, ?JUD_MATCHES), Mod:search(LServer, Data, AllowReturnAll, MaxMatch). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl index 5bb439f8b..d5ec2a8f1 100644 --- a/src/mod_vcard_ldap.erl +++ b/src/mod_vcard_ldap.erl @@ -355,31 +355,15 @@ default_search_reported() -> parse_options(Host, Opts) -> MyHost = gen_mod:get_opt_host(Host, Opts, <<"vjud.@HOST@">>), - Search = gen_mod:get_opt(search, Opts, - fun(B) when is_boolean(B) -> B end, - false), - Matches = gen_mod:get_opt(matches, Opts, - fun(infinity) -> 0; - (I) when is_integer(I), I>0 -> I - end, 30), + Search = gen_mod:get_opt(search, Opts, false), + Matches = gen_mod:get_opt(matches, Opts, 30), Eldap_ID = misc:atom_to_binary(gen_mod:get_module_proc(Host, ?PROCNAME)), Cfg = eldap_utils:get_config(Host, Opts), - UIDsTemp = gen_mod:get_opt( - {ldap_uids, Host}, Opts, - fun(Us) -> - lists:map( - fun({U, P}) -> - {iolist_to_binary(U), - iolist_to_binary(P)}; - ({U}) -> - {iolist_to_binary(U)} - end, Us) - end, [{<<"uid">>, <<"%u">>}]), + UIDsTemp = gen_mod:get_opt({ldap_uids, Host}, Opts, + [{<<"uid">>, <<"%u">>}]), UIDs = eldap_utils:uids_domain_subst(Host, UIDsTemp), SubFilter = eldap_utils:generate_subfilter(UIDs), - UserFilter = case gen_mod:get_opt( - {ldap_filter, Host}, Opts, - fun check_filter/1, <<"">>) of + UserFilter = case gen_mod:get_opt({ldap_filter, Host}, Opts, <<"">>) of <<"">> -> SubFilter; F -> @@ -388,28 +372,11 @@ parse_options(Host, Opts) -> {ok, SearchFilter} = eldap_filter:parse(eldap_filter:do_sub(UserFilter, [{<<"%u">>, <<"*">>}])), - VCardMap = gen_mod:get_opt(ldap_vcard_map, Opts, - fun(Ls) -> - lists:map( - fun({S, [{P, L}]}) -> - {iolist_to_binary(S), - iolist_to_binary(P), - [iolist_to_binary(E) - || E <- L]} - end, Ls) - end, default_vcard_map()), + VCardMap = gen_mod:get_opt(ldap_vcard_map, Opts, default_vcard_map()), SearchFields = gen_mod:get_opt(ldap_search_fields, Opts, - fun(Ls) -> - [{iolist_to_binary(S), - iolist_to_binary(P)} - || {S, P} <- Ls] - end, default_search_fields()), + default_search_fields()), SearchReported = gen_mod:get_opt(ldap_search_reported, Opts, - fun(Ls) -> - [{iolist_to_binary(S), - iolist_to_binary(P)} - || {S, P} <- Ls] - end, default_search_reported()), + default_search_reported()), UIDAttrs = [UAttr || {UAttr, _} <- UIDs], VCardMapAttrs = lists:usort(lists:append([A || {_, _, A} <- VCardMap]) @@ -447,12 +414,7 @@ parse_options(Host, Opts) -> search_reported_attrs = SearchReportedAttrs, matches = Matches}. -check_filter(F) -> - NewF = iolist_to_binary(F), - {ok, _} = eldap_filter:parse(NewF), - NewF. - -mod_opt_type(ldap_filter) -> fun check_filter/1; +mod_opt_type(ldap_filter) -> fun eldap_utils:check_filter/1; mod_opt_type(ldap_search_fields) -> fun (Ls) -> [{iolist_to_binary(S), iolist_to_binary(P)} @@ -525,17 +487,8 @@ mod_opt_type(_) -> ldap_tls_cacertfile, ldap_tls_certfile, ldap_tls_depth, ldap_tls_verify]. -opt_type(ldap_filter) -> fun check_filter/1; -opt_type(ldap_uids) -> - fun (Us) -> - lists:map(fun ({U, P}) -> - {iolist_to_binary(U), iolist_to_binary(P)}; - ({U}) -> {iolist_to_binary(U)} - end, - Us) - end; opt_type(_) -> - [ldap_filter, ldap_uids, deref_aliases, ldap_backups, ldap_base, + [deref_aliases, ldap_backups, ldap_base, ldap_deref_aliases, ldap_encrypt, ldap_password, ldap_port, ldap_rootdn, ldap_servers, ldap_tls_cacertfile, ldap_tls_certfile, ldap_tls_depth, diff --git a/src/mod_vcard_mnesia.erl b/src/mod_vcard_mnesia.erl index 340f8928e..47072ed69 100644 --- a/src/mod_vcard_mnesia.erl +++ b/src/mod_vcard_mnesia.erl @@ -197,9 +197,7 @@ filter_fields([{SVar, [Val]} | Ds], Match, LServer) <<"user">> -> case gen_mod:get_module_opt(LServer, ?MODULE, search_all_hosts, - fun(B) when is_boolean(B) -> - B - end, true) of + true) of true -> Match#vcard_search{luser = make_val(LVal)}; false -> Host = find_my_host(LServer), diff --git a/src/mod_version.erl b/src/mod_version.erl index 2ec713c17..2f43cd891 100644 --- a/src/mod_version.erl +++ b/src/mod_version.erl @@ -40,8 +40,7 @@ -include("xmpp.hrl"). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VERSION, ?MODULE, process_local_iq, IQDisc). @@ -51,9 +50,7 @@ stop(Host) -> ?NS_VERSION). reload(Host, NewOpts, OldOpts) -> - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - fun gen_iq_handler:check_type/1, - one_queue) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VERSION, ?MODULE, process_local_iq, IQDisc); @@ -66,9 +63,7 @@ process_local_iq(#iq{type = set, lang = Lang} = IQ) -> xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); process_local_iq(#iq{type = get, to = To} = IQ) -> Host = To#jid.lserver, - OS = case gen_mod:get_module_opt(Host, ?MODULE, show_os, - fun(B) when is_boolean(B) -> B end, - true) of + OS = case gen_mod:get_module_opt(Host, ?MODULE, show_os, true) of true -> get_os(); false -> undefined end, diff --git a/src/randoms.erl b/src/randoms.erl index 35a5d7580..ad07b47c2 100644 --- a/src/randoms.erl +++ b/src/randoms.erl @@ -55,4 +55,4 @@ bytes(N) -> -spec round_robin(pos_integer()) -> non_neg_integer(). round_robin(N) -> - erlang:unique_integer([monotonic, positive]) rem N. + p1_time_compat:unique_integer([monotonic, positive]) rem N. diff --git a/src/rest.erl b/src/rest.erl index 34e72a674..a3fb0eef2 100644 --- a/src/rest.erl +++ b/src/rest.erl @@ -37,12 +37,7 @@ start(Host) -> p1_http:start(), - Pool_size = - ejabberd_config:get_option({ext_api_http_pool_size, Host}, - fun(X) when is_integer(X), X > 0-> - X - end, - 100), + Pool_size = ejabberd_config:get_option({ext_api_http_pool_size, Host}, 100), p1_http:set_pool_size(Pool_size). stop(_Host) -> @@ -167,9 +162,6 @@ base_url(Server, Path) -> <<"http", _Url/binary>> -> Tail; _ -> Base = ejabberd_config:get_option({ext_api_url, Server}, - fun(X) -> - iolist_to_binary(X) - end, <<"http://localhost/api">>), <<Base/binary, "/", Tail/binary>> end. diff --git a/src/shaper.erl b/src/shaper.erl index b4db64586..ac1ecc36f 100644 --- a/src/shaper.erl +++ b/src/shaper.erl @@ -85,8 +85,7 @@ code_change(_OldVsn, State, _Extra) -> -spec load_from_config() -> ok | {error, any()}. load_from_config() -> - Shapers = ejabberd_config:get_option( - shaper, fun(V) -> V end, []), + Shapers = ejabberd_config:get_option(shaper, []), case mnesia:transaction( fun() -> lists:foreach( diff --git a/src/sql_queries.erl b/src/sql_queries.erl index da18c56f4..5d5729102 100644 --- a/src/sql_queries.erl +++ b/src/sql_queries.erl @@ -246,9 +246,7 @@ users_number(LServer) -> fun(pgsql, _) -> case ejabberd_config:get_option( - {pgsql_users_number_estimate, LServer}, - fun(V) when is_boolean(V) -> V end, - false) of + {pgsql_users_number_estimate, LServer}, false) of true -> ejabberd_sql:sql_query_t( ?SQL("select @(reltuples :: bigint)d from pg_class" @@ -634,13 +632,6 @@ set_roster_version(LUser, Version) -> ["!username=%(LUser)s", "version=%(Version)s"]). -opt_type(sql_type) -> - fun (pgsql) -> pgsql; - (mysql) -> mysql; - (sqlite) -> sqlite; - (mssql) -> mssql; - (odbc) -> odbc - end; opt_type(pgsql_users_number_estimate) -> fun (V) when is_boolean(V) -> V end; -opt_type(_) -> [sql_type, pgsql_users_number_estimate]. +opt_type(_) -> [pgsql_users_number_estimate]. |