From 225ba39bb9d51ffc28397d3856192370679afd0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chrz=C4=85szcz?= Date: Thu, 5 Nov 2020 17:39:20 +0100 Subject: [PATCH 1/3] Sort expected TOML options for easier debugging --- test/config_parser_SUITE.erl | 8 +- .../miscellaneous.options | 50 +- test/config_parser_SUITE_data/modules.options | 520 +++++++++--------- .../mongooseim-pgsql.options | 270 ++++----- .../outgoing_pools.options | 56 +- .../config_parser_SUITE_data/s2s_only.options | 4 +- 6 files changed, 455 insertions(+), 453 deletions(-) diff --git a/test/config_parser_SUITE.erl b/test/config_parser_SUITE.erl index 69176b2b90..139a578786 100644 --- a/test/config_parser_SUITE.erl +++ b/test/config_parser_SUITE.erl @@ -3025,11 +3025,13 @@ test_config_file(Config, File) -> %% Save the parsed TOML options %% - for debugging %% - to update tests after a config change - always check the diff! - FormattedOpts = [io_lib:format("~p.~n", [Opt]) || Opt <- TOMLOpts], - file:write_file(OptionsPath ++ "-parsed", lists:sort(FormattedOpts)), - + save_opts(OptionsPath ++ ".parsed", TOMLOpts), compare_config(ExpectedOpts, TOMLOpts). +save_opts(Path, Opts) -> + FormattedOpts = [io_lib:format("~p.~n", [Opt]) || Opt <- lists:sort(Opts)], + file:write_file(Path, FormattedOpts). + compare_config(C1, C2) -> compare_unordered_lists(C1, C2, fun handle_config_option/2). diff --git a/test/config_parser_SUITE_data/miscellaneous.options b/test/config_parser_SUITE_data/miscellaneous.options index 69b435f4b9..5876cff55b 100644 --- a/test/config_parser_SUITE_data/miscellaneous.options +++ b/test/config_parser_SUITE_data/miscellaneous.options @@ -3,14 +3,14 @@ {local_config,listen, [{{5280,{0,0,0,0},tcp}, ejabberd_cowboy, - [{transport_options,[{num_acceptors,10},{max_connections,1024}]}, - {modules, + [{modules, [{"_","/ws-xmpp",mod_websockets, [{ejabberd_service, [{access,all}, - {shaper_rule,fast}, + {max_fsm_queue,1000}, {password,"secret"}, - {max_fsm_queue,1000}]}]}]}]}]}. + {shaper_rule,fast}]}]}]}, + {transport_options,[{max_connections,1024},{num_acceptors,10}]}]}]}. {local_config,mongooseimctl_access_commands, [{local,["join_cluster"],[{node,"mongooseim@prime"}]}]}. {local_config,rdbms_server_type,mssql}. @@ -18,43 +18,43 @@ [mongoose_router_global,mongoose_router_localdomain]}. {local_config,services, [{service_mongoose_system_metrics, - [report, - {initial_report,300000}, + [{initial_report,300000}, {periodic_report,10800000}, + report, {tracking_id,"UA-123456789"}]}]}. {local_config,{allow_multiple_connections,<<"anonymous.localhost">>},true}. {local_config,{allow_multiple_connections,<<"localhost">>},true}. {local_config,{anonymous_protocol,<<"anonymous.localhost">>},sasl_anon}. {local_config,{anonymous_protocol,<<"localhost">>},sasl_anon}. {local_config,{auth_opts,<<"anonymous.localhost">>}, - [{ldap_pool_tag,default}, - {ldap_bind_pool_tag,bind}, - {ldap_base,"ou=Users,dc=esl,dc=com"}, - {ldap_uids,["uid",{"uid2","%u"}]}, - {ldap_filter,"(&(objectClass=shadowAccount)(memberOf=Jabber Users))"}, - {ldap_dn_filter,{"(&(name=%s)(owner=%D)(user=%u@%d))",["sn"]}}, - {ldap_local_filter,{equal,{"accountStatus",["enabled"]}}}, - {ldap_deref,never}, - {extauth_program,"/usr/bin/authenticator"}, + [{extauth_program,"/usr/bin/authenticator"}, {basic_auth,"admin:admin"}, - {jwt_secret,"secret123"}, {jwt_algorithm,"RS256"}, + {jwt_secret,"secret123"}, {jwt_username_key,user}, - {bucket_type,<<"user_bucket">>}]}. -{local_config,{auth_opts,<<"localhost">>}, - [{ldap_pool_tag,default}, - {ldap_bind_pool_tag,bind}, {ldap_base,"ou=Users,dc=esl,dc=com"}, - {ldap_uids,["uid",{"uid2","%u"}]}, - {ldap_filter,"(&(objectClass=shadowAccount)(memberOf=Jabber Users))"}, + {ldap_bind_pool_tag,bind}, + {ldap_deref,never}, {ldap_dn_filter,{"(&(name=%s)(owner=%D)(user=%u@%d))",["sn"]}}, + {ldap_filter,"(&(objectClass=shadowAccount)(memberOf=Jabber Users))"}, {ldap_local_filter,{equal,{"accountStatus",["enabled"]}}}, - {ldap_deref,never}, - {extauth_program,"/usr/bin/authenticator"}, + {ldap_pool_tag,default}, + {ldap_uids,["uid",{"uid2","%u"}]}, + {bucket_type,<<"user_bucket">>}]}. +{local_config,{auth_opts,<<"localhost">>}, + [{extauth_program,"/usr/bin/authenticator"}, {basic_auth,"admin:admin"}, - {jwt_secret,"secret123"}, {jwt_algorithm,"RS256"}, + {jwt_secret,"secret123"}, {jwt_username_key,user}, + {ldap_base,"ou=Users,dc=esl,dc=com"}, + {ldap_bind_pool_tag,bind}, + {ldap_deref,never}, + {ldap_dn_filter,{"(&(name=%s)(owner=%D)(user=%u@%d))",["sn"]}}, + {ldap_filter,"(&(objectClass=shadowAccount)(memberOf=Jabber Users))"}, + {ldap_local_filter,{equal,{"accountStatus",["enabled"]}}}, + {ldap_pool_tag,default}, + {ldap_uids,["uid",{"uid2","%u"}]}, {bucket_type,<<"user_bucket">>}]}. {local_config,{extauth_instances,<<"anonymous.localhost">>},1}. {local_config,{extauth_instances,<<"localhost">>},1}. diff --git a/test/config_parser_SUITE_data/modules.options b/test/config_parser_SUITE_data/modules.options index e53c5f9292..e8258328a9 100644 --- a/test/config_parser_SUITE_data/modules.options +++ b/test/config_parser_SUITE_data/modules.options @@ -2,76 +2,76 @@ {local_config, {modules,<<"dummy_host">>}, [{mod_jingle_sip, - [{proxy_host,"localhost"}, - {proxy_port,5600}, - {listen_port,5600}, + [{listen_port,5600}, {local_host,"localhost"}, + {proxy_host,"localhost"}, + {proxy_port,5600}, {sdp_origin,"127.0.0.1"}]}, {mod_shared_roster_ldap, [{ldap_base,"ou=Users,dc=ejd,dc=com"}, + {ldap_filter,"(objectClass=inetOrgPerson)"}, + {ldap_group_cache_validity,1}, {ldap_groupattr,"ou"}, {ldap_memberattr,"cn"}, - {ldap_userdesc,"cn"}, - {ldap_filter,"(objectClass=inetOrgPerson)"}, {ldap_rfilter,"(objectClass=inetOrgPerson)"}, - {ldap_group_cache_validity,1}, - {ldap_user_cache_validity,1}]}, + {ldap_user_cache_validity,1}, + {ldap_userdesc,"cn"}]}, {mod_mam_rdbms_user,[muc,pm]}, {mod_global_distrib, - [{global_host,"example.com"}, - {local_host,"datacenter1.example.com"}, + [{bounce,[{max_retries,3},{resend_after_ms,300}]}, + {cache,[{domain_lifetime_seconds,60}]}, {connections, - [{endpoints,[{"172.16.0.2",5555}]}, - {advertised_endpoints,[{"172.16.0.2",5555}]}, + [{advertised_endpoints,[{"172.16.0.2",5555}]}, {connections_per_endpoint,30}, - {tls_opts,[{certfile,"priv/dc1.pem"},{cafile,"priv/ca.pem"}]}]}, - {cache,[{domain_lifetime_seconds,60}]}, - {bounce,[{resend_after_ms,300},{max_retries,3}]}, + {endpoints,[{"172.16.0.2",5555}]}, + {tls_opts,[{cafile,"priv/ca.pem"},{certfile,"priv/dc1.pem"}]}]}, + {global_host,"example.com"}, + {local_host,"datacenter1.example.com"}, {redis,[{pool,global_distrib}]}]}, {mod_register, - [{welcome_message,{"Subject","Body"}}, - {access,all}, + [{access,all}, + {password_strength,32}, {registration_watchers,[<<"JID1">>,<<"JID2">>]}, - {password_strength,32}]}, + {welcome_message,{"Subject","Body"}}]}, {mod_mam_rdbms_async_pool_writer,[pm]}, {mod_adhoc,[{iqdisc,one_queue},{report_commands_node,true}]}, + {mod_muc, + [{access,muc}, + {access_create,muc_create}, + {default_room_options, + [{affiliations, + [{{<<"alice">>,<<"localhost">>,<<"resource1">>},member}, + {{<<"bob">>,<<"localhost">>,<<"resource2">>},owner}]}, + {password_protected,true}]}, + {host,"muc.example.com"}, + {http_auth_pool,my_auth_pool}]}, {mod_event_pusher_sns, [{access_key_id,"AKIAIOSFODNN7EXAMPLE"}, - {secret_access_key,"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}, - {region,"eu-west-1"}, {account_id,"123456789012"}, - {sns_host,"sns.eu-west-1.amazonaws.com"}, {muc_host,"conference.HOST"}, + {muc_messages_topic,"user_messagegroup_sent"}, {plugin_module,mod_event_pusher_sns_defaults}, - {presence_updates_topic,"user_presence_updated"}, {pm_messages_topic,"user_message_sent"}, - {muc_messages_topic,"user_messagegroup_sent"}, {pool_size,100}, + {presence_updates_topic,"user_presence_updated"}, {publish_retry_count,2}, - {publish_retry_time_ms,50}]}, - {mod_muc, - [{host,"muc.example.com"}, - {access,muc}, - {access_create,muc_create}, - {http_auth_pool,my_auth_pool}, - {default_room_options, - [{password_protected,true}, - {affiliations, - [{{<<"alice">>,<<"localhost">>,<<"resource1">>},member}, - {{<<"bob">>,<<"localhost">>,<<"resource2">>},owner}]}]}]}, + {publish_retry_time_ms,50}, + {region,"eu-west-1"}, + {secret_access_key,"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}, + {sns_host,"sns.eu-west-1.amazonaws.com"}]}, {mod_ping, - [{send_pings,true}, - {ping_interval,60}, - {timeout_action,none}, - {ping_req_timeout,32}]}, + [{ping_interval,60}, + {ping_req_timeout,32}, + {send_pings,true}, + {timeout_action,none}]}, {mod_mam, [{archive_chat_markers,true}, {full_text_search,false}, {is_archivable_message,mod_mam_utils}, {no_stanzaid_element,true}]}, {mod_disco, - [{iqdisc,one_queue}, - {extra_domains,[<<"some_domain">>,<<"another_domain">>]}, + [{extra_domains,[<<"some_domain">>,<<"another_domain">>]}, + {iqdisc,one_queue}, {server_info, [{all,"abuse-address",["admin@example.com"]}, {[mod_muc,mod_disco], @@ -80,9 +80,9 @@ {users_can_see_hidden_services,true}]}, {mod_event_pusher_http, [{configs, - [[{pool_name,http_pool}, + [[{callback_module,mod_event_pusher_http_defaults}, {path,"/notifications"}, - {callback_module,mod_event_pusher_http_defaults}]]}]}, + {pool_name,http_pool}]]}]}, {mod_event_pusher_hook_translator,[]}, {mod_mam_mnesia_prefs,[muc]}, {mod_mam_muc, @@ -91,26 +91,26 @@ {host,"muc.example.com"}, {is_archivable_message,mod_mam_utils}]}, {mod_event_pusher_rabbit, - [{presence_exchange,[{name,<<"presence">>},{type,<<"topic">>}]}, - {chat_msg_exchange, + [{chat_msg_exchange, [{name,<<"chat_msg">>}, - {sent_topic,<<"chat_msg_sent">>}, - {recv_topic,<<"chat_msg_recv">>}]}, + {recv_topic,<<"chat_msg_recv">>}, + {sent_topic,<<"chat_msg_sent">>}]}, {groupchat_msg_exchange, [{name,<<"groupchat_msg">>}, - {sent_topic,<<"groupchat_msg_sent">>}, - {recv_topic,<<"groupchat_msg_recv">>}]}]}, + {recv_topic,<<"groupchat_msg_recv">>}, + {sent_topic,<<"groupchat_msg_sent">>}]}, + {presence_exchange,[{name,<<"presence">>},{type,<<"topic">>}]}]}, {mod_vcard, - [{matches,1}, - {search,true}, - {host,"directory.example.com"}, - {ldap_vcard_map, - [{<<"FAMILY">>,<<"%s">>,[<<"sn">>]}, - {<<"FN">>,<<"%s">>,[<<"displayName">>]}]}, + [{host,"directory.example.com"}, {ldap_search_fields, [{<<"User">>,<<"%u">>},{<<"Full Name">>,<<"displayName">>}]}, {ldap_search_reported, - [{<<"Full Name">>,<<"FN">>},{<<"Given Name">>,<<"FIRST">>}]}]}, + [{<<"Full Name">>,<<"FN">>},{<<"Given Name">>,<<"FIRST">>}]}, + {ldap_vcard_map, + [{<<"FAMILY">>,<<"%s">>,[<<"sn">>]}, + {<<"FN">>,<<"%s">>,[<<"displayName">>]}]}, + {matches,1}, + {search,true}]}, {mod_keystore, [{keys, [{access_secret,ram}, @@ -121,17 +121,18 @@ {mod_bosh, [{inactivity,20}, {max_wait,infinity}, - {server_acks,true}, - {maxpause,120}]}, + {maxpause,120}, + {server_acks,true}]}, {mod_push_service_mongoosepush, - [{pool_name,mongoose_push_http}, - {api_version,"v3"}, - {max_http_connections,100}]}, + [{api_version,"v3"}, + {max_http_connections,100}, + {pool_name,mongoose_push_http}]}, {mod_auth_token, [{{validity_period,access},{13,minutes}}, {{validity_period,refresh},{13,days}}]}, {mod_extdisco, - [[{host,"stun1"}, + [[{host,"192.168.0.1"},{type,turn}], + [{host,"stun1"}, {password,"password"}, {port,3478}, {transport,"udp"}, @@ -142,18 +143,17 @@ {port,2222}, {transport,"tcp"}, {type,stun}, - {username,"username"}], - [{host,"192.168.0.1"},{type,turn}]]}, + {username,"username"}]]}, {mod_mam_cache_user,[muc,pm]}, - {mod_roster,[{versioning,true},{store_current_id,true}]}, + {mod_roster,[{store_current_id,true},{versioning,true}]}, {mod_http_upload, - [{host,"upload.@HOST@"}, - {backend,s3}, + [{backend,s3}, {expiration_time,120}, - {s3,[{bucket_url,"https://s3-eu-west-1.amazonaws.com/mybucket"}, - {region,"eu-west-1"}, + {host,"upload.@HOST@"}, + {s3,[{access_key_id,"AKIAIOSFODNN7EXAMPLE"}, {add_acl,true}, - {access_key_id,"AKIAIOSFODNN7EXAMPLE"}, + {bucket_url,"https://s3-eu-west-1.amazonaws.com/mybucket"}, + {region,"eu-west-1"}, {secret_access_key, "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}]}]}, {mod_last,[{backend,mnesia},{iqdisc,{queues,10}}]}, @@ -166,102 +166,102 @@ {db_jid_format,mam_jid_rfc}, {db_message_format,mam_message_xml}]}, {mod_csi,[{buffer_max,40}]}, - {mod_caps,[{cache_size,1000},{cache_life_time,86}]}, + {mod_caps,[{cache_life_time,86},{cache_size,1000}]}, {mod_pubsub, [{access_createnode,pubsub_createnode}, - {ignore_pep_from_offline,false}, {backend,rdbms}, + {ignore_pep_from_offline,false}, {last_item_cache,mnesia}, {max_items_node,1000}, - {plugins,[<<"flat">>,<<"pep">>]}, - {pep_mapping,[{"urn:xmpp:microblog:0","mb"}]}]}, + {pep_mapping,[{"urn:xmpp:microblog:0","mb"}]}, + {plugins,[<<"flat">>,<<"pep">>]}]}, {mod_mam_rdbms_prefs,[pm]}, {mod_mam_meta, - [{backend,rdbms}, - {no_stanzaid_element,true}, - {is_archivable_message,mod_mam_utils}, - {archive_chat_markers,true}, + [{archive_chat_markers,true}, + {backend,rdbms}, {full_text_search,true}, - {pm,[{user_prefs_store,rdbms},{full_text_search,false}]}, + {is_archivable_message,mod_mam_utils}, {muc, - [{host,"muc.example.com"}, + [{async_writer,false}, + {host,"muc.example.com"}, {rdbms_message_format,simple}, - {async_writer,false}, - {user_prefs_store,mnesia}]}]}, + {user_prefs_store,mnesia}]}, + {no_stanzaid_element,true}, + {pm,[{full_text_search,false},{user_prefs_store,rdbms}]}]}, {mod_muc_light, - [{config_schema, - [{"roomname","The Room"}, - {"display-lines",30,display_lines,integer}]}, - {rooms_in_rosters,true}, + [{rooms_per_user,10}, {rooms_per_page,5}, + {rooms_in_rosters,true}, {max_occupants,50}, - {all_can_invite,true}, - {all_can_configure,true}, - {blocking,false}, - {rooms_per_user,10}, {legacy_mode,true}, + {host,"muclight.example.com"}, {equal_occupants,true}, - {host,"muclight.example.com"}]}, + {config_schema, + [{"roomname","The Room"}, + {"display-lines",30,display_lines,integer}]}, + {blocking,false}, + {all_can_invite,true}, + {all_can_configure,true}]}, {mod_stream_management, - [{buffer_max,30}, - {ack_freq,1}, + [{ack_freq,1}, + {buffer_max,30}, {resume_timeout,600}, {stale_h, [{enabled,true}, - {stale_h_repeat_after,1800}, - {stale_h_geriatric,3600}]}]}, + {stale_h_geriatric,3600}, + {stale_h_repeat_after,1800}]}]}, {mod_muc_log, - [{outdir,"www/muc"}, - {access_log,muc}, - {top_link,{"/","Home"}}, - {cssfile,<<"path/to/css/file">>}]}, + [{access_log,muc}, + {cssfile,<<"path/to/css/file">>}, + {outdir,"www/muc"}, + {top_link,{"/","Home"}}]}, {mod_inbox, - [{reset_markers,[displayed]}, - {aff_changes,true}, + [{aff_changes,true}, + {groupchat,[muclight]}, {remove_on_kicked,true}, - {groupchat,[muclight]}]}, + {reset_markers,[displayed]}]}, {mod_event_pusher_push, [{backend,mnesia}, - {wpool,[{workers,200}]}, {plugin_module,mod_event_pusher_push_plugin_defaults}, - {virtual_pubsub_hosts,["host1","host2"]}]}, + {virtual_pubsub_hosts,["host1","host2"]}, + {wpool,[{workers,200}]}]}, {mod_event_pusher, [{backends, - [{sns, - [{access_key_id,"AKIAIOSFODNN7EXAMPLE"}, - {secret_access_key, - "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}, - {region,"eu-west-1"}, - {account_id,"123456789012"}, - {sns_host,"sns.eu-west-1.amazonaws.com"}, - {muc_host,"conference.HOST"}, - {plugin_module,mod_event_pusher_sns_defaults}, - {presence_updates_topic,"user_presence_updated"}, - {pm_messages_topic,"user_message_sent"}, - {muc_messages_topic,"user_messagegroup_sent"}, - {pool_size,100}, - {publish_retry_count,2}, - {publish_retry_time_ms,50}]}, + [{http, + [{callback_module,mod_event_pusher_http_defaults}, + {path,"/notifications"}, + {pool_name,http_pool}]}, {push, [{backend,mnesia}, - {wpool,[{workers,200}]}, {plugin_module,mod_event_pusher_push_plugin_defaults}, - {virtual_pubsub_hosts,["host1","host2"]}]}, - {http, - [{pool_name,http_pool}, - {path,"/notifications"}, - {callback_module,mod_event_pusher_http_defaults}]}, + {virtual_pubsub_hosts,["host1","host2"]}, + {wpool,[{workers,200}]}]}, {rabbit, - [{presence_exchange, - [{name,<<"presence">>},{type,<<"topic">>}]}, - {chat_msg_exchange, + [{chat_msg_exchange, [{name,<<"chat_msg">>}, - {sent_topic,<<"chat_msg_sent">>}, - {recv_topic,<<"chat_msg_recv">>}]}, + {recv_topic,<<"chat_msg_recv">>}, + {sent_topic,<<"chat_msg_sent">>}]}, {groupchat_msg_exchange, [{name,<<"groupchat_msg">>}, - {sent_topic,<<"groupchat_msg_sent">>}, - {recv_topic,<<"groupchat_msg_recv">>}]}]}]}]}, + {recv_topic,<<"groupchat_msg_recv">>}, + {sent_topic,<<"groupchat_msg_sent">>}]}, + {presence_exchange, + [{name,<<"presence">>},{type,<<"topic">>}]}]}, + {sns, + [{access_key_id,"AKIAIOSFODNN7EXAMPLE"}, + {account_id,"123456789012"}, + {muc_host,"conference.HOST"}, + {muc_messages_topic,"user_messagegroup_sent"}, + {plugin_module,mod_event_pusher_sns_defaults}, + {pm_messages_topic,"user_message_sent"}, + {pool_size,100}, + {presence_updates_topic,"user_presence_updated"}, + {publish_retry_count,2}, + {publish_retry_time_ms,50}, + {region,"eu-west-1"}, + {secret_access_key, + "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}, + {sns_host,"sns.eu-west-1.amazonaws.com"}]}]}]}, {mod_revproxy, [{routes, [{"www.erlang-solutions.com","/admin","_", @@ -273,76 +273,76 @@ {local_config, {modules,<<"localhost">>}, [{mod_jingle_sip, - [{proxy_host,"localhost"}, - {proxy_port,5600}, - {listen_port,5600}, + [{listen_port,5600}, {local_host,"localhost"}, + {proxy_host,"localhost"}, + {proxy_port,5600}, {sdp_origin,"127.0.0.1"}]}, {mod_shared_roster_ldap, [{ldap_base,"ou=Users,dc=ejd,dc=com"}, + {ldap_filter,"(objectClass=inetOrgPerson)"}, + {ldap_group_cache_validity,1}, {ldap_groupattr,"ou"}, {ldap_memberattr,"cn"}, - {ldap_userdesc,"cn"}, - {ldap_filter,"(objectClass=inetOrgPerson)"}, {ldap_rfilter,"(objectClass=inetOrgPerson)"}, - {ldap_group_cache_validity,1}, - {ldap_user_cache_validity,1}]}, + {ldap_user_cache_validity,1}, + {ldap_userdesc,"cn"}]}, {mod_mam_rdbms_user,[muc,pm]}, {mod_global_distrib, - [{global_host,"example.com"}, - {local_host,"datacenter1.example.com"}, + [{bounce,[{max_retries,3},{resend_after_ms,300}]}, + {cache,[{domain_lifetime_seconds,60}]}, {connections, - [{endpoints,[{"172.16.0.2",5555}]}, - {advertised_endpoints,[{"172.16.0.2",5555}]}, + [{advertised_endpoints,[{"172.16.0.2",5555}]}, {connections_per_endpoint,30}, - {tls_opts,[{certfile,"priv/dc1.pem"},{cafile,"priv/ca.pem"}]}]}, - {cache,[{domain_lifetime_seconds,60}]}, - {bounce,[{resend_after_ms,300},{max_retries,3}]}, + {endpoints,[{"172.16.0.2",5555}]}, + {tls_opts,[{cafile,"priv/ca.pem"},{certfile,"priv/dc1.pem"}]}]}, + {global_host,"example.com"}, + {local_host,"datacenter1.example.com"}, {redis,[{pool,global_distrib}]}]}, {mod_register, - [{welcome_message,{"Subject","Body"}}, - {access,all}, + [{access,all}, + {password_strength,32}, {registration_watchers,[<<"JID1">>,<<"JID2">>]}, - {password_strength,32}]}, + {welcome_message,{"Subject","Body"}}]}, {mod_mam_rdbms_async_pool_writer,[pm]}, {mod_adhoc,[{iqdisc,one_queue},{report_commands_node,true}]}, + {mod_muc, + [{access,muc}, + {access_create,muc_create}, + {default_room_options, + [{affiliations, + [{{<<"alice">>,<<"localhost">>,<<"resource1">>},member}, + {{<<"bob">>,<<"localhost">>,<<"resource2">>},owner}]}, + {password_protected,true}]}, + {host,"muc.example.com"}, + {http_auth_pool,my_auth_pool}]}, {mod_event_pusher_sns, [{access_key_id,"AKIAIOSFODNN7EXAMPLE"}, - {secret_access_key,"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}, - {region,"eu-west-1"}, {account_id,"123456789012"}, - {sns_host,"sns.eu-west-1.amazonaws.com"}, {muc_host,"conference.HOST"}, + {muc_messages_topic,"user_messagegroup_sent"}, {plugin_module,mod_event_pusher_sns_defaults}, - {presence_updates_topic,"user_presence_updated"}, {pm_messages_topic,"user_message_sent"}, - {muc_messages_topic,"user_messagegroup_sent"}, {pool_size,100}, + {presence_updates_topic,"user_presence_updated"}, {publish_retry_count,2}, - {publish_retry_time_ms,50}]}, - {mod_muc, - [{host,"muc.example.com"}, - {access,muc}, - {access_create,muc_create}, - {http_auth_pool,my_auth_pool}, - {default_room_options, - [{password_protected,true}, - {affiliations, - [{{<<"alice">>,<<"localhost">>,<<"resource1">>},member}, - {{<<"bob">>,<<"localhost">>,<<"resource2">>},owner}]}]}]}, + {publish_retry_time_ms,50}, + {region,"eu-west-1"}, + {secret_access_key,"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}, + {sns_host,"sns.eu-west-1.amazonaws.com"}]}, {mod_ping, - [{send_pings,true}, - {ping_interval,60}, - {timeout_action,none}, - {ping_req_timeout,32}]}, + [{ping_interval,60}, + {ping_req_timeout,32}, + {send_pings,true}, + {timeout_action,none}]}, {mod_mam, [{archive_chat_markers,true}, {full_text_search,false}, {is_archivable_message,mod_mam_utils}, {no_stanzaid_element,true}]}, {mod_disco, - [{iqdisc,one_queue}, - {extra_domains,[<<"some_domain">>,<<"another_domain">>]}, + [{extra_domains,[<<"some_domain">>,<<"another_domain">>]}, + {iqdisc,one_queue}, {server_info, [{all,"abuse-address",["admin@example.com"]}, {[mod_muc,mod_disco], @@ -351,9 +351,9 @@ {users_can_see_hidden_services,true}]}, {mod_event_pusher_http, [{configs, - [[{pool_name,http_pool}, + [[{callback_module,mod_event_pusher_http_defaults}, {path,"/notifications"}, - {callback_module,mod_event_pusher_http_defaults}]]}]}, + {pool_name,http_pool}]]}]}, {mod_event_pusher_hook_translator,[]}, {mod_mam_mnesia_prefs,[muc]}, {mod_mam_muc, @@ -362,26 +362,26 @@ {host,"muc.example.com"}, {is_archivable_message,mod_mam_utils}]}, {mod_event_pusher_rabbit, - [{presence_exchange,[{name,<<"presence">>},{type,<<"topic">>}]}, - {chat_msg_exchange, + [{chat_msg_exchange, [{name,<<"chat_msg">>}, - {sent_topic,<<"chat_msg_sent">>}, - {recv_topic,<<"chat_msg_recv">>}]}, + {recv_topic,<<"chat_msg_recv">>}, + {sent_topic,<<"chat_msg_sent">>}]}, {groupchat_msg_exchange, [{name,<<"groupchat_msg">>}, - {sent_topic,<<"groupchat_msg_sent">>}, - {recv_topic,<<"groupchat_msg_recv">>}]}]}, + {recv_topic,<<"groupchat_msg_recv">>}, + {sent_topic,<<"groupchat_msg_sent">>}]}, + {presence_exchange,[{name,<<"presence">>},{type,<<"topic">>}]}]}, {mod_vcard, - [{matches,1}, - {search,true}, - {host,"directory.example.com"}, - {ldap_vcard_map, - [{<<"FAMILY">>,<<"%s">>,[<<"sn">>]}, - {<<"FN">>,<<"%s">>,[<<"displayName">>]}]}, + [{host,"directory.example.com"}, {ldap_search_fields, [{<<"User">>,<<"%u">>},{<<"Full Name">>,<<"displayName">>}]}, {ldap_search_reported, - [{<<"Full Name">>,<<"FN">>},{<<"Given Name">>,<<"FIRST">>}]}]}, + [{<<"Full Name">>,<<"FN">>},{<<"Given Name">>,<<"FIRST">>}]}, + {ldap_vcard_map, + [{<<"FAMILY">>,<<"%s">>,[<<"sn">>]}, + {<<"FN">>,<<"%s">>,[<<"displayName">>]}]}, + {matches,1}, + {search,true}]}, {mod_keystore, [{keys, [{access_secret,ram}, @@ -392,17 +392,18 @@ {mod_bosh, [{inactivity,20}, {max_wait,infinity}, - {server_acks,true}, - {maxpause,120}]}, + {maxpause,120}, + {server_acks,true}]}, {mod_push_service_mongoosepush, - [{pool_name,mongoose_push_http}, - {api_version,"v3"}, - {max_http_connections,100}]}, + [{api_version,"v3"}, + {max_http_connections,100}, + {pool_name,mongoose_push_http}]}, {mod_auth_token, [{{validity_period,access},{13,minutes}}, {{validity_period,refresh},{13,days}}]}, {mod_extdisco, - [[{host,"stun1"}, + [[{host,"192.168.0.1"},{type,turn}], + [{host,"stun1"}, {password,"password"}, {port,3478}, {transport,"udp"}, @@ -413,18 +414,17 @@ {port,2222}, {transport,"tcp"}, {type,stun}, - {username,"username"}], - [{host,"192.168.0.1"},{type,turn}]]}, + {username,"username"}]]}, {mod_mam_cache_user,[muc,pm]}, - {mod_roster,[{versioning,true},{store_current_id,true}]}, + {mod_roster,[{store_current_id,true},{versioning,true}]}, {mod_http_upload, - [{host,"upload.@HOST@"}, - {backend,s3}, + [{backend,s3}, {expiration_time,120}, - {s3,[{bucket_url,"https://s3-eu-west-1.amazonaws.com/mybucket"}, - {region,"eu-west-1"}, + {host,"upload.@HOST@"}, + {s3,[{access_key_id,"AKIAIOSFODNN7EXAMPLE"}, {add_acl,true}, - {access_key_id,"AKIAIOSFODNN7EXAMPLE"}, + {bucket_url,"https://s3-eu-west-1.amazonaws.com/mybucket"}, + {region,"eu-west-1"}, {secret_access_key, "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}]}]}, {mod_last,[{backend,mnesia},{iqdisc,{queues,10}}]}, @@ -437,102 +437,102 @@ {db_jid_format,mam_jid_rfc}, {db_message_format,mam_message_xml}]}, {mod_csi,[{buffer_max,40}]}, - {mod_caps,[{cache_size,1000},{cache_life_time,86}]}, + {mod_caps,[{cache_life_time,86},{cache_size,1000}]}, {mod_pubsub, [{access_createnode,pubsub_createnode}, - {ignore_pep_from_offline,false}, {backend,rdbms}, + {ignore_pep_from_offline,false}, {last_item_cache,mnesia}, {max_items_node,1000}, - {plugins,[<<"flat">>,<<"pep">>]}, - {pep_mapping,[{"urn:xmpp:microblog:0","mb"}]}]}, + {pep_mapping,[{"urn:xmpp:microblog:0","mb"}]}, + {plugins,[<<"flat">>,<<"pep">>]}]}, {mod_mam_rdbms_prefs,[pm]}, {mod_mam_meta, - [{backend,rdbms}, - {no_stanzaid_element,true}, - {is_archivable_message,mod_mam_utils}, - {archive_chat_markers,true}, + [{archive_chat_markers,true}, + {backend,rdbms}, {full_text_search,true}, - {pm,[{user_prefs_store,rdbms},{full_text_search,false}]}, + {is_archivable_message,mod_mam_utils}, {muc, - [{host,"muc.example.com"}, + [{async_writer,false}, + {host,"muc.example.com"}, {rdbms_message_format,simple}, - {async_writer,false}, - {user_prefs_store,mnesia}]}]}, + {user_prefs_store,mnesia}]}, + {no_stanzaid_element,true}, + {pm,[{full_text_search,false},{user_prefs_store,rdbms}]}]}, {mod_muc_light, - [{config_schema, - [{"roomname","The Room"}, - {"display-lines",30,display_lines,integer}]}, - {rooms_in_rosters,true}, + [{rooms_per_user,10}, {rooms_per_page,5}, + {rooms_in_rosters,true}, {max_occupants,50}, - {all_can_invite,true}, - {all_can_configure,true}, - {blocking,false}, - {rooms_per_user,10}, {legacy_mode,true}, + {host,"muclight.example.com"}, {equal_occupants,true}, - {host,"muclight.example.com"}]}, + {config_schema, + [{"roomname","The Room"}, + {"display-lines",30,display_lines,integer}]}, + {blocking,false}, + {all_can_invite,true}, + {all_can_configure,true}]}, {mod_stream_management, - [{buffer_max,30}, - {ack_freq,1}, + [{ack_freq,1}, + {buffer_max,30}, {resume_timeout,600}, {stale_h, [{enabled,true}, - {stale_h_repeat_after,1800}, - {stale_h_geriatric,3600}]}]}, + {stale_h_geriatric,3600}, + {stale_h_repeat_after,1800}]}]}, {mod_muc_log, - [{outdir,"www/muc"}, - {access_log,muc}, - {top_link,{"/","Home"}}, - {cssfile,<<"path/to/css/file">>}]}, + [{access_log,muc}, + {cssfile,<<"path/to/css/file">>}, + {outdir,"www/muc"}, + {top_link,{"/","Home"}}]}, {mod_inbox, - [{reset_markers,[displayed]}, - {aff_changes,true}, + [{aff_changes,true}, + {groupchat,[muclight]}, {remove_on_kicked,true}, - {groupchat,[muclight]}]}, + {reset_markers,[displayed]}]}, {mod_event_pusher_push, [{backend,mnesia}, - {wpool,[{workers,200}]}, {plugin_module,mod_event_pusher_push_plugin_defaults}, - {virtual_pubsub_hosts,["host1","host2"]}]}, + {virtual_pubsub_hosts,["host1","host2"]}, + {wpool,[{workers,200}]}]}, {mod_event_pusher, [{backends, - [{sns, - [{access_key_id,"AKIAIOSFODNN7EXAMPLE"}, - {secret_access_key, - "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}, - {region,"eu-west-1"}, - {account_id,"123456789012"}, - {sns_host,"sns.eu-west-1.amazonaws.com"}, - {muc_host,"conference.HOST"}, - {plugin_module,mod_event_pusher_sns_defaults}, - {presence_updates_topic,"user_presence_updated"}, - {pm_messages_topic,"user_message_sent"}, - {muc_messages_topic,"user_messagegroup_sent"}, - {pool_size,100}, - {publish_retry_count,2}, - {publish_retry_time_ms,50}]}, + [{http, + [{callback_module,mod_event_pusher_http_defaults}, + {path,"/notifications"}, + {pool_name,http_pool}]}, {push, [{backend,mnesia}, - {wpool,[{workers,200}]}, {plugin_module,mod_event_pusher_push_plugin_defaults}, - {virtual_pubsub_hosts,["host1","host2"]}]}, - {http, - [{pool_name,http_pool}, - {path,"/notifications"}, - {callback_module,mod_event_pusher_http_defaults}]}, + {virtual_pubsub_hosts,["host1","host2"]}, + {wpool,[{workers,200}]}]}, {rabbit, - [{presence_exchange, - [{name,<<"presence">>},{type,<<"topic">>}]}, - {chat_msg_exchange, + [{chat_msg_exchange, [{name,<<"chat_msg">>}, - {sent_topic,<<"chat_msg_sent">>}, - {recv_topic,<<"chat_msg_recv">>}]}, + {recv_topic,<<"chat_msg_recv">>}, + {sent_topic,<<"chat_msg_sent">>}]}, {groupchat_msg_exchange, [{name,<<"groupchat_msg">>}, - {sent_topic,<<"groupchat_msg_sent">>}, - {recv_topic,<<"groupchat_msg_recv">>}]}]}]}]}, + {recv_topic,<<"groupchat_msg_recv">>}, + {sent_topic,<<"groupchat_msg_sent">>}]}, + {presence_exchange, + [{name,<<"presence">>},{type,<<"topic">>}]}]}, + {sns, + [{access_key_id,"AKIAIOSFODNN7EXAMPLE"}, + {account_id,"123456789012"}, + {muc_host,"conference.HOST"}, + {muc_messages_topic,"user_messagegroup_sent"}, + {plugin_module,mod_event_pusher_sns_defaults}, + {pm_messages_topic,"user_message_sent"}, + {pool_size,100}, + {presence_updates_topic,"user_presence_updated"}, + {publish_retry_count,2}, + {publish_retry_time_ms,50}, + {region,"eu-west-1"}, + {secret_access_key, + "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"}, + {sns_host,"sns.eu-west-1.amazonaws.com"}]}]}]}, {mod_revproxy, [{routes, [{"www.erlang-solutions.com","/admin","_", diff --git a/test/config_parser_SUITE_data/mongooseim-pgsql.options b/test/config_parser_SUITE_data/mongooseim-pgsql.options index b91c85d37c..dfe2476eb2 100644 --- a/test/config_parser_SUITE_data/mongooseim-pgsql.options +++ b/test/config_parser_SUITE_data/mongooseim-pgsql.options @@ -26,178 +26,109 @@ {config,{shaper,mam_global_shaper,global},{maxrate,1000}}. {config,{shaper,mam_shaper,global},{maxrate,1}}. {config,{shaper,normal,global},{maxrate,1000}}. -{local_config, - {modules,<<"anonymous.localhost">>}, - [{mod_register, - [{welcome_message,{"Hello","I am MongooseIM"}}, - {ip_access,[{allow,"127.0.0.0/8"},{deny,"0.0.0.0/0"}]}, - {access,register}]}, - {mod_adhoc,[]}, - {mod_sic,[]}, - {mod_private,[{backend,rdbms}]}, - {mod_privacy,[{backend,rdbms}]}, - {mod_disco,[{users_can_see_hidden_services,false}]}, - {mod_commands,[]}, - {mod_muc_light_commands,[]}, - {mod_vcard,[{backend,rdbms},{host,"vjud.@HOST@"}]}, - {mod_blocking,[]}, - {mod_bosh,[]}, - {mod_roster,[{backend,rdbms}]}, - {mod_last,[{backend,rdbms}]}, - {mod_offline,[{backend,rdbms}]}, - {mod_amp,[]}, - {mod_muc_commands,[]}, - {mod_stream_management,[]}, - {mod_carboncopy,[]}]}. -{local_config, - {modules,<<"localhost">>}, - [{mod_register, - [{welcome_message,{"Hello","I am MongooseIM"}}, - {ip_access,[{allow,"127.0.0.0/8"},{deny,"0.0.0.0/0"}]}, - {access,register}]}, - {mod_adhoc,[]}, - {mod_sic,[]}, - {mod_private,[{backend,rdbms}]}, - {mod_privacy,[{backend,rdbms}]}, - {mod_disco,[{users_can_see_hidden_services,false}]}, - {mod_commands,[]}, - {mod_muc_light_commands,[]}, - {mod_vcard,[{backend,rdbms},{host,"vjud.@HOST@"}]}, - {mod_blocking,[]}, - {mod_bosh,[]}, - {mod_roster,[{backend,rdbms}]}, - {mod_last,[{backend,rdbms}]}, - {mod_offline,[{backend,rdbms}]}, - {mod_amp,[]}, - {mod_muc_commands,[]}, - {mod_stream_management,[]}, - {mod_carboncopy,[]}]}. -{local_config, - {modules,<<"localhost.bis">>}, - [{mod_register, - [{welcome_message,{"Hello","I am MongooseIM"}}, - {ip_access,[{allow,"127.0.0.0/8"},{deny,"0.0.0.0/0"}]}, - {access,register}]}, - {mod_adhoc,[]}, - {mod_sic,[]}, - {mod_private,[{backend,rdbms}]}, - {mod_privacy,[{backend,rdbms}]}, - {mod_disco,[{users_can_see_hidden_services,false}]}, - {mod_commands,[]}, - {mod_muc_light_commands,[]}, - {mod_vcard,[{backend,rdbms},{host,"vjud.@HOST@"}]}, - {mod_blocking,[]}, - {mod_bosh,[]}, - {mod_roster,[{backend,rdbms}]}, - {mod_last,[{backend,rdbms}]}, - {mod_offline,[{backend,rdbms}]}, - {mod_amp,[]}, - {mod_muc_commands,[]}, - {mod_stream_management,[]}, - {mod_carboncopy,[]}]}. {local_config,all_metrics_are_global,false}. {local_config,listen, - [{{5280,{0,0,0,0},tcp}, + [{{5222,{0,0,0,0},tcp}, + ejabberd_c2s, + [{access,c2s}, + {max_stanza_size,65536}, + {shaper,c2s_shaper}, + {certfile,"tools/ssl/mongooseim/server.pem"}, + {dhfile,"tools/ssl/mongooseim/dh_server.pem"}, + starttls, + {zlib,10000}]}, + {{5223,{0,0,0,0},tcp}, + ejabberd_c2s, + [{access,c2s},{max_stanza_size,65536},{shaper,c2s_shaper},{zlib,4096}]}, + {{5280,{0,0,0,0},tcp}, ejabberd_cowboy, - [{transport_options,[{num_acceptors,10},{max_connections,1024}]}, - {modules, - [{"_","/http-bind",mod_bosh}, + [{modules, + [{"_","/http-bind",mod_bosh,[]}, {"_","/ws-xmpp",mod_websockets, [{ejabberd_service, - [{access,all},{shaper_rule,fast},{password,"secret"}]}]}]}]}, + [{access,all},{password,"secret"},{shaper_rule,fast}]}]}]}, + {transport_options,[{max_connections,1024},{num_acceptors,10}]}]}, {{5285,{0,0,0,0},tcp}, ejabberd_cowboy, - [{transport_options,[{num_acceptors,10},{max_connections,1024}]}, + [{modules, + [{"_","/http-bind",mod_bosh,[]}, + {"_","/ws-xmpp",mod_websockets, + [{max_stanza_size,100},{ping_rate,none},{timeout,infinity}]}, + {"localhost","/api",mongoose_api_admin, + [{auth,{<<"ala">>,<<"makotaipsa">>}}]}, + {"localhost","/api/contacts/{:jid}",mongoose_api_client,[]}]}, {ssl, [{certfile,"tools/ssl/mongooseim/cert.pem"}, {keyfile,"tools/ssl/mongooseim/key.pem"}, {password,[]}]}, - {modules, - [{"_","/http-bind",mod_bosh}, - {"_","/ws-xmpp",mod_websockets, - [{timeout,infinity},{ping_rate,none},{max_stanza_size,100}]}, - {"localhost","/api",mongoose_api_admin, - [{auth,{<<"ala">>,<<"makotaipsa">>}}]}, - {"localhost","/api/contacts/{:jid}",mongoose_api_client,[]}]}]}, + {transport_options,[{max_connections,1024},{num_acceptors,10}]}]}, {{8088,{127,0,0,1},tcp}, ejabberd_cowboy, - [{transport_options,[{num_acceptors,10},{max_connections,1024}]}, - {modules,[{"localhost","/api",mongoose_api_admin,[]}]}]}, + [{modules,[{"localhost","/api",mongoose_api_admin,[]}]}, + {transport_options,[{max_connections,1024},{num_acceptors,10}]}]}, {{8089,{0,0,0,0},tcp}, ejabberd_cowboy, - [{transport_options,[{num_acceptors,10},{max_connections,1024}]}, - {protocol_options,[{compress,true}]}, - {ssl, - [{certfile,"tools/ssl/mongooseim/cert.pem"}, - {keyfile,"tools/ssl/mongooseim/key.pem"}, - {password,[]}]}, - {modules, - [{"_","/api/sse",lasse_handler,[mongoose_client_api_sse]}, - {"_","/api/messages/[:with]",mongoose_client_api_messages,[]}, + [{modules, + [{"_","/api-docs/[...]",cowboy_static, + {priv_dir,cowboy_swagger,"swagger", + [{mimetypes,cow_mimetypes,all}]}}, + {"_","/api-docs/swagger.json",cowboy_swagger_json_handler,#{}}, + {"_","/api-docs",cowboy_swagger_redirect_handler,#{}}, + {"_","/api/sse",lasse_handler,[mongoose_client_api_sse]}, {"_","/api/contacts/[:jid]",mongoose_client_api_contacts,[]}, + {"_","/api/messages/[:with]",mongoose_client_api_messages,[]}, {"_","/api/rooms/[:id]",mongoose_client_api_rooms,[]}, {"_","/api/rooms/[:id]/config",mongoose_client_api_rooms_config, []}, - {"_","/api/rooms/:id/users/[:user]", - mongoose_client_api_rooms_users,[]}, {"_","/api/rooms/[:id]/messages", mongoose_client_api_rooms_messages,[]}, - {"_","/api-docs",cowboy_swagger_redirect_handler,#{}}, - {"_","/api-docs/swagger.json",cowboy_swagger_json_handler,#{}}, - {"_","/api-docs/[...]",cowboy_static, - {priv_dir,cowboy_swagger,"swagger", - [{mimetypes,cow_mimetypes,all}]}}]}]}, + {"_","/api/rooms/:id/users/[:user]", + mongoose_client_api_rooms_users,[]}]}, + {protocol_options,[{compress,true}]}, + {ssl, + [{certfile,"tools/ssl/mongooseim/cert.pem"}, + {keyfile,"tools/ssl/mongooseim/key.pem"}, + {password,[]}]}, + {transport_options,[{max_connections,1024},{num_acceptors,10}]}]}, {{5288,{127,0,0,1},tcp}, ejabberd_cowboy, - [{transport_options,[{num_acceptors,10},{max_connections,1024}]}, - {modules, + [{modules, [{"localhost","/api",mongoose_api, - [{handlers,[mongoose_api_metrics,mongoose_api_users]}]}]}]}, - {{5222,{0,0,0,0},tcp}, - ejabberd_c2s, - [{certfile,"tools/ssl/mongooseim/server.pem"}, - starttls, - {zlib,10000}, - {access,c2s}, - {shaper,c2s_shaper}, - {max_stanza_size,65536}, - {dhfile,"tools/ssl/mongooseim/dh_server.pem"}]}, - {{5223,{0,0,0,0},tcp}, - ejabberd_c2s, - [{zlib,4096},{access,c2s},{shaper,c2s_shaper},{max_stanza_size,65536}]}, + [{handlers,[mongoose_api_metrics,mongoose_api_users]}]}]}, + {transport_options,[{max_connections,1024},{num_acceptors,10}]}]}, {{5269,{0,0,0,0},tcp}, ejabberd_s2s_in, - [{shaper,s2s_shaper}, - {max_stanza_size,131072}, + [{max_stanza_size,131072}, + {shaper,s2s_shaper}, {dhfile,"tools/ssl/mongooseim/dh_server.pem"}]}, {{8888,{127,0,0,1},tcp}, ejabberd_service, - [{access,all},{shaper_rule,fast},{password,"secret"}]}, + [{access,all},{password,"secret"},{shaper_rule,fast}]}, {{8666,{127,0,0,1},tcp}, ejabberd_service, [{access,all}, {conflict_behaviour,kick_old}, - {shaper_rule,fast}, - {password,"secret"}]}, + {password,"secret"}, + {shaper_rule,fast}]}, {{8189,{127,0,0,1},tcp}, ejabberd_service, [{access,all}, {hidden_components,true}, - {shaper_rule,fast}, - {password,"secret"}]}]}. + {password,"secret"}, + {shaper_rule,fast}]}]}. {local_config,loglevel,warning}. {local_config,max_fsm_queue,1000}. {local_config,outgoing_pools, - [{redis,<<"localhost">>,global_distrib,[{workers,10}],[]}, - {rdbms,global,default, + [{rdbms,global,default, [{workers,5}], [{server, {pgsql,"localhost","ejabberd","ejabberd","mongooseim_secret", [{ssl,required}, {ssl_opts, - [{verify,verify_peer}, - {cacertfile,"priv/ssl/cacert.pem"}, - {server_name_indication,disable}]}]}}]}]}. + [{cacertfile,"priv/ssl/cacert.pem"}, + {server_name_indication,disable}, + {verify,verify_peer}]}]}}]}, + {redis,<<"localhost">>,global_distrib,[{workers,10}],[]}]}. {local_config,outgoing_s2s_port,5299}. {local_config,registration_timeout,infinity}. {local_config,s2s_certfile,"tools/ssl/mongooseim/server.pem"}. @@ -211,19 +142,88 @@ [{initial_report,300000},{periodic_report,10800000}]}]}. {local_config,{allow_multiple_connections,<<"anonymous.localhost">>},true}. {local_config,{anonymous_protocol,<<"anonymous.localhost">>},both}. -{local_config,{auth_method,<<"anonymous.localhost">>},anonymous}. -{local_config,{auth_method,<<"localhost">>},rdbms}. -{local_config,{auth_method,<<"localhost.bis">>},rdbms}. +{local_config,{auth_method,<<"anonymous.localhost">>},[anonymous]}. +{local_config,{auth_method,<<"localhost">>},[rdbms]}. +{local_config,{auth_method,<<"localhost.bis">>},[rdbms]}. {local_config,{auth_opts,<<"anonymous.localhost">>},[]}. {local_config,{auth_opts,<<"localhost">>}, [{password_format,{scram,[sha256]}}, - {scram_iterations,64}, - {cyrsasl_external,standard}]}. + {cyrsasl_external,[standard]}, + {scram_iterations,64}]}. {local_config,{auth_opts,<<"localhost.bis">>}, [{password_format,{scram,[sha256]}}, - {scram_iterations,64}, - {cyrsasl_external,standard}]}. -{local_config,{s2s_addr,<<"fed1">>},{127,0,0,1}}. + {cyrsasl_external,[standard]}, + {scram_iterations,64}]}. +{local_config, + {modules,<<"anonymous.localhost">>}, + [{mod_register, + [{access,register}, + {ip_access,[{allow,"127.0.0.0/8"},{deny,"0.0.0.0/0"}]}, + {welcome_message,{"Hello","I am MongooseIM"}}]}, + {mod_adhoc,[]}, + {mod_sic,[]}, + {mod_private,[{backend,rdbms}]}, + {mod_privacy,[{backend,rdbms}]}, + {mod_disco,[{users_can_see_hidden_services,false}]}, + {mod_commands,[]}, + {mod_muc_light_commands,[]}, + {mod_vcard,[{backend,rdbms},{host,"vjud.@HOST@"}]}, + {mod_blocking,[]}, + {mod_bosh,[]}, + {mod_roster,[{backend,rdbms}]}, + {mod_last,[{backend,rdbms}]}, + {mod_offline,[{backend,rdbms}]}, + {mod_amp,[]}, + {mod_muc_commands,[]}, + {mod_stream_management,[]}, + {mod_carboncopy,[]}]}. +{local_config, + {modules,<<"localhost">>}, + [{mod_register, + [{access,register}, + {ip_access,[{allow,"127.0.0.0/8"},{deny,"0.0.0.0/0"}]}, + {welcome_message,{"Hello","I am MongooseIM"}}]}, + {mod_adhoc,[]}, + {mod_sic,[]}, + {mod_private,[{backend,rdbms}]}, + {mod_privacy,[{backend,rdbms}]}, + {mod_disco,[{users_can_see_hidden_services,false}]}, + {mod_commands,[]}, + {mod_muc_light_commands,[]}, + {mod_vcard,[{backend,rdbms},{host,"vjud.@HOST@"}]}, + {mod_blocking,[]}, + {mod_bosh,[]}, + {mod_roster,[{backend,rdbms}]}, + {mod_last,[{backend,rdbms}]}, + {mod_offline,[{backend,rdbms}]}, + {mod_amp,[]}, + {mod_muc_commands,[]}, + {mod_stream_management,[]}, + {mod_carboncopy,[]}]}. +{local_config, + {modules,<<"localhost.bis">>}, + [{mod_register, + [{access,register}, + {ip_access,[{allow,"127.0.0.0/8"},{deny,"0.0.0.0/0"}]}, + {welcome_message,{"Hello","I am MongooseIM"}}]}, + {mod_adhoc,[]}, + {mod_sic,[]}, + {mod_private,[{backend,rdbms}]}, + {mod_privacy,[{backend,rdbms}]}, + {mod_disco,[{users_can_see_hidden_services,false}]}, + {mod_commands,[]}, + {mod_muc_light_commands,[]}, + {mod_vcard,[{backend,rdbms},{host,"vjud.@HOST@"}]}, + {mod_blocking,[]}, + {mod_bosh,[]}, + {mod_roster,[{backend,rdbms}]}, + {mod_last,[{backend,rdbms}]}, + {mod_offline,[{backend,rdbms}]}, + {mod_amp,[]}, + {mod_muc_commands,[]}, + {mod_stream_management,[]}, + {mod_carboncopy,[]}]}. +{local_config,{s2s_addr,<<"fed1">>},"127.0.0.1"}. {local_config,{s2s_default_policy,<<"anonymous.localhost">>},allow}. {local_config,{s2s_default_policy,<<"localhost">>},allow}. {local_config,{s2s_default_policy,<<"localhost.bis">>},allow}. diff --git a/test/config_parser_SUITE_data/outgoing_pools.options b/test/config_parser_SUITE_data/outgoing_pools.options index ea2592fc51..e4c19d31fe 100644 --- a/test/config_parser_SUITE_data/outgoing_pools.options +++ b/test/config_parser_SUITE_data/outgoing_pools.options @@ -1,43 +1,43 @@ {config,hosts,[<<"localhost">>,<<"anonymous.localhost">>,<<"localhost.bis">>]}. {local_config,outgoing_pools, - [{redis,<<"localhost">>,global_distrib,[{workers,10}],[]}, - {rdbms,global,default, - [{workers,5}], - [{server, - {pgsql,"localhost","ejabberd","ejabberd","mongooseim_secret", - [{ssl,required}, - {ssl_opts, - [{verify,verify_peer}, - {cacertfile,"priv/ssl/cacert.pem"}, - {server_name_indication,disable}]}]}}, - {keepalive_interval,30}]}, + [{cassandra,global,default,[], + [{keyspace,"big_mongooseim"}, + {servers, + [{"cassandra_server1.example.com",9042}, + {"cassandra_server2.example.com",9042}]}]}, + {elastic,global,default,[],[{host,"localhost"}]}, {http,global,mongoose_push_http, [{workers,50}], [{server,"https://localhost:8443"}, {path_prefix,"/"}, {request_timeout,2000}]}, - {riak,global,default, - [{workers,20},{strategy,next_worker}], - [{address,"127.0.0.1"}, - {port,8087}, - {credentials,"username","pass"}, - {cacertfile,"path/to/cacert.pem"}]}, - {cassandra,global,default,[], - [{servers, - [{"cassandra_server1.example.com",9042}, - {"cassandra_server2.example.com",9042}]}, - {keyspace,"big_mongooseim"}]}, - {elastic,global,default,[],[{host,"localhost"}]}, + {ldap,host,default, + [{workers,5}], + [{password,"ldap-admin-password"}, + {rootdn,"cn=admin,dc=example,dc=com"}, + {servers,["ldap-server.example.com"]}]}, {rabbit,host,event_pusher, [{workers,20}], [{amqp_host,"localhost"}, + {amqp_password,"guest"}, {amqp_port,5672}, {amqp_username,"guest"}, - {amqp_password,"guest"}, {confirms_enabled,true}, {max_worker_queue_len,100}]}, - {ldap,host,default, + {rdbms,global,default, [{workers,5}], - [{servers,["ldap-server.example.com"]}, - {rootdn,"cn=admin,dc=example,dc=com"}, - {password,"ldap-admin-password"}]}]}. + [{server, + {pgsql,"localhost","ejabberd","ejabberd","mongooseim_secret", + [{ssl,required}, + {ssl_opts, + [{cacertfile,"priv/ssl/cacert.pem"}, + {server_name_indication,disable}, + {verify,verify_peer}]}]}}, + {keepalive_interval,30}]}, + {redis,<<"localhost">>,global_distrib,[{workers,10}],[]}, + {riak,global,default, + [{strategy,next_worker},{workers,20}], + [{address,"127.0.0.1"}, + {cacertfile,"path/to/cacert.pem"}, + {credentials,"username","pass"}, + {port,8087}]}]}. diff --git a/test/config_parser_SUITE_data/s2s_only.options b/test/config_parser_SUITE_data/s2s_only.options index 28c698d12f..5486d39db8 100644 --- a/test/config_parser_SUITE_data/s2s_only.options +++ b/test/config_parser_SUITE_data/s2s_only.options @@ -4,11 +4,11 @@ {local_config,outgoing_s2s_timeout,10000}. {local_config,s2s_certfile,"tools/ssl/mongooseim/server.pem"}. {local_config,s2s_ciphers,"TLSv1.2:TLSv1.3"}. -{local_config,s2s_dns_options,[{timeout,30},{retries,1}]}. +{local_config,s2s_dns_options,[{retries,1},{timeout,30}]}. {local_config,s2s_use_starttls,optional}. {local_config,{domain_certfile,"example.com"},"/path/to/example_com.pem"}. {local_config,{domain_certfile,"example.org"},"/path/to/example_org.pem"}. -{local_config,{s2s_addr,<<"fed1">>},{127,0,0,1}}. +{local_config,{s2s_addr,<<"fed1">>},"127.0.0.1"}. {local_config,{s2s_default_policy,<<"dummy_host">>},allow}. {local_config,{s2s_default_policy,<<"localhost">>},allow}. {local_config,{s2s_max_retry_delay,<<"dummy_host">>},30}. From d6ac587772fadfefcc7eb8db46fdad38c92842dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chrz=C4=85szcz?= Date: Fri, 6 Nov 2020 18:26:19 +0100 Subject: [PATCH 2/3] Declarative specification of the 'general' section - Temporary code for supporting both 'handler' specifications - Type specs will follow when they stop changing - Code for the decalrative handlers will be removed last Functional changes: - The 'general.mongooseim_access_commands.commands' option no longer accepts the string "all" for type consistency. Now this option has to be omitted to enable all commands. --- include/ejabberd_config.hrl | 13 ++ src/config/mongoose_config_parser_toml.erl | 202 ++++++++++-------- src/config/mongoose_config_spec.erl | 111 ++++++++++ src/config/mongoose_config_validator_toml.erl | 78 +++---- test/config_parser_SUITE.erl | 26 ++- 5 files changed, 283 insertions(+), 147 deletions(-) create mode 100644 src/config/mongoose_config_spec.erl diff --git a/include/ejabberd_config.hrl b/include/ejabberd_config.hrl index d47c9a11ee..fd38cdbcdb 100644 --- a/include/ejabberd_config.hrl +++ b/include/ejabberd_config.hrl @@ -27,4 +27,17 @@ value :: mongoose_config_parser:value() }). +-record(section, {items, + validate = any, + process, + format = default}). +-record(list, {items, + validate = any, + process, + format = default}). +-record(option, {type, + validate = any, + process, + format = default}). + -endif. diff --git a/src/config/mongoose_config_parser_toml.erl b/src/config/mongoose_config_parser_toml.erl index 50da742644..205b3c36fb 100644 --- a/src/config/mongoose_config_parser_toml.erl +++ b/src/config/mongoose_config_parser_toml.erl @@ -118,64 +118,6 @@ process_section([<<"host_config">>] = Path, Content) -> process_section(Path, Content) -> parse_section(Path, Content). -%% path: (host_config[].)general.* --spec process_general(path(), toml_value()) -> [config()]. -process_general([<<"loglevel">>|_], V) -> - [#local_config{key = loglevel, value = b2a(V)}]; -process_general([<<"hosts">>|_] = Path, Hosts) -> - [#config{key = hosts, value = parse_list(Path, Hosts)}]; -process_general([<<"registration_timeout">>|_], V) -> - [#local_config{key = registration_timeout, value = int_or_infinity(V)}]; -process_general([<<"language">>|_], V) -> - [#config{key = language, value = V}]; -process_general([<<"all_metrics_are_global">>|_], V) -> - [#local_config{key = all_metrics_are_global, value = V}]; -process_general([<<"sm_backend">>|_], V) -> - [#config{key = sm_backend, value = {b2a(V), []}}]; -process_general([<<"max_fsm_queue">>|_], V) -> - [#local_config{key = max_fsm_queue, value = V}]; -process_general([<<"http_server_name">>|_], V) -> - [#local_config{key = cowboy_server_name, value = b2l(V)}]; -process_general([<<"rdbms_server_type">>|_], V) -> - [#local_config{key = rdbms_server_type, value = b2a(V)}]; -process_general([<<"override">>|_] = Path, Value) -> - parse_list(Path, Value); -process_general([<<"pgsql_users_number_estimate">>|_], V) -> - ?HOST_F([#local_config{key = {pgsql_users_number_estimate, Host}, value = V}]); -process_general([<<"route_subdomains">>|_], V) -> - ?HOST_F([#local_config{key = {route_subdomains, Host}, value = b2a(V)}]); -process_general([<<"mongooseimctl_access_commands">>|_] = Path, Rules) -> - [#local_config{key = mongooseimctl_access_commands, value = parse_section(Path, Rules)}]; -process_general([<<"routing_modules">>|_] = Path, Mods) -> - [#local_config{key = routing_modules, value = parse_list(Path, Mods)}]; -process_general([<<"replaced_wait_timeout">>|_], V) -> - ?HOST_F([#local_config{key = {replaced_wait_timeout, Host}, value = V}]); -process_general([<<"hide_service_name">>|_], V) -> - ?HOST_F([#local_config{key = {hide_service_name, Host}, value = V}]). - --spec process_host(path(), toml_value()) -> [option()]. -process_host(_Path, Val) -> - [jid:nodeprep(Val)]. - --spec process_override(path(), toml_value()) -> [option()]. -process_override(_Path, Override) -> - [{override, b2a(Override)}]. - --spec ctl_access_rule(path(), toml_section()) -> [option()]. -ctl_access_rule([Rule|_] = Path, Section) -> - limit_keys([<<"commands">>, <<"argument_restrictions">>], Section), - [{b2a(Rule), - parse_kv(Path, <<"commands">>, Section), - parse_kv(Path, <<"argument_restrictions">>, Section, #{})}]. - --spec ctl_access_commands(path(), toml_value()) -> option(). -ctl_access_commands(_Path, <<"all">>) -> all; -ctl_access_commands(Path, Commands) -> parse_list(Path, Commands). - --spec ctl_access_arg_restriction(path(), toml_value()) -> [option()]. -ctl_access_arg_restriction([Key|_], Value) -> - [{b2a(Key), b2l(Value)}]. - %% path: listen.*[] -spec process_listener(path(), toml_section()) -> [option()]. process_listener([_, Type|_] = Path, Content) -> @@ -1760,16 +1702,110 @@ handle(Path, Value) -> Error; (StepName, AccIn) -> try_call(handle_step(StepName, AccIn), StepName, Path, Value) - end, Path, [handle, parse, validate]). + end, Path, [handle, parse, validate, process, format]). handle_step(handle, _) -> fun(Path, _Value) -> handler(Path) end; +handle_step(parse, Spec) when is_tuple(Spec) -> + fun(Path, Value) -> + ParsedValue = case Spec of + #section{} when is_map(Value) -> + parse_section(Path, Value); + #list{} when is_list(Value) -> + parse_list(Path, Value); + #option{type = Type} when not is_list(Value), not is_map(Value) -> + convert(Value, Type) + end, + case extract_errors(ParsedValue) of + [] -> {ParsedValue, Spec}; + Errors -> Errors + end + end; handle_step(parse, Handler) -> Handler; +handle_step(validate, {ParsedValue, Spec}) -> + fun(_Path, _Value) -> + validate(ParsedValue, Spec), + {ParsedValue, Spec} + end; handle_step(validate, ParsedValue) -> fun(Path, _Value) -> mongoose_config_validator_toml:validate(Path, ParsedValue), ParsedValue + end; +handle_step(process, {ParsedValue, Spec}) -> + fun(_Path, _Value) -> + {process_value(ParsedValue, Spec), Spec} + end; +handle_step(process, V) -> + fun(_, _) -> V end; +handle_step(format, {ParsedValue, Spec}) -> + fun(Path, _Value) -> + format(Path, ParsedValue, format_spec(Spec)) + end; +handle_step(format, V) -> + fun(_, _) -> V end. + +validate(Value, #section{validate = Validator}) -> + mongoose_config_validator_toml:validate_section(Value, Validator); +validate(Value, #list{validate = Validator}) -> + mongoose_config_validator_toml:validate_list(Value, Validator); +validate(Value, #option{type = Type, validate = Validator}) -> + mongoose_config_validator_toml:validate(Value, Type, Validator). + +process_value(V, #section{process = undefined}) -> V; +process_value(V, #list{process = undefined}) -> V; +process_value(V, #option{process = undefined}) -> V; +process_value(V, #section{process = Process}) -> Process(V); +process_value(V, #list{process = Process}) -> Process(V); +process_value(V, #option{process = Process}) -> Process(V). + +convert(V, boolean) -> V; +convert(V, binary) -> V; +convert(V, string) -> binary_to_list(V); +convert(V, atom) -> b2a(V); +convert(<<"infinity">>, int_or_infinity) -> infinity; %% TODO maybe use TOML '+inf' +convert(V, int_or_infinity) -> V; +convert(V, integer) -> V. + +format_spec(#section{format = Format}) -> Format; +format_spec(#list{format = Format}) -> Format; +format_spec(#option{format = Format}) -> Format. + +format([Key|_] = Path, V, host_local_config) -> + format(Path, V, {host_local_config, b2a(Key)}); +format([Key|_] = Path, V, local_config) -> + format(Path, V, {local_config, b2a(Key)}); +format([Key|_] = Path, V, config) -> + format(Path, V, {config, b2a(Key)}); +format(Path, V, {host_local_config, Key}) -> + case get_host(Path) of + global -> ?HOST_F([#local_config{key = {Key, Host}, value = V}]); + Host -> [#local_config{key = {Key, Host}, value = V}] + end; +format(Path, V, {local_config, Key}) -> + global = get_host(Path), + [#local_config{key = Key, value = V}]; +format(Path, V, {config, Key}) -> + global = get_host(Path), + [#config{key = Key, value = V}]; +format(Path, V, override) -> + global = get_host(Path), + [{override, V}]; +format([item|_], V, default) -> + [V]; +format([Key|_], V, default) -> + [{b2a(Key), V}]; +format([Key|_], V, prepend_key) -> + L = [b2a(Key) | tuple_to_list(V)], + [list_to_tuple(L)]; +format(_Path, V, none) -> + V. + +get_host(Path) -> + case lists:reverse(Path) of + [<<"host_config">>, {host, Host} | _] -> Host; + _ -> global end. -spec try_call(fun((path(), any()) -> option()), atom(), path(), toml_value()) -> option(). @@ -1790,7 +1826,9 @@ try_call(F, StepName, Path, Value) -> -spec error_text(atom()) -> string(). error_text(handle) -> "Unexpected option in the TOML configuration file"; error_text(parse) -> "Malformed option in the TOML configuration file"; -error_text(validate) -> "Incorrect option value in the TOML configuration file". +error_text(validate) -> "Incorrect option value in the TOML configuration file"; +error_text(process) -> "Unable to process a value the TOML configuration file"; +error_text(format) -> "Unable to format an option in the TOML configuration file". -spec error_fields(any()) -> map(). error_fields(#{what := Reason} = M) -> maps:remove(what, M#{reason => Reason}); @@ -1806,26 +1844,11 @@ node_to_string({host, _}) -> []; node_to_string({tls, TLSAtom}) -> [atom_to_list(TLSAtom)]; node_to_string(Node) -> [binary_to_list(Node)]. --spec handler(path()) -> fun((path(), toml_value()) -> option()). +-spec handler(path()) -> + fun((path(), toml_value()) -> option()) | mongoose_config_spec:config_node(). handler([]) -> fun parse_root/2; handler([_]) -> fun process_section/2; -%% general -handler([_, <<"general">>]) -> fun process_general/2; -handler([_, <<"hosts">>, <<"general">>]) -> fun process_host/2; -handler([_, <<"override">>, <<"general">>]) -> fun process_override/2; -handler([_, <<"mongooseimctl_access_commands">>, <<"general">>]) -> fun ctl_access_rule/2; -handler([<<"commands">>, _, <<"mongooseimctl_access_commands">>, <<"general">>]) -> - fun ctl_access_commands/2; -handler([_, <<"commands">>, _, <<"mongooseimctl_access_commands">>, <<"general">>]) -> - fun(_, Val) -> [b2l(Val)] end; -handler([<<"argument_restrictions">>, _, <<"mongooseimctl_access_commands">>, <<"general">>]) -> - fun parse_section/2; -handler([_, <<"argument_restrictions">>, _, <<"mongooseimctl_access_commands">>, <<"general">>]) -> - fun ctl_access_arg_restriction/2; -handler([_, <<"routing_modules">>, <<"general">>]) -> - fun(_, Val) -> [b2a(Val)] end; - %% listen handler([_, <<"listen">>]) -> fun parse_list/2; handler([_, _, <<"listen">>]) -> fun process_listener/2; @@ -2056,18 +2079,29 @@ handler([_, _, <<"host_config">>]) -> fun process_section/2; handler([_, <<"general">>, _, <<"host_config">>] = P) -> handler_for_host(P); handler([_, <<"s2s">>, _, <<"host_config">>] = P) -> handler_for_host(P); handler(Path) -> - [<<"host_config">>, {host, _} | Rest] = lists:reverse(Path), - handler(lists:reverse(Rest)). + subtree_handler(initial, lists:reverse(Path)). + +subtree_handler(initial, [<<"host_config">>, {host, _} | Subtree]) -> + subtree_handler(subtree, Subtree); +subtree_handler(_, [<<"general">>|_] = Path) -> + mongoose_config_spec:handler(Path); +subtree_handler(subtree, Subtree) -> + handler(lists:reverse(Subtree)). %% 1. Strip host_config, choose the handler for the remaining path %% 2. Wrap the handler in a fun that calls the resulting function F for the current host --spec handler_for_host(path()) -> fun((path(), toml_value()) -> option()). +-spec handler_for_host(path()) -> + fun((path(), toml_value()) -> option()) | mongoose_config_spec:config_node(). handler_for_host(Path) -> [<<"host_config">>, {host, Host} | Rest] = lists:reverse(Path), - Handler = handler(lists:reverse(Rest)), - fun(PathArg, ValueArg) -> - ConfigFunctions = Handler(PathArg, ValueArg), - lists:flatmap(fun(F) -> F(Host) end, ConfigFunctions) + case handler(lists:reverse(Rest)) of + Handler when is_function(Handler) -> + fun(PathArg, ValueArg) -> + ConfigFunctions = Handler(PathArg, ValueArg), + lists:flatmap(fun(F) -> F(Host) end, ConfigFunctions) + end; + Spec -> + Spec end. -spec key(toml_key(), path(), toml_value()) -> tuple() | toml_key(). diff --git a/src/config/mongoose_config_spec.erl b/src/config/mongoose_config_spec.erl new file mode 100644 index 0000000000..9b40ee41c4 --- /dev/null +++ b/src/config/mongoose_config_spec.erl @@ -0,0 +1,111 @@ +-module(mongoose_config_spec). + +-compile(export_all). + +-include("ejabberd_config.hrl"). + +-type config_node() :: #section{} | #option{} | #list{}. + +handler(Path) -> + handler(Path, root()). + +handler([Node], #section{items = Items}) when is_map(Items) -> + maps:get(Node, Items); +handler([_Node], #section{items = Item}) -> + Item; +handler([item], #list{items = Item}) -> + Item; +handler([Node|Rest], #section{items = Items}) when is_map(Items) -> + Item = maps:get(Node, Items), + handler(Rest, Item); +handler([_Node|Rest], #section{items = Item}) -> + handler(Rest, Item); +handler([item|Rest], #list{items = Items}) -> + handler(Rest, Items). + +root() -> + #section{ + items = #{<<"general">> => general()}, + process = fun ?MODULE:process_root/1 + }. + +general() -> + #section{ + items = #{<<"loglevel">> => #option{type = atom, + validate = loglevel, + format = local_config}, + <<"hosts">> => #list{items = #option{type = binary, + validate = non_empty, + process = fun ?MODULE:prepare_host/1}, + validate = unique_non_empty, + format = config}, + <<"registration_timeout">> => #option{type = int_or_infinity, + validate = timeout, + format = local_config}, + <<"language">> => #option{type = binary, + validate = non_empty, + format = config}, + <<"all_metrics_are_global">> => #option{type = boolean, + format = local_config}, + <<"sm_backend">> => #option{type = atom, + validate = {module, ejabberd_sm_}, + process = fun ?MODULE:process_sm_backend/1, + format = config}, + <<"max_fsm_queue">> => #option{type = integer, + validate = positive, + format = local_config}, + <<"http_server_name">> => #option{type = string, + format = {local_config, cowboy_server_name}}, + <<"rdbms_server_type">> => #option{type = atom, + validate = {enum, [mssql, pgsql]}, + format = local_config}, + <<"override">> => #list{items = #option{type = atom, + validate = {enum, [local, global, acls]}, + format = override}, + validate = unique_non_empty, + format = none}, + <<"pgsql_users_number_estimate">> => #option{type = boolean, + format = host_local_config}, + <<"route_subdomains">> => #option{type = atom, + validate = {enum, [s2s]}, + format = host_local_config}, + <<"mongooseimctl_access_commands">> => #section{items = ctl_access_rule(), + format = local_config}, + <<"routing_modules">> => #list{items = #option{type = atom, + validate = module}, + format = local_config}, + <<"replaced_wait_timeout">> => #option{type = integer, + validate = positive, + format = host_local_config}, + <<"hide_service_name">> => #option{type = boolean, + format = host_local_config} + } + }. + +ctl_access_rule() -> + #section{ + items = #{<<"commands">> => #list{items = #option{type = string}}, + <<"argument_restrictions">> => #section{items = #option{type = string}} + }, + process = fun ?MODULE:process_ctl_access_rule/1, + format = prepend_key + }. + +process_root(KVs) -> + true = lists:any(fun(#local_config{key = hosts}) -> true; + (_) -> false + end, KVs), + KVs. + +process_ctl_access_rule(KVs) -> + Commands = proplists:get_value(commands, KVs, all), + ArgRestrictions = proplists:get_value(argument_restrictions, KVs, []), + {Commands, ArgRestrictions}. + +process_sm_backend(Backend) -> + {Backend, []}. + +prepare_host(Host) -> + Node = jid:nodeprep(Host), + true = Node =/= error, + Node. diff --git a/src/config/mongoose_config_validator_toml.erl b/src/config/mongoose_config_validator_toml.erl index f9d1e6a92c..e0949feeda 100644 --- a/src/config/mongoose_config_validator_toml.erl +++ b/src/config/mongoose_config_validator_toml.erl @@ -1,6 +1,8 @@ -module(mongoose_config_validator_toml). --export([validate/2]). +-export([validate/2, + validate/3]). +-compile(export_all). -include("mongoose.hrl"). -include("ejabberd_config.hrl"). @@ -14,59 +16,6 @@ validate(Path, [F]) when is_function(F, 1) -> validate(Path, F(?HOST)); -%% general -validate([<<"loglevel">>, <<"general">>], - [#local_config{value = Val}]) -> validate_loglevel(Val); -validate([item, <<"hosts">>, <<"general">>], - [Value]) -> - validate_non_empty_binary(Value); -validate([<<"hosts">>, <<"general">>], - [#config{value = Val}]) -> - validate_hosts(Val); -validate([<<"registration_timeout">>, <<"general">>], - [#local_config{value = Val}]) -> - validate_timeout(Val); -validate([<<"language">>, <<"general">>], - [#config{value = Value}]) -> - validate_non_empty_binary(Value); -validate([<<"all_metrics_are_global">>, <<"general">>], - [#local_config{value = Val}]) -> - validate_boolean(Val); -validate([<<"sm_backend">>, <<"general">>], - [#config{value = {Backend, []}}]) -> - validate_module(list_to_atom("ejabberd_sm_" ++ atom_to_list(Backend))); -validate([<<"max_fsm_queue">>, <<"general">>], - [#local_config{value = Value}]) -> - validate_positive_integer(Value); -validate([<<"rdbms_server_type">>, <<"general">>], - [#local_config{value = Value}]) -> - validate_enum(Value, [mssql, pgsql]); -validate([item, <<"override">>, <<"general">>], - [{override, Value}]) -> - validate_enum(Value, [local, global, acls]); -validate([<<"override">>, <<"general">>], - Items) -> - validate_unique_items(Items); -validate([<<"pgsql_users_number_estimate">>, <<"general">>|Path], - [#local_config{value = Value}]) -> - validate_root_or_host_config(Path), - validate_boolean(Value); -validate([<<"route_subdomains">>, <<"general">>|Path], - [#local_config{value = Value}]) -> - validate_root_or_host_config(Path), - validate_enum(Value, [s2s]); -validate([item, <<"routing_modules">>, <<"general">>], - [Value]) -> - validate_module(Value); -validate([<<"replaced_wait_timeout">>, <<"general">>|Path], - [#local_config{value = Value}]) -> - validate_root_or_host_config(Path), - validate_positive_integer(Value); -validate([<<"hide_service_name">>, <<"general">>|Path], - [#local_config{value = Value}]) -> - validate_root_or_host_config(Path), - validate_boolean(Value); - %% listen validate([item, _Type, <<"listen">>], [{{Port, _IPT, _Proto}, _Module, _Opts}]) -> @@ -1578,6 +1527,27 @@ validate([<<"timeout_action">>, <<"mod_ping">>, <<"modules">>|_], validate(_Path, _Value) -> ok. +validate(V, boolean, any) -> validate_boolean(V); +validate(V, binary, domain) -> validate_binary_domain(V); +validate(V, binary, non_empty) -> validate_non_empty_binary(V); +validate(V, integer, positive) -> validate_positive_integer(V); +validate(V, int_or_infinity, timeout) -> validate_timeout(V); +validate(V, string, url) -> validate_url(V); +validate(V, string, non_empty) -> validate_non_empty_string(V); +validate(V, atom, module) -> validate_module(V); +validate(V, atom, {module, Prefix}) -> + validate_module(list_to_atom(atom_to_list(Prefix) ++ atom_to_list(V))); +validate(V, atom, loglevel) -> validate_loglevel(V); +validate(V, _, {enum, Values}) -> validate_enum(V, Values); +validate(_V, _, any) -> ok. + +validate_list([_|_], non_empty) -> ok; +validate_list(L = [_|_], unique_non_empty) -> + validate_unique_items(L); +validate_list(L, any) when is_list(L) -> ok. + +validate_section([_|_], non_empty) -> ok; +validate_section(L, any) when is_list(L) -> ok. %% validators diff --git a/test/config_parser_SUITE.erl b/test/config_parser_SUITE.erl index 139a578786..93617cda80 100644 --- a/test/config_parser_SUITE.erl +++ b/test/config_parser_SUITE.erl @@ -312,18 +312,26 @@ mongooseimctl_access_commands(_Config) -> parse(#{<<"general">> => #{<<"mongooseimctl_access_commands">> => #{<<"local">> => AccessRule}}})), ?eq([#local_config{key = mongooseimctl_access_commands, - value = [{local, all, []}] + value = [{local, all, [{node, "mim1@host1"}]}] + }], + parse(#{<<"general">> => #{<<"mongooseimctl_access_commands">> => + #{<<"local">> => maps:remove(<<"commands">>, + AccessRule)}}})), + ?eq([#local_config{key = mongooseimctl_access_commands, + value = [{local, ["join_cluster"], []}] }], parse(#{<<"general">> => #{<<"mongooseimctl_access_commands">> => - #{<<"local">> => #{<<"commands">> => <<"all">>}}}})), - ?err(parse(#{<<"general">> => - #{<<"mongooseimctl_access_commands">> => - #{<<"local">> => #{<<"argument_restrictions">> => - #{<<"node">> => <<"mim1@host1">>}}} - }})), + #{<<"local">> => maps:remove(<<"argument_restrictions">>, + AccessRule)}}})), + ?eq([#local_config{key = mongooseimctl_access_commands, + value = [{local, all, []}] + }], + parse(#{<<"general">> => #{<<"mongooseimctl_access_commands">> => #{<<"local">> => #{}}}})), + ?err(parse(#{<<"general">> => #{<<"mongooseimctl_access_commands">> => + #{<<"local">> => #{<<"commands">> => <<"all">>}}}})), ?err(parse(#{<<"general">> => #{<<"mongooseimctl_access_commands">> => - #{<<"local">> => #{<<"commands">> => <<"none">>}} - }})). + #{<<"local">> => #{<<"argument_restrictions">> => + [<<"none">>]}}}})). routing_modules(_Config) -> ?eq([#local_config{key = routing_modules, value = [mongoose_router_global, From 2df5dfa3d575b3ad26619c3fbedf08c76db829dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chrz=C4=85szcz?= Date: Tue, 10 Nov 2020 14:44:36 +0100 Subject: [PATCH 3/3] Document the changed format of mongooseim_access_commands --- doc/advanced-configuration/general.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/doc/advanced-configuration/general.md b/doc/advanced-configuration/general.md index 0caf2a03e3..e9fab2068a 100644 --- a/doc/advanced-configuration/general.md +++ b/doc/advanced-configuration/general.md @@ -69,8 +69,8 @@ User access rules are configured mainly in the [`acl`](acl.md) and [`access`](ac ## `general.mongooseimctl_access_commands` * **Scope:** local * **Syntax:** TOML table, whose **keys** are the names of the access rules defined in the [`access`](access.md) config section and **values** specify allowed administration commands. Each value is a table with the following nested options: - * `commands`: mandatory, a list of strings representing the allowed commands, or the string `"all"` - * `argument_restrictions`: optional, a table whose keys are the argument names and the values are strings representing the allowed values + * `commands`: optional, a list of strings representing the allowed commands. When not specified, all commands are allowed. + * `argument_restrictions`: optional, a table whose keys are the argument names and the values are strings representing the allowed values. When not specified, there are no restrictions. * **Default:** not set By default all admin operations are permitted with the `mongooseimctl` command without authentication. You can change that by setting this option for a specific access rule. When the rule returns the value `"allow"`, the user is permitted to use the specified commands with the optional restrictions. @@ -79,7 +79,6 @@ By default all admin operations are permitted with the `mongooseimctl` command w ``` [general.mongooseimctl_access_commands.admin] - commands = "all" ``` The `admin` rule needs to be defined in the `access` section.