1: -module(config_parser_SUITE). 2: -compile([export_all, nowarn_export_all]). 3: 4: -include_lib("eunit/include/eunit.hrl"). 5: 6: -define(HOST, <<"example.com">>). 7: 8: -define(eq(Expected, Actual), ?assertEqual(Expected, Actual)). 9: 10: %% Assertions 11: 12: %% global config options 13: -define(cfg(Key, Value, RawConfig), ?cfg([{Key, Value}], RawConfig)). 14: -define(cfg(ExpectedOpts, RawConfig), assert_options(ExpectedOpts, parse(RawConfig))). 15: 16: %% global config error 17: -define(err(RawConfig), ?err(_, RawConfig)). 18: -define(err(Pattern, RawConfig), ?assertError({config_error, _, Pattern}, parse(RawConfig))). 19: 20: %% host-or-global config options 21: -define(cfgh(KeyPrefix, Value, RawConfig), ?cfgh([{KeyPrefix, Value}], RawConfig)). 22: -define(cfgh(ExpectedOpts, RawConfig), 23: begin 24: ?cfg(host_opts(ExpectedOpts), RawConfig), 25: ?cfg(host_opts(ExpectedOpts), host_config(RawConfig)) 26: end). 27: 28: %% host-or-global config error 29: -define(errh(RawConfig), ?errh(_, RawConfig)). 30: -define(errh(Pattern, RawConfig), 31: begin 32: ?err(Pattern, RawConfig), 33: ?err(Pattern, host_config(RawConfig)) 34: end). 35: 36: -import(mongoose_config_parser_toml, [extract_errors/1]). 37: 38: -type key_prefix() :: top_level_key_prefix() | key_path_prefix(). 39: -type top_level_key_prefix() :: atom(). 40: -type key_path_prefix() :: [atom() | binary()]. 41: 42: all() -> 43: [{group, file}, 44: {group, dynamic_domains}, 45: {group, general}, 46: {group, listen}, 47: {group, auth}, 48: {group, pool}, 49: {group, shaper_acl_access}, 50: {group, s2s}, 51: {group, modules}, 52: {group, services}]. 53: 54: groups() -> 55: [{file, [parallel], [sample_pgsql, 56: miscellaneous, 57: s2s, 58: modules, 59: outgoing_pools, 60: host_types_file]}, 61: {dynamic_domains, [parallel], [supported_features, 62: unsupported_features]}, 63: {general, [parallel], [loglevel, 64: hosts, 65: host_types, 66: default_server_domain, 67: registration_timeout, 68: language, 69: all_metrics_are_global, 70: sm_backend, 71: max_fsm_queue, 72: http_server_name, 73: rdbms_server_type, 74: route_subdomains, 75: mongooseimctl_access_commands, 76: routing_modules, 77: replaced_wait_timeout, 78: hide_service_name, 79: domain_certfile]}, 80: {listen, [parallel], [listen_portip, 81: listen_proto, 82: listen_duplicate, 83: listen_ip_version, 84: listen_backlog, 85: listen_proxy_protocol, 86: listen_num_acceptors, 87: listen_access, 88: listen_shaper, 89: listen_xml_socket, 90: listen_zlib, 91: listen_hibernate_after, 92: listen_max_fsm_queue, 93: listen_max_stanza_size, 94: listen_tls_mode, 95: listen_tls_module, 96: listen_tls_verify, 97: listen_tls_verify_mode, 98: listen_tls_crl_files, 99: listen_tls_certfile, 100: listen_tls_cacertfile, 101: listen_tls_dhfile, 102: listen_tls_ciphers, 103: listen_tls_versions, 104: listen_tls_protocol_options, 105: listen_check_from, 106: listen_hidden_components, 107: listen_conflict_behaviour, 108: listen_password, 109: listen_http_num_acceptors, 110: listen_http_max_connections, 111: listen_http_compress, 112: listen_http_handlers, 113: listen_http_handlers_websockets, 114: listen_http_handlers_lasse, 115: listen_http_handlers_static, 116: listen_http_handlers_api, 117: listen_http_handlers_domain]}, 118: {auth, [parallel], [auth_methods, 119: auth_password, 120: auth_sasl_external, 121: auth_allow_multiple_connections, 122: auth_anonymous_protocol, 123: auth_sasl_mechanisms, 124: auth_ldap_pool, 125: auth_ldap_bind_pool, 126: auth_ldap_base, 127: auth_ldap_uids, 128: auth_ldap_filter, 129: auth_ldap_dn_filter, 130: auth_ldap_local_filter, 131: auth_ldap_deref, 132: auth_external, 133: auth_http_basic_auth, 134: auth_jwt, 135: auth_riak_bucket_type, 136: auth_rdbms_users_number_estimate, 137: auth_dummy]}, 138: {pool, [parallel], [pool_type, 139: pool_tag, 140: pool_scope, 141: pool_workers, 142: pool_strategy, 143: pool_call_timeout, 144: pool_rdbms_settings, 145: pool_rdbms_keepalive_interval, 146: pool_rdbms_server, 147: pool_rdbms_port, 148: pool_rdbms_tls, 149: pool_http_host, 150: pool_http_path_prefix, 151: pool_http_request_timeout, 152: pool_http_tls, 153: pool_redis_host, 154: pool_redis_port, 155: pool_redis_database, 156: pool_redis_password, 157: pool_riak_address, 158: pool_riak_port, 159: pool_riak_credentials, 160: pool_riak_cacertfile, 161: pool_riak_tls, 162: pool_cassandra_servers, 163: pool_cassandra_keyspace, 164: pool_cassandra_auth, 165: pool_cassandra_tls, 166: pool_ldap_host, 167: pool_ldap_port, 168: pool_ldap_servers, 169: pool_ldap_encrypt, 170: pool_ldap_rootdn, 171: pool_ldap_password, 172: pool_ldap_connect_interval, 173: pool_ldap_tls]}, 174: {shaper_acl_access, [parallel], [shaper, 175: acl, 176: acl_merge_host_and_global, 177: access, 178: access_merge_host_and_global]}, 179: {s2s, [parallel], [s2s_dns_timeout, 180: s2s_dns_retries, 181: s2s_outgoing_port, 182: s2s_outgoing_ip_versions, 183: s2s_outgoing_timeout, 184: s2s_use_starttls, 185: s2s_certfile, 186: s2s_default_policy, 187: s2s_host_policy, 188: s2s_address, 189: s2s_ciphers, 190: s2s_shared, 191: s2s_max_retry_delay]}, 192: {modules, [parallel], [mod_adhoc, 193: mod_auth_token, 194: mod_bosh, 195: mod_caps, 196: mod_cache_users, 197: mod_carboncopy, 198: mod_csi, 199: mod_disco, 200: mod_inbox, 201: mod_global_distrib, 202: mod_global_distrib_connections, 203: mod_global_distrib_connections_endpoints, 204: mod_global_distrib_connections_advertised_endpoints, 205: mod_global_distrib_connections_tls, 206: mod_global_distrib_redis, 207: mod_global_distrib_cache, 208: mod_global_distrib_bounce, 209: mod_event_pusher_sns, 210: mod_event_pusher_push, 211: mod_event_pusher_http, 212: mod_event_pusher_rabbit, 213: mod_extdisco, 214: mod_http_upload, 215: mod_http_upload_s3, 216: mod_jingle_sip, 217: mod_keystore, 218: mod_keystore_keys, 219: mod_last, 220: mod_mam_meta, 221: mod_mam_meta_pm, 222: mod_mam_meta_muc, 223: mod_muc, 224: mod_muc_default_room, 225: mod_muc_default_room_affiliations, 226: mod_muc_log, 227: mod_muc_log_top_link, 228: mod_muc_light, 229: mod_muc_light_config_schema, 230: mod_offline, 231: mod_ping, 232: mod_privacy, 233: mod_private, 234: mod_pubsub, 235: mod_pubsub_pep_mapping, 236: mod_pubsub_default_node_config, 237: mod_push_service_mongoosepush, 238: mod_register, 239: mod_roster, 240: mod_shared_roster_ldap, 241: mod_sic, 242: mod_stream_management, 243: mod_stream_management_stale_h, 244: mod_time, 245: mod_vcard, 246: mod_vcard_ldap_uids, 247: mod_vcard_ldap_vcard_map, 248: mod_vcard_ldap_search_fields, 249: mod_vcard_ldap_search_reported, 250: mod_version, 251: modules_without_config, 252: incorrect_module]}, 253: {services, [parallel], [service_admin_extra, 254: service_mongoose_system_metrics]} 255: ]. 256: 257: init_per_suite(Config) -> 258: {ok, _} = application:ensure_all_started(jid), 259: create_files(Config), 260: Config. 261: 262: end_per_suite(_Config) -> 263: ok. 264: 265: init_per_group(dynamic_domains, Config) -> 266: meck:new(ejabberd_auth_http, [passthrough, no_link]), 267: meck:new(mod_test, [non_strict, no_link]), 268: meck:expect(ejabberd_auth_http, supported_features, fun() -> [] end), 269: meck:expect(mod_test, supported_features, fun() -> [] end), 270: Config; 271: init_per_group(_, Config) -> 272: Config. 273: 274: end_per_group(dynamic_domains, _Config) -> 275: meck:unload(); 276: end_per_group(_, _Config) -> 277: ok. 278: 279: init_per_testcase(_, Config) -> 280: Config. 281: 282: end_per_testcase(_, _Config) -> 283: ok. 284: 285: sample_pgsql(Config) -> 286: test_config_file(Config, "mongooseim-pgsql"). 287: 288: miscellaneous(Config) -> 289: test_config_file(Config, "miscellaneous"). 290: 291: s2s(Config) -> 292: test_config_file(Config, "s2s_only"). 293: 294: modules(Config) -> 295: test_config_file(Config, "modules"). 296: 297: outgoing_pools(Config) -> 298: test_config_file(Config, "outgoing_pools"). 299: 300: host_types_file(Config) -> 301: test_config_file(Config, "host_types"). 302: 303: supported_features(_Config) -> 304: Gen = #{<<"general">> => #{<<"host_types">> => [<<"type1">>, <<"type2">>]}}, 305: Auth = #{<<"auth">> => #{<<"internal">> => #{}}}, 306: Mod = #{<<"modules">> => #{<<"mod_amp">> => #{}}}, 307: ?cfg([{auth, <<"type1">>}, methods], [internal], maps:merge(Gen, Auth)), 308: ?cfg([{auth, <<"type1">>}, methods], [internal], 309: Gen#{<<"host_config">> => [Auth#{<<"host_type">> => <<"type1">>}]}), 310: ?cfg([{modules, <<"type1">>}, mod_amp], [], maps:merge(Gen, Mod)), 311: ?cfg([{modules, <<"type1">>}, mod_amp], [], 312: Gen#{<<"host_config">> => [Mod#{<<"host_type">> => <<"type1">>}]}). 313: 314: unsupported_features(_Config) -> 315: % ejabberd_auth_http and mod_test are mocked and they don't support dynamic domains 316: Gen = #{<<"general">> => #{<<"host_types">> => [<<"type1">>, <<"type2">>]}}, 317: Auth = #{<<"auth">> => #{<<"http">> => #{}}}, 318: Mod = #{<<"modules">> => #{<<"mod_test">> => #{}}}, 319: ?err([#{reason := dynamic_domains_not_supported, 320: unsupported_auth_methods := [http], 321: unsupported_modules := []}], 322: maps:merge(Gen, Auth)), 323: ?err([#{reason := dynamic_domains_not_supported, 324: unsupported_auth_methods := [http], 325: unsupported_modules := []}], 326: Gen#{<<"host_config">> => [Auth#{<<"host_type">> => <<"type1">>}]}), 327: ?err([#{reason := dynamic_domains_not_supported, 328: unsupported_auth_methods := [], 329: unsupported_modules := [mod_test]}], 330: maps:merge(Gen, Mod)), 331: ?err([#{reason := dynamic_domains_not_supported, 332: unsupported_auth_methods := [], 333: unsupported_modules := [mod_test]}], 334: Gen#{<<"host_config">> => [Mod#{<<"host_type">> => <<"type1">>}]}). 335: 336: %% tests: general 337: loglevel(_Config) -> 338: ?cfg(loglevel, warning, #{}), % default 339: ?cfg(loglevel, debug, #{<<"general">> => #{<<"loglevel">> => <<"debug">>}}), 340: ?err(#{<<"general">> => #{<<"loglevel">> => <<"bebug">>}}), 341: %% make sure non-host options are not accepted in host_config 342: ?err(host_config(#{<<"general">> => #{<<"loglevel">> => <<"debug">>}})). 343: 344: hosts(_Config) -> 345: ?cfg(hosts, [], % default 346: #{<<"general">> => #{<<"host_types">> => [<<"type1">>]}, without => [<<"hosts">>]}), 347: ?cfg(hosts, [<<"host1">>], 348: #{<<"general">> => #{<<"hosts">> => [<<"host1">>]}}), 349: ?cfg(hosts, [<<"host1">>, <<"host2">>], 350: #{<<"general">> => #{<<"hosts">> => [<<"host1">>, <<"host2">>]}}), 351: ?err(#{<<"general">> => #{<<"hosts">> => [<<"what is this?">>]}}), 352: ?err(#{<<"general">> => #{<<"hosts">> => [<<>>]}}), 353: ?err(#{<<"general">> => #{<<"hosts">> => [<<"host1">>, <<"host1">>]}}), 354: %% at least one host or host_type must be provided 355: ?err(#{<<"general">> => #{}, without => [<<"hosts">>]}), 356: ?err(#{<<"general">> => #{<<"hosts">> => []}}), 357: ?err(#{<<"general">> => #{<<"host_types">> => []}, without => [<<"hosts">>]}), 358: ?err(#{<<"general">> => #{<<"hosts">> => [], <<"host_types">> => []}}). 359: 360: host_types(_Config) -> 361: ?cfg(host_types, [], #{}), % default 362: ?cfg([{host_types, [<<"type 1">>]}, 363: {hosts, []}], 364: #{<<"general">> => #{<<"host_types">> => [<<"type 1">>]}, without => [<<"hosts">>]}), 365: ?cfg([{host_types, [<<"type 1">>, <<"type 2">>]}, 366: {hosts, []}], 367: #{<<"general">> => #{<<"host_types">> => [<<"type 1">>, <<"type 2">>], 368: <<"hosts">> => []}}), 369: ?err(#{<<"general">> => #{<<"host_types">> => [<<>>]}}), 370: ?err(#{<<"general">> => #{<<"host_types">> => [<<"type1">>, <<"type1">>]}}), 371: %% either hosts and host_types cannot have the same values 372: ?err(#{<<"general">> => #{<<"host_types">> => [<<"type1">>], 373: <<"hosts">> => [<<"type1">>]}}). 374: 375: default_server_domain(_Config) -> 376: ?cfg(default_server_domain, <<"host1">>, 377: #{<<"general">> => #{<<"default_server_domain">> => <<"host1">>}}), 378: ?err(#{<<"general">> => #{<<"default_server_domain">> => <<"what is this?">>}}), 379: ?err(#{<<"general">> => #{<<"default_server_domain">> => <<>>}}), 380: %% default_server_domain must be provided 381: ?err(#{without => [<<"default_server_domain">>]}). 382: 383: registration_timeout(_Config) -> 384: ?cfg(registration_timeout, 600, #{}), % default 385: ?cfg(registration_timeout, infinity, 386: #{<<"general">> => #{<<"registration_timeout">> => <<"infinity">>}}), 387: ?cfg(registration_timeout, 300, 388: #{<<"general">> => #{<<"registration_timeout">> => 300}}), 389: ?err(#{<<"general">> => #{<<"registration_timeout">> => 0}}). 390: 391: language(_Config) -> 392: ?cfg(language, <<"en">>, #{}), % default 393: ?cfg(language, <<"pl">>, #{<<"general">> => #{<<"language">> => <<"pl">>}}), 394: ?err(#{<<"general">> => #{<<"language">> => <<>>}}). 395: 396: all_metrics_are_global(_Config) -> 397: ?cfg(all_metrics_are_global, false, #{}), % default 398: ?cfg(all_metrics_are_global, true, #{<<"general">> => #{<<"all_metrics_are_global">> => true}}), 399: ?err(#{<<"general">> => #{<<"all_metrics_are_global">> => <<"true">>}}). 400: 401: sm_backend(_Config) -> 402: ?cfg(sm_backend, {mnesia, []}, #{}), % default 403: ?cfg(sm_backend, {mnesia, []}, #{<<"general">> => #{<<"sm_backend">> => <<"mnesia">>}}), 404: ?cfg(sm_backend, {redis, []}, #{<<"general">> => #{<<"sm_backend">> => <<"redis">>}}), 405: ?err(#{<<"general">> => #{<<"sm_backend">> => <<"amnesia">>}}). 406: 407: max_fsm_queue(_Config) -> 408: ?cfg(max_fsm_queue, 100, #{<<"general">> => #{<<"max_fsm_queue">> => 100}}), 409: ?err(#{<<"general">> => #{<<"max_fsm_queue">> => -10}}). 410: 411: http_server_name(_Config) -> 412: ?cfg(cowboy_server_name, "my server", 413: #{<<"general">> => #{<<"http_server_name">> => <<"my server">>}}), 414: ?err(#{<<"general">> => #{<<"http_server_name">> => #{}}}). 415: 416: rdbms_server_type(_Config) -> 417: ?cfg(rdbms_server_type, generic, #{}), % default 418: ?cfg(rdbms_server_type, mssql, #{<<"general">> => #{<<"rdbms_server_type">> => <<"mssql">>}}), 419: ?cfg(rdbms_server_type, pgsql, #{<<"general">> => #{<<"rdbms_server_type">> => <<"pgsql">>}}), 420: ?err(#{<<"general">> => #{<<"rdbms_server_type">> => <<"nosql">>}}). 421: 422: route_subdomains(_Config) -> 423: ?cfgh(route_subdomains, s2s, #{<<"general">> => #{<<"route_subdomains">> => <<"s2s">>}}), 424: ?errh(#{<<"general">> => #{<<"route_subdomains">> => <<"c2s">>}}). 425: 426: mongooseimctl_access_commands(_Config) -> 427: ?cfg(mongooseimctl_access_commands, [], #{}), % default 428: AccessRule = #{<<"commands">> => [<<"join_cluster">>], 429: <<"argument_restrictions">> => #{<<"node">> => <<"mim1@host1">>}}, 430: ?cfg(mongooseimctl_access_commands, [{local, ["join_cluster"], [{node, "mim1@host1"}]}], 431: #{<<"general">> => #{<<"mongooseimctl_access_commands">> => 432: #{<<"local">> => AccessRule}}}), 433: ?cfg(mongooseimctl_access_commands, [{local, all, [{node, "mim1@host1"}]}], 434: #{<<"general">> => #{<<"mongooseimctl_access_commands">> => 435: #{<<"local">> => maps:remove(<<"commands">>, AccessRule)}}}), 436: ?cfg(mongooseimctl_access_commands, [{local, ["join_cluster"], []}], 437: #{<<"general">> => #{<<"mongooseimctl_access_commands">> => 438: #{<<"local">> => maps:remove(<<"argument_restrictions">>, 439: AccessRule)}}}), 440: ?cfg(mongooseimctl_access_commands, [{local, all, []}], 441: #{<<"general">> => #{<<"mongooseimctl_access_commands">> => #{<<"local">> => #{}}}}), 442: ?err(#{<<"general">> => #{<<"mongooseimctl_access_commands">> => 443: #{<<"local">> => #{<<"commands">> => <<"all">>}}}}), 444: ?err(#{<<"general">> => #{<<"mongooseimctl_access_commands">> => 445: #{<<"local">> => #{<<"argument_restrictions">> => 446: [<<"none">>]}}}}). 447: 448: routing_modules(_Config) -> 449: ?cfg(routing_modules, mongoose_router:default_routing_modules(), #{}), % default 450: ?cfg(routing_modules, [mongoose_router_global, mongoose_router_localdomain], 451: #{<<"general">> => #{<<"routing_modules">> => [<<"mongoose_router_global">>, 452: <<"mongoose_router_localdomain">>]}}), 453: ?err(#{<<"general">> => #{<<"routing_modules">> => [<<"moongoose_router_global">>]}}). 454: 455: replaced_wait_timeout(_Config) -> 456: ?cfg({replaced_wait_timeout, ?HOST}, 2000, #{}), % global default 457: ?cfgh(replaced_wait_timeout, 1000, #{<<"general">> => #{<<"replaced_wait_timeout">> => 1000}}), 458: ?errh(#{<<"general">> => #{<<"replaced_wait_timeout">> => 0}}). 459: 460: hide_service_name(_Config) -> 461: ?cfg(hide_service_name, false, #{}), % default 462: ?cfg(hide_service_name, true, #{<<"general">> => #{<<"hide_service_name">> => true}}), 463: ?err(#{<<"general">> => #{<<"hide_service_name">> => []}}). 464: 465: domain_certfile(_Config) -> 466: DomCert = #{<<"domain">> => <<"myxmpp.com">>, 467: <<"certfile">> => <<"priv/cert.pem">>}, 468: ?cfg(domain_certfile, #{<<"myxmpp.com">> => "priv/cert.pem"}, 469: #{<<"general">> => #{<<"domain_certfile">> => [DomCert]}}), 470: ?err([#{reason := invalid_filename}], 471: #{<<"general">> => #{<<"domain_certfile">> => 472: [DomCert#{<<"certfile">> => <<"missing.pem">>}]}}), 473: [?err(#{<<"general">> => #{<<"domain_certfile">> => [maps:without([K], DomCert)]}}) 474: || K <- maps:keys(DomCert)], 475: [?err(#{<<"general">> => #{<<"domain_certfile">> => [DomCert#{K := <<>>}]}}) 476: || K <- maps:keys(DomCert)], 477: ?err(#{<<"general">> => #{<<"domain_certfile">> => [DomCert, DomCert]}}). 478: 479: %% tests: listen 480: 481: listen_portip(_Config) -> 482: ?cfg(listen, [], #{}), 483: ?cfg(listener_config(ejabberd_c2s, #{}), listen_raw(<<"c2s">>, #{})), 484: ?cfg(listener_config(ejabberd_c2s, #{ip_address => "192.168.1.16", 485: ip_tuple => {192, 168, 1, 16}}), 486: listen_raw(<<"c2s">>, #{<<"ip_address">> => <<"192.168.1.16">>})), 487: ?cfg(listener_config(ejabberd_c2s, #{ip_address => "2001:db8:3:4:5:6:7:8", 488: ip_tuple => {8193, 3512, 3, 4, 5, 6, 7, 8}, 489: ip_version => 6}), 490: listen_raw(<<"c2s">>, #{<<"ip_address">> => <<"2001:db8:3:4:5:6:7:8">>})), 491: ?err(listen_raw(<<"c2s">>, #{<<"ip_address">> => <<"192.168.1.999">>})), 492: ?err(#{<<"listen">> => #{<<"c2s">> => [#{<<"ip_address">> => <<"192.168.1.16">>}]}}), 493: ?err(#{<<"listen">> => #{<<"c2s">> => [#{<<"port">> => <<"5222">>}]}}), 494: ?err(#{<<"listen">> => #{<<"c2s">> => [#{<<"port">> => 522222}]}}). 495: 496: listen_proto(_Config) -> 497: ?cfg(listener_config(ejabberd_c2s, #{}), 498: listen_raw(<<"c2s">>, #{<<"proto">> => <<"tcp">>})), 499: ?cfg(listener_config(ejabberd_c2s, #{proto => udp}), 500: listen_raw(<<"c2s">>, #{<<"proto">> => <<"udp">>})), 501: ?err(listen_raw(<<"c2s">>, #{<<"proto">> => <<"pigeon">>})). 502: 503: listen_duplicate(_Config) -> 504: ?cfg(listen, [listener(ejabberd_c2s, #{}), 505: listener(ejabberd_c2s, #{port => 5223})], 506: #{<<"listen">> => #{<<"c2s">> => [#{<<"port">> => 5222, 507: <<"ip_address">> => <<"0">>}, 508: #{<<"port">> => 5223}]}}), 509: ?err([#{reason := duplicate_listeners, 510: duplicates := [{5222, {0, 0, 0, 0}, tcp}]}], 511: #{<<"listen">> => #{<<"c2s">> => [#{<<"port">> => 5222, 512: <<"ip_address">> => <<"0">>}, 513: #{<<"port">> => 5222}]}}). 514: 515: listen_ip_version(_Config) -> 516: ?cfg(listener_config(ejabberd_c2s, #{}), 517: listen_raw(<<"c2s">>, #{<<"ip_version">> => 4})), 518: ?cfg(listener_config(ejabberd_c2s, #{ip_address => "::", 519: ip_tuple => {0, 0, 0, 0, 0, 0, 0, 0}, 520: ip_version => 6}), 521: listen_raw(<<"c2s">>, #{<<"ip_version">> => 6})), 522: ?err(listen_raw(<<"c2s">>, #{<<"ip_version">> => 7})). 523: 524: listen_backlog(_Config) -> 525: ?cfg(listener_config(ejabberd_c2s, #{backlog => 10}), 526: listen_raw(<<"c2s">>, #{<<"backlog">> => 10})), 527: ?err(listen_raw(<<"c2s">>, #{<<"backlog">> => -10})). 528: 529: listen_proxy_protocol(_Config) -> 530: ?cfg(listener_config(ejabberd_c2s, #{proxy_protocol => true}), 531: listen_raw(<<"c2s">>, #{<<"proxy_protocol">> => true})), 532: ?cfg(listener_config(ejabberd_s2s_in, #{proxy_protocol => true}), 533: listen_raw(<<"s2s">>, #{<<"proxy_protocol">> => true})), 534: ?cfg(listener_config(ejabberd_service, #{proxy_protocol => true}), 535: listen_raw(<<"service">>, #{<<"proxy_protocol">> => true})), 536: ?err(listen_raw(<<"c2s">>, #{<<"proxy_protocol">> => <<"awesome">>})). 537: 538: listen_num_acceptors(_Config) -> 539: ?cfg(listener_config(ejabberd_c2s, #{acceptors_num => 100}), 540: listen_raw(<<"c2s">>, #{<<"num_acceptors">> => 100})), 541: ?cfg(listener_config(ejabberd_s2s_in, #{acceptors_num => 100}), 542: listen_raw(<<"s2s">>, #{<<"num_acceptors">> => 100})), 543: ?cfg(listener_config(ejabberd_service, #{acceptors_num => 100}), 544: listen_raw(<<"service">>, #{<<"num_acceptors">> => 100})), 545: ?err(listen_raw(<<"c2s">>, #{<<"num_acceptors">> => 0})). 546: 547: listen_access(_Config) -> 548: ?cfg(listener_config(ejabberd_c2s, #{access => rule1}), 549: listen_raw(<<"c2s">>, #{<<"access">> => <<"rule1">>})), 550: ?cfg(listener_config(ejabberd_service, #{access => rule1}), 551: listen_raw(<<"service">>, #{<<"access">> => <<"rule1">>})), 552: ?err(listen_raw(<<"c2s">>, #{<<"access">> => <<>>})). 553: 554: listen_shaper(_Config) -> 555: ?cfg(listener_config(ejabberd_c2s, #{shaper => c2s_shaper}), 556: listen_raw(<<"c2s">>, #{<<"shaper">> => <<"c2s_shaper">>})), 557: ?cfg(listener_config(ejabberd_s2s_in, #{shaper => s2s_shaper}), 558: listen_raw(<<"s2s">>, #{<<"shaper">> => <<"s2s_shaper">>})), 559: ?cfg(listener_config(ejabberd_service, #{shaper_rule => fast}), 560: listen_raw(<<"service">>, #{<<"shaper_rule">> => <<"fast">>})), 561: ?err(listen_raw(<<"s2s">>, #{<<"shaper">> => <<>>})). 562: 563: listen_xml_socket(_Config) -> 564: ?cfg(listener_config(ejabberd_c2s, #{xml_socket => true}), 565: listen_raw(<<"c2s">>, #{<<"xml_socket">> => true})), 566: ?err(listen_raw(<<"c2s">>, #{<<"xml_socket">> => 10})). 567: 568: listen_zlib(_Config) -> 569: ?cfg(listener_config(ejabberd_c2s, #{zlib => 1024}), 570: listen_raw(<<"c2s">>, #{<<"zlib">> => 1024})), 571: ?err(listen_raw(<<"c2s">>, #{<<"zlib">> => 0})). 572: 573: listen_hibernate_after(_Config) -> 574: ?cfg(listener_config(ejabberd_c2s, #{hibernate_after => 10}), 575: listen_raw(<<"c2s">>, #{<<"hibernate_after">> => 10})), 576: ?cfg(listener_config(ejabberd_s2s_in, #{hibernate_after => 10}), 577: listen_raw(<<"s2s">>, #{<<"hibernate_after">> => 10})), 578: ?cfg(listener_config(ejabberd_service, #{hibernate_after => 10}), 579: listen_raw(<<"service">>, #{<<"hibernate_after">> => 10})), 580: ?err(listen_raw(<<"c2s">>, #{<<"hibernate_after">> => -10})). 581: 582: listen_max_stanza_size(_Config) -> 583: ?cfg(listener_config(ejabberd_c2s, #{max_stanza_size => 10000}), 584: listen_raw(<<"c2s">>, #{<<"max_stanza_size">> => 10000})), 585: ?cfg(listener_config(ejabberd_s2s_in, #{max_stanza_size => 10000}), 586: listen_raw(<<"s2s">>, #{<<"max_stanza_size">> => 10000})), 587: ?cfg(listener_config(ejabberd_service, #{max_stanza_size => 10000}), 588: listen_raw(<<"service">>, #{<<"max_stanza_size">> => 10000})), 589: ?err(listen_raw(<<"c2s">>, #{<<"max_stanza_size">> => <<"infinity">>})). 590: 591: listen_max_fsm_queue(_Config) -> 592: ?cfg(listener_config(ejabberd_c2s, #{max_fsm_queue => 1000}), 593: listen_raw(<<"c2s">>, #{<<"max_fsm_queue">> => 1000})), 594: ?cfg(listener_config(ejabberd_service, #{max_fsm_queue => 1000}), 595: listen_raw(<<"service">>, #{<<"max_fsm_queue">> => 1000})), 596: ?err(listen_raw(<<"s2s">>, #{<<"max_fsm_queue">> => 1000})), % only for c2s and service 597: ?err(listen_raw(<<"c2s">>, #{<<"max_fsm_queue">> => 0})). 598: 599: listen_tls_mode(_Config) -> 600: ?cfg(listener_config(ejabberd_c2s, #{tls => [starttls]}), 601: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"mode">> => <<"starttls">>}})), 602: ?err(listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"mode">> => <<"stoptls">>}})). 603: 604: listen_tls_module(_Config) -> 605: ?cfg(listener_config(ejabberd_c2s, #{tls => [{tls_module, just_tls}]}), 606: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"module">> => <<"just_tls">>}})), 607: ?cfg(listener_config(ejabberd_c2s, #{tls => []}), 608: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"module">> => <<"fast_tls">>}})), 609: ?err(listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"module">> => <<"slow_tls">>}})). 610: 611: listen_tls_verify(_Config) -> 612: ?cfg(listener_config(ejabberd_c2s, #{tls => [verify_peer]}), 613: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"verify_peer">> => true}})), 614: ?cfg(listener_config(ejabberd_c2s, #{tls => [verify_none]}), 615: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"verify_peer">> => false}})), 616: ?cfg(listener_config(ejabberd_c2s, #{tls => [{tls_module, just_tls}, verify_peer]}), 617: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"module">> => <<"just_tls">>, 618: <<"verify_peer">> => true}})), 619: ?cfg(listener_config(ejabberd_cowboy, #{ssl => [{verify, verify_peer}]}), 620: listen_raw(<<"http">>, #{<<"tls">> => #{<<"verify_peer">> => true}})), 621: ?cfg(listener_config(ejabberd_c2s, #{tls => [{tls_module, just_tls}, verify_none]}), 622: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"module">> => <<"just_tls">>, 623: <<"verify_peer">> => false}})), 624: ?err(listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"verify_peer">> => <<"maybe">>}})). 625: 626: listen_tls_verify_mode(_Config) -> 627: ?cfg(listener_config(ejabberd_c2s, #{tls => [{tls_module, just_tls}, 628: {ssl_options, [{verify_fun, {peer, true}}]}]}), 629: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"module">> => <<"just_tls">>, 630: <<"verify_mode">> => <<"peer">>}})), 631: ?cfg(listener_config(ejabberd_c2s, #{tls => [{tls_module, just_tls}, 632: {ssl_options, [{verify_fun, 633: {selfsigned_peer, false}}]}]}), 634: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"module">> => <<"just_tls">>, 635: <<"verify_mode">> => <<"selfsigned_peer">>, 636: <<"disconnect_on_failure">> => false}})), 637: ?cfg(listener_config(ejabberd_cowboy, #{ssl => [{verify_mode, peer}]}), 638: listen_raw(<<"http">>, #{<<"tls">> => #{<<"verify_mode">> => <<"peer">>}})), 639: ?err(listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"module">> => <<"just_tls">>, 640: <<"verify_mode">> => <<"peer">>, 641: <<"disconnect_on_failure">> => <<"false">>}})), 642: ?err(listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"module">> => <<"just_tls">>, 643: <<"verify_mode">> => <<"whatever">>}})), 644: ?err(listen_raw(<<"http">>, #{<<"tls">> => #{<<"verify_mode">> => <<"whatever">>}})). 645: 646: listen_tls_crl_files(_Config) -> 647: ?cfg(listener_config(ejabberd_c2s, #{tls => [{tls_module, just_tls}, 648: {crlfiles, ["file1", "file2"]}]}), 649: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"module">> => <<"just_tls">>, 650: <<"crl_files">> => [<<"file1">>, 651: <<"file2">>]}})), 652: ?err(listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"module">> => <<"just_tls">>, 653: <<"crl_files">> => [<<>>]}})), 654: %% only for just_tls 655: ?err(listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"crl_files">> => [<<"file1">>, 656: <<"file2">>]}})). 657: 658: listen_tls_certfile(_Config) -> 659: ?cfg(listener_config(ejabberd_c2s, #{tls => [{certfile, "priv/cert.pem"}]}), 660: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"certfile">> => <<"priv/cert.pem">>}})), 661: ?cfg(listener_config(ejabberd_c2s, #{tls => [{tls_module, just_tls}, 662: {ssl_options, [{certfile, "priv/cert.pem"}]}]}), 663: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"module">> => <<"just_tls">>, 664: <<"certfile">> => <<"priv/cert.pem">>}})), 665: ?cfg(listener_config(ejabberd_cowboy, #{ssl => [{certfile, "priv/cert.pem"}]}), 666: listen_raw(<<"http">>, #{<<"tls">> => #{<<"certfile">> => <<"priv/cert.pem">>}})), 667: ?err(listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"certfile">> => <<"no_such_file.pem">>}})). 668: 669: listen_tls_cacertfile(_Config) -> 670: ?cfg(listener_config(ejabberd_c2s, #{tls => [{cafile, "priv/ca.pem"}]}), 671: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"cacertfile">> => <<"priv/ca.pem">>}})), 672: ?cfg(listener_config(ejabberd_s2s_in, #{tls => [{cafile, "priv/ca.pem"}]}), 673: listen_raw(<<"s2s">>, #{<<"tls">> => #{<<"cacertfile">> => <<"priv/ca.pem">>}})), 674: ?cfg(listener_config(ejabberd_c2s, #{tls => [{tls_module, just_tls}, 675: {ssl_options, [{cacertfile, "priv/ca.pem"}]}]}), 676: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"module">> => <<"just_tls">>, 677: <<"cacertfile">> => <<"priv/ca.pem">>}})), 678: ?cfg(listener_config(ejabberd_cowboy, #{ssl => [{cacertfile, "priv/ca.pem"}]}), 679: listen_raw(<<"http">>, #{<<"tls">> => #{<<"cacertfile">> => <<"priv/ca.pem">>}})), 680: ?err(listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"cacertfile">> => <<"no_such_file.pem">>}})). 681: 682: listen_tls_dhfile(_Config) -> 683: ?cfg(listener_config(ejabberd_c2s, #{tls => [{dhfile, "priv/dh.pem"}]}), 684: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"dhfile">> => <<"priv/dh.pem">>}})), 685: ?cfg(listener_config(ejabberd_s2s_in, #{tls => [{dhfile, "priv/dh.pem"}]}), 686: listen_raw(<<"s2s">>, #{<<"tls">> => #{<<"dhfile">> => <<"priv/dh.pem">>}})), 687: ?cfg(listener_config(ejabberd_c2s, #{tls => [{tls_module, just_tls}, 688: {ssl_options, [{dhfile, "priv/dh.pem"}]}]}), 689: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"module">> => <<"just_tls">>, 690: <<"dhfile">> => <<"priv/dh.pem">>}})), 691: ?cfg(listener_config(ejabberd_cowboy, #{ssl => [{dhfile, "priv/dh.pem"}]}), 692: listen_raw(<<"http">>, #{<<"tls">> => #{<<"dhfile">> => <<"priv/dh.pem">>}})), 693: ?err(listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"dhfile">> => <<"no_such_file.pem">>}})). 694: 695: listen_tls_ciphers(_Config) -> 696: ?cfg(listener_config(ejabberd_c2s, #{tls => [{ciphers, "TLS_AES_256_GCM_SHA384"}]}), 697: listen_raw(<<"c2s">>, 698: #{<<"tls">> => #{<<"ciphers">> => <<"TLS_AES_256_GCM_SHA384">>}})), 699: ?cfg(listener_config(ejabberd_c2s, #{tls => [{tls_module, just_tls}, 700: {ssl_options, 701: [{ciphers, "TLS_AES_256_GCM_SHA384"}]}]}), 702: listen_raw(<<"c2s">>, 703: #{<<"tls">> => #{<<"module">> => <<"just_tls">>, 704: <<"ciphers">> => <<"TLS_AES_256_GCM_SHA384">>}})), 705: ?cfg(listener_config(ejabberd_s2s_in, #{tls => [{ciphers, "TLS_AES_256_GCM_SHA384"}]}), 706: listen_raw(<<"s2s">>, 707: #{<<"tls">> => #{<<"ciphers">> => <<"TLS_AES_256_GCM_SHA384">>}})), 708: ?cfg(listener_config(ejabberd_cowboy, #{ssl => [{ciphers, "TLS_AES_256_GCM_SHA384"}]}), 709: listen_raw(<<"http">>, 710: #{<<"tls">> => #{<<"ciphers">> => <<"TLS_AES_256_GCM_SHA384">>}})), 711: ?err(listen_raw(<<"c2s">>, 712: #{<<"tls">> => #{<<"ciphers">> => [<<"TLS_AES_256_GCM_SHA384">>]}})). 713: 714: listen_tls_versions(_Config) -> 715: ?cfg(listener_config(ejabberd_c2s, #{tls => [{tls_module, just_tls}, 716: {ssl_options, 717: [{versions, ['tlsv1.2', 'tlsv1.3']}]}]}), 718: listen_raw(<<"c2s">>, 719: #{<<"tls">> => #{<<"module">> => <<"just_tls">>, 720: <<"versions">> => [<<"tlsv1.2">>, <<"tlsv1.3">>]}})), 721: ?err(listen_raw(<<"c2s">>, 722: #{<<"tls">> => #{<<"module">> => <<"just_tls">>, 723: <<"versions">> => <<"tlsv1.2">>}})). 724: 725: listen_tls_protocol_options(_Config) -> 726: ?cfg(listener_config(ejabberd_c2s, #{tls => [{protocol_options, ["nosslv2"]}]}), 727: listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"protocol_options">> => [<<"nosslv2">>]}})), 728: ?cfg(listener_config(ejabberd_s2s_in, #{tls => [{protocol_options, ["nosslv2"]}]}), 729: listen_raw(<<"s2s">>, #{<<"tls">> => #{<<"protocol_options">> => [<<"nosslv2">>]}})), 730: ?err(listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"protocol_options">> => [<<>>]}})), 731: ?err(listen_raw(<<"s2s">>, #{<<"tls">> => #{<<"protocol_options">> => [<<>>]}})), 732: ?err(listen_raw(<<"c2s">>, #{<<"tls">> => #{<<"module">> => <<"just_tls">>, 733: <<"protocol_options">> => [<<"nosslv2">>]}})). 734: 735: listen_check_from(_Config) -> 736: ?cfg(listener_config(ejabberd_service, #{service_check_from => false}), 737: listen_raw(<<"service">>, #{<<"check_from">> => false})), 738: ?err(listen_raw(<<"service">>, #{<<"check_from">> => 1})). 739: 740: listen_hidden_components(_Config) -> 741: ?cfg(listener_config(ejabberd_service, #{hidden_components => true}), 742: listen_raw(<<"service">>, #{<<"hidden_components">> => true})), 743: ?err(listen_raw(<<"service">>, #{<<"hidden_components">> => <<"yes">>})). 744: 745: listen_conflict_behaviour(_Config) -> 746: ?cfg(listener_config(ejabberd_service, #{conflict_behaviour => kick_old}), 747: listen_raw(<<"service">>, #{<<"conflict_behaviour">> => <<"kick_old">>})), 748: ?err(listen_raw(<<"service">>, #{<<"conflict_behaviour">> => <<"kill_server">>})). 749: 750: listen_password(_Config) -> 751: ?cfg(listener_config(ejabberd_service, #{password => "secret"}), 752: listen_raw(<<"service">>, #{<<"password">> => <<"secret">>})), 753: ?err(listen_raw(<<"service">>, #{<<"password">> => <<>>})). 754: 755: listen_http_num_acceptors(_Config) -> 756: ?cfg(listener_config(ejabberd_cowboy, #{transport_options => [{num_acceptors, 10}]}), 757: listen_raw(<<"http">>, #{<<"transport">> => #{<<"num_acceptors">> => 10}})), 758: ?err(listen_raw(<<"http">>, #{<<"transport">> => #{<<"num_acceptors">> => 0}})). 759: 760: listen_http_max_connections(_Config) -> 761: ?cfg(listener_config(ejabberd_cowboy, #{transport_options => [{max_connections, 100}]}), 762: listen_raw(<<"http">>, #{<<"transport">> => #{<<"max_connections">> => 100}})), 763: ?cfg(listener_config(ejabberd_cowboy, #{transport_options => [{max_connections, infinity}]}), 764: listen_raw(<<"http">>, #{<<"transport">> => 765: #{<<"max_connections">> => <<"infinity">>}})), 766: ?err(listen_raw(<<"http">>, #{<<"transport">> => #{<<"max_connections">> => -1}})). 767: 768: listen_http_compress(_Config) -> 769: ?cfg(listener_config(ejabberd_cowboy, #{protocol_options => [{compress, true}]}), 770: listen_raw(<<"http">>, #{<<"protocol">> => #{<<"compress">> => true}})), 771: ?err(listen_raw(<<"http">>, #{<<"protocol">> => #{<<"compress">> => 0}})). 772: 773: listen_http_handlers(_Config) -> 774: ?cfg(listener_config(ejabberd_cowboy, #{modules => [{"_", "/http-bind", mod_bosh, []}]}), 775: listen_raw(<<"http">>, #{<<"handlers">> => 776: #{<<"mod_bosh">> => 777: [#{<<"host">> => <<"_">>, 778: <<"path">> => <<"/http-bind">>}]}})), 779: ?err(listen_raw(<<"http">>, #{<<"handlers">> => 780: #{<<"mod_bosch">> => 781: [#{<<"host">> => <<"dishwasher">>, 782: <<"path">> => <<"/cutlery">>}]}})), 783: ?err(listen_raw(<<"http">>, #{<<"handlers">> => 784: #{<<"mod_bosh">> => 785: [#{<<"host">> => <<"pathless">>}]}})), 786: ?err(listen_raw(<<"http">>, #{<<"handlers">> => 787: #{<<"mod_bosh">> => 788: [#{<<"host">> => <<>>, 789: <<"path">> => <<"/">>}]}})), 790: ?err(listen_raw(<<"http">>, #{<<"handlers">> => 791: #{<<"mod_bosh">> => 792: [#{<<"path">> => <<"hostless">>}]}})). 793: 794: listen_http_handlers_websockets(_Config) -> 795: ?cfg(listener_config(ejabberd_cowboy, #{modules => [{"localhost", "/api", mod_websockets, []}]}), 796: http_handler_raw(<<"mod_websockets">>, #{})), 797: ?cfg(listener_config(ejabberd_cowboy, #{modules => [{"localhost", "/api", mod_websockets, 798: [{ejabberd_service, [{access, all}]}] 799: }]}), 800: http_handler_raw(<<"mod_websockets">>, #{<<"service">> => #{<<"access">> => <<"all">>}})), 801: ?err(http_handler_raw(<<"mod_websockets">>, #{<<"service">> => <<"unbelievable">>})). 802: 803: listen_http_handlers_lasse(_Config) -> 804: ?cfg(listener_config(ejabberd_cowboy, #{modules => [{"localhost", "/api", lasse_handler, 805: [mongoose_client_api_sse] 806: }]}), 807: http_handler_raw(<<"lasse_handler">>, #{<<"module">> => <<"mongoose_client_api_sse">>})), 808: ?err(http_handler_raw(<<"lasse_handler">>, #{<<"module">> => <<"mooongooose_api_ssie">>})), 809: ?err(http_handler_raw(<<"lasse_handler">>, #{})). 810: 811: listen_http_handlers_static(_Config) -> 812: ?cfg(listener_config(ejabberd_cowboy, #{modules => [{"localhost", "/api", cowboy_static, 813: {priv_dir, cowboy_swagger, "swagger", 814: [{mimetypes, cow_mimetypes, all}]} 815: }]}), 816: http_handler_raw(<<"cowboy_static">>, #{<<"type">> => <<"priv_dir">>, 817: <<"app">> => <<"cowboy_swagger">>, 818: <<"content_path">> => <<"swagger">>})), 819: ?err(http_handler_raw(<<"cowboy_static">>, #{<<"type">> => <<"priv_dir">>, 820: <<"app">> => <<"cowboy_swagger">>})). 821: 822: listen_http_handlers_api(_Config) -> 823: ?cfg(listener_config(ejabberd_cowboy, #{modules => [{"localhost", "/api", mongoose_api, 824: [{handlers, [mongoose_api_metrics, 825: mongoose_api_users]}]} 826: ]}), 827: http_handler_raw(<<"mongoose_api">>, #{<<"handlers">> => [<<"mongoose_api_metrics">>, 828: <<"mongoose_api_users">>]})), 829: ?err(http_handler_raw(<<"mongoose_api">>, #{<<"handlers">> => [<<"not_an_api_module">>]})), 830: ?err(http_handler_raw(<<"mongoose_api">>, #{})). 831: 832: listen_http_handlers_domain(_Config) -> 833: ?cfg(listener_config(ejabberd_cowboy, 834: #{modules => [{"localhost", "/api", mongoose_domain_handler, 835: [{password, <<"cool">>}, {username, <<"admin">>}] 836: }]}), 837: http_handler_raw(<<"mongoose_domain_handler">>, 838: #{<<"username">> => <<"admin">>, <<"password">> => <<"cool">>})), 839: ?cfg(listener_config(ejabberd_cowboy, 840: #{modules => [{"localhost", "/api", mongoose_domain_handler, 841: [] }]}), 842: http_handler_raw(<<"mongoose_domain_handler">>, #{})), 843: %% Both username and password required. Or none. 844: ?err(http_handler_raw(<<"mongoose_domain_handler">>, #{<<"username">> => <<"admin">>})), 845: ?err(http_handler_raw(<<"mongoose_domain_handler">>, #{<<"password">> => <<"cool">>})). 846: 847: %% tests: auth 848: 849: auth_methods(_Config) -> 850: ?cfg([{auth, ?HOST}, methods], [], #{}), % global default 851: ?cfgh([auth, methods], [], #{<<"auth">> => #{}}), % default 852: ?cfgh([auth, methods], [internal, rdbms], % default alphabetical order 853: #{<<"auth">> => #{<<"internal">> => #{}, 854: <<"rdbms">> => #{}}}), 855: ?cfgh([auth, methods], [rdbms, internal], % specified order 856: #{<<"auth">> => #{<<"internal">> => #{}, 857: <<"rdbms">> => #{}, 858: <<"methods">> => [<<"rdbms">>, <<"internal">>]}}), 859: ?cfgh([auth, methods], [internal], % only one of the defined methods is enabled 860: #{<<"auth">> => #{<<"internal">> => #{}, 861: <<"rdbms">> => #{}, 862: <<"methods">> => [<<"internal">>]}}), 863: ?errh(#{<<"auth">> => #{<<"rdbms">> => <<"enabled">>}}), 864: ?errh(#{<<"auth">> => #{<<"supernatural">> => #{}}}), 865: ?errh(#{<<"auth">> => #{<<"methods">> => [<<"rdbms">>]}}). 866: 867: auth_password(_Config) -> 868: Defaults = #{format => scram, scram_iterations => 10000}, 869: ?cfg([{auth, ?HOST}, password], Defaults, #{}), % global default 870: ?cfgh([auth, password], Defaults, #{<<"auth">> => #{}}), % default 871: ?cfgh([auth, password], Defaults, #{<<"auth">> => #{<<"password">> => #{}}}), % default 872: ?cfgh([auth, password, format], plain, 873: #{<<"auth">> => #{<<"password">> => #{<<"format">> => <<"plain">>}}}), 874: ?errh(#{<<"auth">> => #{<<"password">> => #{<<"format">> => <<"plane">>}}}), 875: ?cfgh([auth, password, hash], [sha, sha256], 876: #{<<"auth">> => #{<<"password">> => #{<<"hash">> => [<<"sha">>, <<"sha256">>]}}}), 877: ?errh(#{<<"auth">> => #{<<"password">> => #{<<"hash">> => [<<"sha1234">>]}}}), 878: ?errh(#{<<"auth">> => #{<<"password">> => #{<<"harsh">> => [<<"sha">>]}}}), 879: ?cfgh([auth, password, scram_iterations], 1000, 880: #{<<"auth">> => #{<<"password">> => #{<<"scram_iterations">> => 1000}}}), 881: ?errh(#{<<"auth">> => #{<<"password">> => #{<<"scram_iterations">> => false}}}). 882: 883: auth_sasl_external(_Config) -> 884: ?cfg([{auth, ?HOST}, sasl_external], [standard], #{}), % global default 885: ?cfgh([auth, sasl_external], [standard], #{<<"auth">> => #{}}), % default 886: ?cfgh([auth, sasl_external], [standard, 887: common_name, 888: {mod, cyrsasl_external_verification}], 889: #{<<"auth">> => #{<<"sasl_external">> => 890: [<<"standard">>, 891: <<"common_name">>, 892: <<"cyrsasl_external_verification">>]}}), 893: ?errh(#{<<"auth">> => #{<<"sasl_external">> => [<<"unknown">>]}}). 894: 895: auth_sasl_mechanisms(_Config) -> 896: Default = cyrsasl:default_modules(), 897: ?cfg([{auth, ?HOST}, sasl_mechanisms], Default, #{}), % global default 898: ?cfg([{auth, ?HOST}, sasl_mechanisms], Default, #{<<"auth">> => #{}}), % default 899: ?cfgh([auth, sasl_mechanisms], [cyrsasl_external, cyrsasl_scram], 900: #{<<"auth">> => #{<<"sasl_mechanisms">> => [<<"external">>, <<"scram">>]}}), 901: ?errh(#{<<"auth">> => #{<<"sasl_mechanisms">> => [<<"none">>]}}). 902: 903: auth_allow_multiple_connections(_Config) -> 904: ?cfgh([auth, anonymous, allow_multiple_connections], true, 905: auth_raw(<<"anonymous">>, #{<<"allow_multiple_connections">> => true})), 906: ?errh(auth_raw(<<"anonymous">>, #{<<"allow_multiple_connections">> => <<"yes">>})). 907: 908: auth_anonymous_protocol(_Config) -> 909: ?cfgh([auth, anonymous, protocol], login_anon, 910: auth_raw(<<"anonymous">>, #{<<"protocol">> => <<"login_anon">>})), 911: ?errh(auth_raw(<<"anonymous">>, #{<<"protocol">> => <<"none">>})). 912: 913: auth_ldap_pool(_Config) -> 914: ?cfgh([auth, ldap, pool_tag], default, auth_ldap_raw(#{})), % default 915: ?cfgh([auth, ldap, pool_tag], ldap_pool, 916: auth_ldap_raw(#{<<"pool_tag">> => <<"ldap_pool">>})), 917: ?errh(auth_ldap_raw(#{<<"pool_tag">> => <<>>})). 918: 919: auth_ldap_bind_pool(_Config) -> 920: ?cfgh([auth, ldap, bind_pool_tag], bind, auth_ldap_raw(#{})), % default 921: ?cfgh([auth, ldap, bind_pool_tag], ldap_bind_pool, 922: auth_ldap_raw(#{<<"bind_pool_tag">> => <<"ldap_bind_pool">>})), 923: ?errh(auth_ldap_raw(#{<<"bind_pool_tag">> => true})). 924: 925: auth_ldap_base(_Config) -> 926: ?cfgh([auth, ldap, base], <<>>, auth_ldap_raw(#{})), % default 927: ?cfgh([auth, ldap, base], <<"ou=Users,dc=example,dc=com">>, 928: auth_ldap_raw(#{<<"base">> => <<"ou=Users,dc=example,dc=com">>})), 929: ?errh(auth_ldap_raw(#{<<"base">> => 10})). 930: 931: auth_ldap_uids(_Config) -> 932: ?cfgh([auth, ldap, uids], [{<<"uid">>, <<"%u">>}], auth_ldap_raw(#{})), % default 933: ?cfgh([auth, ldap, uids], [{<<"uid1">>, <<"user=%u">>}], 934: auth_ldap_raw(#{<<"uids">> => [#{<<"attr">> => <<"uid1">>, 935: <<"format">> => <<"user=%u">>}]})), 936: ?cfgh([auth, ldap, uids], [<<"uid1">>], 937: auth_ldap_raw(#{<<"uids">> => [#{<<"attr">> => <<"uid1">>}]})), 938: ?errh(auth_ldap_raw(#{<<"uids">> => [#{<<"format">> => <<"user=%u">>}]})). 939: 940: auth_ldap_filter(_Config) -> 941: ?cfgh([auth, ldap, filter], <<>>, auth_ldap_raw(#{})), % default 942: ?cfgh([auth, ldap, filter], <<"(objectClass=inetOrgPerson)">>, 943: auth_ldap_raw(#{<<"filter">> => <<"(objectClass=inetOrgPerson)">>})), 944: ?errh(auth_ldap_raw(#{<<"filter">> => 10})). 945: 946: auth_ldap_dn_filter(_Config) -> 947: ?cfgh([auth, ldap, dn_filter], {undefined, []}, auth_ldap_raw(#{})), % default 948: ?cfgh([auth, ldap, dn_filter], {<<"(user=%u@%d)">>, []}, 949: auth_ldap_raw(#{<<"dn_filter">> => #{<<"filter">> => <<"(user=%u@%d)">>}})), 950: Pattern = <<"(&(name=%s)(owner=%D)(user=%u@%d))">>, 951: ?cfgh([auth, ldap, dn_filter], {Pattern, [<<"sn">>]}, 952: auth_ldap_raw(#{<<"dn_filter">> => #{<<"filter">> => Pattern, 953: <<"attributes">> => [<<"sn">>]}})), 954: ?errh(auth_ldap_raw(#{<<"dn_filter">> => #{<<"attributes">> => [<<"sn">>]}})), 955: ?errh(auth_ldap_raw(#{<<"dn_filter">> => #{<<"filter">> => 12}})), 956: ?errh(auth_ldap_raw(#{<<"dn_filter">> => #{<<"filter">> => Pattern, 957: <<"attributes">> => <<"sn">>}})). 958: 959: auth_ldap_local_filter(_Config) -> 960: ?cfgh([auth, ldap, local_filter], undefined, auth_ldap_raw(#{})), % default 961: Filter = #{<<"operation">> => <<"equal">>, 962: <<"attribute">> => <<"accountStatus">>, 963: <<"values">> => [<<"enabled">>]}, 964: ?cfgh([auth, ldap, local_filter], {equal, {"accountStatus", ["enabled"]}}, 965: auth_ldap_raw(#{<<"local_filter">> => Filter})), 966: [?errh(auth_ldap_raw(#{<<"local_filter">> => maps:remove(K, Filter)})) || 967: K <- maps:keys(Filter)], 968: ?errh(auth_ldap_raw(#{<<"local_filter">> => Filter#{<<"operation">> := <<"lt">>}})), 969: ?errh(auth_ldap_raw(#{<<"local_filter">> => Filter#{<<"attribute">> := <<>>}})), 970: ?errh(auth_ldap_raw(#{<<"local_filter">> => Filter#{<<"values">> := []}})). 971: 972: auth_ldap_deref(_Config) -> 973: ?cfgh([auth, ldap, deref], never, auth_ldap_raw(#{})), % default 974: ?cfgh([auth, ldap, deref], always, auth_ldap_raw(#{<<"deref">> => <<"always">>})), 975: ?errh(auth_ldap_raw(#{<<"deref">> => <<"sometimes">>})). 976: 977: auth_external(_Config) -> 978: RequiredOpts = #{<<"program">> => <<"/usr/bin/auth">>}, 979: Config = #{program => "/usr/bin/auth", 980: instances => 1}, % default 981: ?cfgh([auth, external], Config, 982: auth_raw(<<"external">>, RequiredOpts)), 983: ?cfgh([auth, external, instances], 2, 984: auth_raw(<<"external">>, RequiredOpts#{<<"instances">> => 2})), 985: ?errh(auth_raw(<<"external">>, #{<<"program">> => <<>>})), 986: ?errh(auth_raw(<<"external">>, #{<<"instances">> => 2})), 987: ?errh(auth_raw(<<"external">>, RequiredOpts#{<<"instances">> => 0})). 988: 989: auth_http_basic_auth(_Config) -> 990: ?cfgh([auth, http, basic_auth], "admin:admin123", 991: auth_raw(<<"http">>, #{<<"basic_auth">> => <<"admin:admin123">>})), 992: ?errh(auth_raw(<<"http">>, #{<<"basic_auth">> => true})). 993: 994: auth_jwt(_Config) -> 995: Opts = #{<<"secret">> => #{<<"value">> => <<"secret123">>}, 996: <<"algorithm">> => <<"HS512">>, 997: <<"username_key">> => <<"user">>}, % tested together as all options are required 998: Config = #{algorithm => <<"HS512">>, 999: secret => {value, "secret123"}, 1000: username_key => user}, 1001: ?cfgh([auth, jwt], Config, 1002: auth_raw(<<"jwt">>, Opts)), 1003: ?cfgh([auth, jwt, secret], {file, "/home/user/jwt_secret"}, 1004: auth_raw(<<"jwt">>, Opts#{<<"secret">> := #{<<"file">> => <<"/home/user/jwt_secret">>}})), 1005: ?cfgh([auth, jwt, secret], {env, "SECRET"}, 1006: auth_raw(<<"jwt">>, Opts#{<<"secret">> := #{<<"env">> => <<"SECRET">>}})), 1007: ?errh(auth_raw(<<"jwt">>, Opts#{<<"secret">> := #{<<"value">> => 123}})), 1008: ?errh(auth_raw(<<"jwt">>, Opts#{<<"secret">> := #{<<"file">> => <<>>}})), 1009: ?errh(auth_raw(<<"jwt">>, Opts#{<<"secret">> := #{<<"env">> => <<>>}})), 1010: ?errh(auth_raw(<<"jwt">>, Opts#{<<"secret">> := #{<<"file">> => <<"/jwt_secret">>, 1011: <<"env">> => <<"SECRET">>}})), 1012: ?errh(auth_raw(<<"jwt">>, Opts#{<<"algorithm">> := <<"bruteforce">>})), 1013: ?errh(auth_raw(<<"jwt">>, Opts#{<<"username_key">> := <<>>})), 1014: [?errh(auth_raw(<<"jwt">>, maps:without([K], Opts))) || K <- maps:keys(Opts)]. 1015: 1016: auth_riak_bucket_type(_Config) -> 1017: ?cfgh([auth, riak, bucket_type], <<"users">>, auth_raw(<<"riak">>, #{})), % default 1018: ?cfgh([auth, riak, bucket_type], <<"buckethead">>, 1019: auth_raw(<<"riak">>, #{<<"bucket_type">> => <<"buckethead">>})), 1020: ?errh(auth_raw(<<"riak">>, #{<<"bucket_type">> => <<>>})). 1021: 1022: auth_rdbms_users_number_estimate(_Config) -> 1023: ?cfgh([auth, rdbms, users_number_estimate], false, auth_raw(<<"rdbms">>, #{})), % default 1024: ?cfgh([auth, rdbms, users_number_estimate], true, 1025: auth_raw(<<"rdbms">>, #{<<"users_number_estimate">> => true})), 1026: ?errh(auth_raw(<<"rdbms">>, #{<<"users_number_estimate">> => 1200})). 1027: 1028: auth_dummy(_Config) -> 1029: ?cfgh([auth, dummy], #{base_time => 50, variance => 450}, auth_raw(<<"dummy">>, #{})), % default 1030: ?cfgh([auth, dummy, base_time], 0, auth_raw(<<"dummy">>, #{<<"base_time">> => 0})), 1031: ?cfgh([auth, dummy, variance], 10, auth_raw(<<"dummy">>, #{<<"variance">> => 10})), 1032: ?errh(auth_raw(<<"dummy">>, #{<<"base_time">> => -5})), 1033: ?errh(auth_raw(<<"dummy">>, #{<<"variance">> => 0})). 1034: 1035: %% tests: outgoing_pools 1036: 1037: pool_type(_Config) -> 1038: ?cfg(pool_config({http, global, default, [], []}), 1039: pool_raw(<<"http">>, <<"default">>, #{})), 1040: ?err(pool_raw(<<"swimming_pool">>, <<"default">>, #{})). 1041: 1042: pool_tag(_Config) -> 1043: ?cfg(pool_config({http, global, my_pool, [], []}), 1044: pool_raw(<<"http">>, <<"my_pool">>, #{})), 1045: ?err(pool_raw(<<"http">>, 1000, #{})). 1046: 1047: pool_scope(_Config) -> 1048: ?cfg(pool_config({http, global, default, [], []}), 1049: pool_raw(<<"http">>, <<"default">>, #{})), 1050: ?cfg(pool_config({http, global, default, [], []}), 1051: pool_raw(<<"http">>, <<"default">>, #{<<"scope">> => <<"global">>})), 1052: ?cfg(pool_config({http, host, default, [], []}), 1053: pool_raw(<<"http">>, <<"default">>, #{<<"scope">> => <<"host">>})), 1054: ?cfg(pool_config({http, <<"localhost">>, default, [], []}), 1055: pool_raw(<<"http">>, <<"default">>, #{<<"scope">> => <<"single_host">>, 1056: <<"host">> => <<"localhost">>})), 1057: ?err(pool_raw(<<"http">>, <<"default">>, #{<<"scope">> => <<"whatever">>})), 1058: ?err(pool_raw(<<"http">>, <<"default">>, #{<<"scope">> => <<"single_host">>})). 1059: 1060: pool_workers(_Config) -> 1061: ?cfg(pool_config({http, global, default, [{workers, 10}], []}), 1062: pool_raw(<<"http">>, <<"default">>, #{<<"workers">> => 10})), 1063: ?err(pool_raw(<<"http">>, <<"default">>, #{<<"workers">> => 0})). 1064: 1065: pool_strategy(_Config) -> 1066: ?cfg(pool_config({http, global, default, [{strategy, best_worker}], []}), 1067: pool_raw(<<"http">>, <<"default">>, #{<<"strategy">> => <<"best_worker">>})), 1068: ?err(pool_raw(<<"http">>, <<"default">>, #{<<"strategy">> => <<"worst_worker">>})). 1069: 1070: pool_call_timeout(_Config) -> 1071: ?cfg(pool_config({http, global, default, [{call_timeout, 5000}], []}), 1072: pool_raw(<<"http">>, <<"default">>, #{<<"call_timeout">> => 5000})), 1073: ?err(pool_raw(<<"http">>, <<"default">>, #{<<"call_timeout">> => 0})). 1074: 1075: pool_rdbms_settings(_Config) -> 1076: ?cfg(pool_config({rdbms, global, default, [], [{server, "DSN=mydb"}]}), 1077: pool_conn_raw(<<"rdbms">>, #{<<"driver">> => <<"odbc">>, 1078: <<"settings">> => <<"DSN=mydb">>})), 1079: ?err(pool_conn_raw(<<"rdbms">>, #{<<"driver">> => <<"mysql">>, 1080: <<"settings">> => <<"DSN=mydb">>})), 1081: ?err(pool_conn_raw(<<"rdbms">>, #{<<"driver">> => <<"odbc">>, 1082: <<"settings">> => true})), 1083: ?err(pool_conn_raw(<<"rdbms">>, #{<<"driver">> => <<"odbc">>})). 1084: 1085: pool_rdbms_keepalive_interval(_Config) -> 1086: ?cfg(pool_config({rdbms, global, default, [], [{server, "DSN=mydb"}, 1087: {keepalive_interval, 1000}]}), 1088: pool_conn_raw(<<"rdbms">>, #{<<"driver">> => <<"odbc">>, 1089: <<"settings">> => <<"DSN=mydb">>, 1090: <<"keepalive_interval">> => 1000})), 1091: ?err(pool_conn_raw(<<"rdbms">>, #{<<"driver">> => <<"odbc">>, 1092: <<"settings">> => <<"DSN=mydb">>, 1093: <<"keepalive_interval">> => false})). 1094: 1095: pool_rdbms_server(_Config) -> 1096: ServerOpts = rdbms_opts(), 1097: ?cfg(pool_config({rdbms, global, default, [], 1098: [{server, {pgsql, "localhost", "db", "dbuser", "secret"}}]}), 1099: pool_conn_raw(<<"rdbms">>, ServerOpts)), 1100: ?err(pool_conn_raw(<<"rdbms">>, ServerOpts#{<<"driver">> := <<"odbc">>})), 1101: [?err(pool_conn_raw(<<"rdbms">>, maps:without([K], ServerOpts))) || 1102: K <- maps:keys(ServerOpts)], 1103: [?err(pool_conn_raw(<<"rdbms">>, ServerOpts#{K := 123})) || 1104: K <- maps:keys(ServerOpts)]. 1105: 1106: pool_rdbms_port(_Config) -> 1107: ServerOpts = rdbms_opts(), 1108: ?cfg(pool_config({rdbms, global, default, [], 1109: [{server, {pgsql, "localhost", 1234, "db", "dbuser", "secret"}}]}), 1110: pool_conn_raw(<<"rdbms">>, ServerOpts#{<<"port">> => 1234})), 1111: ?err(pool_conn_raw(<<"rdbms">>, ServerOpts#{<<"port">> => <<"airport">>})). 1112: 1113: pool_rdbms_tls(_Config) -> 1114: ServerOpts = rdbms_opts(), 1115: ?cfg(pool_config({rdbms, global, default, [], 1116: [{server, {pgsql, "localhost", "db", "dbuser", "secret", 1117: [{ssl, required}]}}]}), 1118: pool_conn_raw(<<"rdbms">>, ServerOpts#{<<"tls">> => #{<<"required">> => true}})), 1119: ?cfg(pool_config({rdbms, global, default, [], 1120: [{server, {pgsql, "localhost", "db", "dbuser", "secret", 1121: [{ssl, true}]}}]}), 1122: pool_conn_raw(<<"rdbms">>, ServerOpts#{<<"tls">> => #{}})), 1123: ?cfg(pool_config({rdbms, global, default, [], 1124: [{server, {mysql, "localhost", "db", "dbuser", "secret", []}}]}), 1125: pool_conn_raw(<<"rdbms">>, ServerOpts#{<<"driver">> => <<"mysql">>, 1126: <<"tls">> => #{}})), 1127: ?cfg(pool_config({rdbms, global, default, [], 1128: [{server, {pgsql, "localhost", 1234, "db", "dbuser", "secret", 1129: [{ssl, true}]}}]}), 1130: pool_conn_raw(<<"rdbms">>, ServerOpts#{<<"tls">> => #{}, 1131: <<"port">> => 1234})), 1132: 1133: %% one option tested here as they are all checked by 'listen_tls_*' tests 1134: ?cfg(pool_config({rdbms, global, default, [], 1135: [{server, {pgsql, "localhost", "db", "dbuser", "secret", 1136: [{ssl, true}, {ssl_opts, [{certfile, "cert.pem"}]}]}}]}), 1137: pool_conn_raw(<<"rdbms">>, ServerOpts#{<<"tls">> => 1138: #{<<"certfile">> => <<"cert.pem">>}})), 1139: ?err(pool_conn_raw(<<"rdbms">>, ServerOpts#{<<"tls">> => 1140: #{<<"certfile">> => true}})), 1141: ?err(pool_conn_raw(<<"rdbms">>, ServerOpts#{<<"tls">> => <<"secure">>})). 1142: 1143: pool_http_host(_Config) -> 1144: ?cfg(pool_config({http, global, default, [], [{server, "https://localhost:8443"}]}), 1145: pool_conn_raw(<<"http">>, #{<<"host">> => <<"https://localhost:8443">>})), 1146: ?err(pool_conn_raw(<<"http">>, #{<<"host">> => 8443})), 1147: ?err(pool_conn_raw(<<"http">>, #{<<"host">> => ""})). 1148: 1149: pool_http_path_prefix(_Config) -> 1150: ?cfg(pool_config({http, global, default, [], [{path_prefix, "/"}]}), 1151: pool_conn_raw(<<"http">>, #{<<"path_prefix">> => <<"/">>})), 1152: ?err(pool_conn_raw(<<"http">>, #{<<"path_prefix">> => 8443})), 1153: ?err(pool_conn_raw(<<"http">>, #{<<"path_prefix">> => ""})). 1154: 1155: pool_http_request_timeout(_Config) -> 1156: ?cfg(pool_config({http, global, default, [], [{request_timeout, 2000}]}), 1157: pool_conn_raw(<<"http">>, #{<<"request_timeout">> => 2000})), 1158: ?err(pool_conn_raw(<<"http">>, #{<<"request_timeout">> => -1000})), 1159: ?err(pool_conn_raw(<<"http">>, #{<<"request_timeout">> => <<"infinity">>})). 1160: 1161: pool_http_tls(_Config) -> 1162: ?cfg(pool_config({http, global, default, [], [{http_opts, [{certfile, "cert.pem"} ]}]}), 1163: pool_conn_raw(<<"http">>, #{<<"tls">> => #{<<"certfile">> => <<"cert.pem">>}})), 1164: ?err(pool_conn_raw(<<"http">>, #{<<"tls">> => #{<<"certfile">> => true}})), 1165: ?err(pool_conn_raw(<<"http">>, #{<<"tls">> => <<"secure">>})). 1166: 1167: pool_redis_host(_Config) -> 1168: ?cfg(pool_config({redis, global, default, [], [{host, "localhost"}]}), 1169: pool_conn_raw(<<"redis">>, #{<<"host">> => <<"localhost">>})), 1170: ?err(pool_conn_raw(<<"redis">>, #{<<"host">> => 8443})), 1171: ?err(pool_conn_raw(<<"redis">>, #{<<"host">> => ""})). 1172: 1173: pool_redis_port(_Config) -> 1174: ?cfg(pool_config({redis, global, default, [], [{port, 6379}]}), 1175: pool_conn_raw(<<"redis">>, #{<<"port">> => 6379})), 1176: ?err(pool_conn_raw(<<"redis">>, #{<<"port">> => 666666})), 1177: ?err(pool_conn_raw(<<"redis">>, #{<<"port">> => <<"airport">>})). 1178: 1179: pool_redis_database(_Config) -> 1180: ?cfg(pool_config({redis, global, default, [], [{database, 0}]}), 1181: pool_conn_raw(<<"redis">>, #{<<"database">> => 0})), 1182: ?err(pool_conn_raw(<<"redis">>, #{<<"database">> => -1})), 1183: ?err(pool_conn_raw(<<"redis">>, #{<<"database">> => <<"my_database">>})). 1184: 1185: pool_redis_password(_Config) -> 1186: ?cfg(pool_config({redis, global, default, [], [{password, ""}]}), 1187: pool_conn_raw(<<"redis">>, #{<<"password">> => <<"">>})), 1188: ?cfg(pool_config({redis, global, default, [], [{password, "password1"}]}), 1189: pool_conn_raw(<<"redis">>, #{<<"password">> => <<"password1">>})), 1190: ?err(pool_conn_raw(<<"redis">>, #{<<"password">> => 0})). 1191: 1192: pool_riak_address(_Config) -> 1193: ?cfg(pool_config({riak, global, default, [], [{address, "127.0.0.1"}]}), 1194: pool_conn_raw(<<"riak">>, #{<<"address">> => <<"127.0.0.1">>})), 1195: ?err(pool_conn_raw(<<"riak">>, #{<<"address">> => 66})), 1196: ?err(pool_conn_raw(<<"riak">>, #{<<"address">> => <<"">>})). 1197: 1198: pool_riak_port(_Config) -> 1199: ?cfg(pool_config({riak, global, default, [], [{port, 8087}]}), 1200: pool_conn_raw(<<"riak">>, #{<<"port">> => 8087})), 1201: ?err(pool_conn_raw(<<"riak">>, #{<<"port">> => 666666})), 1202: ?err(pool_conn_raw(<<"riak">>, #{<<"port">> => <<"airport">>})). 1203: 1204: pool_riak_credentials(_Config) -> 1205: ?cfg(pool_config({riak, global, default, [], [{credentials, "user", "pass"}]}), 1206: pool_conn_raw(<<"riak">>, #{<<"credentials">> => 1207: #{<<"user">> => <<"user">>, <<"password">> => <<"pass">>}})), 1208: ?err(pool_conn_raw(<<"riak">>, #{<<"credentials">> => #{<<"user">> => <<"user">>}})), 1209: ?err(pool_conn_raw(<<"riak">>, #{<<"credentials">> => 1210: #{<<"user">> => <<"">>, <<"password">> => 011001}})). 1211: 1212: pool_riak_cacertfile(_Config) -> 1213: ?cfg(pool_config({riak, global, default, [], [{cacertfile, "cacert.pem"}]}), 1214: pool_conn_raw(<<"riak">>, #{<<"tls">> => #{<<"cacertfile">> => <<"cacert.pem">>}})), 1215: ?err(pool_conn_raw(<<"riak">>, #{<<"cacertfile">> => <<"">>})). 1216: 1217: pool_riak_tls(_Config) -> 1218: %% make sure these options are not extracted out of 'ssl_opts' 1219: %% all the TLS options are checked by 'listen_tls_*' tests 1220: ?cfg(pool_config({riak, global, default, [], [{ssl_opts, [{certfile, "path/to/cert.pem"}, 1221: {dhfile, "cert.pem"}, 1222: {keyfile, "path/to/key.pem"}]}]}), 1223: pool_conn_raw(<<"riak">>, #{<<"tls">> => #{<<"certfile">> => <<"path/to/cert.pem">>, 1224: <<"dhfile">> => <<"cert.pem">>, 1225: <<"keyfile">> => <<"path/to/key.pem">>}})), 1226: ?err(pool_conn_raw(<<"riak">>, #{<<"tls">> => #{<<"dhfile">> => true}})), 1227: ?err(pool_conn_raw(<<"riak">>, #{<<"tls">> => <<"secure">>})). 1228: 1229: pool_cassandra_servers(_Config) -> 1230: ?cfg(pool_config({cassandra, global, default, [], 1231: [{servers, [{"cassandra_server1.example.com", 9042}, 1232: {"cassandra_server2.example.com", 9042}]}]}), 1233: pool_conn_raw(<<"cassandra">>, 1234: #{<<"servers">> => [#{<<"ip_address">> => <<"cassandra_server1.example.com">>, 1235: <<"port">> => 9042}, 1236: #{<<"ip_address">> => <<"cassandra_server2.example.com">>, 1237: <<"port">> => 9042}]})), 1238: ?err(pool_conn_raw(<<"cassandra">>, 1239: #{<<"servers">> => #{<<"ip_address">> => <<"cassandra_server1.example.com">>, 1240: <<"port">> => 9042}})). 1241: 1242: pool_cassandra_keyspace(_Config) -> 1243: ?cfg(pool_config({cassandra, global, default, [], [{keyspace, "big_mongooseim"}]}), 1244: pool_conn_raw(<<"cassandra">>, #{<<"keyspace">> => <<"big_mongooseim">>})), 1245: ?err(pool_conn_raw(<<"cassandra">>, #{<<"keyspace">> => <<"">>})). 1246: 1247: pool_cassandra_auth(_Config) -> 1248: ?cfg(pool_config({cassandra, global, default, [], [{auth, {cqerl_auth_plain_handler, 1249: [{<<"auser">>, <<"secretpass">>}] 1250: }}]}), 1251: pool_conn_raw(<<"cassandra">>, 1252: #{<<"auth">> => #{<<"plain">> => #{<<"username">> => <<"auser">>, 1253: <<"password">> => <<"secretpass">>}}})), 1254: ?err(pool_conn_raw(<<"cassandra">>, #{<<"tls">> => #{<<"verify">> => <<"verify_none">>}})). 1255: 1256: pool_cassandra_tls(_Config) -> 1257: %% one option tested here as they are all checked by 'listen_tls_*' tests 1258: ?cfg(pool_config({cassandra, global, default, [], [{ssl, [{verify, verify_none}]}]}), 1259: pool_conn_raw(<<"cassandra">>, #{<<"tls">> => #{<<"verify_peer">> => false}})), 1260: ?err(pool_conn_raw(<<"cassandra">>, #{<<"tls">> => #{<<"verify">> => <<"verify_none">>}})). 1261: 1262: pool_elastic_host(_Config) -> 1263: ?cfg(pool_config({elastic, global, default, [], [{host, "localhost"}]}), 1264: pool_conn_raw(<<"elastic">>, #{<<"host">> => <<"localhost">>})), 1265: ?err(pool_conn_raw(<<"elastic">>, #{<<"host">> => <<"">>})). 1266: 1267: pool_elastic_port(_Config) -> 1268: ?cfg(pool_config({elastic, global, default, [], [{port, 9200}]}), 1269: pool_conn_raw(<<"elastic">>, #{<<"port">> => 9200})), 1270: ?err(pool_conn_raw(<<"elastic">>, #{<<"port">> => 122333})), 1271: ?err(pool_conn_raw(<<"elastic">>, #{<<"port">> => <<"airport">>})). 1272: 1273: pool_rabbit_amqp_host(_Config) -> 1274: ?cfg(pool_config({rabbit, global, default, [], [{amqp_host, "localhost"}]}), 1275: pool_conn_raw(<<"rabbit">>, #{<<"amqp_host">> => <<"localhost">>})), 1276: ?err(pool_conn_raw(<<"rabbit">>, #{<<"amqp_host">> => <<"">>})). 1277: 1278: pool_rabbit_amqp_port(_Config) -> 1279: ?cfg(pool_config({rabbit, global, default, [], [{amqp_port, 5672}]}), 1280: pool_conn_raw(<<"rabbit">>, #{<<"amqp_port">> => 5672})), 1281: ?err(pool_conn_raw(<<"rabbit">>, #{<<"amqp_port">> => <<"airport">>})). 1282: 1283: pool_rabbit_amqp_username(_Config) -> 1284: ?cfg(pool_config({rabbit, global, default, [], [{amqp_username, "guest"}]}), 1285: pool_conn_raw(<<"rabbit">>, #{<<"amqp_username">> => <<"guest">>})), 1286: ?err(pool_conn_raw(<<"rabbit">>, #{<<"amqp_username">> => <<"">>})). 1287: 1288: pool_rabbit_amqp_password(_Config) -> 1289: ?cfg(pool_config({rabbit, global, default, [], [{amqp_password, "guest"}]}), 1290: pool_conn_raw(<<"rabbit">>, #{<<"amqp_password">> => <<"guest">>})), 1291: ?err(pool_conn_raw(<<"rabbit">>, #{<<"amqp_password">> => <<"">>})). 1292: 1293: pool_rabbit_amqp_confirms_enabled(_Config) -> 1294: ?cfg(pool_config({rabbit, global, default, [], [{confirms_enabled, true}]}), 1295: pool_conn_raw(<<"rabbit">>, #{<<"confirms_enabled">> => true})), 1296: ?err(pool_conn_raw(<<"rabbit">>, #{<<"confirms_enabled">> => <<"yes">>})). 1297: 1298: pool_rabbit_amqp_max_worker_queue_len(_Config) -> 1299: ?cfg(pool_config({rabbit, global, default, [], [{max_worker_queue_len, 100}]}), 1300: pool_conn_raw(<<"rabbit">>, #{<<"max_worker_queue_len">> => 100})), 1301: ?err(pool_conn_raw(<<"rabbit">>, #{<<"max_worker_queue_len">> => 0})). 1302: 1303: pool_ldap_host(_Config) -> 1304: ?cfg(pool_config({ldap, global, default, [], [{host, "localhost"}]}), 1305: pool_conn_raw(<<"ldap">>, #{<<"host">> => <<"localhost">>})), 1306: ?err(pool_conn_raw(<<"ldap">>, #{<<"host">> => <<"">>})). 1307: 1308: pool_ldap_port(_Config) -> 1309: ?cfg(pool_config({ldap, global, default, [], [{port, 389}]}), 1310: pool_conn_raw(<<"ldap">>, #{<<"port">> => 389})), 1311: ?err(pool_conn_raw(<<"ldap">>, #{<<"port">> => <<"airport">>})). 1312: 1313: pool_ldap_servers(_Config) -> 1314: ?cfg(pool_config({ldap, global, default, [], 1315: [{servers, ["primary-ldap-server.example.com", 1316: "secondary-ldap-server.example.com"]}]}), 1317: pool_conn_raw(<<"ldap">>, #{<<"servers">> => [<<"primary-ldap-server.example.com">>, 1318: <<"secondary-ldap-server.example.com">>]})), 1319: ?err(pool_conn_raw(<<"ldap">>, #{<<"servers">> => #{<<"server">> => <<"example.com">>}})). 1320: 1321: pool_ldap_encrypt(_Config) -> 1322: ?cfg(pool_config({ldap, global, default, [], [{encrypt, none}]}), 1323: pool_conn_raw(<<"ldap">>, #{<<"encrypt">> => <<"none">>})), 1324: ?err(pool_conn_raw(<<"ldap">>, #{<<"encrypt">> => true})). 1325: 1326: pool_ldap_rootdn(_Config) -> 1327: ?cfg(pool_config({ldap, global, default, [], [{rootdn, ""}]}), 1328: pool_conn_raw(<<"ldap">>, #{<<"rootdn">> => <<"">>})), 1329: ?err(pool_conn_raw(<<"ldap">>, #{<<"rootdn">> => false})). 1330: 1331: pool_ldap_password(_Config) -> 1332: ?cfg(pool_config({ldap, global, default, [], [{password, "pass"}]}), 1333: pool_conn_raw(<<"ldap">>, #{<<"password">> => <<"pass">>})), 1334: ?err(pool_conn_raw(<<"ldap">>, #{<<"password">> => true})). 1335: 1336: pool_ldap_connect_interval(_Config) -> 1337: ?cfg(pool_config({ldap, global, default, [], [{connect_interval, 10000}]}), 1338: pool_conn_raw(<<"ldap">>, #{<<"connect_interval">> => 10000})), 1339: ?err(pool_conn_raw(<<"ldap">>, #{<<"connect_interval">> => <<"infinity">>})). 1340: 1341: pool_ldap_tls(_Config) -> 1342: %% one option tested here as they are all checked by 'listen_tls_*' tests 1343: ?cfg(pool_config({ldap, global, default, [], [{tls_options, [{verify, verify_peer}]}]}), 1344: pool_conn_raw(<<"ldap">>, #{<<"tls">> => #{<<"verify_peer">> => true}})), 1345: ?err(pool_conn_raw(<<"ldap">>, #{<<"tls">> => #{<<"verify">> => <<"verify_none">>}})). 1346: 1347: %% tests: shaper, acl, access 1348: shaper(_Config) -> 1349: ?cfg([shaper, normal], #{max_rate => 1000}, 1350: #{<<"shaper">> => #{<<"normal">> => #{<<"max_rate">> => 1000}}}), 1351: ?err(#{<<"shaper">> => #{<<"unlimited">> => #{<<"max_rate">> => <<"infinity">>}}}), 1352: ?err(#{<<"shaper">> => #{<<"fast">> => #{}}}). 1353: 1354: acl(_Config) -> 1355: ?cfgh([acl, local], [#{match => all}], 1356: #{<<"acl">> => #{<<"local">> => [#{<<"match">> => <<"all">>}]}}), 1357: ?cfgh([acl, local], [#{match => any_hosted_domain}], 1358: #{<<"acl">> => #{<<"local">> => [#{<<"match">> => <<"any_hosted_domain">>}]}}), 1359: ?cfgh([acl, local], [#{match => current_domain, 1360: user_regexp => <<>>}], 1361: #{<<"acl">> => #{<<"local">> => [#{<<"user_regexp">> => <<>>}]}}), 1362: ?cfgh([acl, alice], [#{match => current_domain, 1363: user_regexp => <<"ali.*">>, 1364: server_regexp => <<".*host">>}], 1365: #{<<"acl">> => #{<<"alice">> => [#{<<"user_regexp">> => <<"aLi.*">>, 1366: <<"server_regexp">> => <<".*HosT">>}]}}), 1367: ?cfgh([acl, alice], [#{match => current_domain, 1368: user => <<"alice">>, 1369: server => <<"localhost">>}], 1370: #{<<"acl">> => #{<<"alice">> => [#{<<"user">> => <<"alice">>, 1371: <<"server">> => <<"localhost">>}]}}), 1372: ?errh(#{<<"acl">> => #{<<"local">> => <<"everybody">>}}), 1373: ?errh(#{<<"acl">> => #{<<"local">> => [#{<<"match">> => <<"lit">>}]}}), 1374: ?errh(#{<<"acl">> => #{<<"alice">> => [#{<<"user_glob">> => <<"a*">>, 1375: <<"server_blog">> => <<"bloghost">>}]}}), 1376: ?errh([#{reason := incorrect_acl_condition_value}], 1377: #{<<"acl">> => #{<<"local">> => [#{<<"user">> => <<"@@@">>}]}}). 1378: 1379: acl_merge_host_and_global(_Config) -> 1380: G = #{<<"acl">> => #{<<"admin">> => [#{<<"user">> => <<"george">>}]}}, 1381: H1 = #{<<"acl">> => #{<<"admin">> => [#{<<"user">> => <<"henry">>}]}}, 1382: H2 = #{<<"acl">> => #{<<"hostile">> => [#{<<"user">> => <<"hacker">>}]}}, 1383: ?cfg([{{acl, global}, #{admin => [#{user => <<"george">>, match => current_domain}]}}, 1384: {{acl, ?HOST}, #{admin => [#{user => <<"george">>, match => current_domain}]}}], 1385: maps:merge(G, host_config(G))), 1386: ?cfg([{{acl, global}, #{admin => [#{user => <<"george">>, match => current_domain}]}}, 1387: {{acl, ?HOST}, #{admin => [#{user => <<"george">>, match => current_domain}, 1388: #{user => <<"henry">>, match => current_domain}]}}], 1389: maps:merge(G, host_config(H1))), 1390: ?cfg([{{acl, global}, #{admin => [#{user => <<"george">>, match => current_domain}]}}, 1391: {{acl, ?HOST}, #{admin => [#{user => <<"george">>, match => current_domain}], 1392: hostile => [#{user => <<"hacker">>, match => current_domain}]}}], 1393: maps:merge(G, host_config(H2))). 1394: 1395: access(_Config) -> 1396: ?cfgh([access, c2s], [#{acl => blocked, value => deny}, 1397: #{acl => all, value => allow}], 1398: access_raw(<<"c2s">>, [#{<<"acl">> => <<"blocked">>, <<"value">> => <<"deny">>}, 1399: #{<<"acl">> => <<"all">>, <<"value">> => <<"allow">>}])), 1400: ?cfgh([access, max_user_sessions], [#{acl => all, value => 10}], 1401: access_raw(<<"max_user_sessions">>, [#{<<"acl">> => <<"all">>, <<"value">> => 10}])), 1402: ?errh(access_raw(<<"max_user_sessions">>, [#{<<"acl">> => <<"all">>}])), 1403: ?errh(access_raw(<<"max_user_sessions">>, [#{<<"value">> => 10}])), 1404: ?errh(access_raw(<<"max_user_sessions">>, [#{<<"acl">> => 10, <<"value">> => 10}])). 1405: 1406: access_merge_host_and_global(_Config) -> 1407: G1 = access_raw(<<"c2s">>, [#{<<"acl">> => <<"good">>, <<"value">> => <<"allow">>}]), 1408: G2 = access_raw(<<"c2s">>, [#{<<"acl">> => <<"gangsters">>, <<"value">> => <<"deny">>}, 1409: #{<<"acl">> => <<"all">>, <<"value">> => <<"allow">>}]), 1410: H1 = access_raw(<<"c2s">>, [#{<<"acl">> => <<"harmless">>, <<"value">> => <<"allow">>}]), 1411: H2 = access_raw(<<"s2s">>, [#{<<"acl">> => <<"harmless">>, <<"value">> => <<"allow">>}]), 1412: H3 = access_raw(<<"c2s">>, [#{<<"acl">> => <<"hackers">>, <<"value">> => <<"deny">>}]), 1413: ?cfg([{{access, global}, #{c2s => [#{acl => good, value => allow}]}}, 1414: {{access, ?HOST}, #{c2s => [#{acl => good, value => allow}]}}], 1415: maps:merge(G1, host_config(G1))), 1416: ?cfg([{{access, global}, #{c2s => [#{acl => good, value => allow}]}}, 1417: {{access, ?HOST}, #{c2s => [#{acl => good, value => allow}, 1418: #{acl => harmless, value => allow}]}}], 1419: maps:merge(G1, host_config(H1))), 1420: ?cfg([{{access, global}, #{c2s => [#{acl => good, value => allow}]}}, 1421: {{access, ?HOST}, #{c2s => [#{acl => good, value => allow}], 1422: s2s => [#{acl => harmless, value => allow}]}}], 1423: maps:merge(G1, host_config(H2))), 1424: ?cfg([{{access, global}, #{c2s => [#{acl => gangsters, value => deny}, 1425: #{acl => all, value => allow}]}}, 1426: {{access, ?HOST}, #{c2s => [#{acl => gangsters, value => deny}, 1427: #{acl => hackers, value => deny}, 1428: #{acl => all, value => allow}]}}], 1429: maps:merge(G2, host_config(H3))). 1430: 1431: %% tests: s2s 1432: 1433: s2s_dns_timeout(_Config) -> 1434: ?cfg(s2s_dns_options, [{timeout, 5}], #{<<"s2s">> => #{<<"dns">> => #{<<"timeout">> => 5}}}), 1435: ?err(#{<<"s2s">> => #{<<"dns">> => #{<<"timeout">> => 0}}}). 1436: 1437: s2s_dns_retries(_Config) -> 1438: ?cfg(s2s_dns_options, [{retries, 1}], #{<<"s2s">> => #{<<"dns">> => #{<<"retries">> => 1}}}), 1439: ?err(#{<<"s2s">> => #{<<"dns">> => #{<<"retries">> => 0}}}). 1440: 1441: s2s_outgoing_port(_Config) -> 1442: ?cfg(outgoing_s2s_port, 5270, #{<<"s2s">> => #{<<"outgoing">> => #{<<"port">> => 5270}}}), 1443: ?err(#{<<"s2s">> => #{<<"outgoing">> => #{<<"port">> => <<"http">>}}}). 1444: 1445: s2s_outgoing_ip_versions(_Config) -> 1446: ?cfg(outgoing_s2s_families, [ipv6, ipv4], 1447: #{<<"s2s">> => #{<<"outgoing">> => #{<<"ip_versions">> => [6, 4]}}}), 1448: ?err(#{<<"s2s">> => #{<<"outgoing">> => #{<<"ip_versions">> => []}}}), 1449: ?err(#{<<"s2s">> => #{<<"outgoing">> => #{<<"ip_versions">> => [<<"http">>]}}}). 1450: 1451: s2s_outgoing_timeout(_Config) -> 1452: ?cfg(outgoing_s2s_timeout, 5, 1453: #{<<"s2s">> => #{<<"outgoing">> => #{<<"connection_timeout">> => 5}}}), 1454: ?cfg(outgoing_s2s_timeout, infinity, 1455: #{<<"s2s">> => #{<<"outgoing">> => #{<<"connection_timeout">> => <<"infinity">>}}}), 1456: ?err(#{<<"s2s">> => #{<<"outgoing">> => #{<<"connection_timeout">> => 0}}}). 1457: 1458: s2s_use_starttls(_Config) -> 1459: ?cfg(s2s_use_starttls, required, #{<<"s2s">> => #{<<"use_starttls">> => <<"required">>}}), 1460: ?err(#{<<"s2s">> => #{<<"use_starttls">> => <<"unnecessary">>}}). 1461: 1462: s2s_certfile(_Config) -> 1463: ?cfg(s2s_certfile, "cert.pem", #{<<"s2s">> => #{<<"certfile">> => <<"cert.pem">>}}), 1464: ?err(#{<<"s2s">> => #{<<"certfile">> => []}}). 1465: 1466: s2s_default_policy(_Config) -> 1467: ?cfgh(s2s_default_policy, deny, #{<<"s2s">> => #{<<"default_policy">> => <<"deny">>}}), 1468: ?errh(#{<<"s2s">> => #{<<"default_policy">> => <<"ask">>}}). 1469: 1470: s2s_host_policy(_Config) -> 1471: Policy = #{<<"host">> => <<"host1">>, 1472: <<"policy">> => <<"allow">>}, 1473: ?cfgh(s2s_host_policy, #{<<"host1">> => allow}, 1474: #{<<"s2s">> => #{<<"host_policy">> => [Policy]}}), 1475: ?cfgh(s2s_host_policy, #{<<"host1">> => allow, 1476: <<"host2">> => deny}, 1477: #{<<"s2s">> => #{<<"host_policy">> => [Policy, #{<<"host">> => <<"host2">>, 1478: <<"policy">> => <<"deny">>}]}}), 1479: ?errh(#{<<"s2s">> => #{<<"host_policy">> => [maps:without([<<"host">>], Policy)]}}), 1480: ?errh(#{<<"s2s">> => #{<<"host_policy">> => [maps:without([<<"policy">>], Policy)]}}), 1481: ?errh(#{<<"s2s">> => #{<<"host_policy">> => [Policy#{<<"host">> => <<>>}]}}), 1482: ?errh(#{<<"s2s">> => #{<<"host_policy">> => [Policy#{<<"policy">> => <<"huh">>}]}}), 1483: ?errh(#{<<"s2s">> => #{<<"host_policy">> => [Policy, 1484: Policy#{<<"policy">> => <<"deny">>}]}}). 1485: 1486: s2s_address(_Config) -> 1487: Addr = #{<<"host">> => <<"host1">>, 1488: <<"ip_address">> => <<"192.168.1.2">>, 1489: <<"port">> => 5321}, 1490: ?cfg(s2s_address, #{<<"host1">> => {"192.168.1.2", 5321}}, 1491: #{<<"s2s">> => #{<<"address">> => [Addr]}}), 1492: ?cfg(s2s_address, #{<<"host1">> => "192.168.1.2"}, 1493: #{<<"s2s">> => #{<<"address">> => [maps:without([<<"port">>], Addr)]}}), 1494: ?err(#{<<"s2s">> => #{<<"address">> => [maps:without([<<"host">>], Addr)]}}), 1495: ?err(#{<<"s2s">> => #{<<"address">> => [maps:without([<<"ip_address">>], Addr)]}}), 1496: ?err(#{<<"s2s">> => #{<<"address">> => [Addr#{<<"host">> => <<>>}]}}), 1497: ?err(#{<<"s2s">> => #{<<"address">> => [Addr#{<<"ip_address">> => <<"host2">>}]}}), 1498: ?err(#{<<"s2s">> => #{<<"address">> => [Addr#{<<"port">> => <<"seaport">>}]}}), 1499: ?err(#{<<"s2s">> => #{<<"address">> => [Addr, maps:remove(<<"port">>, Addr)]}}). 1500: 1501: s2s_ciphers(_Config) -> 1502: ?cfg(s2s_ciphers, "TLSv1.2:TLSv1.3", 1503: #{<<"s2s">> => #{<<"ciphers">> => <<"TLSv1.2:TLSv1.3">>}}), 1504: ?err(#{<<"s2s">> => #{<<"ciphers">> => [<<"cipher1">>, <<"cipher2">>]}}). 1505: 1506: s2s_shared(_Config) -> 1507: ?cfgh(s2s_shared, <<"secret">>, #{<<"s2s">> => #{<<"shared">> => <<"secret">>}}), 1508: ?errh(#{<<"s2s">> => #{<<"shared">> => 536837}}). 1509: 1510: s2s_max_retry_delay(_Config) -> 1511: ?cfgh(s2s_max_retry_delay, 120, #{<<"s2s">> => #{<<"max_retry_delay">> => 120}}), 1512: ?errh(#{<<"s2s">> => #{<<"max_retry_delay">> => 0}}). 1513: 1514: %% modules 1515: 1516: mod_adhoc(_Config) -> 1517: check_iqdisc(mod_adhoc), 1518: M = fun(K, V) -> modopts(mod_adhoc, [{K, V}]) end, 1519: T = fun(K, V) -> #{<<"modules">> => #{<<"mod_adhoc">> => #{K => V}}} end, 1520: %% report_commands_node is boolean 1521: ?cfgh(M(report_commands_node, true), T(<<"report_commands_node">>, true)), 1522: ?cfgh(M(report_commands_node, false), T(<<"report_commands_node">>, false)), 1523: %% not boolean 1524: ?errh(T(<<"report_commands_node">>, <<"hello">>)). 1525: 1526: mod_auth_token(_Config) -> 1527: check_iqdisc(mod_auth_token), 1528: P = fun(X) -> 1529: Opts = #{<<"validity_period">> => X}, 1530: #{<<"modules">> => #{<<"mod_auth_token">> => Opts}} 1531: end, 1532: ?cfgh(modopts(mod_auth_token, [{{validity_period, access}, {13, minutes}}, 1533: {{validity_period, refresh}, {31, days}}]), 1534: P([#{<<"token">> => <<"access">>, <<"value">> => 13, <<"unit">> => <<"minutes">>}, 1535: #{<<"token">> => <<"refresh">>, <<"value">> => 31, <<"unit">> => <<"days">>}])), 1536: ?errh(P([#{<<"token">> => <<"access">>, <<"value">> => <<"13">>, 1537: <<"unit">> => <<"minutes">>}])), 1538: ?errh(P([#{<<"token">> => <<"access">>, <<"value">> => 13, <<"unit">> => <<"minute">>}])), 1539: ?errh(P([#{<<"token">> => <<"Access">>, <<"value">> => 13, <<"unit">> => <<"minutes">>}])), 1540: ?errh(P([#{<<"value">> => 13, <<"unit">> => <<"minutes">>}])), 1541: ?errh(P([#{<<"token">> => <<"access">>, <<"unit">> => <<"minutes">>}])), 1542: ?errh(P([#{<<"token">> => <<"access">>, <<"value">> => 13}])). 1543: 1544: mod_bosh(_Config) -> 1545: T = fun(K, V) -> #{<<"modules">> => #{<<"mod_bosh">> => #{K => V}}} end, 1546: M = fun(K, V) -> modopts(mod_bosh, [{K, V}]) end, 1547: ?cfgh(M(inactivity, 10), T(<<"inactivity">>, 10)), 1548: ?cfgh(M(inactivity, infinity), T(<<"inactivity">>, <<"infinity">>)), 1549: ?cfgh(M(inactivity, 10), T(<<"inactivity">>, 10)), 1550: ?cfgh(M(max_wait, infinity), T(<<"max_wait">>, <<"infinity">>)), 1551: ?cfgh(M(server_acks, true), T(<<"server_acks">>, true)), 1552: ?cfgh(M(server_acks, false), T(<<"server_acks">>, false)), 1553: ?cfgh(M(maxpause, 10), T(<<"max_pause">>, 10)), 1554: ?errh(T(<<"inactivity">>, -1)), 1555: ?errh(T(<<"inactivity">>, <<"10">>)), 1556: ?errh(T(<<"inactivity">>, <<"inactivity">>)), 1557: ?errh(T(<<"max_wait">>, <<"10">>)), 1558: ?errh(T(<<"max_wait">>, -1)), 1559: ?errh(T(<<"server_acks">>, -1)), 1560: ?errh(T(<<"maxpause">>, 0)). 1561: 1562: mod_caps(_Config) -> 1563: T = fun(K, V) -> #{<<"modules">> => #{<<"mod_caps">> => #{K => V}}} end, 1564: M = fun(K, V) -> modopts(mod_caps, [{K, V}]) end, 1565: ?cfgh(M(cache_size, 10), T(<<"cache_size">>, 10)), 1566: ?cfgh(M(cache_life_time, 10), T(<<"cache_life_time">>, 10)), 1567: ?errh(T(<<"cache_size">>, 0)), 1568: ?errh(T(<<"cache_size">>, <<"infinity">>)), 1569: ?errh(T(<<"cache_life_time">>, 0)), 1570: ?errh(T(<<"cache_life_time">>, <<"infinity">>)). 1571: 1572: mod_cache_users(_Config) -> 1573: T = fun(K, V) -> #{<<"modules">> => #{<<"mod_cache_users">> => #{K => V}}} end, 1574: M = fun(K, V) -> modopts(mod_cache_users, [{K, V}]) end, 1575: ?cfgh(M(time_to_live, 8600), T(<<"time_to_live">>, 8600)), 1576: ?cfgh(M(time_to_live, infinity), T(<<"time_to_live">>, <<"infinity">>)), 1577: ?cfgh(M(number_of_segments, 10), T(<<"number_of_segments">>, 10)), 1578: ?cfgh(M(strategy, fifo), T(<<"strategy">>, <<"fifo">>)), 1579: ?errh(T(<<"time_to_live">>, 0)), 1580: ?errh(T(<<"strategy">>, <<"lifo">>)), 1581: ?errh(T(<<"number_of_segments">>, 0)), 1582: ?errh(T(<<"number_of_segments">>, <<"infinity">>)). 1583: 1584: mod_carboncopy(_Config) -> 1585: check_iqdisc(mod_carboncopy). 1586: 1587: mod_csi(_Config) -> 1588: T = fun(K, V) -> #{<<"modules">> => #{<<"mod_csi">> => #{K => V}}} end, 1589: M = fun(K, V) -> modopts(mod_csi, [{K, V}]) end, 1590: ?cfgh(M(buffer_max, 10), T(<<"buffer_max">>, 10)), 1591: ?cfgh(M(buffer_max, infinity), T(<<"buffer_max">>, <<"infinity">>)), 1592: ?errh(T(<<"buffer_max">>, -1)). 1593: 1594: mod_disco(_Config) -> 1595: check_iqdisc(mod_disco), 1596: T = fun(K, V) -> #{<<"modules">> => #{<<"mod_disco">> => #{K => V}}} end, 1597: ?cfgh(modopts(mod_disco, [{users_can_see_hidden_services, true}]), 1598: T(<<"users_can_see_hidden_services">>, true)), 1599: ?cfgh(modopts(mod_disco, [{users_can_see_hidden_services, false}]), 1600: T(<<"users_can_see_hidden_services">>, false)), 1601: %% extra_domains are binaries 1602: ?cfgh(modopts(mod_disco, [{extra_domains, [<<"localhost">>, <<"erlang-solutions.com">>]}]), 1603: T(<<"extra_domains">>, [<<"localhost">>, <<"erlang-solutions.com">>])), 1604: ?cfgh(modopts(mod_disco, [{extra_domains, []}]), 1605: T(<<"extra_domains">>, [])), 1606: Info = #{<<"name">> => <<"abuse-address">>, 1607: <<"urls">> => [<<"admin@example.com">>]}, 1608: SpiritUrls = [<<"spirit1@localhost">>, <<"spirit2@localhost">>], 1609: ?cfgh(modopts(mod_disco, [{server_info, [[{name, <<"abuse-address">>}, 1610: {urls, [<<"admin@example.com">>]}], 1611: [{modules, [mod_muc, mod_disco]}, 1612: {name, <<"friendly-spirits">>}, 1613: {urls, SpiritUrls}] 1614: ]} 1615: ]), 1616: T(<<"server_info">>, [Info, #{<<"modules">> => [<<"mod_muc">>, <<"mod_disco">>], 1617: <<"name">> => <<"friendly-spirits">>, 1618: <<"urls">> => SpiritUrls} 1619: ])), 1620: ?errh(T(<<"users_can_see_hidden_services">>, 1)), 1621: ?errh(T(<<"users_can_see_hidden_services">>, <<"true">>)), 1622: ?errh(T(<<"extra_domains">>, [<<"user@localhost">>])), 1623: ?errh(T(<<"extra_domains">>, [1])), 1624: ?errh(T(<<"extra_domains">>, <<"domains domains domains">>)), 1625: ?errh(T(<<"server_info">>, [Info#{<<"name">> => 1}])), 1626: ?errh(T(<<"server_info">>, [Info#{<<"name">> => <<"">>}])), 1627: ?errh(T(<<"server_info">>, [Info#{<<"modules">> => <<"roll">>}])), 1628: ?errh(T(<<"server_info">>, [Info#{<<"modules">> => [<<"meow_meow_meow">>]}])), 1629: ?errh(T(<<"server_info">>, [Info#{<<"urls">> => [1]}])), 1630: ?errh(T(<<"server_info">>, [Info#{<<"urls">> => [<<"">>]}])), 1631: ?errh(T(<<"server_info">>, [maps:remove(<<"name">>, Info)])), 1632: ?errh(T(<<"server_info">>, [maps:remove(<<"urls">>, Info)])). 1633: 1634: mod_extdisco(_Config) -> 1635: T = fun(Opts) -> #{<<"modules">> => 1636: #{<<"mod_extdisco">> => 1637: #{<<"service">> => [Opts]}}} 1638: end, 1639: M = fun(Opts) -> modopts(mod_extdisco, [Opts]) end, 1640: RequiredOpts = #{ 1641: <<"type">> => <<"stun">>, 1642: <<"host">> => <<"stun1">>}, 1643: ExpectedCfg = [{host, "stun1"}, 1644: {type, stun}], 1645: ?cfgh(M(ExpectedCfg), T(RequiredOpts)), 1646: ?cfgh(M(ExpectedCfg ++ [{port, 3478}]), 1647: T(RequiredOpts#{<<"port">> => 3478})), 1648: ?cfgh(M(ExpectedCfg ++ [{transport, "udp"}]), 1649: T(RequiredOpts#{<<"transport">> => <<"udp">>})), 1650: ?cfgh(M(ExpectedCfg ++ [{username, "username"}]), 1651: T(RequiredOpts#{<<"username">> => <<"username">>})), 1652: ?cfgh(M(ExpectedCfg ++ [{password, "password"}]), 1653: T(RequiredOpts#{<<"password">> => <<"password">>})), 1654: [?errh(T(maps:remove(Key, RequiredOpts))) || Key <- maps:keys(RequiredOpts)], 1655: [?errh(T(RequiredOpts#{Key => 1})) || Key <- maps:keys(RequiredOpts)], 1656: ?errh(T(RequiredOpts#{<<"type">> => <<"">>})), 1657: ?errh(T(RequiredOpts#{<<"host">> => <<"">>})), 1658: ?errh(T(RequiredOpts#{<<"port">> => -1})), 1659: ?errh(T(RequiredOpts#{<<"transport">> => <<"">>})), 1660: ?errh(T(RequiredOpts#{<<"username">> => <<"">>})), 1661: ?errh(T(RequiredOpts#{<<"password">> => <<"">>})). 1662: 1663: mod_inbox(_Config) -> 1664: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_inbox">> => Opts}} end, 1665: M = fun(Opts) -> modopts(mod_inbox, Opts) end, 1666: ChatMarkers = [<<"displayed">>, <<"received">>, <<"acknowledged">>], 1667: ?cfgh(M([{reset_markers, ChatMarkers}]), 1668: T(#{<<"reset_markers">> => ChatMarkers})), 1669: ?cfgh(M([{groupchat, [muc, muclight]}]), 1670: T(#{<<"groupchat">> => [<<"muc">>, <<"muclight">>]})), 1671: ?cfgh(M([{aff_changes, true}]), 1672: T(#{<<"aff_changes">> => true})), 1673: ?cfgh(M([{remove_on_kicked, false}]), 1674: T(#{<<"remove_on_kicked">> => false})), 1675: ?errh(T(#{<<"reset_markers">> => 1})), 1676: ?errh(T(#{<<"reset_markers">> => [<<"destroyed">>]})), 1677: ?errh(T(#{<<"groupchat">> => [<<"test">>]})), 1678: ?errh(T(#{<<"aff_changes">> => 1})), 1679: ?errh(T(#{<<"remove_on_kicked">> => 1})), 1680: check_iqdisc(mod_inbox). 1681: 1682: mod_global_distrib(_Config) -> 1683: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_global_distrib">> => Opts}} end, 1684: M = fun(Cfg) -> modopts(mod_global_distrib, Cfg) end, 1685: RequiredOpts = global_distrib_required_opts(), 1686: ExpectedCfg = global_distrib_expected_config(), 1687: ?cfgh(M(ExpectedCfg), T(RequiredOpts)), 1688: ?cfgh(M(ExpectedCfg ++ [{message_ttl, 42}]), 1689: T(RequiredOpts#{<<"message_ttl">> => 42})), 1690: ?cfgh(M(ExpectedCfg ++ [{hosts_refresh_interval, 100}]), 1691: T(RequiredOpts#{<<"hosts_refresh_interval">> => 100})), 1692: [?errh(T(maps:remove(Key, RequiredOpts))) || Key <- maps:keys(RequiredOpts)], 1693: ?errh(T(RequiredOpts#{<<"global_host">> => <<"">>})), 1694: ?errh(T(RequiredOpts#{<<"local_host">> => <<"">>})), 1695: ?errh(T(RequiredOpts#{<<"message_ttl">> => -1})), 1696: ?errh(T(RequiredOpts#{<<"hosts_refresh_interval">> => -1})). 1697: 1698: mod_global_distrib_connections(_Config) -> 1699: RequiredOpts = global_distrib_required_opts(), 1700: T = fun(Opts) -> #{<<"modules">> => 1701: #{<<"mod_global_distrib">> => 1702: RequiredOpts#{<<"connections">> => Opts}}} 1703: end, 1704: M = fun(Cfg) -> modopts(mod_global_distrib, 1705: global_distrib_expected_config() ++ [{connections, Cfg}]) 1706: end, 1707: ?cfgh(M([]), T(#{})), 1708: ?cfgh(M([{connections_per_endpoint, 22}]), 1709: T(#{<<"connections_per_endpoint">> => 22})), 1710: ?cfgh(M([{endpoint_refresh_interval, 120}]), 1711: T(#{<<"endpoint_refresh_interval">> => 120})), 1712: ?cfgh(M([{endpoint_refresh_interval_when_empty, 5}]), 1713: T(#{<<"endpoint_refresh_interval_when_empty">> => 5})), 1714: ?cfgh(M([{disabled_gc_interval, 60}]), 1715: T(#{<<"disabled_gc_interval">> => 60})), 1716: ?errh(T(#{<<"connections_per_endpoint">> => -1})), 1717: ?errh(T(#{<<"endpoint_refresh_interval">> => 0})), 1718: ?errh(T(#{<<"endpoint_refresh_interval_when_empty">> => 0})), 1719: ?errh(T(#{<<"disabled_gc_interval">> => 0})). 1720: 1721: mod_global_distrib_connections_endpoints(_Config) -> 1722: check_mod_global_distrib_endpoints(<<"endpoints">>). 1723: 1724: mod_global_distrib_connections_advertised_endpoints(_Config) -> 1725: check_mod_global_distrib_endpoints(<<"advertised_endpoints">>). 1726: 1727: check_mod_global_distrib_endpoints(OptKey) -> 1728: CfgKey = binary_to_atom(OptKey, utf8), 1729: RequiredModOpts = global_distrib_required_opts(), 1730: T = fun(Opts) -> #{<<"modules">> => 1731: #{<<"mod_global_distrib">> => 1732: RequiredModOpts#{<<"connections">> => #{OptKey => Opts}}}} 1733: end, 1734: M = fun(Cfg) -> modopts(mod_global_distrib, 1735: global_distrib_expected_config() ++ 1736: [{connections, [{CfgKey, Cfg}]}]) 1737: end, 1738: RequiredOpts = #{<<"host">> => <<"172.16.0.2">>, 1739: <<"port">> => 5555}, 1740: ?cfgh(M([{"172.16.0.2", 5555}]), T([RequiredOpts])), 1741: [?errh(T(maps:remove(Key, RequiredOpts))) || Key <- maps:keys(RequiredOpts)], 1742: ?errh(T([RequiredOpts#{<<"host">> => <<>>}])), 1743: ?errh(T([RequiredOpts#{<<"port">> => -1}])). 1744: 1745: mod_global_distrib_connections_tls(_Config) -> 1746: RequiredModOpts = global_distrib_required_opts(), 1747: T = fun(Opts) -> #{<<"modules">> => 1748: #{<<"mod_global_distrib">> => 1749: RequiredModOpts#{<<"connections">> => #{<<"tls">> => Opts}}}} 1750: end, 1751: M = fun(Cfg) -> modopts(mod_global_distrib, 1752: global_distrib_expected_config() ++ 1753: [{connections, [{tls_opts, Cfg}]}]) 1754: end, 1755: RequiredOpts = #{<<"certfile">> => <<"priv/cert.pem">>, 1756: <<"cacertfile">> => <<"priv/ca.pem">>}, 1757: ExpectedCfg = [{certfile, "priv/cert.pem"}, 1758: {cafile, "priv/ca.pem"}], 1759: ?cfgh(M(ExpectedCfg), T(RequiredOpts)), 1760: ?cfgh(M(ExpectedCfg ++ [{ciphers, "TLS_AES_256_GCM_SHA384"}]), 1761: T(RequiredOpts#{<<"ciphers">> => <<"TLS_AES_256_GCM_SHA384">>})), 1762: ?cfgh(M(ExpectedCfg ++ [{dhfile, "priv/cert.pem"}]), 1763: T(RequiredOpts#{<<"dhfile">> => <<"priv/cert.pem">>})), 1764: [?errh(T(maps:remove(Key, RequiredOpts))) || Key <- maps:keys(RequiredOpts)], 1765: ?errh(T(RequiredOpts#{<<"certfile">> => <<"/this/does/not/exist">>})), 1766: ?errh(T(RequiredOpts#{<<"cacertfile">> => <<"/this/does/not/exist">>})), 1767: ?errh(T(RequiredOpts#{<<"dhfile">> => <<"/this/does/not/exist">>})), 1768: ?errh(T(RequiredOpts#{<<"ciphers">> => 42})). 1769: 1770: mod_global_distrib_redis(_Config) -> 1771: RequiredModOpts = global_distrib_required_opts(), 1772: T = fun(Opts) -> #{<<"modules">> => 1773: #{<<"mod_global_distrib">> => 1774: RequiredModOpts#{<<"redis">> => Opts}}} 1775: end, 1776: M = fun(Cfg) -> modopts(mod_global_distrib, 1777: global_distrib_expected_config() ++ [{redis, Cfg}]) 1778: end, 1779: ?cfgh(M([]), T(#{})), 1780: ?cfgh(M([{pool, global_distrib}]), 1781: T(#{<<"pool">> => <<"global_distrib">>})), 1782: ?cfgh(M([{expire_after, 120}]), 1783: T(#{<<"expire_after">> => 120})), 1784: ?cfgh(M([{refresh_after, 60}]), 1785: T(#{<<"refresh_after">> => 60})), 1786: ?errh(T(#{<<"pool">> => <<"">>})), 1787: ?errh(T(#{<<"expire_after">> => 0})), 1788: ?errh(T(#{<<"refresh_after">> => -1})). 1789: 1790: mod_global_distrib_cache(_Config) -> 1791: RequiredModOpts = global_distrib_required_opts(), 1792: T = fun(Opts) -> #{<<"modules">> => 1793: #{<<"mod_global_distrib">> => 1794: RequiredModOpts#{<<"cache">> => Opts}}} 1795: end, 1796: M = fun(Cfg) -> modopts(mod_global_distrib, 1797: global_distrib_expected_config() ++ [{cache, Cfg}]) 1798: end, 1799: ?cfgh(M([]), T(#{})), 1800: ?cfgh(M([{cache_missed, false}]), 1801: T(#{<<"cache_missed">> => false})), 1802: ?cfgh(M([{domain_lifetime_seconds, 60}]), 1803: T(#{<<"domain_lifetime_seconds">> => 60})), 1804: ?cfgh(M([{jid_lifetime_seconds, 30}]), 1805: T(#{<<"jid_lifetime_seconds">> => 30})), 1806: ?cfgh(M([{max_jids, 9999}]), 1807: T(#{<<"max_jids">> => 9999})), 1808: ?errh(T(#{<<"cache_missed">> => <<"yes">>})), 1809: ?errh(T(#{<<"domain_lifetime_seconds">> => -1})), 1810: ?errh(T(#{<<"jid_lifetime_seconds">> => -1})), 1811: ?errh(T(#{<<"max_jids">> => -1})). 1812: 1813: mod_global_distrib_bounce(_Config) -> 1814: RequiredModOpts = global_distrib_required_opts(), 1815: T = fun(Opts) -> #{<<"modules">> => 1816: #{<<"mod_global_distrib">> => 1817: RequiredModOpts#{<<"bounce">> => Opts}}} 1818: end, 1819: M = fun(Cfg) -> modopts(mod_global_distrib, 1820: global_distrib_expected_config() ++ [{bounce, Cfg}]) 1821: end, 1822: ?cfgh(M(false), 1823: T(#{<<"enabled">> => false})), 1824: ?cfgh(M([]), 1825: T(#{<<"enabled">> => true})), 1826: ?cfgh(M([{resend_after_ms, 300}]), 1827: T(#{<<"resend_after_ms">> => 300})), 1828: ?cfgh(M([{max_retries, 3}]), 1829: T(#{<<"max_retries">> => 3})), 1830: ?errh(T(#{<<"enabled">> => <<"">>})), 1831: ?errh(T(#{<<"resend_after_ms">> => -1})), 1832: ?errh(T(#{<<"max_retries">> => -1})). 1833: 1834: global_distrib_required_opts() -> 1835: #{<<"global_host">> => <<"example.com">>, 1836: <<"local_host">> => <<"datacenter1.example.com">>}. 1837: 1838: global_distrib_expected_config() -> 1839: [{global_host, "example.com"}, 1840: {local_host, "datacenter1.example.com"}]. 1841: 1842: mod_event_pusher_sns(_Config) -> 1843: RequiredOpts = #{<<"access_key_id">> => <<"AKIAIOSFODNN7EXAMPLE">>, 1844: <<"secret_access_key">> => <<"KEY">>, 1845: <<"region">> => <<"eu-west-1">>, 1846: <<"account_id">> => <<"123456789012">>, 1847: <<"sns_host">> => <<"sns.eu-west-1.amazonaws.com">>}, 1848: ExpectedCfg = [{access_key_id, "AKIAIOSFODNN7EXAMPLE"}, 1849: {secret_access_key, "KEY"}, 1850: {region, "eu-west-1"}, 1851: {account_id, "123456789012"}, 1852: {sns_host, "sns.eu-west-1.amazonaws.com"}], 1853: T = fun(Opts) -> #{<<"modules">> => 1854: #{<<"mod_event_pusher">> => 1855: #{<<"backend">> => #{<<"sns">> => Opts}}}} 1856: end, 1857: M = fun(Cfg) -> modopts(mod_event_pusher, [{backends, [{sns, Cfg}]}]) end, 1858: ?cfgh(M(ExpectedCfg), 1859: T(RequiredOpts)), 1860: ?cfgh(M(ExpectedCfg ++ [{presence_updates_topic, "pres"}]), 1861: T(RequiredOpts#{<<"presence_updates_topic">> => <<"pres">>})), 1862: ?cfgh(M(ExpectedCfg ++ [{pm_messages_topic, "pm"}]), 1863: T(RequiredOpts#{<<"pm_messages_topic">> => <<"pm">>})), 1864: ?cfgh(M(ExpectedCfg ++ [{muc_messages_topic, "muc"}]), 1865: T(RequiredOpts#{<<"muc_messages_topic">> => <<"muc">>})), 1866: ?cfgh(M(ExpectedCfg ++ [{plugin_module, mod_event_pusher_sns_defaults}]), 1867: T(RequiredOpts#{<<"plugin_module">> => <<"mod_event_pusher_sns_defaults">>})), 1868: ?cfgh(M(ExpectedCfg ++ [{pool_size, 10}]), 1869: T(RequiredOpts#{<<"pool_size">> => 10})), 1870: ?cfgh(M(ExpectedCfg ++ [{publish_retry_count, 1}]), 1871: T(RequiredOpts#{<<"publish_retry_count">> => 1})), 1872: ?cfgh(M(ExpectedCfg ++ [{publish_retry_time_ms, 100}]), 1873: T(RequiredOpts#{<<"publish_retry_time_ms">> => 100})), 1874: [?errh(T(maps:remove(Key, RequiredOpts))) || Key <- maps:keys(RequiredOpts)], 1875: [?errh(T(RequiredOpts#{Key => 1})) || Key <- maps:keys(RequiredOpts)], 1876: ?errh(T(RequiredOpts#{<<"presence_updates_topic">> => #{}})), 1877: ?errh(T(RequiredOpts#{<<"pm_messages_topic">> => true})), 1878: ?errh(T(RequiredOpts#{<<"muc_messages_topic">> => [1, 2]})), 1879: ?errh(T(RequiredOpts#{<<"plugin_module">> => <<"plug_and_play">>})), 1880: ?errh(T(RequiredOpts#{<<"pool_size">> => 0})), 1881: ?errh(T(RequiredOpts#{<<"publish_retry_count">> => -1})), 1882: ?errh(T(RequiredOpts#{<<"publish_retry_time_ms">> => -1})). 1883: 1884: mod_event_pusher_push(_Config) -> 1885: T = fun(Opts) -> #{<<"modules">> => 1886: #{<<"mod_event_pusher">> => 1887: #{<<"backend">> => #{<<"push">> => Opts}}}} 1888: end, 1889: M = fun(Cfg) -> modopts(mod_event_pusher, [{backends, [{push, Cfg}]}]) end, 1890: ?cfgh(M([{backend, rdbms}]), 1891: T(#{<<"backend">> => <<"rdbms">>})), 1892: ?cfgh(M([{wpool, [{workers, 200}]}]), 1893: T(#{<<"wpool">> => #{<<"workers">> => 200}})), 1894: ?cfgh(M([{plugin_module, mod_event_pusher_push_plugin_defaults}]), 1895: T(#{<<"plugin_module">> => <<"mod_event_pusher_push_plugin_defaults">>})), 1896: ?cfgh(M([{virtual_pubsub_hosts, [{fqdn, <<"host1">>}, {fqdn, <<"host2">>}]}]), 1897: T(#{<<"virtual_pubsub_hosts">> => [<<"host1">>, <<"host2">>]})), 1898: ?cfgh(M([{virtual_pubsub_hosts, [{prefix, <<"pubsub.">>}, {prefix, <<"pub-sub.">>}]}]), 1899: T(#{<<"virtual_pubsub_hosts">> => [<<"pubsub.@HOST@">>, <<"pub-sub.@HOST@">>]})), 1900: ?errh(T(#{<<"backend">> => <<"redis">>})), 1901: ?errh(T(#{<<"wpool">> => true})), 1902: ?errh(T(#{<<"wpool">> => #{<<"workers">> => <<"500">>}})), 1903: ?errh(T(#{<<"plugin_module">> => <<"wow_cool_but_missing">>})), 1904: ?errh(T(#{<<"plugin_module">> => 1})), 1905: ?errh(T(#{<<"virtual_pubsub_hosts">> => [<<"host with whitespace">>]})), 1906: ?errh(T(#{<<"virtual_pubsub_hosts">> => [<<"invalid.sub@HOST@">>]})), 1907: ?errh(T(#{<<"virtual_pubsub_hosts">> => [<<"invalid.sub.@HOST@.as.well">>]})). 1908: 1909: mod_event_pusher_http(_Config) -> 1910: T = fun(Opts) -> #{<<"modules">> => 1911: #{<<"mod_event_pusher">> => 1912: #{<<"backend">> => #{<<"http">> => Opts}}}} 1913: end, 1914: M = fun(Cfg) -> modopts(mod_event_pusher, [{backends, [{http, Cfg}]}]) end, 1915: ?cfgh(M([{pool_name, http_pool}]), 1916: T(#{<<"pool_name">> => <<"http_pool">>})), 1917: ?cfgh(M([{path, "/notifications"}]), 1918: T(#{<<"path">> => <<"/notifications">>})), 1919: ?cfgh(M([{callback_module, mod_event_pusher_http_defaults}]), 1920: T(#{<<"callback_module">> => <<"mod_event_pusher_http_defaults">>})), 1921: ?errh(T(#{<<"pool_name">> => <<>>})), 1922: ?errh(T(#{<<"path">> => true})), 1923: ?errh(T(#{<<"callback_module">> => <<"wow_cool_but_missing">>})), 1924: ?errh(T(#{<<"callback_module">> => 1})). 1925: 1926: mod_event_pusher_rabbit(_Config) -> 1927: T = fun(Opts) -> #{<<"modules">> => 1928: #{<<"mod_event_pusher">> => 1929: #{<<"backend">> => #{<<"rabbit">> => Opts}}}} 1930: end, 1931: M = fun(Cfg) -> modopts(mod_event_pusher, [{backends, [{rabbit, Cfg}]}]) end, 1932: ?cfgh(M([{presence_exchange, [{name, <<"pres">>}]}]), 1933: T(#{<<"presence_exchange">> => #{<<"name">> => <<"pres">>}})), 1934: ?cfgh(M([{presence_exchange, [{type, <<"topic">>}]}]), 1935: T(#{<<"presence_exchange">> => #{<<"type">> => <<"topic">>}})), 1936: 1937: %% first two keys are the same as before, test them together 1938: ?cfgh(M([{chat_msg_exchange, [{name, <<"pres1">>}, 1939: {type, <<"topic1">>}]}]), 1940: T(#{<<"chat_msg_exchange">> => #{<<"name">> => <<"pres1">>, 1941: <<"type">> => <<"topic1">>}})), 1942: ?cfgh(M([{chat_msg_exchange, [{sent_topic, <<"sent_topic1">>}]}]), 1943: T(#{<<"chat_msg_exchange">> => #{<<"sent_topic">> => <<"sent_topic1">>}})), 1944: ?cfgh(M([{chat_msg_exchange, [{recv_topic, <<"recv_topic1">>}]}]), 1945: T(#{<<"chat_msg_exchange">> => #{<<"recv_topic">> => <<"recv_topic1">>}})), 1946: 1947: %% all keys are the same as before, test them together 1948: ?cfgh(M([{groupchat_msg_exchange, [{name, <<"pres2">>}, 1949: {type, <<"topic2">>}, 1950: {sent_topic, <<"sent_topic2">>}, 1951: {recv_topic, <<"recv_topic2">>}]}]), 1952: T(#{<<"groupchat_msg_exchange">> => #{<<"name">> => <<"pres2">>, 1953: <<"type">> => <<"topic2">>, 1954: <<"sent_topic">> => <<"sent_topic2">>, 1955: <<"recv_topic">> => <<"recv_topic2">>}})), 1956: 1957: Exchanges = [<<"presence_exchange">>, <<"chat_msg_exchange">>, <<"groupchat_msg_exchange">>], 1958: Keys = [<<"name">>, <<"topic">>, <<"sent_topic">>, <<"recv_topic">>], 1959: [?errh(T(#{Exch => #{Key => <<>>}})) || Exch <- Exchanges, Key <- Keys], 1960: [?errh(T(#{Exch => #{<<"badkey">> => <<"goodvalue">>}})) || Exch <- Exchanges], 1961: ?errh(T(#{<<"money_exchange">> => #{<<"name">> => <<"kantor">>}})). 1962: 1963: mod_http_upload(_Config) -> 1964: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_http_upload">> => Opts}} end, 1965: M = fun(Cfg) -> modopts(mod_http_upload, Cfg) end, 1966: RequiredOpts = #{<<"s3">> => http_upload_s3_required_opts()}, 1967: ExpectedCfg = [{s3, http_upload_s3_expected_cfg()}], 1968: ?cfgh(M(ExpectedCfg), T(RequiredOpts)), 1969: ?cfgh(M(ExpectedCfg ++ [{host, {prefix, <<"upload.">>}}]), 1970: T(RequiredOpts#{<<"host">> => <<"upload.@HOST@">>})), 1971: ?cfgh(M(ExpectedCfg ++ [{host, {fqdn, <<"upload.test">>}}]), 1972: T(RequiredOpts#{<<"host">> => <<"upload.test">>})), 1973: ?cfgh(M(ExpectedCfg ++ [{backend, s3}]), 1974: T(RequiredOpts#{<<"backend">> => <<"s3">>})), 1975: ?cfgh(M(ExpectedCfg ++ [{expiration_time, 666}]), 1976: T(RequiredOpts#{<<"expiration_time">> => 666})), 1977: ?cfgh(M(ExpectedCfg ++ [{token_bytes, 32}]), 1978: T(RequiredOpts#{<<"token_bytes">> => 32})), 1979: ?cfgh(M(ExpectedCfg ++ [{max_file_size, 42}]), 1980: T(RequiredOpts#{<<"max_file_size">> => 42})), 1981: ?errh(T(#{})), %% missing 's3' 1982: ?errh(T(RequiredOpts#{<<"backend">> => <<"">>})), 1983: ?errh(T(RequiredOpts#{<<"expiration_time">> => 0})), 1984: ?errh(T(RequiredOpts#{<<"token_bytes">> => 0})), 1985: ?errh(T(RequiredOpts#{<<"max_file_size">> => 0})), 1986: ?errh(T(RequiredOpts#{<<"host">> => <<"is this a host? no.">>})), 1987: ?errh(T(RequiredOpts#{<<"host">> => [<<"invalid.sub@HOST@">>]})), 1988: ?errh(T(RequiredOpts#{<<"host">> => [<<"invalid.sub.@HOST@.as.well">>]})), 1989: ?errh(T(RequiredOpts#{<<"host">> => [<<"not.supported.any.more.@HOSTS@">>]})), 1990: check_iqdisc(mod_http_upload, ExpectedCfg, RequiredOpts). 1991: 1992: mod_http_upload_s3(_Config) -> 1993: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_http_upload">> => 1994: #{<<"s3">> => Opts}}} end, 1995: M = fun(Cfg) -> modopts(mod_http_upload, [{s3, Cfg}]) end, 1996: RequiredOpts = http_upload_s3_required_opts(), 1997: ExpectedCfg = http_upload_s3_expected_cfg(), 1998: ?cfgh(M(ExpectedCfg), T(RequiredOpts)), 1999: ?cfgh(M(ExpectedCfg ++ [{add_acl, true}]), 2000: T(RequiredOpts#{<<"add_acl">> => true})), 2001: [?errh(T(maps:remove(Key, RequiredOpts))) || Key <- maps:keys(RequiredOpts)], 2002: ?errh(T(RequiredOpts#{<<"bucket_url">> => <<>>})), 2003: ?errh(T(RequiredOpts#{<<"region">> => true})), 2004: ?errh(T(RequiredOpts#{<<"access_key_id">> => []})), 2005: ?errh(T(RequiredOpts#{<<"secret_access_key">> => 3})), 2006: ?errh(T(RequiredOpts#{<<"add_acl">> => <<"true">>})). 2007: 2008: http_upload_s3_required_opts() -> 2009: #{<<"bucket_url">> => <<"https://s3-eu-west-1.amazonaws.com/mybucket">>, 2010: <<"region">> => <<"antarctica-1">>, 2011: <<"access_key_id">> => <<"PLEASE">>, 2012: <<"secret_access_key">> => <<"ILOVEU">>}. 2013: 2014: http_upload_s3_expected_cfg() -> 2015: [{access_key_id, "PLEASE"}, 2016: {bucket_url, "https://s3-eu-west-1.amazonaws.com/mybucket"}, 2017: {region, "antarctica-1"}, 2018: {secret_access_key, "ILOVEU"}]. 2019: 2020: mod_jingle_sip(_Config) -> 2021: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_jingle_sip">> => Opts}} end, 2022: M = fun(Cfg) -> modopts(mod_jingle_sip, Cfg) end, 2023: ?cfgh(M([{proxy_host, "proxxxy"}]), 2024: T(#{<<"proxy_host">> => <<"proxxxy">>})), 2025: ?cfgh(M([{proxy_port, 5601}]), 2026: T(#{<<"proxy_port">> => 5601})), 2027: ?cfgh(M([{listen_port, 5602}]), 2028: T(#{<<"listen_port">> => 5602})), 2029: ?cfgh(M([{local_host, "localhost"}]), 2030: T(#{<<"local_host">> => <<"localhost">>})), 2031: ?cfgh(M([{sdp_origin, "127.0.0.1"}]), 2032: T(#{<<"sdp_origin">> => <<"127.0.0.1">>})), 2033: ?errh(T(#{<<"proxy_host">> => 1})), 2034: ?errh(T(#{<<"proxy_port">> => 1000000})), 2035: ?errh(T(#{<<"listen_port">> => -1})), 2036: ?errh(T(#{<<"local_host">> => <<>>})), 2037: ?errh(T(#{<<"sdp_origin">> => <<"abc">>})). 2038: 2039: mod_keystore(_Config) -> 2040: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_keystore">> => Opts}} end, 2041: M = fun(Cfg) -> modopts(mod_keystore, Cfg) end, 2042: ?cfgh(M([{ram_key_size, 1024}]), 2043: T(#{<<"ram_key_size">> => 1024})), 2044: ?errh(T(#{<<"ram_key_size">> => -1})). 2045: 2046: mod_keystore_keys(_Config) -> 2047: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_keystore">> => 2048: #{<<"keys">> => Opts}}} 2049: end, 2050: M = fun(Cfg) -> modopts(mod_keystore, [{keys, Cfg}]) end, 2051: RequiredOpts = #{<<"name">> => <<"access_secret">>, 2052: <<"type">> => <<"ram">>}, 2053: ?cfgh(M([{access_secret, ram}]), 2054: T([RequiredOpts])), 2055: ?cfgh(M([{access_secret, {file, "priv/access_psk"}}]), 2056: T([RequiredOpts#{<<"type">> => <<"file">>, 2057: <<"path">> => <<"priv/access_psk">>}])), 2058: [?errh(T([maps:remove(Key, RequiredOpts)])) || Key <- maps:keys(RequiredOpts)], 2059: ?errh(T([RequiredOpts#{<<"name">> => <<>>}])), 2060: ?errh(T([RequiredOpts#{<<"type">> => <<"rampampam">>}])), 2061: ?errh(T([RequiredOpts#{<<"type">> => <<"file">>}])), 2062: ?errh(T([RequiredOpts#{<<"type">> => <<"file">>, 2063: <<"path">> => <<"does/not/exists">>}])). 2064: 2065: mod_last(_Config) -> 2066: check_iqdisc(mod_last), 2067: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_last">> => Opts}} end, 2068: M = fun(Cfg) -> modopts(mod_last, Cfg) end, 2069: ?cfgh(M([{backend, mnesia}]), 2070: T(#{<<"backend">> => <<"mnesia">>})), 2071: ?cfgh(M([{bucket_type, <<"test">>}]), 2072: T(#{<<"riak">> => #{<<"bucket_type">> => <<"test">>}})), 2073: 2074: ?errh(T(#{<<"backend">> => <<"frontend">>})), 2075: ?errh(T(#{<<"riak">> => #{<<"bucket_type">> => 1}})). 2076: 2077: mod_mam_meta(_Config) -> 2078: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_mam_meta">> => Opts}} end, 2079: M = fun(Cfg) -> modopts(mod_mam_meta, Cfg) end, 2080: test_mod_mam_meta(T, M), 2081: ?cfgh(M([{bucket_type, <<"mam_bucket">>}]), 2082: T(#{<<"riak">> => #{<<"bucket_type">> => <<"mam_bucket">>}})), 2083: ?cfgh(M([{search_index, <<"mam_index">>}]), 2084: T(#{<<"riak">> => #{<<"search_index">> => <<"mam_index">>}})), 2085: ?errh(T(#{<<"riak">> => #{<<"bucket_type">> => <<>>}})), 2086: ?errh(T(#{<<"riak">> => #{<<"search_index">> => <<>>}})). 2087: 2088: mod_mam_meta_pm(_Config) -> 2089: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_mam_meta">> => #{<<"pm">> => Opts}}} end, 2090: M = fun(Cfg) -> modopts(mod_mam_meta, [{pm, Cfg}]) end, 2091: test_mod_mam_meta(T, M), 2092: ?cfgh(M([{archive_groupchats, true}]), 2093: T(#{<<"archive_groupchats">> => true})), 2094: ?cfgh(M([{same_mam_id_for_peers, true}]), 2095: T(#{<<"same_mam_id_for_peers">> => true})), 2096: ?errh(T(#{<<"archive_groupchats">> => <<"not really">>})), 2097: ?errh(T(#{<<"same_mam_id_for_peers">> => <<"not really">>})). 2098: 2099: mod_mam_meta_muc(_Config) -> 2100: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_mam_meta">> => #{<<"muc">> => Opts}}} end, 2101: M = fun(Cfg) -> modopts(mod_mam_meta, [{muc, Cfg}]) end, 2102: test_mod_mam_meta(T, M), 2103: ?cfgh(M([{host, {prefix, <<"muc.">>}}]), 2104: T(#{<<"host">> => <<"muc.@HOST@">>})), 2105: ?cfgh(M([{host, {fqdn, <<"muc.test">>}}]), 2106: T(#{<<"host">> => <<"muc.test">>})), 2107: ?errh(T(#{<<"host">> => <<"is this a host? no.">>})), 2108: ?errh(T(#{<<"host">> => [<<"invalid.sub@HOST@">>]})), 2109: ?errh(T(#{<<"host">> => [<<"invalid.sub.@HOST@.as.well">>]})), 2110: ?errh(T(#{<<"archive_groupchats">> => true})), 2111: ?errh(T(#{<<"same_mam_id_for_peers">> => true})). 2112: 2113: test_mod_mam_meta(T, M) -> 2114: test_async_worker(T, M), 2115: test_cache_config(T, M), 2116: ?cfgh(M([{backend, rdbms}]), 2117: T(#{<<"backend">> => <<"rdbms">>})), 2118: ?cfgh(M([{no_stanzaid_element, true}]), 2119: T(#{<<"no_stanzaid_element">> => true})), 2120: ?cfgh(M([{is_archivable_message, mod_mam_utils}]), 2121: T(#{<<"is_archivable_message">> => <<"mod_mam_utils">>})), 2122: ?cfgh(M([{archive_chat_markers, false}]), 2123: T(#{<<"archive_chat_markers">> => false})), 2124: ?cfgh(M([{message_retraction, true}]), 2125: T(#{<<"message_retraction">> => true})), 2126: ?cfgh(M([{rdbms_message_format, simple}]), 2127: T(#{<<"rdbms_message_format">> => <<"simple">>})), 2128: ?cfgh(M([{user_prefs_store, rdbms}]), 2129: T(#{<<"user_prefs_store">> => <<"rdbms">>})), 2130: ?cfgh(M([{full_text_search, false}]), 2131: T(#{<<"full_text_search">> => false})), 2132: ?cfgh(M([{default_result_limit, 100}]), 2133: T(#{<<"default_result_limit">> => 100})), 2134: ?cfgh(M([{max_result_limit, 1000}]), 2135: T(#{<<"max_result_limit">> => 1000})), 2136: ?cfgh(M([{db_jid_format, mam_jid_rfc}]), 2137: T(#{<<"db_jid_format">> => <<"mam_jid_rfc">>})), 2138: ?cfgh(M([{db_message_format, mam_message_xml}]), 2139: T(#{<<"db_message_format">> => <<"mam_message_xml">>})), 2140: ?cfgh(M([{simple, false}]), 2141: T(#{<<"simple">> => false})), 2142: ?cfgh(M([{extra_fin_element, mod_mam_utils}]), 2143: T(#{<<"extra_fin_element">> => <<"mod_mam_utils">>})), 2144: ?cfgh(M([{extra_lookup_params, mod_mam_utils}]), 2145: T(#{<<"extra_lookup_params">> => <<"mod_mam_utils">>})), 2146: ?errh(T(#{<<"backend">> => <<"notepad">>})), 2147: ?errh(T(#{<<"no_stanzaid_element">> => <<"true">>})), 2148: ?errh(T(#{<<"is_archivable_message">> => <<"mod_mam_fake">>})), 2149: ?errh(T(#{<<"archive_chat_markers">> => <<"maybe">>})), 2150: ?errh(T(#{<<"message_retraction">> => 1})), 2151: ?errh(T(#{<<"rdbms_message_format">> => <<"complex">>})), 2152: ?errh(T(#{<<"user_prefs_store">> => <<"textfile">>})), 2153: ?errh(T(#{<<"full_text_search">> => <<"disabled">>})), 2154: ?errh(T(#{<<"default_result_limit">> => -1})), 2155: ?errh(T(#{<<"max_result_limit">> => -2})), 2156: ?errh(T(#{<<"db_jid_format">> => <<"not_a_module">>})), 2157: ?errh(T(#{<<"db_message_format">> => <<"not_a_module">>})), 2158: ?errh(T(#{<<"simple">> => <<"yes">>})), 2159: ?errh(T(#{<<"extra_fin_element">> => <<"bad_module">>})), 2160: ?errh(T(#{<<"extra_lookup_params">> => <<"bad_module">>})). 2161: 2162: test_cache_config(T, M) -> 2163: ?cfgh(M([{cache_users, false}]), 2164: T(#{<<"cache_users">> => false})), 2165: ?errh(T(#{<<"cache_users">> => []})), 2166: test_segmented_cache_config(<<"cache">>, cache, T, M). 2167: 2168: test_segmented_cache_config(NameK, NameV, T, M) -> 2169: ?cfgh(M([{NameV, [{module, internal}]}]), 2170: T(#{NameK => #{<<"module">> => <<"internal">>}})), 2171: ?cfgh(M([{NameV, [{time_to_live, 8600}]}]), 2172: T(#{NameK => #{<<"time_to_live">> => 8600}})), 2173: ?cfgh(M([{NameV, [{time_to_live, infinity}]}]), 2174: T(#{NameK => #{<<"time_to_live">> => <<"infinity">>}})), 2175: ?cfgh(M([{NameV, [{number_of_segments, 10}]}]), 2176: T(#{NameK => #{<<"number_of_segments">> => 10}})), 2177: ?cfgh(M([{NameV, [{strategy, fifo}]}]), 2178: T(#{NameK => #{<<"strategy">> => <<"fifo">>}})), 2179: ?errh(T(#{NameK => #{<<"module">> => <<"mod_wrong_cache">>}})), 2180: ?errh(T(#{NameK => #{<<"module">> => <<"mod_cache_users">>, 2181: <<"time_to_live">> => 8600}})), 2182: ?errh(T(#{NameK => #{<<"time_to_live">> => 0}})), 2183: ?errh(T(#{NameK => #{<<"strategy">> => <<"lifo">>}})), 2184: ?errh(T(#{NameK => #{<<"number_of_segments">> => 0}})), 2185: ?errh(T(#{NameK => #{<<"number_of_segments">> => <<"infinity">>}})). 2186: 2187: test_async_worker(T, M) -> 2188: ?cfgh(M([{async_writer, [{flush_interval, 1500}]}]), 2189: T(#{<<"async_writer">> => #{<<"flush_interval">> => 1500}})), 2190: ?cfgh(M([{async_writer, [{batch_size, 1500}]}]), 2191: T(#{<<"async_writer">> => #{<<"batch_size">> => 1500}})), 2192: ?cfgh(M([{async_writer, [{pool_size, 1500}]}]), 2193: T(#{<<"async_writer">> => #{<<"pool_size">> => 1500}})), 2194: ?cfgh(M([{async_writer, [{enabled, false}]}]), 2195: T(#{<<"async_writer">> => #{<<"enabled">> => false}})), 2196: ?errh(T(#{<<"async_writer">> => #{<<"flush_interval">> => -1}})), 2197: ?errh(T(#{<<"async_writer">> => #{<<"batch_size">> => -1}})), 2198: ?errh(T(#{<<"async_writer">> => #{<<"pool_size">> => -1}})), 2199: ?errh(T(#{<<"async_writer">> => #{<<"enabled">> => <<"wrong">>}})). 2200: 2201: mod_muc(_Config) -> 2202: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_muc">> => Opts}} end, 2203: M = fun(Cfg) -> modopts(mod_muc, Cfg) end, 2204: ?cfgh(M([{host, {prefix, <<"conference.">>}}]), 2205: T(#{<<"host">> => <<"conference.@HOST@">>})), 2206: ?cfgh(M([{host, {fqdn, <<"conference.test">>}}]), 2207: T(#{<<"host">> => <<"conference.test">>})), 2208: ?cfgh(M([{backend, mnesia}]), 2209: T(#{<<"backend">> => <<"mnesia">>})), 2210: ?cfgh(M([{access, all}]), 2211: T(#{<<"access">> => <<"all">>})), 2212: ?cfgh(M([{access_create, admin}]), 2213: T(#{<<"access_create">> => <<"admin">>})), 2214: ?cfgh(M([{access_admin, none}]), 2215: T(#{<<"access_admin">> => <<"none">>})), 2216: ?cfgh(M([{access_persistent, all}]), 2217: T(#{<<"access_persistent">> => <<"all">>})), 2218: ?cfgh(M([{history_size, 20}]), 2219: T(#{<<"history_size">> => 20})), 2220: ?cfgh(M([{room_shaper, muc_room_shaper}]), 2221: T(#{<<"room_shaper">> => <<"muc_room_shaper">>})), 2222: ?cfgh(M([{max_room_id, infinity}]), 2223: T(#{<<"max_room_id">> => <<"infinity">>})), 2224: ?cfgh(M([{max_room_name, 30}]), 2225: T(#{<<"max_room_name">> => 30})), 2226: ?cfgh(M([{max_room_desc, 0}]), 2227: T(#{<<"max_room_desc">> => 0})), 2228: ?cfgh(M([{min_message_interval, 10}]), 2229: T(#{<<"min_message_interval">> => 10})), 2230: ?cfgh(M([{min_presence_interval, 0}]), 2231: T(#{<<"min_presence_interval">> => 0})), 2232: ?cfgh(M([{max_users, 30}]), 2233: T(#{<<"max_users">> => 30})), 2234: ?cfgh(M([{max_users_admin_threshold, 2}]), 2235: T(#{<<"max_users_admin_threshold">> => 2})), 2236: ?cfgh(M([{user_message_shaper, muc_msg_shaper}]), 2237: T(#{<<"user_message_shaper">> => <<"muc_msg_shaper">>})), 2238: ?cfgh(M([{user_presence_shaper, muc_pres_shaper}]), 2239: T(#{<<"user_presence_shaper">> => <<"muc_pres_shaper">>})), 2240: ?cfgh(M([{max_user_conferences, 10}]), 2241: T(#{<<"max_user_conferences">> => 10})), 2242: ?cfgh(M([{http_auth_pool, external_auth}]), 2243: T(#{<<"http_auth_pool">> => <<"external_auth">>})), 2244: ?cfgh(M([{load_permanent_rooms_at_startup, true}]), 2245: T(#{<<"load_permanent_rooms_at_startup">> => true})), 2246: ?cfgh(M([{hibernate_timeout, infinity}]), 2247: T(#{<<"hibernate_timeout">> => <<"infinity">>})), 2248: ?cfgh(M([{hibernated_room_check_interval, 5000}]), 2249: T(#{<<"hibernated_room_check_interval">> => 5000})), 2250: ?cfgh(M([{hibernated_room_timeout, 0}]), 2251: T(#{<<"hibernated_room_timeout">> => 0})), 2252: ?errh(T(#{<<"host">> => <<>>})), 2253: ?errh(T(#{<<"host">> => <<"is this a host? no.">>})), 2254: ?errh(T(#{<<"host">> => [<<"invalid.sub@HOST@">>]})), 2255: ?errh(T(#{<<"host">> => [<<"invalid.sub.@HOST@.as.well">>]})), 2256: ?errh(T(#{<<"backend">> => <<"amnesia">>})), 2257: ?errh(T(#{<<"access">> => <<>>})), 2258: ?errh(T(#{<<"access_create">> => 1})), 2259: ?errh(T(#{<<"access_admin">> => []})), 2260: ?errh(T(#{<<"access_persistent">> => true})), 2261: ?errh(T(#{<<"history_size">> => <<"20">>})), 2262: ?errh(T(#{<<"room_shaper">> => <<>>})), 2263: ?errh(T(#{<<"max_room_id">> => #{}})), 2264: ?errh(T(#{<<"max_room_name">> => <<"infinite!">>})), 2265: ?errh(T(#{<<"max_room_desc">> => -1})), 2266: ?errh(T(#{<<"min_message_interval">> => -10})), 2267: ?errh(T(#{<<"min_presence_interval">> => <<"infinity">>})), 2268: ?errh(T(#{<<"max_users">> => 0})), 2269: ?errh(T(#{<<"max_users_admin_threshold">> => 0})), 2270: ?errh(T(#{<<"user_message_shaper">> => []})), 2271: ?errh(T(#{<<"user_presence_shaper">> => <<>>})), 2272: ?errh(T(#{<<"max_user_conferences">> => -1})), 2273: ?errh(T(#{<<"http_auth_pool">> => <<>>})), 2274: ?errh(T(#{<<"load_permanent_rooms_at_startup">> => <<"true">>})), 2275: ?errh(T(#{<<"hibernate_timeout">> => <<"really big">>})), 2276: ?errh(T(#{<<"hibernated_room_check_interval">> => -1})), 2277: ?errh(T(#{<<"hibernated_room_timeout">> => false})). 2278: 2279: mod_muc_default_room(_Config) -> 2280: T = fun(Opts) -> #{<<"modules">> => 2281: #{<<"mod_muc">> => #{<<"default_room">> => Opts}}} end, 2282: M = fun(Cfg) -> modopts(mod_muc, [{default_room_options, Cfg}]) end, 2283: ?cfgh(M([]), T(#{})), 2284: ?cfgh(M([{title, <<"living room">>}]), 2285: T(#{<<"title">> => <<"living room">>})), 2286: ?cfgh(M([{description, <<"a room that is alive">>}]), 2287: T(#{<<"description">> => <<"a room that is alive">>})), 2288: ?cfgh(M([{allow_change_subj, true}]), 2289: T(#{<<"allow_change_subj">> => true})), 2290: ?cfgh(M([{allow_query_users, false}]), 2291: T(#{<<"allow_query_users">> => false})), 2292: ?cfgh(M([{allow_private_messages, true}]), 2293: T(#{<<"allow_private_messages">> => true})), 2294: ?cfgh(M([{allow_visitor_status, false}]), 2295: T(#{<<"allow_visitor_status">> => false})), 2296: ?cfgh(M([{allow_visitor_nickchange, true}]), 2297: T(#{<<"allow_visitor_nickchange">> => true})), 2298: ?cfgh(M([{public, false}]), 2299: T(#{<<"public">> => false})), 2300: ?cfgh(M([{public_list, true}]), 2301: T(#{<<"public_list">> => true})), 2302: ?cfgh(M([{persistent, true}]), 2303: T(#{<<"persistent">> => true})), 2304: ?cfgh(M([{moderated, false}]), 2305: T(#{<<"moderated">> => false})), 2306: ?cfgh(M([{members_by_default, true}]), 2307: T(#{<<"members_by_default">> => true})), 2308: ?cfgh(M([{members_only, false}]), 2309: T(#{<<"members_only">> => false})), 2310: ?cfgh(M([{allow_user_invites, true}]), 2311: T(#{<<"allow_user_invites">> => true})), 2312: ?cfgh(M([{allow_multiple_sessions, false}]), 2313: T(#{<<"allow_multiple_sessions">> => false})), 2314: ?cfgh(M([{password_protected, true}]), 2315: T(#{<<"password_protected">> => true})), 2316: ?cfgh(M([{password, <<"secret">>}]), 2317: T(#{<<"password">> => <<"secret">>})), 2318: ?cfgh(M([{anonymous, true}]), 2319: T(#{<<"anonymous">> => true})), 2320: ?cfgh(M([{max_users, 100}]), 2321: T(#{<<"max_users">> => 100})), 2322: ?cfgh(M([{logging, false}]), 2323: T(#{<<"logging">> => false})), 2324: ?cfgh(M([{maygetmemberlist, [moderator]}]), 2325: T(#{<<"maygetmemberlist">> => [<<"moderator">>]})), 2326: ?cfgh(M([{subject, <<"Lambda days">>}]), 2327: T(#{<<"subject">> => <<"Lambda days">>})), 2328: ?cfgh(M([{subject_author, <<"Alice">>}]), 2329: T(#{<<"subject_author">> => <<"Alice">>})), 2330: ?errh(T(<<"bad value">>)), 2331: ?errh(T(#{<<"title">> => true})), 2332: ?errh(T(#{<<"description">> => 1})), 2333: ?errh(T(#{<<"allow_change_subj">> => <<"true">>})), 2334: ?errh(T(#{<<"allow_query_users">> => <<>>})), 2335: ?errh(T(#{<<"allow_private_messages">> => 1})), 2336: ?errh(T(#{<<"allow_visitor_status">> => []})), 2337: ?errh(T(#{<<"allow_visitor_nickchange">> => #{}})), 2338: ?errh(T(#{<<"public">> => 0})), 2339: ?errh(T(#{<<"public_list">> => [false]})), 2340: ?errh(T(#{<<"persistent">> => 1})), 2341: ?errh(T(#{<<"moderated">> => <<"yes">>})), 2342: ?errh(T(#{<<"members_by_default">> => 0})), 2343: ?errh(T(#{<<"members_only">> => [true]})), 2344: ?errh(T(#{<<"allow_user_invites">> => <<>>})), 2345: ?errh(T(#{<<"allow_multiple_sessions">> => []})), 2346: ?errh(T(#{<<"password_protected">> => #{}})), 2347: ?errh(T(#{<<"password">> => false})), 2348: ?errh(T(#{<<"anonymous">> => <<"maybe">>})), 2349: ?errh(T(#{<<"max_users">> => 0})), 2350: ?errh(T(#{<<"logging">> => [true, false]})), 2351: ?errh(T(#{<<"maygetmemberlist">> => <<"moderator">>})), 2352: ?errh(T(#{<<"maygetmemberlist">> => [<<>>]})), 2353: ?errh(T(#{<<"subject">> => [<<"subjective">>]})), 2354: ?errh(T(#{<<"subject_author">> => 1})). 2355: 2356: mod_muc_default_room_affiliations(_Config) -> 2357: T = fun(Opts) -> #{<<"modules">> => 2358: #{<<"mod_muc">> => 2359: #{<<"default_room">> => #{<<"affiliations">> => Opts}}}} end, 2360: M = fun(Cfg) -> modopts(mod_muc, [{default_room_options, [{affiliations, Cfg}]}]) end, 2361: RequiredOpts = #{<<"user">> => <<"alice">>, 2362: <<"server">> => <<"localhost">>, 2363: <<"resource">> => <<"phone">>, 2364: <<"affiliation">> => <<"moderator">>}, 2365: ExpectedCfg = {{<<"alice">>, <<"localhost">>, <<"phone">>}, moderator}, 2366: ?cfgh(M([]), T([])), 2367: ?cfgh(M([ExpectedCfg]), T([RequiredOpts])), 2368: [?errh(T([maps:remove(Key, RequiredOpts)])) || Key <- maps:keys(RequiredOpts)], 2369: ?errh(T([RequiredOpts#{<<"user">> := <<>>}])), 2370: ?errh(T([RequiredOpts#{<<"server">> := <<"domain? not really!">>}])), 2371: ?errh(T([RequiredOpts#{<<"resource">> := false}])), 2372: ?errh(T([RequiredOpts#{<<"affiliation">> := <<>>}])). 2373: 2374: mod_muc_log(_Config) -> 2375: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_muc_log">> => Opts}} end, 2376: M = fun(Cfg) -> modopts(mod_muc_log, Cfg) end, 2377: ?cfgh(M([{outdir, "www/muc"}]), 2378: T(#{<<"outdir">> => <<"www/muc">>})), 2379: ?cfgh(M([{access_log, muc_admin}]), 2380: T(#{<<"access_log">> => <<"muc_admin">>})), 2381: ?cfgh(M([{dirtype, subdirs}]), 2382: T(#{<<"dirtype">> => <<"subdirs">>})), 2383: ?cfgh(M([{dirname, room_name}]), 2384: T(#{<<"dirname">> => <<"room_name">>})), 2385: ?cfgh(M([{file_format, html}]), 2386: T(#{<<"file_format">> => <<"html">>})), 2387: ?cfgh(M([{cssfile, <<"path/to/css_file">>}]), 2388: T(#{<<"css_file">> => <<"path/to/css_file">>})), 2389: ?cfgh(M([{timezone, local}]), 2390: T(#{<<"timezone">> => <<"local">>})), 2391: ?cfgh(M([{spam_prevention, false}]), 2392: T(#{<<"spam_prevention">> => false})), 2393: ?errh(T(#{<<"outdir">> => <<"does/not/exist">>})), 2394: ?errh(T(#{<<"access_log">> => 1})), 2395: ?errh(T(#{<<"dirtype">> => <<"imaginary">>})), 2396: ?errh(T(#{<<"dirname">> => <<"dyrektory">>})), 2397: ?errh(T(#{<<"file_format">> => <<"none">>})), 2398: ?errh(T(#{<<"css_file">> => <<>>})), 2399: ?errh(T(#{<<"timezone">> => <<"yes">>})), 2400: ?errh(T(#{<<"spam_prevention">> => <<"spam and eggs and spam">>})). 2401: 2402: mod_muc_log_top_link(_Config) -> 2403: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_muc_log">> => #{<<"top_link">> => Opts}}} end, 2404: M = fun(Cfg) -> modopts(mod_muc_log, [{top_link, Cfg}]) end, 2405: RequiredOpts = #{<<"target">> => <<"https://esl.github.io/MongooseDocs/">>, 2406: <<"text">> => <<"Docs">>}, 2407: ExpectedCfg = {"https://esl.github.io/MongooseDocs/", "Docs"}, 2408: ?cfgh(M(ExpectedCfg), T(RequiredOpts)), 2409: [?errh(T(maps:remove(K, RequiredOpts))) || K <- maps:keys(RequiredOpts)], 2410: ?errh(T(RequiredOpts#{<<"target">> => true})), 2411: ?errh(T(RequiredOpts#{<<"text">> => <<"">>})). 2412: 2413: mod_muc_light(_Config) -> 2414: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_muc_light">> => Opts}} end, 2415: M = fun(Cfg) -> modopts(mod_muc_light, Cfg) end, 2416: test_segmented_cache_config(<<"cache_affs">>, cache_affs, T, M), 2417: ?cfgh(M([{backend, mnesia}]), 2418: T(#{<<"backend">> => <<"mnesia">>})), 2419: ?cfgh(M([{host, {prefix, <<"muclight.">>}}]), 2420: T(#{<<"host">> => <<"muclight.@HOST@">>})), 2421: ?cfgh(M([{host, {fqdn, <<"muclight.test">>}}]), 2422: T(#{<<"host">> => <<"muclight.test">>})), 2423: ?cfgh(M([{equal_occupants, true}]), 2424: T(#{<<"equal_occupants">> => true})), 2425: ?cfgh(M([{legacy_mode, false}]), 2426: T(#{<<"legacy_mode">> => false})), 2427: ?cfgh(M([{rooms_per_user, 100}]), 2428: T(#{<<"rooms_per_user">> => 100})), 2429: ?cfgh(M([{blocking, false}]), 2430: T(#{<<"blocking">> => false})), 2431: ?cfgh(M([{all_can_configure, true}]), 2432: T(#{<<"all_can_configure">> => true})), 2433: ?cfgh(M([{all_can_invite, false}]), 2434: T(#{<<"all_can_invite">> => false})), 2435: ?cfgh(M([{max_occupants, infinity}]), 2436: T(#{<<"max_occupants">> => <<"infinity">>})), 2437: ?cfgh(M([{rooms_per_page, 10}]), 2438: T(#{<<"rooms_per_page">> => 10})), 2439: ?cfgh(M([{rooms_in_rosters, true}]), 2440: T(#{<<"rooms_in_rosters">> => true})), 2441: ?errh(T(#{<<"backend">> => <<"frontend">>})), 2442: ?errh(T(#{<<"host">> => <<"what is a domain?!">>})), 2443: ?errh(T(#{<<"host">> => [<<"invalid.sub@HOST@">>]})), 2444: ?errh(T(#{<<"host">> => [<<"invalid.sub.@HOST@.as.well">>]})), 2445: ?errh(T(#{<<"equal_occupants">> => <<"true">>})), 2446: ?errh(T(#{<<"legacy_mode">> => 1234})), 2447: ?errh(T(#{<<"rooms_per_user">> => 0})), 2448: ?errh(T(#{<<"blocking">> => <<"true">>})), 2449: ?errh(T(#{<<"all_can_configure">> => []})), 2450: ?errh(T(#{<<"all_can_invite">> => #{}})), 2451: ?errh(T(#{<<"max_occupants">> => <<"seven">>})), 2452: ?errh(T(#{<<"rooms_per_page">> => false})), 2453: ?errh(T(#{<<"rooms_in_rosters">> => [1, 2, 3]})). 2454: 2455: mod_muc_light_config_schema(_Config) -> 2456: T = fun(Opts) -> #{<<"modules">> => 2457: #{<<"mod_muc_light">> => #{<<"config_schema">> => Opts}}} end, 2458: M = fun(Cfg) -> modopts(mod_muc_light, [{config_schema, Cfg}]) end, 2459: Field = #{<<"field">> => <<"my_field">>}, 2460: ?cfgh(M([]), T([])), 2461: ?cfgh(M([{<<"my_field">>, <<"My Room">>, my_field, binary}]), 2462: T([Field#{<<"string_value">> => <<"My Room">>}])), 2463: ?cfgh(M([{<<"my_field">>, 1, my_field, integer}]), 2464: T([Field#{<<"integer_value">> => 1}])), 2465: ?cfgh(M([{<<"my_field">>, 0.5, my_field, float}]), 2466: T([Field#{<<"float_value">> => 0.5}])), 2467: ?cfgh(M([{<<"my_field">>, 0, your_field, integer}]), 2468: T([Field#{<<"integer_value">> => 0, 2469: <<"internal_key">> => <<"your_field">>}])), 2470: ?cfgh(M([{<<"żółć"/utf8>>, <<"Рентгеноэлектрокардиографический"/utf8>>, 'żółć', binary}]), 2471: T([#{<<"field">> => <<"żółć"/utf8>>, 2472: <<"string_value">> => <<"Рентгеноэлектрокардиографический"/utf8>>}])), 2473: ?cfgh(M([{<<"first">>, 1, first, integer}, % the config is u-key-sorted 2474: {<<"second">>, <<"two">>, second, binary}]), 2475: T([#{<<"field">> => <<"second">>, <<"string_value">> => <<"two">>}, 2476: #{<<"field">> => <<"second">>, <<"float_value">> => 2.0}, 2477: #{<<"field">> => <<"first">>, <<"integer_value">> => 1}])), 2478: ?errh(T([#{<<"string_value">> => <<"My Room">>}])), 2479: ?errh(T([#{<<"field">> => <<>>, 2480: <<"string_value">> => <<"My Room">>}])), 2481: ?errh(T([Field#{<<"string_value">> => 0}])), 2482: ?errh(T([Field#{<<"integer_value">> => 1.5}])), 2483: ?errh(T([Field#{<<"float_value">> => 1}])), 2484: ?errh(T([Field#{<<"integer_value">> => 0, 2485: <<"string_value">> => <<"My Room">>}])), 2486: ?errh(T([Field#{<<"integer_value">> => 0, 2487: <<"internal_key">> => <<>>}])). 2488: 2489: mod_offline(_Config) -> 2490: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_offline">> => Opts}} end, 2491: M = fun(Cfg) -> modopts(mod_offline, Cfg) end, 2492: ?cfgh(M([{access_max_user_messages, max_user_offline_messages}]), 2493: T(#{<<"access_max_user_messages">> => <<"max_user_offline_messages">>})), 2494: ?cfgh(M([{backend, rdbms}]), 2495: T(#{<<"backend">> => <<"rdbms">>})), 2496: ?cfgh(M([{bucket_type, <<"test">>}]), 2497: T(#{<<"riak">> => #{<<"bucket_type">> => <<"test">>}})), 2498: ?errh(T(#{<<"access_max_user_messages">> => 1})), 2499: ?errh(T(#{<<"backend">> => <<"riak_is_the_best">>})), 2500: ?errh(T(#{<<"riak">> => #{<<"bucket_type">> => 1}})), 2501: ?errh(T(#{<<"riak">> => #{<<"bucket">> => <<"leaky">>}})). 2502: 2503: mod_ping(_Config) -> 2504: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_ping">> => Opts}} end, 2505: M = fun(Cfg) -> modopts(mod_ping, Cfg) end, 2506: ?cfgh(M([{send_pings, true}]), 2507: T(#{<<"send_pings">> => true})), 2508: ?cfgh(M([{ping_interval, timer:seconds(10)}]), 2509: T(#{<<"ping_interval">> => 10})), 2510: ?cfgh(M([{timeout_action, kill}]), 2511: T(#{<<"timeout_action">> => <<"kill">>})), 2512: ?cfgh(M([{ping_req_timeout, timer:seconds(20)}]), 2513: T(#{<<"ping_req_timeout">> => 20})), 2514: ?errh(T(#{<<"send_pings">> => 1})), 2515: ?errh(T(#{<<"ping_interval">> => 0})), 2516: ?errh(T(#{<<"timeout_action">> => <<"kill_them_all">>})), 2517: ?errh(T(#{<<"ping_req_timeout">> => 0})), 2518: check_iqdisc(mod_ping). 2519: 2520: mod_privacy(_Config) -> 2521: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_privacy">> => Opts}} end, 2522: M = fun(Cfg) -> modopts(mod_privacy, Cfg) end, 2523: ?cfgh(M([{backend, mnesia}]), 2524: T(#{<<"backend">> => <<"mnesia">>})), 2525: ?cfgh(M([{defaults_bucket_type, <<"defaults">>}]), 2526: T(#{<<"riak">> => #{<<"defaults_bucket_type">> => <<"defaults">>}})), 2527: ?cfgh(M([{names_bucket_type, <<"names">>}]), 2528: T(#{<<"riak">> => #{<<"names_bucket_type">> => <<"names">>}})), 2529: ?cfgh(M([{bucket_type, <<"bucket">>}]), 2530: T(#{<<"riak">> => #{<<"bucket_type">> => <<"bucket">>}})), 2531: ?errh(T(#{<<"backend">> => <<"mongoddt">>})), 2532: ?errh(T(#{<<"riak">> => #{<<"defaults_bucket_type">> => <<>>}})), 2533: ?errh(T(#{<<"riak">> => #{<<"names_bucket_type">> => 1}})), 2534: ?errh(T(#{<<"riak">> => #{<<"bucket_type">> => 1}})). 2535: 2536: mod_private(_Config) -> 2537: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_private">> => Opts}} end, 2538: M = fun(Cfg) -> modopts(mod_private, Cfg) end, 2539: ?cfgh(M([{backend, riak}]), 2540: T(#{<<"backend">> => <<"riak">>})), 2541: ?cfgh(M([{bucket_type, <<"private_stuff">>}]), 2542: T(#{<<"riak">> => #{<<"bucket_type">> => <<"private_stuff">>}})), 2543: ?errh(T(#{<<"backend">> => <<"mssql">>})), 2544: ?errh(T(#{<<"riak">> => #{<<"bucket_type">> => 1}})), 2545: check_iqdisc(mod_private). 2546: 2547: mod_pubsub(_Config) -> 2548: check_iqdisc(mod_pubsub), 2549: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_pubsub">> => Opts}} end, 2550: M = fun(Cfg) -> modopts(mod_pubsub, Cfg) end, 2551: ?cfgh(M([{host, {prefix, <<"pubsub.">>}}]), 2552: T(#{<<"host">> => <<"pubsub.@HOST@">>})), 2553: ?cfgh(M([{host, {fqdn, <<"pubsub.test">>}}]), 2554: T(#{<<"host">> => <<"pubsub.test">>})), 2555: ?cfgh(M([{backend, rdbms}]), 2556: T(#{<<"backend">> => <<"rdbms">>})), 2557: ?cfgh(M([{access_createnode, all}]), 2558: T(#{<<"access_createnode">> => <<"all">>})), 2559: ?cfgh(M([{max_items_node, 20}]), 2560: T(#{<<"max_items_node">> => 20})), 2561: ?cfgh(M([{max_subscriptions_node, 30}]), 2562: T(#{<<"max_subscriptions_node">> => 30})), 2563: ?cfgh(M([{nodetree, <<"tree">>}]), 2564: T(#{<<"nodetree">> => <<"tree">>})), 2565: ?cfgh(M([{ignore_pep_from_offline, false}]), 2566: T(#{<<"ignore_pep_from_offline">> => false})), 2567: ?cfgh(M([{last_item_cache, rdbms}]), 2568: T(#{<<"last_item_cache">> => <<"rdbms">>})), 2569: ?cfgh(M([{plugins, [<<"flat">>, <<"dag">>]}]), 2570: T(#{<<"plugins">> => [<<"flat">>, <<"dag">>]})), 2571: ?cfgh(M([{item_publisher, true}]), 2572: T(#{<<"item_publisher">> => true})), 2573: ?cfgh(M([{sync_broadcast, false}]), 2574: T(#{<<"sync_broadcast">> => false})), 2575: ?errh(T(#{<<"host">> => <<"">>})), 2576: ?errh(T(#{<<"host">> => <<"is this a host? no.">>})), 2577: ?errh(T(#{<<"host">> => [<<"invalid.sub@HOST@">>]})), 2578: ?errh(T(#{<<"host">> => [<<"invalid.sub.@HOST@.as.well">>]})), 2579: ?errh(T(#{<<"backend">> => <<"amnesia">>})), 2580: ?errh(T(#{<<"access_createnode">> => <<"">>})), 2581: ?errh(T(#{<<"max_items_node">> => -1})), 2582: ?errh(T(#{<<"max_subscriptions_node">> => 3.1415})), 2583: ?errh(T(#{<<"nodetree">> => <<"christmas_tree">>})), 2584: ?errh(T(#{<<"ignore_pep_from_offline">> => <<"maybe">>})), 2585: ?errh(T(#{<<"last_item_cache">> => false})), 2586: ?errh(T(#{<<"plugins">> => [<<"deep">>]})), 2587: ?errh(T(#{<<"item_publisher">> => 1})), 2588: ?errh(T(#{<<"sync_broadcast">> => []})). 2589: 2590: mod_pubsub_pep_mapping(_Config) -> 2591: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_pubsub">> => 2592: #{<<"pep_mapping">> => Opts}}} end, 2593: M = fun(Cfg) -> modopts(mod_pubsub, [{pep_mapping, Cfg}]) end, 2594: RequiredOpts = #{<<"namespace">> => <<"urn:xmpp:microblog:0">>, 2595: <<"node">> => <<"mb">>}, 2596: ?cfgh(M([{<<"urn:xmpp:microblog:0">>, <<"mb">>}]), 2597: T([RequiredOpts])), 2598: [?errh(T([maps:remove(Key, RequiredOpts)])) || Key <- maps:keys(RequiredOpts)], 2599: [?errh(T([RequiredOpts#{Key => <<>>}])) || Key <- maps:keys(RequiredOpts)]. 2600: 2601: mod_pubsub_default_node_config(_Config) -> 2602: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_pubsub">> => 2603: #{<<"default_node_config">> => Opts}}} end, 2604: M = fun(Cfg) -> modopts(mod_pubsub, [{default_node_config, Cfg}]) end, 2605: ?cfgh(M([{access_model, open}]), 2606: T(#{<<"access_model">> => <<"open">>})), 2607: ?cfgh(M([{deliver_notifications, true}]), 2608: T(#{<<"deliver_notifications">> => true})), 2609: ?cfgh(M([{deliver_payloads, false}]), 2610: T(#{<<"deliver_payloads">> => false})), 2611: ?cfgh(M([{max_items, 1000}]), 2612: T(#{<<"max_items">> => 1000})), 2613: ?cfgh(M([{max_payload_size, 1000}]), 2614: T(#{<<"max_payload_size">> => 1000})), 2615: ?cfgh(M([{node_type, dag}]), 2616: T(#{<<"node_type">> => <<"dag">>})), 2617: ?cfgh(M([{notification_type, headline}]), 2618: T(#{<<"notification_type">> => <<"headline">>})), 2619: ?cfgh(M([{notify_config, true}]), 2620: T(#{<<"notify_config">> => true})), 2621: ?cfgh(M([{notify_delete, false}]), 2622: T(#{<<"notify_delete">> => false})), 2623: ?cfgh(M([{notify_retract, true}]), 2624: T(#{<<"notify_retract">> => true})), 2625: ?cfgh(M([{persist_items, false}]), 2626: T(#{<<"persist_items">> => false})), 2627: ?cfgh(M([{presence_based_delivery, true}]), 2628: T(#{<<"presence_based_delivery">> => true})), 2629: ?cfgh(M([{publish_model, open}]), 2630: T(#{<<"publish_model">> => <<"open">>})), 2631: ?cfgh(M([{purge_offline, false}]), 2632: T(#{<<"purge_offline">> => false})), 2633: ?cfgh(M([{roster_groups_allowed, [<<"friends">>]}]), 2634: T(#{<<"roster_groups_allowed">> => [<<"friends">>]})), 2635: ?cfgh(M([{send_last_published_item, on_sub_and_presence}]), 2636: T(#{<<"send_last_published_item">> => <<"on_sub_and_presence">>})), 2637: ?cfgh(M([{subscribe, true}]), 2638: T(#{<<"subscribe">> => true})), 2639: ?errh(T(#{<<"access_model">> => <<>>})), 2640: ?errh(T(#{<<"deliver_notifications">> => <<"yes">>})), 2641: ?errh(T(#{<<"deliver_payloads">> => 0})), 2642: ?errh(T(#{<<"max_items">> => -1})), 2643: ?errh(T(#{<<"max_payload_size">> => -1})), 2644: ?errh(T(#{<<"node_type">> => [<<"dag">>]})), 2645: ?errh(T(#{<<"notification_type">> => <<>>})), 2646: ?errh(T(#{<<"notify_config">> => <<"false">>})), 2647: ?errh(T(#{<<"notify_delete">> => [true]})), 2648: ?errh(T(#{<<"notify_retract">> => #{}})), 2649: ?errh(T(#{<<"persist_items">> => 1})), 2650: ?errh(T(#{<<"presence_based_delivery">> => []})), 2651: ?errh(T(#{<<"publish_model">> => <<"">>})), 2652: ?errh(T(#{<<"purge_offline">> => 1})), 2653: ?errh(T(#{<<"roster_groups_allowed">> => [<<>>]})), 2654: ?errh(T(#{<<"send_last_published_item">> => <<>>})), 2655: ?errh(T(#{<<"subscribe">> => <<"never">>})). 2656: 2657: mod_push_service_mongoosepush(_Config) -> 2658: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_push_service_mongoosepush">> => Opts}} end, 2659: M = fun(Cfg) -> modopts(mod_push_service_mongoosepush, Cfg) end, 2660: ?cfgh(M([{pool_name, test_pool}]), 2661: T(#{<<"pool_name">> => <<"test_pool">>})), 2662: ?cfgh(M([{api_version, "v3"}]), 2663: T(#{<<"api_version">> => <<"v3">>})), 2664: ?cfgh(M([{max_http_connections, 100}]), 2665: T(#{<<"max_http_connections">> => 100})), 2666: ?errh(T(#{<<"pool_name">> => 1})), 2667: ?errh(T(#{<<"api_version">> => <<"v4">>})), 2668: ?errh(T(#{<<"max_http_connections">> => -1})). 2669: 2670: mod_register(_Config) -> 2671: ?cfgh(modopts(mod_register, [{access,register}, 2672: {ip_access, [{allow,"127.0.0.0/8"}, 2673: {deny,"0.0.0.0"}]} 2674: ]), 2675: ip_access_register(<<"0.0.0.0">>)), 2676: ?cfgh(modopts(mod_register, [{access,register}, 2677: {ip_access, [{allow,"127.0.0.0/8"}, 2678: {deny,"0.0.0.4"}]} 2679: ]), 2680: ip_access_register(<<"0.0.0.4">>)), 2681: ?cfgh(modopts(mod_register, [{access,register}, 2682: {ip_access, [{allow,"127.0.0.0/8"}, 2683: {deny,"::1"}]} 2684: ]), 2685: ip_access_register(<<"::1">>)), 2686: ?cfgh(modopts(mod_register, [{access,register}, 2687: {ip_access, [{allow,"127.0.0.0/8"}, 2688: {deny,"::1/128"}]} 2689: ]), 2690: ip_access_register(<<"::1/128">>)), 2691: ?errh(invalid_ip_access_register()), 2692: ?errh(invalid_ip_access_register_ipv6()), 2693: ?errh(ip_access_register(<<"hello">>)), 2694: ?errh(ip_access_register(<<"0.d">>)), 2695: ?cfgh(modopts(mod_register, [{welcome_message, {"Subject", "Body"}}]), 2696: welcome_message()), 2697: %% List of jids 2698: ?cfgh(modopts(mod_register, [{registration_watchers, 2699: [<<"alice@bob">>, <<"ilovemongoose@help">>]}]), 2700: registration_watchers([<<"alice@bob">>, <<"ilovemongoose@help">>])), 2701: ?errh(registration_watchers([<<"alice@bob">>, <<"jids@have@no@feelings!">>])), 2702: %% non-negative integer 2703: ?cfgh(modopts(mod_register, [{password_strength, 42}]), 2704: password_strength_register(42)), 2705: ?errh(password_strength_register(<<"42">>)), 2706: ?errh(password_strength_register(<<"strong">>)), 2707: ?errh(password_strength_register(-150)), 2708: ?errh(welcome_message(<<"Subject">>, 1)), 2709: ?errh(welcome_message(1, <<"Body">>)), 2710: check_iqdisc(mod_register). 2711: 2712: welcome_message() -> 2713: welcome_message(<<"Subject">>, <<"Body">>). 2714: 2715: welcome_message(S, B) -> 2716: Opts = #{<<"welcome_message">> => #{<<"subject">> => S, <<"body">> => B}}, 2717: #{<<"modules">> => #{<<"mod_register">> => Opts}}. 2718: 2719: password_strength_register(Strength) -> 2720: Opts = #{<<"password_strength">> => Strength}, 2721: #{<<"modules">> => #{<<"mod_register">> => Opts}}. 2722: 2723: ip_access_register(Ip) -> 2724: Opts = #{<<"access">> => <<"register">>, 2725: <<"ip_access">> => 2726: [#{<<"address">> => <<"127.0.0.0/8">>, <<"policy">> => <<"allow">>}, 2727: #{<<"address">> => Ip, <<"policy">> => <<"deny">>}]}, 2728: #{<<"modules">> => #{<<"mod_register">> => Opts}}. 2729: 2730: invalid_ip_access_register() -> 2731: Opts = #{<<"access">> => <<"register">>, 2732: <<"ip_access">> => 2733: [#{<<"address">> => <<"127.0.0.0/8">>, <<"policy">> => <<"allawww">>}, 2734: #{<<"address">> => <<"8.8.8.8">>, <<"policy">> => <<"denyh">>}]}, 2735: #{<<"modules">> => #{<<"mod_register">> => Opts}}. 2736: 2737: invalid_ip_access_register_ipv6() -> 2738: Opts = #{<<"access">> => <<"register">>, 2739: <<"ip_access">> => 2740: [#{<<"address">> => <<"::1/129">>, <<"policy">> => <<"allow">>}]}, 2741: #{<<"modules">> => #{<<"mod_register">> => Opts}}. 2742: 2743: registration_watchers(JidBins) -> 2744: Opts = #{<<"registration_watchers">> => JidBins}, 2745: #{<<"modules">> => #{<<"mod_register">> => Opts}}. 2746: 2747: mod_roster(_Config) -> 2748: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_roster">> => Opts}} end, 2749: M = fun(Cfg) -> modopts(mod_roster, Cfg) end, 2750: 2751: ?cfgh(M([{versioning, false}]), 2752: T(#{<<"versioning">> => false})), 2753: ?cfgh(M([{store_current_id, false}]), 2754: T(#{<<"store_current_id">> => false})), 2755: ?cfgh(M([{backend, mnesia}]), 2756: T(#{<<"backend">> => <<"mnesia">>})), 2757: ?cfgh(M([{bucket_type, <<"rosters">>}]), 2758: T(#{<<"riak">> => #{<<"bucket_type">> => <<"rosters">>}})), 2759: ?cfgh(M([{version_bucket_type, <<"roster_versions">>}]), 2760: T(#{<<"riak">> => #{<<"version_bucket_type">> => <<"roster_versions">>}})), 2761: 2762: ?errh(T(#{<<"versioning">> => 1})), 2763: ?errh(T(#{<<"store_current_id">> => 1})), 2764: ?errh(T(#{<<"backend">> => 1})), 2765: ?errh(T(#{<<"backend">> => <<"iloveyou">>})), 2766: ?errh(T(#{<<"riak">> => #{<<"version_bucket_type">> => 1}})), 2767: ?errh(T(#{<<"riak">> => #{<<"bucket_type">> => 1}})), 2768: check_iqdisc(mod_roster). 2769: 2770: mod_shared_roster_ldap(_Config) -> 2771: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_shared_roster_ldap">> => Opts}} end, 2772: M = fun(Cfg) -> modopts(mod_shared_roster_ldap, Cfg) end, 2773: ?cfgh(M([{ldap_pool_tag, default}]), 2774: T(#{<<"ldap_pool_tag">> => <<"default">>})), 2775: ?cfgh(M([{ldap_base, "string"}]), 2776: T(#{<<"ldap_base">> => <<"string">>})), 2777: ?cfgh(M([{ldap_deref, never}]), 2778: T(#{<<"ldap_deref">> => <<"never">>})), 2779: %% Options: attributes 2780: ?cfgh(M([ {ldap_groupattr, "cn"}]), 2781: T(#{<<"ldap_groupattr">> => <<"cn">>})), 2782: ?cfgh(M([{ldap_groupdesc, "default"}]), 2783: T(#{<<"ldap_groupdesc">> => <<"default">>})), 2784: ?cfgh(M([{ldap_userdesc, "cn"}]), 2785: T(#{<<"ldap_userdesc">> => <<"cn">>})), 2786: ?cfgh(M([{ldap_useruid, "cn"}]), 2787: T(#{<<"ldap_useruid">> => <<"cn">>})), 2788: ?cfgh(M([{ldap_memberattr, "memberUid"}]), 2789: T(#{<<"ldap_memberattr">> => <<"memberUid">>})), 2790: ?cfgh(M([{ldap_memberattr_format, "%u"}]), 2791: T(#{<<"ldap_memberattr_format">> => <<"%u">>})), 2792: ?cfgh(M([{ldap_memberattr_format_re,""}]), 2793: T(#{<<"ldap_memberattr_format_re">> => <<"">>})), 2794: %% Options: parameters 2795: ?cfgh(M([ {ldap_auth_check, true}]), 2796: T(#{<<"ldap_auth_check">> => true})), 2797: ?cfgh(M([{ldap_user_cache_validity, 300}]), 2798: T(#{<<"ldap_user_cache_validity">> => 300})), 2799: ?cfgh(M([{ldap_group_cache_validity, 300}]), 2800: T(#{<<"ldap_group_cache_validity">> => 300})), 2801: ?cfgh(M([{ldap_user_cache_size, 300}]), 2802: T(#{<<"ldap_user_cache_size">> => 300})), 2803: ?cfgh(M([{ldap_group_cache_size, 300}]), 2804: T(#{<<"ldap_group_cache_size">> => 300})), 2805: %% Options: LDAP filters 2806: ?cfgh(M([{ldap_rfilter, "rfilter_test"}]), 2807: T(#{<<"ldap_rfilter">> => <<"rfilter_test">>})), 2808: ?cfgh(M([{ldap_gfilter, "gfilter_test"}]), 2809: T(#{<<"ldap_gfilter">> => <<"gfilter_test">>})), 2810: ?cfgh(M([{ldap_ufilter, "ufilter_test"}]), 2811: T(#{<<"ldap_ufilter">> => <<"ufilter_test">>})), 2812: ?cfgh(M([{ldap_filter, "filter_test"}]), 2813: T(#{<<"ldap_filter">> => <<"filter_test">>})), 2814: ?errh(T(#{<<"ldap_pool_tag">> => 1})), 2815: ?errh(T(#{<<"ldap_base">> => 1})), 2816: ?errh(T(#{<<"ldap_deref">> => 1})), 2817: %% Options: attributes 2818: ?errh(T(#{<<"ldap_groupattr">> => 1})), 2819: ?errh(T(#{<<"ldap_groupdesc">> => 1})), 2820: ?errh(T(#{<<"ldap_userdesc">> => 1})), 2821: ?errh(T(#{<<"ldap_useruid">> => 1})), 2822: ?errh(T(#{<<"ldap_memberattr">> => 1})), 2823: ?errh(T(#{<<"ldap_memberattr_format">> => 1})), 2824: ?errh(T(#{<<"ldap_memberattr_format_re">> => 1})), 2825: %% Options: parameters 2826: ?errh(T(#{<<"ldap_auth_check">> => 1})), 2827: ?errh(T(#{<<"ldap_user_cache_validity">> => -1})), 2828: ?errh(T(#{<<"ldap_group_cache_validity">> => -1})), 2829: ?errh(T(#{<<"ldap_user_cache_size">> => -1})), 2830: ?errh(T(#{<<"ldap_group_cache_size">> => -1})), 2831: %% Options: LDAP filters 2832: ?errh(T(#{<<"ldap_rfilter">> => 1})), 2833: ?errh(T(#{<<"ldap_gfilter">> => 1})), 2834: ?errh(T(#{<<"ldap_ufilter">> => 1})), 2835: ?errh(T(#{<<"ldap_filter">> => 1})). 2836: 2837: mod_sic(_Config) -> 2838: check_iqdisc(mod_sic), 2839: ?cfgh(modopts(mod_sic, []), #{<<"modules">> => #{<<"mod_sic">> => #{}}}). 2840: 2841: mod_stream_management(_Config) -> 2842: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_stream_management">> => Opts}} end, 2843: M = fun(Cfg) -> modopts(mod_stream_management, Cfg) end, 2844: ?cfgh(M([{buffer_max, no_buffer}]), T(#{<<"buffer">> => false})), 2845: ?cfgh(M([{buffer_max, 10}]), T(#{<<"buffer_max">> => 10})), 2846: ?cfgh(M([{ack_freq, never}]), T(#{<<"ack">> => false})), 2847: ?cfgh(M([{ack_freq, 1}]), T(#{<<"ack_freq">> => 1})), 2848: ?cfgh(M([{resume_timeout, 600}]), T(#{<<"resume_timeout">> => 600})), 2849: 2850: ?errh(T(#{<<"buffer">> => 0})), 2851: ?errh(T(#{<<"buffer_max">> => -1})), 2852: ?errh(T(#{<<"ack">> => <<"false">>})), 2853: ?errh(T(#{<<"ack_freq">> => 0})), 2854: ?errh(T(#{<<"resume_timeout">> => true})). 2855: 2856: mod_stream_management_stale_h(_Config) -> 2857: T = fun(Opts) -> #{<<"modules">> => 2858: #{<<"mod_stream_management">> => #{<<"stale_h">> => Opts}}} end, 2859: M = fun(Cfg) -> modopts(mod_stream_management, [{stale_h, Cfg}]) end, 2860: ?cfgh(M([{enabled, true}]), T(#{<<"enabled">> => true})), 2861: ?cfgh(M([{stale_h_repeat_after, 1800}]), T(#{<<"repeat_after">> => 1800})), 2862: ?cfgh(M([{stale_h_geriatric, 3600}]), T(#{<<"geriatric">> => 3600})), 2863: 2864: ?errh(T(#{<<"enabled">> => <<"true">>})), 2865: ?errh(T(#{<<"repeat_after">> => -1})), 2866: ?errh(T(#{<<"geriatric">> => <<"one">>})). 2867: 2868: mod_time(_Config) -> 2869: check_iqdisc(mod_time), 2870: ?cfgh(modopts(mod_time, []), #{<<"modules">> => #{<<"mod_time">> => #{}}}). 2871: 2872: mod_vcard(_Config) -> 2873: check_iqdisc(mod_vcard), 2874: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_vcard">> => Opts}} end, 2875: M = fun(Cfg) -> modopts(mod_vcard, Cfg) end, 2876: ?cfgh(M([{iqdisc, one_queue}]), 2877: T(#{<<"iqdisc">> => #{<<"type">> => <<"one_queue">>}})), 2878: ?cfgh(M([{host, {prefix, <<"vjud.">>}}]), 2879: T(#{<<"host">> => <<"vjud.@HOST@">>})), 2880: ?cfgh(M([{host, {fqdn, <<"vjud.test">>}}]), 2881: T(#{<<"host">> => <<"vjud.test">>})), 2882: ?cfgh(M([{search, true}]), 2883: T(#{<<"search">> => true})), 2884: ?cfgh(M([{backend, mnesia}]), 2885: T(#{<<"backend">> => <<"mnesia">>})), 2886: ?cfgh(M([{matches, infinity}]), 2887: T(#{<<"matches">> => <<"infinity">>})), 2888: %% ldap 2889: ?cfgh(M([{ldap_pool_tag, default}]), 2890: T(#{<<"ldap_pool_tag">> => <<"default">>})), 2891: ?cfgh(M([{ldap_base, "ou=Users,dc=ejd,dc=com"}]), 2892: T(#{<<"ldap_base">> => <<"ou=Users,dc=ejd,dc=com">>})), 2893: ?cfgh(M([{ldap_filter, <<"(&(objectClass=shadowAccount)(memberOf=Jabber Users))">>}]), 2894: T(#{<<"ldap_filter">> => <<"(&(objectClass=shadowAccount)(memberOf=Jabber Users))">>})), 2895: ?cfgh(M([{ldap_deref, never}]), 2896: T(#{<<"ldap_deref">> => <<"never">>})), 2897: ?cfgh(M([{ldap_search_operator, 'or'}]), 2898: T(#{<<"ldap_search_operator">> => <<"or">>})), 2899: ?cfgh(M([{ldap_binary_search_fields, [<<"PHOTO">>]}]), 2900: T(#{<<"ldap_binary_search_fields">> => [<<"PHOTO">>]})), 2901: %% riak 2902: ?cfgh(M([{bucket_type, <<"vcard">>}]), 2903: T(#{<<"riak">> => #{<<"bucket_type">> => <<"vcard">>}})), 2904: ?cfgh(M([{search_index, <<"vcard">>}]), 2905: T(#{<<"riak">> => #{<<"search_index">> => <<"vcard">>}})), 2906: 2907: ?errh(T(#{<<"host">> => 1})), 2908: ?errh(T(#{<<"host">> => <<"is this a host? no.">>})), 2909: ?errh(T(#{<<"host">> => [<<"invalid.sub@HOST@">>]})), 2910: ?errh(T(#{<<"host">> => [<<"invalid.sub.@HOST@.as.well">>]})), 2911: ?errh(T(#{<<"search">> => 1})), 2912: ?errh(T(#{<<"backend">> => <<"mememesia">>})), 2913: ?errh(T(#{<<"matches">> => -1})), 2914: %% ldap 2915: ?errh(T(#{<<"ldap_pool_tag">> => -1})), 2916: ?errh(T(#{<<"ldap_base">> => -1})), 2917: ?errh(T(#{<<"ldap_field">> => -1})), 2918: ?errh(T(#{<<"ldap_deref">> => <<"nevernever">>})), 2919: ?errh(T(#{<<"ldap_search_operator">> => <<"more">>})), 2920: ?errh(T(#{<<"ldap_binary_search_fields">> => [1]})), 2921: %% riak 2922: ?errh(T(#{<<"riak">> => #{<<"bucket_type">> => 1}})), 2923: ?errh(T(#{<<"riak">> => #{<<"search_index">> => 1}})). 2924: 2925: mod_vcard_ldap_uids(_Config) -> 2926: T = fun(Opts) -> #{<<"modules">> => 2927: #{<<"mod_vcard">> => #{<<"ldap_uids">> => Opts}}} end, 2928: M = fun(Cfg) -> modopts(mod_vcard, [{ldap_uids, Cfg}]) end, 2929: RequiredOpts = #{<<"attr">> => <<"name">>}, 2930: ExpectedCfg = <<"name">>, 2931: ?cfgh(M([]), T([])), 2932: ?cfgh(M([ExpectedCfg]), T([RequiredOpts])), 2933: ?cfgh(M([{<<"name">>, <<"%u@mail.example.org">>}]), 2934: T([RequiredOpts#{<<"format">> => <<"%u@mail.example.org">>}])), 2935: ?cfgh(M([{<<"name">>, <<"%u@mail.example.org">>}, ExpectedCfg]), 2936: T([RequiredOpts#{<<"format">> => <<"%u@mail.example.org">>}, RequiredOpts])), 2937: [?errh(T([maps:remove(Key, RequiredOpts)])) || Key <- maps:keys(RequiredOpts)], 2938: ?errh(T(RequiredOpts#{<<"attr">> := 1})), 2939: ?errh(T(RequiredOpts#{<<"format">> => true})). 2940: 2941: mod_vcard_ldap_vcard_map(_Config) -> 2942: T = fun(Opts) -> #{<<"modules">> => 2943: #{<<"mod_vcard">> => #{<<"ldap_vcard_map">> => Opts}}} end, 2944: M = fun(Cfg) -> modopts(mod_vcard, [{ldap_vcard_map, Cfg}]) end, 2945: RequiredOpts = #{<<"vcard_field">> => <<"FAMILY">>, 2946: <<"ldap_pattern">> => <<"%s">>, 2947: <<"ldap_field">> => <<"sn">>}, 2948: ExpectedCfg = {<<"FAMILY">>, <<"%s">>, [<<"sn">>]}, 2949: ?cfgh(M([]), T([])), 2950: ?cfgh(M([ExpectedCfg]), T([RequiredOpts])), 2951: [?errh(T([maps:remove(Key, RequiredOpts)])) || Key <- maps:keys(RequiredOpts)], 2952: ?errh(T(RequiredOpts#{<<"vcard_field">> := false})), 2953: ?errh(T(RequiredOpts#{<<"ldap_pattern">> := false})), 2954: ?errh(T(RequiredOpts#{<<"ldap_field">> := -1})). 2955: 2956: mod_vcard_ldap_search_fields(_Config) -> 2957: T = fun(Opts) -> #{<<"modules">> => 2958: #{<<"mod_vcard">> => #{<<"ldap_search_fields">> => Opts}}} end, 2959: M = fun(Cfg) -> modopts(mod_vcard, [{ldap_search_fields, Cfg}]) end, 2960: RequiredOpts = #{<<"search_field">> => <<"Full Name">>, 2961: <<"ldap_field">> => <<"cn">>}, 2962: ExpectedCfg = {<<"Full Name">>, <<"cn">>}, 2963: ?cfgh(M([]), T([])), 2964: ?cfgh(M([ExpectedCfg]), T([RequiredOpts])), 2965: [?errh(T([maps:remove(Key, RequiredOpts)])) || Key <- maps:keys(RequiredOpts)], 2966: ?errh(T(RequiredOpts#{<<"search_field">> := false})), 2967: ?errh(T(RequiredOpts#{<<"ldap_field">> := -1})). 2968: 2969: mod_vcard_ldap_search_reported(_Config) -> 2970: T = fun(Opts) -> #{<<"modules">> => 2971: #{<<"mod_vcard">> => #{<<"ldap_search_reported">> => Opts}}} end, 2972: M = fun(Cfg) -> modopts(mod_vcard, [{ldap_search_reported, Cfg}]) end, 2973: RequiredOpts = #{<<"search_field">> => <<"Full Name">>, 2974: <<"vcard_field">> => <<"FN">>}, 2975: ExpectedCfg = {<<"Full Name">>, <<"FN">>}, 2976: ?cfgh(M([]), T([])), 2977: ?cfgh(M([ExpectedCfg]), T([RequiredOpts])), 2978: [?errh(T([maps:remove(Key, RequiredOpts)])) || Key <- maps:keys(RequiredOpts)], 2979: ?errh(T(RequiredOpts#{<<"search_field">> := false})), 2980: ?errh(T(RequiredOpts#{<<"vcard_field">> := -1})). 2981: 2982: mod_version(_Config) -> 2983: T = fun(Opts) -> #{<<"modules">> => #{<<"mod_version">> => Opts}} end, 2984: ?cfgh(modopts(mod_version, [{os_info, false}]), T(#{<<"os_info">> => false})), 2985: ?errh(T(#{<<"os_info">> => 1})), 2986: check_iqdisc(mod_version). 2987: 2988: modules_without_config(_Config) -> 2989: ?cfgh(modopts(mod_amp, []), #{<<"modules">> => #{<<"mod_amp">> => #{}}}), 2990: ?errh(#{<<"modules">> => #{<<"mod_wrong">> => #{}}}). 2991: 2992: incorrect_module(_Config) -> 2993: ?errh(#{<<"modules">> => #{<<"mod_incorrect">> => #{}}}). 2994: 2995: %% Services 2996: 2997: service_admin_extra(_Config) -> 2998: T = fun(Opts) -> #{<<"services">> => #{<<"service_admin_extra">> => Opts}} end, 2999: ?cfg(servopts(service_admin_extra, [{submods, [node]}]), 3000: T(#{<<"submods">> => [<<"node">>]})), 3001: ?err(T(#{<<"submods">> => 1})), 3002: ?err(T(#{<<"submods">> => [1]})), 3003: ?err(T(#{<<"submods">> => [<<"nodejshaha">>]})), 3004: ok. 3005: 3006: service_mongoose_system_metrics(_Config) -> 3007: M = service_mongoose_system_metrics, 3008: T = fun(Opts) -> #{<<"services">> => #{<<"service_mongoose_system_metrics">> => Opts}} end, 3009: ?cfg(servopts(M, [{initial_report, 5000}]), 3010: T(#{<<"initial_report">> => 5000})), 3011: ?cfg(servopts(M, [{periodic_report, 5000}]), 3012: T(#{<<"periodic_report">> => 5000})), 3013: ?cfg(servopts(M, [{tracking_id, "UA-123456789"}]), 3014: T(#{<<"tracking_id">> => <<"UA-123456789">>})), 3015: ?cfg(servopts(M, [no_report]), 3016: T(#{<<"report">> => false})), 3017: %% error cases 3018: ?err(T(#{<<"initial_report">> => <<"forever">>})), 3019: ?err(T(#{<<"periodic_report">> => <<"forever">>})), 3020: ?err(T(#{<<"initial_report">> => -1})), 3021: ?err(T(#{<<"periodic_report">> => -1})), 3022: ?err(T(#{<<"tracking_id">> => 666})), 3023: ok. 3024: 3025: %% Helpers for module tests 3026: 3027: iqdisc({queues, Workers}) -> #{<<"type">> => <<"queues">>, <<"workers">> => Workers}; 3028: iqdisc(Atom) -> #{<<"type">> => atom_to_binary(Atom, utf8)}. 3029: 3030: iq_disc_generic(Module, RequiredOpts, Value) -> 3031: Opts = RequiredOpts#{<<"iqdisc">> => Value}, 3032: #{<<"modules">> => #{atom_to_binary(Module, utf8) => Opts}}. 3033: 3034: check_iqdisc(Module) -> 3035: check_iqdisc(Module, [], #{}). 3036: 3037: check_iqdisc(Module, ExpectedCfg, RequiredOpts) -> 3038: ?cfgh(modopts(Module, ExpectedCfg ++ [{iqdisc, {queues, 10}}]), 3039: iq_disc_generic(Module, RequiredOpts, iqdisc({queues, 10}))), 3040: ?cfgh(modopts(Module, ExpectedCfg ++ [{iqdisc, parallel}]), 3041: iq_disc_generic(Module, RequiredOpts, iqdisc(parallel))), 3042: ?errh(iq_disc_generic(Module, RequiredOpts, iqdisc(bad_haha))). 3043: 3044: modopts(Mod, Opts) -> 3045: [{[modules, Mod], Opts}]. 3046: 3047: servopts(Service, Opts) -> 3048: [{services, [{Service, Opts}]}]. 3049: 3050: %% helpers for 'listen' tests 3051: 3052: listener_config(Mod, Opts) -> 3053: [{listen, [listener(Mod, Opts)]}]. 3054: 3055: listener(Mod, Opts) -> 3056: maps:merge(#{port => 5222, 3057: ip_address => "0", 3058: ip_tuple => {0, 0, 0, 0}, 3059: ip_version => 4, 3060: proto => tcp, 3061: module => Mod}, Opts). 3062: 3063: http_handler_raw(Type, Opts) -> 3064: listen_raw(<<"http">>, #{<<"handlers">> => 3065: #{Type => 3066: [Opts#{<<"host">> => <<"localhost">>, 3067: <<"path">> => <<"/api">>}] 3068: }}). 3069: 3070: listen_raw(Type, Opts) -> 3071: #{<<"listen">> => #{Type => [Opts#{<<"port">> => 5222}]}}. 3072: 3073: %% helpers for 'auth' tests 3074: 3075: auth_ldap_raw(Opts) -> 3076: auth_raw(<<"ldap">>, Opts). 3077: 3078: auth_raw(Method, Opts) -> 3079: #{<<"auth">> => #{Method => Opts}}. 3080: 3081: %% helpers for 'pool' tests 3082: 3083: pool_config(Pool) -> 3084: [{outgoing_pools, [Pool]}]. 3085: 3086: pool_raw(Type, Tag, Opts) -> 3087: #{<<"outgoing_pools">> => #{Type => #{Tag => Opts}}}. 3088: 3089: pool_conn_raw(Type, Opts) -> 3090: #{<<"outgoing_pools">> => #{Type => #{<<"default">> => #{<<"connection">> => Opts}}}}. 3091: 3092: rdbms_opts() -> 3093: #{<<"driver">> => <<"pgsql">>, 3094: <<"host">> => <<"localhost">>, 3095: <<"database">> => <<"db">>, 3096: <<"username">> => <<"dbuser">>, 3097: <<"password">> => <<"secret">>}. 3098: 3099: %% helpers for 'access' tests 3100: 3101: access_raw(RuleName, RuleSpec) -> 3102: #{<<"access">> => #{RuleName => RuleSpec}}. 3103: 3104: %% helpers for 'host_config' tests 3105: 3106: host_config(Config) -> 3107: #{<<"host_config">> => [Config#{<<"host_type">> => ?HOST}]}. 3108: 3109: %% helpers for parsing 3110: 3111: -spec parse(map()) -> [mongoose_config_parser_toml:config()]. 3112: parse(M0) -> 3113: %% As 'hosts' (or 'host_types') and 'default_server_domain' options are mandatory, 3114: %% this function inserts them with dummy values if they are missing. 3115: %% To prevent the insertion, add a 'without' option to the map, e.g. without => [<<"hosts">>] 3116: %% The resulting map is then passed to the TOML config parser. 3117: M = maybe_insert_dummy_domain(M0), 3118: mongoose_config_parser:get_opts(mongoose_config_parser_toml:process(M)). 3119: 3120: maybe_insert_dummy_domain(M) -> 3121: DummyGenM = #{<<"default_server_domain">> => ?HOST, 3122: <<"hosts">> => [?HOST]}, 3123: {FilteredGenM, RawConfig} = case maps:take(without, M) of 3124: {Keys, Cfg} -> {maps:without(Keys, DummyGenM), Cfg}; 3125: error -> {DummyGenM, M} 3126: end, 3127: OldGenM = maps:get(<<"general">>, RawConfig, #{}), 3128: NewGenM = maps:merge(FilteredGenM, OldGenM), 3129: RawConfig#{<<"general">> => NewGenM}. 3130: 3131: %% helpers for testing individual options 3132: 3133: -spec host_opts([{key_prefix(), mongoose_config:value()}]) -> 3134: [{mongoose_config:key() | mongoose_config:key_path(), mongoose_config:value()}]. 3135: host_opts(ExpectedOptions) -> 3136: [{host_key(Key), Value} || {Key, Value} <- ExpectedOptions]. 3137: 3138: %% @doc Build full per-host config key for host-or-global options 3139: -spec host_key(top_level_key_prefix()) -> mongoose_config:key(); 3140: (key_path_prefix()) -> mongoose_config:key_path(). 3141: host_key([TopKey | Rest]) when is_atom(TopKey) -> 3142: [{TopKey, ?HOST} | Rest]; 3143: host_key(Key) when is_atom(Key) -> 3144: {Key, ?HOST}. 3145: 3146: -spec assert_options([{mongoose_config:key() | mongoose_config:key_path(), mongoose_config:value()}], 3147: [mongoose_config_parser_toml:config()]) -> any(). 3148: assert_options(ExpectedOptions, Config) -> 3149: lists:foreach(fun({Key, Value}) -> assert_option(Key, Value, Config) end, ExpectedOptions). 3150: 3151: -spec assert_option(mongoose_config:key() | mongoose_config:key_path(), mongoose_config:value(), 3152: [mongoose_config_parser_toml:config()]) -> any(). 3153: assert_option(KeyPath, Value, Config) when is_list(KeyPath) -> 3154: compare_nodes(KeyPath, Value, get_config_value(KeyPath, Config)); 3155: assert_option(Key, Value, Config) -> 3156: assert_option([Key], Value, Config). 3157: 3158: -spec get_config_value(mongoose_config:key_path(), [mongoose_config_parser_toml:config()]) -> 3159: mongoose_config:value(). 3160: get_config_value([TopKey | Rest], Config) -> 3161: case lists:keyfind(TopKey, 1, Config) of 3162: false -> ct:fail({"option not found", TopKey, Config}); 3163: {_, TopValue} -> lists:foldl(fun maps:get/2, TopValue, Rest) 3164: end. 3165: 3166: -spec assert_error([mongoose_config_parser_toml:config()]) -> 3167: [mongoose_config_parser_toml:config_error()]. 3168: assert_error(Config) -> 3169: case extract_errors(Config) of 3170: [] -> 3171: ct:fail({"Expected errors but found none", Config}); 3172: Errors -> 3173: [?assertMatch(#{class := error, 3174: what := toml_processing_failed}, Error) || Error <- Errors], 3175: Errors 3176: end. 3177: 3178: %% helpers for file tests 3179: 3180: test_config_file(Config, File) -> 3181: OptionsPath = ejabberd_helper:data(Config, File ++ ".options"), 3182: ExpectedOpts = config_parser_helper:options(File), 3183: 3184: TOMLPath = ejabberd_helper:data(Config, File ++ ".toml"), 3185: State = mongoose_config_parser:parse_file(TOMLPath), 3186: TOMLOpts = mongoose_config_parser:get_opts(State), 3187: 3188: %% Save the parsed TOML options 3189: %% - for debugging 3190: %% - to update tests after a config change - always check the diff! 3191: save_opts(OptionsPath ++ ".parsed", TOMLOpts), 3192: compare_config(ExpectedOpts, TOMLOpts). 3193: 3194: save_opts(Path, Opts) -> 3195: FormattedOpts = [io_lib:format("~p.~n", [Opt]) || Opt <- lists:sort(Opts)], 3196: file:write_file(Path, FormattedOpts). 3197: 3198: compare_config(C1, C2) -> 3199: compare_unordered_lists(C1, C2, fun handle_config_option/2). 3200: 3201: handle_config_option({K1, V1}, {K2, V2}) -> 3202: ?eq(K1, K2), 3203: compare_nodes([K1], V1, V2); 3204: handle_config_option(Opt1, Opt2) -> 3205: ?eq(Opt1, Opt2). 3206: 3207: %% Comparisons for config options that have paths (top-level or nested in maps) 3208: 3209: -spec compare_nodes(mongoose_config:key_path(), mongoose_config:value(), mongoose_config:value()) -> 3210: any(). 3211: compare_nodes([listen], V1, V2) -> 3212: compare_unordered_lists(V1, V2, fun handle_listener/2); 3213: compare_nodes([outgoing_pools], V1, V2) -> 3214: compare_unordered_lists(V1, V2, fun handle_conn_pool/2); 3215: compare_nodes([services], V1, V2) -> 3216: compare_unordered_lists(V1, V2, fun handle_item_with_opts/2); 3217: compare_nodes([{auth_method, _}], V1, V2) when is_atom(V1) -> 3218: ?eq([V1], V2); 3219: compare_nodes([{s2s_addr, _}], {_, _, _, _} = IP1, IP2) -> 3220: ?eq(inet:ntoa(IP1), IP2); 3221: compare_nodes([s2s_dns_options], V1, V2) -> 3222: compare_unordered_lists(V1, V2); 3223: compare_nodes([{modules, _}, mod_extdisco], V1, V2) -> 3224: compare_ordered_lists(V1, V2, fun compare_unordered_lists/2); 3225: compare_nodes([{modules, _}, _Module], V1, V2) -> 3226: compare_unordered_lists(V1, V2, fun handle_module_options/2); 3227: compare_nodes(Node, V1, V2) when is_map(V1), is_map(V2) -> 3228: compare_maps(V1, V2, fun({K1, MV1}, {K2, MV2}) -> 3229: ?eq(K1, K2), 3230: compare_nodes(Node ++ [K1], MV1, MV2) 3231: end); 3232: compare_nodes(Node, V1, V2) -> 3233: ?eq({Node, V1}, {Node, V2}). 3234: 3235: %% Comparisons of internal config option parts 3236: 3237: handle_listener(V1, V2) -> 3238: compare_maps(V1, V2, fun handle_listener_option/2). 3239: 3240: handle_listener_option({tls, O1}, {tls, O2}) -> 3241: compare_unordered_lists(O1, O2); 3242: handle_listener_option({modules, M1}, {modules, M2}) -> 3243: compare_unordered_lists(M1, M2, fun handle_listener_module/2); 3244: handle_listener_option({transport_options, O1}, {transport_options, O2}) -> 3245: compare_unordered_lists(O1, O2); 3246: handle_listener_option(V1, V2) -> ?eq(V1, V2). 3247: 3248: handle_listener_module({H1, P1, M1}, M2) -> 3249: handle_listener_module({H1, P1, M1, []}, M2); 3250: handle_listener_module({H1, P1, M1, O1}, {H2, P2, M2, O2}) -> 3251: ?eq(H1, H2), 3252: ?eq(P1, P2), 3253: ?eq(M1, M2), 3254: compare_listener_module_options(M1, O1, O2). 3255: 3256: compare_listener_module_options(mod_websockets, L1, L2) -> 3257: E1 = proplists:get_value(ejabberd_service, L1, []), 3258: E2 = proplists:get_value(ejabberd_service, L2, []), 3259: T1 = proplists:delete(ejabberd_service, L1), 3260: T2 = proplists:delete(ejabberd_service, L2), 3261: compare_unordered_lists(E1, E2), 3262: compare_unordered_lists(T1, T2); 3263: compare_listener_module_options(_, O1, O2) -> 3264: ?eq(O1, O2). 3265: 3266: handle_item_with_opts({M1, O1}, {M2, O2}) -> 3267: ?eq(M1, M2), 3268: compare_unordered_lists(O1, O2). 3269: 3270: handle_conn_pool({Type1, Scope1, Tag1, POpts1, COpts1}, 3271: {Type2, Scope2, Tag2, POpts2, COpts2}) -> 3272: ?eq(Type1, Type2), 3273: ?eq(Scope1, Scope2), 3274: ?eq(Tag1, Tag2), 3275: compare_unordered_lists(POpts1, POpts2), 3276: compare_unordered_lists(COpts1, COpts2, fun handle_conn_opt/2). 3277: 3278: handle_conn_opt({server, {D1, H1, DB1, U1, P1, O1}}, 3279: {server, {D2, H2, DB2, U2, P2, O2}}) -> 3280: ?eq(D1, D2), 3281: ?eq(H1, H2), 3282: ?eq(DB1, DB2), 3283: ?eq(U1, U2), 3284: ?eq(P1, P2), 3285: compare_unordered_lists(O1, O2, fun handle_db_server_opt/2); 3286: handle_conn_opt(V1, V2) -> ?eq(V1, V2). 3287: 3288: handle_db_server_opt({ssl_opts, O1}, {ssl_opts, O2}) -> 3289: compare_unordered_lists(O1, O2); 3290: handle_db_server_opt(V1, V2) -> ?eq(V1, V2). 3291: 3292: handle_module_options({configs, [Configs1]}, {configs, [Configs2]}) -> 3293: compare_unordered_lists(Configs1, Configs2, fun handle_module_options/2); 3294: handle_module_options({Name, Opts = [{_, _}|_]}, {Name2, Opts2 = [{_, _}|_]}) -> 3295: ?eq(Name, Name2), 3296: compare_unordered_lists(Opts, Opts2, fun handle_module_options/2); 3297: handle_module_options(V1, V2) -> 3298: ?eq(V1, V2). 3299: 3300: %% Generic assertions, use the 'F' handler for any custom cases 3301: compare_unordered_lists(L1, L2) -> 3302: compare_unordered_lists(L1, L2, fun(V1, V2) -> ?eq(V1, V2) end). 3303: 3304: compare_unordered_lists(L1, L2, F) -> 3305: SL1 = lists:sort(L1), 3306: SL2 = lists:sort(L2), 3307: compare_ordered_lists(SL1, SL2, F). 3308: 3309: compare_ordered_lists([H1|T1], [H1|T2], F) -> 3310: compare_ordered_lists(T1, T2, F); 3311: compare_ordered_lists([H1|T1] = L1, [H2|T2] = L2, F) -> 3312: try F(H1, H2) 3313: catch error:R:S -> 3314: ct:fail({"Failed to compare ordered lists", L1, L2, R, S}) 3315: end, 3316: compare_ordered_lists(T1, T2, F); 3317: compare_ordered_lists([], [], _) -> 3318: ok. 3319: 3320: compare_maps(M1, M2) -> 3321: compare_maps(M1, M2, fun(V1, V2) -> ?eq(V1, V2) end). 3322: 3323: compare_maps(M1, M2, F) -> 3324: compare_unordered_lists(maps:to_list(M1), maps:to_list(M2), F). 3325: 3326: create_files(Config) -> 3327: %% The files must exist for validation to pass 3328: Root = small_path_helper:repo_dir(Config), 3329: file:make_dir("priv"), 3330: PrivkeyPath = filename:join(Root, "tools/ssl/mongooseim/privkey.pem"), 3331: CertPath = filename:join(Root, "tools/ssl/mongooseim/cert.pem"), 3332: CaPath = filename:join(Root, "tools/ssl/ca/cacert.pem"), 3333: DHPath = filename:join(Root, "tools/ssl/mongooseim/dh_server.pem"), 3334: ok = file:write_file("priv/access_psk", ""), 3335: ok = file:write_file("priv/provision_psk", ""), 3336: ok = filelib:ensure_dir("www/muc/dummy"), 3337: ensure_copied(CaPath, "priv/ca.pem"), 3338: ensure_copied(CertPath, "priv/cert.pem"), 3339: ensure_copied(PrivkeyPath, "priv/dc1.pem"), 3340: ensure_copied(DHPath, "priv/dh.pem"). 3341: 3342: ensure_copied(From, To) -> 3343: case file:copy(From, To) of 3344: {ok,_} -> 3345: ok; 3346: Other -> 3347: error(#{what => ensure_copied_failed, from => From, to => To, 3348: reason => Other}) 3349: end.