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