aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--.travis/mysql_repo_key.asc10
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--README.md2
-rw-r--r--configure.ac15
-rw-r--r--ejabberd.yml.example9
-rw-r--r--include/adhoc.hrl2
-rw-r--r--include/bosh.hrl2
-rw-r--r--include/ejabberd_auth.hrl2
-rw-r--r--include/ejabberd_commands.hrl2
-rw-r--r--include/ejabberd_config.hrl2
-rw-r--r--include/ejabberd_ctl.hrl2
-rw-r--r--include/ejabberd_http.hrl2
-rw-r--r--include/ejabberd_oauth.hrl2
-rw-r--r--include/ejabberd_sm.hrl2
-rw-r--r--include/ejabberd_sql_pt.hrl2
-rw-r--r--include/ejabberd_stacktrace.hrl27
-rw-r--r--include/ejabberd_web_admin.hrl2
-rw-r--r--include/eldap.hrl2
-rw-r--r--include/http_bind.hrl2
-rw-r--r--include/logger.hrl2
-rw-r--r--include/mod_announce.hrl2
-rw-r--r--include/mod_caps.hrl2
-rw-r--r--include/mod_last.hrl2
-rw-r--r--include/mod_mam.hrl2
-rw-r--r--include/mod_muc.hrl2
-rw-r--r--include/mod_muc_room.hrl6
-rw-r--r--include/mod_offline.hrl2
-rw-r--r--include/mod_privacy.hrl2
-rw-r--r--include/mod_private.hrl2
-rw-r--r--include/mod_proxy65.hrl2
-rw-r--r--include/mod_push.hrl2
-rw-r--r--include/mod_roster.hrl2
-rw-r--r--include/mod_shared_roster.hrl2
-rw-r--r--include/mod_vcard.hrl2
-rw-r--r--include/mod_vcard_xupdate.hrl2
-rw-r--r--include/pubsub.hrl4
-rw-r--r--lib/ejabberd/config/config.ex4
-rw-r--r--lib/ejabberd/config/ejabberd_module.ex1
-rw-r--r--lib/ejabberd/config/logger/ejabberd_logger.ex2
-rw-r--r--lib/ejabberd/config/validator/validation.ex2
-rw-r--r--lib/ejabberd/config/validator/validator_attrs.ex2
-rw-r--r--lib/mix/tasks/deps.tree.ex4
-rw-r--r--lib/mod_presence_demo.ex9
-rw-r--r--mix.exs31
-rw-r--r--mix.lock9
-rw-r--r--rebar.config22
-rw-r--r--rebar.config.script2
-rw-r--r--rel/reltool.config.script2
-rw-r--r--sql/lite.new.sql2
-rw-r--r--sql/lite.sql2
-rw-r--r--sql/mssql.sql2
-rw-r--r--sql/mysql.new.sql2
-rw-r--r--sql/mysql.sql2
-rw-r--r--sql/pg.new.sql2
-rw-r--r--sql/pg.sql2
-rw-r--r--src/acl.erl2
-rw-r--r--src/ejabberd.app.src.in3
-rw-r--r--src/ejabberd.erl6
-rw-r--r--src/ejabberd_access_permissions.erl27
-rw-r--r--src/ejabberd_acme.erl148
-rw-r--r--src/ejabberd_admin.erl2
-rw-r--r--src/ejabberd_app.erl29
-rw-r--r--src/ejabberd_auth.erl2
-rw-r--r--src/ejabberd_auth_anonymous.erl2
-rw-r--r--src/ejabberd_auth_external.erl2
-rw-r--r--src/ejabberd_auth_ldap.erl2
-rw-r--r--src/ejabberd_auth_mnesia.erl2
-rw-r--r--src/ejabberd_auth_pam.erl2
-rw-r--r--src/ejabberd_auth_riak.erl2
-rw-r--r--src/ejabberd_auth_sql.erl2
-rw-r--r--src/ejabberd_backend_sup.erl2
-rw-r--r--src/ejabberd_bosh.erl2
-rw-r--r--src/ejabberd_c2s.erl9
-rw-r--r--src/ejabberd_c2s_config.erl2
-rw-r--r--src/ejabberd_captcha.erl5
-rw-r--r--src/ejabberd_cluster.erl2
-rw-r--r--src/ejabberd_cluster_mnesia.erl2
-rw-r--r--src/ejabberd_commands.erl3
-rw-r--r--src/ejabberd_commands_doc.erl2
-rw-r--r--src/ejabberd_config.erl18
-rw-r--r--src/ejabberd_ctl.erl9
-rw-r--r--src/ejabberd_hooks.erl17
-rw-r--r--src/ejabberd_http.erl31
-rw-r--r--src/ejabberd_http_ws.erl2
-rw-r--r--src/ejabberd_iq.erl8
-rw-r--r--src/ejabberd_listener.erl2
-rw-r--r--src/ejabberd_local.erl8
-rw-r--r--src/ejabberd_logger.erl2
-rw-r--r--src/ejabberd_mnesia.erl7
-rw-r--r--src/ejabberd_oauth.erl2
-rw-r--r--src/ejabberd_oauth_mnesia.erl2
-rw-r--r--src/ejabberd_oauth_rest.erl2
-rw-r--r--src/ejabberd_oauth_sql.erl2
-rw-r--r--src/ejabberd_piefxis.erl18
-rw-r--r--src/ejabberd_pkix.erl2
-rw-r--r--src/ejabberd_rdbms.erl7
-rw-r--r--src/ejabberd_redis.erl7
-rw-r--r--src/ejabberd_redis_sup.erl2
-rw-r--r--src/ejabberd_regexp.erl2
-rw-r--r--src/ejabberd_riak.erl2
-rw-r--r--src/ejabberd_riak_sup.erl2
-rw-r--r--src/ejabberd_router.erl8
-rw-r--r--src/ejabberd_router_mnesia.erl2
-rw-r--r--src/ejabberd_router_multicast.erl2
-rw-r--r--src/ejabberd_router_redis.erl2
-rw-r--r--src/ejabberd_router_riak.erl2
-rw-r--r--src/ejabberd_router_sql.erl8
-rw-r--r--src/ejabberd_s2s.erl11
-rw-r--r--src/ejabberd_s2s_in.erl2
-rw-r--r--src/ejabberd_s2s_out.erl2
-rw-r--r--src/ejabberd_service.erl2
-rw-r--r--src/ejabberd_shaper.erl2
-rw-r--r--src/ejabberd_sip.erl2
-rw-r--r--src/ejabberd_sm.erl8
-rw-r--r--src/ejabberd_sm_mnesia.erl2
-rw-r--r--src/ejabberd_sm_redis.erl2
-rw-r--r--src/ejabberd_sm_riak.erl2
-rw-r--r--src/ejabberd_sm_sql.erl2
-rw-r--r--src/ejabberd_sql.erl63
-rw-r--r--src/ejabberd_sql_pt.erl2
-rw-r--r--src/ejabberd_sql_sup.erl2
-rw-r--r--src/ejabberd_stun.erl2
-rw-r--r--src/ejabberd_sup.erl2
-rw-r--r--src/ejabberd_system_monitor.erl2
-rw-r--r--src/ejabberd_tmp_sup.erl2
-rw-r--r--src/ejabberd_update.erl2
-rw-r--r--src/ejabberd_web.erl2
-rw-r--r--src/ejabberd_web_admin.erl12
-rw-r--r--src/ejabberd_websocket.erl2
-rw-r--r--src/ejabberd_xmlrpc.erl2
-rw-r--r--src/ejd2sql.erl2
-rw-r--r--src/eldap_filter.erl2
-rw-r--r--src/eldap_pool.erl2
-rw-r--r--src/eldap_utils.erl2
-rw-r--r--src/elixir_logger_backend.erl2
-rw-r--r--src/ext_mod.erl2
-rw-r--r--src/extauth.erl2
-rw-r--r--src/extauth_sup.erl2
-rw-r--r--src/gen_iq_handler.erl8
-rw-r--r--src/gen_mod.erl19
-rw-r--r--src/gen_pubsub_node.erl2
-rw-r--r--src/gen_pubsub_nodetree.erl2
-rw-r--r--src/jd2ejd.erl2
-rw-r--r--src/misc.erl2
-rw-r--r--src/mod_adhoc.erl2
-rw-r--r--src/mod_admin_extra.erl50
-rw-r--r--src/mod_admin_update_sql.erl2
-rw-r--r--src/mod_announce.erl2
-rw-r--r--src/mod_announce_mnesia.erl2
-rw-r--r--src/mod_announce_riak.erl2
-rw-r--r--src/mod_announce_sql.erl2
-rw-r--r--src/mod_avatar.erl2
-rw-r--r--src/mod_block_strangers.erl2
-rw-r--r--src/mod_blocking.erl2
-rw-r--r--src/mod_bosh.erl2
-rw-r--r--src/mod_bosh_mnesia.erl2
-rw-r--r--src/mod_bosh_redis.erl2
-rw-r--r--src/mod_bosh_riak.erl2
-rw-r--r--src/mod_bosh_sql.erl2
-rw-r--r--src/mod_caps.erl2
-rw-r--r--src/mod_caps_mnesia.erl2
-rw-r--r--src/mod_caps_riak.erl2
-rw-r--r--src/mod_caps_sql.erl2
-rw-r--r--src/mod_carboncopy.erl2
-rw-r--r--src/mod_client_state.erl2
-rw-r--r--src/mod_configure.erl2
-rw-r--r--src/mod_delegation.erl2
-rw-r--r--src/mod_disco.erl2
-rw-r--r--src/mod_echo.erl2
-rw-r--r--src/mod_fail2ban.erl2
-rw-r--r--src/mod_http_api.erl57
-rw-r--r--src/mod_http_fileserver.erl2
-rw-r--r--src/mod_http_upload.erl2
-rw-r--r--src/mod_http_upload_quota.erl2
-rw-r--r--src/mod_last.erl2
-rw-r--r--src/mod_last_mnesia.erl2
-rw-r--r--src/mod_last_riak.erl2
-rw-r--r--src/mod_last_sql.erl2
-rw-r--r--src/mod_legacy_auth.erl2
-rw-r--r--src/mod_mam.erl251
-rw-r--r--src/mod_mam_mnesia.erl25
-rw-r--r--src/mod_mam_sql.erl22
-rw-r--r--src/mod_metrics.erl2
-rw-r--r--src/mod_muc.erl30
-rw-r--r--src/mod_muc_admin.erl112
-rw-r--r--src/mod_muc_log.erl2
-rw-r--r--src/mod_muc_mnesia.erl2
-rw-r--r--src/mod_muc_riak.erl2
-rw-r--r--src/mod_muc_room.erl120
-rw-r--r--src/mod_muc_sql.erl2
-rw-r--r--src/mod_multicast.erl2
-rw-r--r--src/mod_offline.erl43
-rw-r--r--src/mod_offline_mnesia.erl2
-rw-r--r--src/mod_offline_riak.erl2
-rw-r--r--src/mod_offline_sql.erl2
-rw-r--r--src/mod_ping.erl43
-rw-r--r--src/mod_pres_counter.erl2
-rw-r--r--src/mod_privacy.erl2
-rw-r--r--src/mod_privacy_mnesia.erl2
-rw-r--r--src/mod_privacy_riak.erl2
-rw-r--r--src/mod_privacy_sql.erl2
-rw-r--r--src/mod_private.erl4
-rw-r--r--src/mod_private_mnesia.erl2
-rw-r--r--src/mod_private_riak.erl2
-rw-r--r--src/mod_private_sql.erl2
-rw-r--r--src/mod_privilege.erl2
-rw-r--r--src/mod_proxy65.erl2
-rw-r--r--src/mod_proxy65_lib.erl2
-rw-r--r--src/mod_proxy65_mnesia.erl2
-rw-r--r--src/mod_proxy65_redis.erl2
-rw-r--r--src/mod_proxy65_riak.erl2
-rw-r--r--src/mod_proxy65_service.erl2
-rw-r--r--src/mod_proxy65_sql.erl2
-rw-r--r--src/mod_proxy65_stream.erl2
-rw-r--r--src/mod_pubsub.erl2
-rw-r--r--src/mod_push.erl45
-rw-r--r--src/mod_push_keepalive.erl2
-rw-r--r--src/mod_push_mnesia.erl2
-rw-r--r--src/mod_push_sql.erl2
-rw-r--r--src/mod_register.erl2
-rw-r--r--src/mod_register_web.erl2
-rw-r--r--src/mod_roster.erl17
-rw-r--r--src/mod_roster_mnesia.erl2
-rw-r--r--src/mod_roster_riak.erl2
-rw-r--r--src/mod_roster_sql.erl2
-rw-r--r--src/mod_s2s_dialback.erl2
-rw-r--r--src/mod_service_log.erl2
-rw-r--r--src/mod_shared_roster.erl39
-rw-r--r--src/mod_shared_roster_ldap.erl2
-rw-r--r--src/mod_shared_roster_mnesia.erl2
-rw-r--r--src/mod_shared_roster_riak.erl2
-rw-r--r--src/mod_shared_roster_sql.erl2
-rw-r--r--src/mod_sic.erl2
-rw-r--r--src/mod_sip.erl2
-rw-r--r--src/mod_sip_proxy.erl2
-rw-r--r--src/mod_sip_registrar.erl2
-rw-r--r--src/mod_stats.erl2
-rw-r--r--src/mod_stream_mgmt.erl2
-rw-r--r--src/mod_time.erl2
-rw-r--r--src/mod_vcard.erl2
-rw-r--r--src/mod_vcard_ldap.erl2
-rw-r--r--src/mod_vcard_mnesia.erl2
-rw-r--r--src/mod_vcard_riak.erl2
-rw-r--r--src/mod_vcard_sql.erl2
-rw-r--r--src/mod_vcard_xupdate.erl2
-rw-r--r--src/mod_version.erl2
-rw-r--r--src/node_buddy.erl2
-rw-r--r--src/node_club.erl2
-rw-r--r--src/node_dag.erl2
-rw-r--r--src/node_dispatch.erl2
-rw-r--r--src/node_flat.erl2
-rw-r--r--src/node_flat_sql.erl2
-rw-r--r--src/node_hometree.erl2
-rw-r--r--src/node_hometree_sql.erl2
-rw-r--r--src/node_mb.erl2
-rw-r--r--src/node_mb_sql.erl2
-rw-r--r--src/node_mix.erl2
-rw-r--r--src/node_mix_sql.erl2
-rw-r--r--src/node_online.erl2
-rw-r--r--src/node_pep.erl2
-rw-r--r--src/node_pep_sql.erl2
-rw-r--r--src/node_private.erl2
-rw-r--r--src/node_public.erl2
-rw-r--r--src/nodetree_dag.erl2
-rw-r--r--src/nodetree_tree.erl2
-rw-r--r--src/nodetree_tree_sql.erl2
-rw-r--r--src/nodetree_virtual.erl2
-rw-r--r--src/prosody2ejabberd.erl41
-rw-r--r--src/proxy_protocol.erl2
-rw-r--r--src/pubsub_db_sql.erl2
-rw-r--r--src/pubsub_index.erl2
-rw-r--r--src/pubsub_migrate.erl2
-rw-r--r--src/pubsub_subscription.erl2
-rw-r--r--src/pubsub_subscription_sql.erl2
-rw-r--r--src/rest.erl2
-rw-r--r--src/str.erl2
-rw-r--r--src/translate.erl2
-rw-r--r--src/win32_dns.erl2
-rw-r--r--src/xml_compress.erl4
-rw-r--r--test/acl_test.exs389
-rw-r--r--test/announce_tests.erl2
-rw-r--r--test/carbons_tests.erl2
-rw-r--r--test/csi_tests.erl2
-rw-r--r--test/ejabberd_SUITE.erl6
-rw-r--r--test/ejabberd_admin_test.exs88
-rw-r--r--test/ejabberd_auth_mock.exs74
-rw-r--r--test/ejabberd_hooks_test.exs203
-rw-r--r--test/ejabberd_oauth_mock.exs50
-rw-r--r--test/ejabberd_sm_mock.exs121
-rw-r--r--test/elixir_SUITE.erl119
-rw-r--r--test/example_tests.erl2
-rw-r--r--test/jid_test.exs45
-rw-r--r--test/ldap_srv.erl2
-rw-r--r--test/mam_tests.erl34
-rw-r--r--test/mix_tests.erl154
-rw-r--r--test/mod_admin_extra_test.exs374
-rw-r--r--test/mod_http_api_mock_test.exs270
-rw-r--r--test/mod_http_api_test.exs127
-rw-r--r--test/mod_last_mock.exs79
-rw-r--r--test/mod_roster_mock.exs159
-rw-r--r--test/muc_tests.erl2
-rw-r--r--test/offline_tests.erl2
-rw-r--r--test/privacy_tests.erl2
-rw-r--r--test/private_tests.erl48
-rw-r--r--test/proxy65_tests.erl2
-rw-r--r--test/pubsub_tests.erl2
-rw-r--r--test/push_tests.erl2
-rw-r--r--test/replaced_tests.erl2
-rw-r--r--test/roster_tests.erl2
-rw-r--r--test/sm_tests.erl2
-rw-r--r--test/suite.erl2
-rw-r--r--test/test_helper.exs7
-rw-r--r--test/upload_tests.erl2
-rw-r--r--test/vcard_tests.erl2
-rw-r--r--tools/xml_compress_gen.erl6
-rw-r--r--vars.config.in3
317 files changed, 1233 insertions, 3158 deletions
diff --git a/.travis.yml b/.travis.yml
index e93703efc..efe6a63a5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,7 +3,7 @@ language: erlang
otp_release:
- 19.0
- 20.3
- - 21.1
+ - 21.2
services:
- redis-server
diff --git a/.travis/mysql_repo_key.asc b/.travis/mysql_repo_key.asc
index 6c9fd8dec..281e134fb 100644
--- a/.travis/mysql_repo_key.asc
+++ b/.travis/mysql_repo_key.asc
@@ -1,5 +1,5 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.4.5 (GNU/Linux)
+Version: GnuPG v1
mQGiBD4+owwRBAC14GIfUfCyEDSIePvEW3SAFUdJBtoQHH/nJKZyQT7h9bPlUWC3
RODjQReyCITRrdwyrKUGku2FmeVGwn2u2WmDMNABLnpprWPkBdCk96+OmSLN9brZ
@@ -11,9 +11,9 @@ kYpXBACmWpP8NJTkamEnPCia2ZoOHODANwpUkP43I7jsDmgtobZX9qnrAXw+uNDI
QJEXM6FSbi0LLtZciNlYsafwAPEOMDKpMqAK6IyisNtPvaLd8lH0bPAnWqcyefep
rv0sxxqUEMcM3o7wwgfN83POkDasDbs3pjwPhxvhz6//62zQJ7Q2TXlTUUwgUmVs
ZWFzZSBFbmdpbmVlcmluZyA8bXlzcWwtYnVpbGRAb3NzLm9yYWNsZS5jb20+iGwE
-ExECACwCGyMCHgECF4ACGQEGCwkIBwMCBhUKCQgCAwUWAgMBAAUCWKcFIAUJHirJ
-FAAKCRCMcY07UHLh9VcFAJ46pUyVd8BZ2r5CppMC1tmyQ3ceRgCfVPwuVsiS0VER
-5WUqtAQDt+DoetCIaQQTEQIAKQIbIwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAhkB
+ExECACwCGyMCHgECF4ACGQEGCwkIBwMCBhUKCQgCAwUWAgMBAAUCXEBY+wUJI87e
+5AAKCRCMcY07UHLh9RZPAJ9uvm0zlzfCN+DHxHVaoFLFjdVYTQCfborsC9tmEZYa
+whhogjeBkZkorbyIaQQTEQIAKQIbIwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAhkB
BQJTAdRmBQkaZsvLAAoJEIxxjTtQcuH1X4MAoKNLWAbCBUj96637kv6Xa/fJuX5m
AJwPtmgDfjUe2iuhXdTrFEPT19SB6ohmBBMRAgAmAhsjBgsJCAcDAgQVAggDBBYC
AwECHgECF4AFAk53PioFCRP7AhUACgkQjHGNO1By4fUmzACeJdfqgc9gWTUhgmcM
@@ -428,5 +428,5 @@ GoaU9u41oyZTIiXPiFidJoIZCh7fdurP8pn3X+R5HUNXMr7M+ba8lSNxce/F3kmH
0L7rsKqdh9d/aVxhJINJ+inVDnrXWVoXu9GBjT8Nco1iU9SIVAQYEQIADAUCTnc9
7QUJE/sBuAASB2VHUEcAAQEJEIxxjTtQcuH1FJsAmwWK9vmwRJ/y9gTnJ8PWf0BV
roUTAKClYAhZuX2nUNwH4vlEJQHDqYa5yQ==
-=HfUN
+=ghXk
-----END PGP PUBLIC KEY BLOCK-----
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 9d6220841..9ac1c6b2e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -124,7 +124,7 @@ That's it! Thank you for your contribution!
## <a name="cla"></a> Signing the Contributor License Agreement (CLA)
-Upon submmitting a Pull Request, we will ask you to sign our CLA if you haven't done
+Upon submitting a Pull Request, we will ask you to sign our CLA if you haven't done
so before. It's a quick process, we promise, and you will be able to do it all online
You can read [ProcessOne Contribution License Agreement][cla] in PDF.
diff --git a/README.md b/README.md
index 6221eae37..b410b2ac2 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-ejabberd Community Edition
+ejabberd Community Edition
==========================
[![Build Status](https://travis-ci.org/processone/ejabberd.svg?branch=master)](https://travis-ci.org/processone/ejabberd) [![Hex version](https://img.shields.io/hexpm/v/ejabberd.svg "Hex version")](https://hex.pm/packages/ejabberd)
diff --git a/configure.ac b/configure.ac
index d23bf9b6b..81f0167ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -109,10 +109,10 @@ AC_ARG_ENABLE(mssql,
esac],[db_type=generic])
AC_ARG_ENABLE(all,
-[AC_HELP_STRING([--enable-all], [same as --enable-odbc --enable-mysql --enable-pgsql --enable-sqlite --enable-pam --enable-zlib --enable-riak --enable-redis --enable-elixir --enable-iconv --enable-stun --enable-sip --enable-debug --enable-tools (useful for Dialyzer checks, default: no)])],
+[AC_HELP_STRING([--enable-all], [same as --enable-odbc --enable-mysql --enable-pgsql --enable-sqlite --enable-pam --enable-zlib --enable-riak --enable-redis --enable-elixir --enable-stun --enable-sip --enable-debug --enable-tools (useful for Dialyzer checks, default: no)])],
[case "${enableval}" in
- yes) odbc=true mysql=true pgsql=true sqlite=true pam=true zlib=true riak=true redis=true elixir=true iconv=true stun=true sip=true debug=true tools=true ;;
- no) odbc=false mysql=false pgsql=false sqlite=false pam=false zlib=false riak=false redis=false elixir=false iconv=false stun=false sip=false debug=false tools=false ;;
+ yes) odbc=true mysql=true pgsql=true sqlite=true pam=true zlib=true riak=true redis=true elixir=true stun=true sip=true debug=true tools=true ;;
+ no) odbc=false mysql=false pgsql=false sqlite=false pam=false zlib=false riak=false redis=false elixir=false stun=false sip=false debug=false tools=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-all) ;;
esac],[])
@@ -196,14 +196,6 @@ AC_ARG_ENABLE(elixir,
*) AC_MSG_ERROR(bad value ${enableval} for --enable-elixir) ;;
esac],[if test "x$elixir" = "x"; then elixir=false; fi])
-AC_ARG_ENABLE(iconv,
-[AC_HELP_STRING([--enable-iconv], [enable iconv support (default: no)])],
-[case "${enableval}" in
- yes) iconv=true ;;
- no) iconv=false ;;
- *) AC_MSG_ERROR(bad value ${enableval} for --enable-iconv) ;;
-esac],[if test "x$iconv" = "x"; then iconv=false; fi])
-
AC_ARG_ENABLE(debug,
[AC_HELP_STRING([--enable-debug], [enable debug information (default: yes)])],
[case "${enableval}" in
@@ -307,7 +299,6 @@ AC_SUBST(zlib)
AC_SUBST(riak)
AC_SUBST(redis)
AC_SUBST(elixir)
-AC_SUBST(iconv)
AC_SUBST(stun)
AC_SUBST(sip)
AC_SUBST(debug)
diff --git a/ejabberd.yml.example b/ejabberd.yml.example
index 66d65450c..0a38a2b7f 100644
--- a/ejabberd.yml.example
+++ b/ejabberd.yml.example
@@ -46,7 +46,7 @@ define_macro:
- "no_sslv2"
- "no_sslv3"
- # TLS options for client able to use moder ciphers (Windows 7+, Android 5.0+)
+ # TLS options for client able to use modern ciphers (Windows 7+, Android 5.0+)
CIPHERS_MODERN: "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"
PROTOCOL_OPTIONS_MODERN:
- "no_sslv2"
@@ -85,6 +85,11 @@ listen:
ciphers: CIPHERS_INTERMEDIATE
protocol_options: PROTOCOL_OPTIONS_INTERMEDIATE
tls: true
+ -
+ port: 5280
+ ip: "::"
+ module: ejabberd_http
+ web_admin: true
s2s_use_starttls: optional
@@ -190,6 +195,8 @@ modules:
- allow: admin
access_create: muc_create
access_persistent: muc_create
+ access_mam:
+ - allow
default_room_options:
mam: true
mod_muc_admin: {}
diff --git a/include/adhoc.hrl b/include/adhoc.hrl
index 1f95ea466..9471557d0 100644
--- a/include/adhoc.hrl
+++ b/include/adhoc.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/bosh.hrl b/include/bosh.hrl
index 906f375bb..57fd644a5 100644
--- a/include/bosh.hrl
+++ b/include/bosh.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_auth.hrl b/include/ejabberd_auth.hrl
index baf755916..8b9cb47fe 100644
--- a/include/ejabberd_auth.hrl
+++ b/include/ejabberd_auth.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_commands.hrl b/include/ejabberd_commands.hrl
index ebe8418b6..1e24cc5d5 100644
--- a/include/ejabberd_commands.hrl
+++ b/include/ejabberd_commands.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_config.hrl b/include/ejabberd_config.hrl
index a4d98c88a..d83e07b3c 100644
--- a/include/ejabberd_config.hrl
+++ b/include/ejabberd_config.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_ctl.hrl b/include/ejabberd_ctl.hrl
index 009075124..f11e22f3b 100644
--- a/include/ejabberd_ctl.hrl
+++ b/include/ejabberd_ctl.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_http.hrl b/include/ejabberd_http.hrl
index e0183a531..33c02ca2b 100644
--- a/include/ejabberd_http.hrl
+++ b/include/ejabberd_http.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_oauth.hrl b/include/ejabberd_oauth.hrl
index f6fd71a8c..51e77636f 100644
--- a/include/ejabberd_oauth.hrl
+++ b/include/ejabberd_oauth.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_sm.hrl b/include/ejabberd_sm.hrl
index 188ed3f29..0d216e90c 100644
--- a/include/ejabberd_sm.hrl
+++ b/include/ejabberd_sm.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_sql_pt.hrl b/include/ejabberd_sql_pt.hrl
index e3b27303b..50f902fc6 100644
--- a/include/ejabberd_sql_pt.hrl
+++ b/include/ejabberd_sql_pt.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_stacktrace.hrl b/include/ejabberd_stacktrace.hrl
new file mode 100644
index 000000000..4fdec33ea
--- /dev/null
+++ b/include/ejabberd_stacktrace.hrl
@@ -0,0 +1,27 @@
+%%%----------------------------------------------------------------------
+%%%
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
+%%%
+%%% This program is free software; you can redistribute it and/or
+%%% modify it under the terms of the GNU General Public License as
+%%% published by the Free Software Foundation; either version 2 of the
+%%% License, or (at your option) any later version.
+%%%
+%%% This program is distributed in the hope that it will be useful,
+%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+%%% General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License along
+%%% with this program; if not, write to the Free Software Foundation, Inc.,
+%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+%%%
+%%%----------------------------------------------------------------------
+
+-ifdef(DEPRECATED_GET_STACKTRACE).
+-define(EX_RULE(Class, Reason, Stack), Class:Reason:Stack).
+-define(EX_STACK(Stack), Stack).
+-else.
+-define(EX_RULE(Class, Reason, _), Class:Reason).
+-define(EX_STACK(_), erlang:get_stacktrace()).
+-endif.
diff --git a/include/ejabberd_web_admin.hrl b/include/ejabberd_web_admin.hrl
index b9549df05..477ee97a2 100644
--- a/include/ejabberd_web_admin.hrl
+++ b/include/ejabberd_web_admin.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/eldap.hrl b/include/eldap.hrl
index 995c8d79e..f839aa94f 100644
--- a/include/eldap.hrl
+++ b/include/eldap.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/http_bind.hrl b/include/http_bind.hrl
index 7e44f429b..457480c22 100644
--- a/include/http_bind.hrl
+++ b/include/http_bind.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/logger.hrl b/include/logger.hrl
index a407b2e21..2dd23e1ad 100644
--- a/include/logger.hrl
+++ b/include/logger.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_announce.hrl b/include/mod_announce.hrl
index d7e3bf6b5..5f716655d 100644
--- a/include/mod_announce.hrl
+++ b/include/mod_announce.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_caps.hrl b/include/mod_caps.hrl
index b875f825c..22dd23b7e 100644
--- a/include/mod_caps.hrl
+++ b/include/mod_caps.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_last.hrl b/include/mod_last.hrl
index 108278430..8bfec3edd 100644
--- a/include/mod_last.hrl
+++ b/include/mod_last.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_mam.hrl b/include/mod_mam.hrl
index 52a1481e2..e02b9249d 100644
--- a/include/mod_mam.hrl
+++ b/include/mod_mam.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_muc.hrl b/include/mod_muc.hrl
index a623e1eab..028662fe0 100644
--- a/include/mod_muc.hrl
+++ b/include/mod_muc.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_muc_room.hrl b/include/mod_muc_room.hrl
index 65f3c5479..40b1b9c04 100644
--- a/include/mod_muc_room.hrl
+++ b/include/mod_muc_room.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -100,7 +100,7 @@
room = <<"">> :: binary(),
host = <<"">> :: binary(),
server_host = <<"">> :: binary(),
- access = {none,none,none,none} :: {atom(), atom(), atom(), atom()},
+ access = {none,none,none,none,none} :: {atom(), atom(), atom(), atom(), atom()},
jid = #jid{} :: jid(),
config = #config{} :: config(),
users = #{} :: map(),
@@ -113,7 +113,7 @@
history :: lqueue(),
subject = [] :: [text()],
subject_author = <<"">> :: binary(),
- just_created = false :: boolean(),
+ just_created = misc:now_to_usec(now()) :: true | integer(),
activity = treap:empty() :: treap:treap(),
room_shaper = none :: shaper:shaper(),
room_queue :: p1_queue:queue() | undefined
diff --git a/include/mod_offline.hrl b/include/mod_offline.hrl
index 9641827bf..a705aabe2 100644
--- a/include/mod_offline.hrl
+++ b/include/mod_offline.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_privacy.hrl b/include/mod_privacy.hrl
index 64507aec8..291970cce 100644
--- a/include/mod_privacy.hrl
+++ b/include/mod_privacy.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_private.hrl b/include/mod_private.hrl
index a013b24e5..4dddd29ed 100644
--- a/include/mod_private.hrl
+++ b/include/mod_private.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_proxy65.hrl b/include/mod_proxy65.hrl
index 58f2ac8fd..197d97d7f 100644
--- a/include/mod_proxy65.hrl
+++ b/include/mod_proxy65.hrl
@@ -2,7 +2,7 @@
%%% RFC 1928 constants.
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_push.hrl b/include/mod_push.hrl
index 589cfac00..24f02a3ff 100644
--- a/include/mod_push.hrl
+++ b/include/mod_push.hrl
@@ -1,5 +1,5 @@
%%%----------------------------------------------------------------------
-%%% ejabberd, Copyright (C) 2017-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2017-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_roster.hrl b/include/mod_roster.hrl
index 5ddd596d4..c795aabc7 100644
--- a/include/mod_roster.hrl
+++ b/include/mod_roster.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_shared_roster.hrl b/include/mod_shared_roster.hrl
index 3287b6e0c..d0fbeaa56 100644
--- a/include/mod_shared_roster.hrl
+++ b/include/mod_shared_roster.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_vcard.hrl b/include/mod_vcard.hrl
index 09e0891ea..94f286bfc 100644
--- a/include/mod_vcard.hrl
+++ b/include/mod_vcard.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_vcard_xupdate.hrl b/include/mod_vcard_xupdate.hrl
index 95ada7c26..25b73adef 100644
--- a/include/mod_vcard_xupdate.hrl
+++ b/include/mod_vcard_xupdate.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/pubsub.hrl b/include/pubsub.hrl
index 923f5f5a9..735cfc737 100644
--- a/include/pubsub.hrl
+++ b/include/pubsub.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -27,7 +27,7 @@
%% this is currently a hard limit.
%% Would be nice to have it configurable.
--define(MAX_PAYLOAD_SIZE, 60000).
+-define(MAX_PAYLOAD_SIZE, 250000).
%% -------------------------------
%% Pubsub types
diff --git a/lib/ejabberd/config/config.ex b/lib/ejabberd/config/config.ex
index 4d1270bc1..4d1728d16 100644
--- a/lib/ejabberd/config/config.ex
+++ b/lib/ejabberd/config/config.ex
@@ -23,7 +23,7 @@ defmodule Ejabberd.Config do
# Could be also possible to interrupt the compilation&execution by throwing
# an exception if necessary.
def __before_compile__(_env) do
- get_modules_parsed_in_order
+ get_modules_parsed_in_order()
|> EjabberdModule.validate
|> EjabberdLogger.log_errors
end
@@ -48,7 +48,7 @@ defmodule Ejabberd.Config do
Returns a list with all the opts, formatted for ejabberd.
"""
def get_ejabberd_opts do
- get_general_opts
+ get_general_opts()
|> Dict.put(:modules, get_modules_parsed_in_order())
|> Dict.put(:listeners, get_listeners_parsed_in_order())
|> Ejabberd.Config.OptsFormatter.format_opts_for_ejabberd
diff --git a/lib/ejabberd/config/ejabberd_module.ex b/lib/ejabberd/config/ejabberd_module.ex
index 4de9a302e..6a74fe460 100644
--- a/lib/ejabberd/config/ejabberd_module.ex
+++ b/lib/ejabberd/config/ejabberd_module.ex
@@ -12,7 +12,6 @@ defmodule Ejabberd.Config.EjabberdModule do
defstruct [:module, :attrs]
alias Ejabberd.Config.EjabberdModule
- alias Ejabberd.Config.Attr
alias Ejabberd.Config.Validation
@doc """
diff --git a/lib/ejabberd/config/logger/ejabberd_logger.ex b/lib/ejabberd/config/logger/ejabberd_logger.ex
index 270fbfaa6..90970ba73 100644
--- a/lib/ejabberd/config/logger/ejabberd_logger.ex
+++ b/lib/ejabberd/config/logger/ejabberd_logger.ex
@@ -21,7 +21,7 @@ defmodule Ejabberd.Config.EjabberdLogger do
defp do_log_errors({:attribute, errors}), do: Enum.each errors, &log_attribute_error/1
defp do_log_errors({:dependency, errors}), do: Enum.each errors, &log_dependency_error/1
- defp log_attribute_error({{attr_name, val}, :attr_not_supported}), do:
+ defp log_attribute_error({{attr_name, _val}, :attr_not_supported}), do:
IO.puts "[ WARN ] Annotation @#{attr_name} is not supported."
defp log_attribute_error({{attr_name, val}, :type_not_supported}), do:
diff --git a/lib/ejabberd/config/validator/validation.ex b/lib/ejabberd/config/validator/validation.ex
index 2fe00361a..af582676e 100644
--- a/lib/ejabberd/config/validator/validation.ex
+++ b/lib/ejabberd/config/validator/validation.ex
@@ -7,9 +7,7 @@ defmodule Ejabberd.Config.Validation do
@type mod_validation_result :: {:ok, EjabberdModule.t} | {:error, EjabberdModule.t, map}
alias Ejabberd.Config.EjabberdModule
- alias Ejabberd.Config.Attr
alias Ejabberd.Config.Validator
- alias Ejabberd.Config.ValidatorUtility
@doc """
Given a module or a list of modules it runs validators on them
diff --git a/lib/ejabberd/config/validator/validator_attrs.ex b/lib/ejabberd/config/validator/validator_attrs.ex
index 94117ab21..6a85c068d 100644
--- a/lib/ejabberd/config/validator/validator_attrs.ex
+++ b/lib/ejabberd/config/validator/validator_attrs.ex
@@ -18,7 +18,7 @@ defmodule Ejabberd.Config.Validator.Attrs do
def validate({modules, mod, errors}) do
errors = Enum.reduce mod.attrs, errors, fn(attr, err) ->
case Attr.validate(attr) do
- {:ok, attr} -> err
+ {:ok, _attr} -> err
{:error, attr, cause} -> put_error(err, :attribute, {attr, cause})
end
end
diff --git a/lib/mix/tasks/deps.tree.ex b/lib/mix/tasks/deps.tree.ex
index 94cb85a50..9937270cd 100644
--- a/lib/mix/tasks/deps.tree.ex
+++ b/lib/mix/tasks/deps.tree.ex
@@ -40,7 +40,7 @@ defmodule Mix.Tasks.Ejabberd.Deps.Tree do
end
end
- defp build_dependency_tree(mods, mod, []), do: %{module: mod, dependency: []}
+ defp build_dependency_tree(_mods, mod, []), do: %{module: mod, dependency: []}
defp build_dependency_tree(mods, mod, deps) when is_list(deps) do
dependencies = Enum.map deps, fn dep ->
dep_deps = get_dependencies_of_mod(mods, dep)
@@ -65,7 +65,7 @@ defmodule Mix.Tasks.Ejabberd.Deps.Tree do
defp keep_only_mods_not_used_as_dep(mods, mods_used_as_dep) do
Enum.filter mods, fn %{module: mod} ->
- not mod in mods_used_as_dep
+ not (mod in mods_used_as_dep)
end
end
diff --git a/lib/mod_presence_demo.ex b/lib/mod_presence_demo.ex
index 09bf58405..3ce512c3d 100644
--- a/lib/mod_presence_demo.ex
+++ b/lib/mod_presence_demo.ex
@@ -17,4 +17,13 @@ defmodule ModPresenceDemo do
info('Receive presence for #{user}')
:none
end
+
+ def depends(_host, _opts) do
+ []
+ end
+
+ def mod_options(_host) do
+ []
+ end
+
end
diff --git a/mix.exs b/mix.exs
index 176e229f6..fec5c2603 100644
--- a/mix.exs
+++ b/mix.exs
@@ -3,7 +3,7 @@ defmodule Ejabberd.Mixfile do
def project do
[app: :ejabberd,
- version: "18.12.0",
+ version: "18.12.1",
description: description(),
elixir: "~> 1.4",
elixirc_paths: ["lib"],
@@ -25,12 +25,12 @@ defmodule Ejabberd.Mixfile do
def application do
[mod: {:ejabberd_app, []},
- applications: [:ssl, :os_mon],
+ applications: [:kernel, :stdlib, :sasl, :ssl],
included_applications: [:lager, :mnesia, :inets, :p1_utils, :cache_tab,
:fast_tls, :stringprep, :fast_xml, :xmpp,
:stun, :fast_yaml, :esip, :jiffy, :p1_oauth2,
- :eimp, :base64url, :jose, :pkix]
- ++ cond_apps()]
+ :eimp, :base64url, :jose, :pkix, :os_mon]
+ ++ cond_apps()]
end
defp if_function_exported(mod, fun, arity, okResult) do
@@ -42,10 +42,19 @@ defmodule Ejabberd.Mixfile do
end
end
+ defp if_version_above(ver, okResult) do
+ if :erlang.system_info(:otp_release) > ver do
+ okResult
+ else
+ []
+ end
+ end
+
defp erlc_options do
# Use our own includes + includes from all dependencies
includes = ["include"] ++ deps_include(["fast_xml", "xmpp", "p1_utils"])
[:debug_info, {:d, :ELIXIR_ENABLED}] ++ cond_options() ++ Enum.map(includes, fn(path) -> {:i, path} end) ++
+ if_version_above('20', [{:d, :DEPRECATED_GET_STACKTRACE}]) ++
if_function_exported(:crypto, :strong_rand_bytes, 1, [{:d, :STRONG_RAND_BYTES}]) ++
if_function_exported(:rand, :uniform, 1, [{:d, :RAND_UNIFORM}]) ++
if_function_exported(:gb_sets, :iterator_from, 2, [{:d, :GB_SETS_ITERATOR_FROM}]) ++
@@ -61,7 +70,7 @@ defmodule Ejabberd.Mixfile do
[{:lager, "~> 3.6.0"},
{:p1_utils, "~> 1.0"},
{:fast_xml, "~> 1.1"},
- {:xmpp, "~> 1.2"},
+ {:xmpp, "~> 1.3.0"},
{:cache_tab, "~> 1.0"},
{:stringprep, "~> 1.0"},
{:fast_yaml, "~> 1.0"},
@@ -72,7 +81,7 @@ defmodule Ejabberd.Mixfile do
{:p1_pgsql, "~> 1.1"},
{:jiffy, "~> 0.14.7"},
{:p1_oauth2, "~> 0.6.1"},
- {:distillery, "~> 1.0"},
+ {:distillery, "~> 2.0"},
{:pkix, "~> 1.0"},
{:ex_doc, ">= 0.0.0", only: :dev},
{:eimp, "~> 1.0"},
@@ -94,11 +103,8 @@ defmodule Ejabberd.Mixfile do
{config(:riak), {:riakc, "~> 2.4"}},
{config(:redis), {:eredis, "~> 1.0"}},
{config(:zlib), {:ezlib, "~> 1.0"}},
- {config(:iconv), {:iconv, "~> 1.0"}},
{config(:pam), {:epam, "~> 1.0"}},
- {config(:tools), {:luerl, "~> 0.3.1"}},
- {config(:tools), {:meck, "~> 0.8.4"}},
- {config(:tools), {:moka, github: "processone/moka", tag: "1.0.5c"}}], do:
+ {config(:tools), {:luerl, "~> 0.3.1"}}], do:
dep
end
@@ -107,8 +113,7 @@ defmodule Ejabberd.Mixfile do
{config(:mysql), :p1_mysql},
{config(:pgsql), :p1_pgsql},
{config(:sqlite), :sqlite3},
- {config(:zlib), :ezlib},
- {config(:iconv), :iconv}], do:
+ {config(:zlib), :ezlib}], do:
app
end
@@ -126,7 +131,7 @@ defmodule Ejabberd.Mixfile do
defp vars do
case :file.consult("vars.config") do
{:ok,config} -> config
- _ -> [zlib: true, iconv: false]
+ _ -> [zlib: true]
end
end
diff --git a/mix.lock b/mix.lock
index c97ae37d7..8afa8f006 100644
--- a/mix.lock
+++ b/mix.lock
@@ -1,7 +1,8 @@
%{
+ "artificery": {:hex, :artificery, "0.2.6", "f602909757263f7897130cbd006b0e40514a541b148d366ad65b89236b93497a", [:mix], [], "hexpm"},
"base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm"},
"cache_tab": {:hex, :cache_tab, "1.0.17", "0020e1036d7074d83a71be28b329ceb3e7f9d41cc5a8529b06c32ce4d8ee4995", [:rebar3], [{:p1_utils, "1.0.13", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm"},
- "distillery": {:hex, :distillery, "1.5.5", "c6132d5c0152bdce6850fb6c942d58f1971b169b6965d908dc4e8767cfa51a95", [:mix], [], "hexpm"},
+ "distillery": {:hex, :distillery, "2.0.12", "6e78fe042df82610ac3fa50bd7d2d8190ad287d120d3cd1682d83a44e8b34dfb", [:mix], [{:artificery, "~> 0.2", [hex: :artificery, repo: "hexpm", optional: false]}], "hexpm"},
"earmark": {:hex, :earmark, "1.3.0", "17f0c38eaafb4800f746b457313af4b2442a8c2405b49c645768680f900be603", [:mix], [], "hexpm"},
"eimp": {:hex, :eimp, "1.0.9", "daf0d2904be3ef5e4128d946e158113cdb4d52555023746d29b83ce86b531f3c", [:rebar3], [{:p1_utils, "1.0.13", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm"},
"epam": {:hex, :epam, "1.0.4", "2a5e40cbf9b2cf41df515782894c3b33c81b8ad32fff2fc847c3f725071dfaed", [:rebar3], [], "hexpm"},
@@ -14,15 +15,12 @@
"fast_yaml": {:hex, :fast_yaml, "1.0.17", "e945ef64e0cb7c311c7b42804dbe32a24e13a2afc0ffe249b7e0f9f9ac08e176", [:rebar3], [{:p1_utils, "1.0.13", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm"},
"goldrush": {:hex, :goldrush, "0.1.9", "f06e5d5f1277da5c413e84d5a2924174182fb108dabb39d5ec548b27424cd106", [:rebar3], [], "hexpm"},
"hamcrest": {:hex, :basho_hamcrest, "0.4.1", "fb7b2c92d252a1e9db936750b86089addaebeb8f87967fb4bbdda61e8863338e", [:make, :mix, :rebar3], [], "hexpm"},
- "iconv": {:hex, :iconv, "1.0.10", "fc7de75c0a1fbc1e4ed0c68637ae7464a5dd9eee81710fff26321922d144ecea", [:rebar3], [{:p1_utils, "1.0.13", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm"},
"jiffy": {:hex, :jiffy, "0.14.13", "225a9a35e26417832c611526567194b4d3adc4f0dfa5f2f7008f4684076f2a01", [:rebar3], [], "hexpm"},
"jose": {:hex, :jose, "1.8.4", "7946d1e5c03a76ac9ef42a6e6a20001d35987afd68c2107bcd8f01a84e75aa73", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, repo: "hexpm", optional: false]}], "hexpm"},
"lager": {:hex, :lager, "3.6.7", "2fbf823944caa0fc10df5ec13f3f047524a249bb32f0d801b7900c9610264286", [:rebar3], [{:goldrush, "0.1.9", [hex: :goldrush, repo: "hexpm", optional: false]}], "hexpm"},
"luerl": {:hex, :luerl, "0.3.1", "5412807630aac1aaf59ffe5a1bc09259c447b4faeb1d3fe2d4ef41b87676cb04", [:rebar3], [], "hexpm"},
"makeup": {:hex, :makeup, "0.5.5", "9e08dfc45280c5684d771ad58159f718a7b5788596099bdfb0284597d368a882", [:mix], [{:nimble_parsec, "~> 0.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
"makeup_elixir": {:hex, :makeup_elixir, "0.10.0", "0f09c2ddf352887a956d84f8f7e702111122ca32fbbc84c2f0569b8b65cbf7fa", [:mix], [{:makeup, "~> 0.5.5", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
- "meck": {:hex, :meck, "0.8.12", "1f7b1a9f5d12c511848fec26bbefd09a21e1432eadb8982d9a8aceb9891a3cf2", [:rebar3], [], "hexpm"},
- "moka": {:git, "https://github.com/processone/moka.git", "3eed3a6dd7dedb70a6cd18f86c7561a18626eb3b", [tag: "1.0.5c"]},
"nimble_parsec": {:hex, :nimble_parsec, "0.4.0", "ee261bb53214943679422be70f1658fff573c5d0b0a1ecd0f18738944f818efe", [:mix], [], "hexpm"},
"p1_mysql": {:hex, :p1_mysql, "1.0.8", "34ed5fe2f0e16a6ee5805c0c6c1d30ffbc4c5c9753197cdf384ee6e82c57b506", [:rebar3], [], "hexpm"},
"p1_oauth2": {:hex, :p1_oauth2, "0.6.3", "fbd91ba86bd7f03d2a4f6e62affa86bab9930abfd6b473d61eefb148f246cd46", [:rebar3], [], "hexpm"},
@@ -31,9 +29,8 @@
"pkix": {:hex, :pkix, "1.0.0", "d88658eccc30227e929efa91c6ca6a4d2b4d40b4db3635ebd6ed9e246ecfcf82", [:rebar3], [], "hexpm"},
"riak_pb": {:hex, :riak_pb, "2.3.2", "48ffbf66dbb3f136ab9a7134bac4e496754baa5ef58c4f50a61326736d996390", [:make, :mix, :rebar3], [{:hamcrest, "~> 0.4.1", [hex: :basho_hamcrest, repo: "hexpm", optional: false]}], "hexpm"},
"riakc": {:hex, :riakc, "2.5.3", "6132d9e687a0dfd314b2b24c4594302ca8b55568a5d733c491d8fb6cd4004763", [:make, :mix, :rebar3], [{:riak_pb, "~> 2.3", [hex: :riak_pb, repo: "hexpm", optional: false]}], "hexpm"},
- "samerlib": {:git, "https://github.com/processone/samerlib", "fbbba035b1548ac4e681df00d61bf609645333a0", [tag: "0.8.0c"]},
"sqlite3": {:hex, :sqlite3, "1.1.6", "4ea71af0b45908b5f02c9b09e4c87177039ef404f20accb35049cd8924cc417c", [:rebar3], [], "hexpm"},
"stringprep": {:hex, :stringprep, "1.0.14", "230a2d1c576bba168749d653fd6681166d02431ef07161a918444f3edb478ad0", [:rebar3], [{:p1_utils, "1.0.13", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm"},
"stun": {:hex, :stun, "1.0.26", "87b05229d0519f0db5c6b67b5c25ed3b79766beb96eba83d29bde4cae9e702e4", [:rebar3], [{:fast_tls, "1.0.26", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.13", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm"},
- "xmpp": {:hex, :xmpp, "1.2.8", "c506ea4c7e4b8d042654d54b080f4b6b4135c93658d7e156968a073c5b5f99a1", [:rebar3], [{:ezlib, "1.0.4", [hex: :ezlib, repo: "hexpm", optional: false]}, {:fast_tls, "1.0.26", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:fast_xml, "1.1.34", [hex: :fast_xml, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.13", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stringprep, "1.0.14", [hex: :stringprep, repo: "hexpm", optional: false]}], "hexpm"},
+ "xmpp": {:hex, :xmpp, "1.3.0", "29f2192d9d45a40abbb7a3637c81af5e0f08b7e8d6a9e12471dc6095675d7a92", [:rebar3], [{:ezlib, "1.0.4", [hex: :ezlib, repo: "hexpm", optional: false]}, {:fast_tls, "1.0.26", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:fast_xml, "1.1.34", [hex: :fast_xml, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.13", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stringprep, "1.0.14", [hex: :stringprep, repo: "hexpm", optional: false]}], "hexpm"},
}
diff --git a/rebar.config b/rebar.config
index 72908852e..39608346d 100644
--- a/rebar.config
+++ b/rebar.config
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -24,11 +24,11 @@
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.0.26"}}},
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.14"}}},
{fast_xml, ".*", {git, "https://github.com/processone/fast_xml", {tag, "1.1.34"}}},
- {xmpp, ".*", {git, "https://github.com/processone/xmpp", "278ddf9"}},
+ {xmpp, ".*", {git, "https://github.com/processone/xmpp", {tag, "1.3.0"}}},
{fast_yaml, ".*", {git, "https://github.com/processone/fast_yaml", {tag, "1.0.17"}}},
{jiffy, ".*", {git, "https://github.com/davisp/jiffy", {tag, "0.14.8"}}},
{p1_oauth2, ".*", {git, "https://github.com/processone/p1_oauth2", {tag, "0.6.3"}}},
- {pkix, ".*", {git, "https://github.com/processone/pkix", {tag, "1.0.0"}}},
+ {pkix, ".*", {git, "https://github.com/processone/pkix", {tag, "1.0.0"}}},
{jose, ".*", {git, "https://github.com/potatosalad/erlang-jose", {tag, "1.8.4"}}},
{eimp, ".*", {git, "https://github.com/processone/eimp", {tag, "1.0.9"}}},
{if_var_true, stun, {stun, ".*", {git, "https://github.com/processone/stun", {tag, "1.0.26"}}}},
@@ -51,12 +51,8 @@
%% TODO: When modules are fully migrated to new structure and mix, we will not need anymore rebar_elixir_plugin
{if_not_rebar3, {if_var_true, elixir, {rebar_elixir_plugin, ".*",
{git, "https://github.com/processone/rebar_elixir_plugin", "0.1.0"}}}},
- {if_var_true, iconv, {iconv, ".*", {git, "https://github.com/processone/iconv",
- {tag, "1.0.10"}}}},
{if_var_true, tools, {luerl, ".*", {git, "https://github.com/rvirding/luerl",
{tag, "v0.3"}}}},
- {if_var_true, tools, {meck, "0.8.*", {git, "https://github.com/eproxus/meck",
- {tag, "0.8.12"}}}},
{if_var_true, redis, {eredis, ".*", {git, "https://github.com/wooga/eredis",
{tag, "v1.0.8"}}}}]}.
@@ -76,8 +72,7 @@
epam,
ezlib,
eimp,
- pkix,
- iconv]}}.
+ pkix]}}.
{erl_first_files, ["src/ejabberd_sql_pt.erl", "src/ejabberd_config.erl",
"src/gen_mod.erl", "src/mod_muc_room.erl",
@@ -92,6 +87,7 @@
{if_var_true, debug, debug_info},
{if_var_true, sip, {d, 'SIP'}},
{if_var_true, stun, {d, 'STUN'}},
+ {if_version_above, "20", {d, 'DEPRECATED_GET_STACKTRACE'}},
{if_var_true, roster_gateway_workaround, {d, 'ROSTER_GATWAY_WORKAROUND'}},
{if_var_match, db_type, mssql, {d, 'mssql'}},
{if_var_true, elixir, {d, 'ELIXIR_ENABLED'}},
@@ -133,7 +129,6 @@
{if_var_true, riak, "(\"riak_object\":_/_)"},
{if_var_false, zlib, "(\"ezlib\":_/_)"},
{if_var_false, http, "(\"lhttpc\":_/_)"},
- {if_var_false, iconv, "(\"iconv\":_/_)"},
{if_var_false, odbc, "(\"odbc\":_/_)"},
{if_var_false, sqlite, "(\"sqlite3\":_/_)"},
{if_var_false, elixir, "(\"Elixir.*\":_/_)"},
@@ -145,19 +140,18 @@
{i, "deps/fast_xml/include"},
{i, "deps/xmpp/include"}]}.
-{if_version_above, "17", {cover_enabled, true}}.
+{cover_enabled, true}.
{cover_export_enabled, true}.
{recursive_cmds, ['configure-deps']}.
{post_hook_configure, [{"fast_tls", []},
{"stringprep", []},
{"fast_yaml", []},
- {"eimp", []},
+ {"eimp", []},
{if_var_true, sip, {"esip", []}},
{"fast_xml", [{if_var_true, full_xml, "--enable-full-xml"}]},
{if_var_true, pam, {"epam", []}},
- {if_var_true, zlib, {"ezlib", []}},
- {if_var_true, iconv, {"iconv", []}}]}.
+ {if_var_true, zlib, {"ezlib", []}}]}.
%% Local Variables:
%% mode: erlang
diff --git a/rebar.config.script b/rebar.config.script
index 00b32b38e..694d6879f 100644
--- a/rebar.config.script
+++ b/rebar.config.script
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/rel/reltool.config.script b/rel/reltool.config.script
index 2a8566d54..f0a15012c 100644
--- a/rel/reltool.config.script
+++ b/rel/reltool.config.script
@@ -1,6 +1,6 @@
%%%-------------------------------------------------------------------
%%% @author Evgeniy Khramtsov <ekhramtsov@process-one.net>
-%%% @copyright (C) 2013-2017, Evgeniy Khramtsov
+%%% @copyright (C) 2013-2019, Evgeniy Khramtsov
%%% @doc
%%%
%%% @end
diff --git a/sql/lite.new.sql b/sql/lite.new.sql
index 6ec7ea876..ab229c6b1 100644
--- a/sql/lite.new.sql
+++ b/sql/lite.new.sql
@@ -1,5 +1,5 @@
--
--- ejabberd, Copyright (C) 2002-2017 ProcessOne
+-- ejabberd, Copyright (C) 2002-2019 ProcessOne
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
diff --git a/sql/lite.sql b/sql/lite.sql
index 177454c7b..8f128c331 100644
--- a/sql/lite.sql
+++ b/sql/lite.sql
@@ -1,5 +1,5 @@
--
--- ejabberd, Copyright (C) 2002-2017 ProcessOne
+-- ejabberd, Copyright (C) 2002-2019 ProcessOne
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
diff --git a/sql/mssql.sql b/sql/mssql.sql
index 9393a19c1..7c3713b76 100644
--- a/sql/mssql.sql
+++ b/sql/mssql.sql
@@ -1,5 +1,5 @@
--
--- ejabberd, Copyright (C) 2002-2017 ProcessOne
+-- ejabberd, Copyright (C) 2002-2019 ProcessOne
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
diff --git a/sql/mysql.new.sql b/sql/mysql.new.sql
index 832910d2c..65b6d1b78 100644
--- a/sql/mysql.new.sql
+++ b/sql/mysql.new.sql
@@ -1,5 +1,5 @@
--
--- ejabberd, Copyright (C) 2002-2017 ProcessOne
+-- ejabberd, Copyright (C) 2002-2019 ProcessOne
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
diff --git a/sql/mysql.sql b/sql/mysql.sql
index 568d2b41c..2dc02bf69 100644
--- a/sql/mysql.sql
+++ b/sql/mysql.sql
@@ -1,5 +1,5 @@
--
--- ejabberd, Copyright (C) 2002-2017 ProcessOne
+-- ejabberd, Copyright (C) 2002-2019 ProcessOne
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
diff --git a/sql/pg.new.sql b/sql/pg.new.sql
index 721ce1ae9..495441147 100644
--- a/sql/pg.new.sql
+++ b/sql/pg.new.sql
@@ -1,5 +1,5 @@
--
--- ejabberd, Copyright (C) 2002-2017 ProcessOne
+-- ejabberd, Copyright (C) 2002-2019 ProcessOne
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
diff --git a/sql/pg.sql b/sql/pg.sql
index b9797b820..250a22d2d 100644
--- a/sql/pg.sql
+++ b/sql/pg.sql
@@ -1,5 +1,5 @@
--
--- ejabberd, Copyright (C) 2002-2017 ProcessOne
+-- ejabberd, Copyright (C) 2002-2019 ProcessOne
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
diff --git a/src/acl.erl b/src/acl.erl
index 1bffd8fa9..959faeaf0 100644
--- a/src/acl.erl
+++ b/src/acl.erl
@@ -5,7 +5,7 @@
%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd.app.src.in b/src/ejabberd.app.src.in
index 407fc68e1..f1d08b8c7 100644
--- a/src/ejabberd.app.src.in
+++ b/src/ejabberd.app.src.in
@@ -5,7 +5,8 @@
{vsn, "@PACKAGE_VERSION@"},
{modules, []},
{registered, []},
- {applications, [kernel, stdlib]},
+ {applications, [kernel, stdlib, sasl, ssl]},
+ {included_applications, [os_mon, lager, mnesia, inets, p1_utils, fast_yaml, fast_tls, pkix, xmpp, cache_tab, eimp]},
{env, [{enabled_backends, [@enabled_backends@]}]},
{mod, {ejabberd_app, []}}]}.
diff --git a/src/ejabberd.erl b/src/ejabberd.erl
index 4d08fa5b3..a7de9ab11 100644
--- a/src/ejabberd.erl
+++ b/src/ejabberd.erl
@@ -5,7 +5,7 @@
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -43,12 +43,10 @@
-include("logger.hrl").
start() ->
- %%ejabberd_cover:start(),
- application:start(ejabberd).
+ application:ensure_all_started(ejabberd).
stop() ->
application:stop(ejabberd).
- %%ejabberd_cover:stop().
halt() ->
application:stop(lager),
diff --git a/src/ejabberd_access_permissions.erl b/src/ejabberd_access_permissions.erl
index 23dd9446d..0c53795b8 100644
--- a/src/ejabberd_access_permissions.erl
+++ b/src/ejabberd_access_permissions.erl
@@ -5,7 +5,7 @@
%%% Created : 7 Sep 2016 by Paweł Chmielowski <pawel@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -130,11 +130,12 @@ init([]) ->
handle_call({can_access, Cmd, CallerInfo}, _From, State) ->
CallerModule = maps:get(caller_module, CallerInfo, none),
Host = maps:get(caller_host, CallerInfo, global),
+ Tag = maps:get(tag, CallerInfo, none),
{State2, Defs0} = get_definitions(State),
Defs = maps:get(extra_permissions, CallerInfo, []) ++ Defs0,
Res = lists:foldl(
fun({Name, _} = Def, none) ->
- case matches_definition(Def, Cmd, CallerModule, Host, CallerInfo) of
+ case matches_definition(Def, Cmd, CallerModule, Tag, Host, CallerInfo) of
true ->
?DEBUG("Command '~p' execution allowed by rule '~s' (CallerInfo=~p)", [Cmd, Name, CallerInfo]),
allow;
@@ -261,10 +262,12 @@ get_definitions(#state{definitions = none, fragments_generators = Gens} = State)
end,
{State#state{definitions = NDefs}, NDefs}.
-matches_definition({_Name, {From, Who, What}}, Cmd, Module, Host, CallerInfo) ->
+matches_definition({_Name, {From, Who, What}}, Cmd, Module, Tag, Host, CallerInfo) ->
case What == all orelse lists:member(Cmd, What) of
true ->
- case From == [] orelse lists:member(Module, From) of
+ {Tags, Modules} = lists:partition(fun({tag, _}) -> true; (_) -> false end, From),
+ case (Modules == [] orelse lists:member(Module, Modules)) andalso
+ (Tags == [] orelse lists:member({tag, Tag}, Tags)) of
true ->
Scope = maps:get(oauth_scope, CallerInfo, none),
lists:any(
@@ -347,13 +350,15 @@ parse_api_permission(Name, Args0) ->
parse_from(_Name, Module) when is_atom(Module) ->
[Module];
parse_from(Name, Modules) when is_list(Modules) ->
- lists:foreach(fun(Module) when is_atom(Module) ->
- ok;
- (Val) ->
- report_error(<<"Invalid value '~p' used inside 'from' section for api_permission '~s'">>,
- [Val, Name])
- end, Modules),
- Modules;
+ lists:map(
+ fun(Module) when is_atom(Module) ->
+ Module;
+ ([{tag, Tag}]) when is_binary(Tag) ->
+ {tag, Tag};
+ (Val) ->
+ report_error(<<"Invalid value '~p' used inside 'from' section for api_permission '~s'">>,
+ [Val, Name])
+ end, Modules);
parse_from(Name, Val) ->
report_error(<<"Invalid value '~p' used inside 'from' section for api_permission '~s'">>,
[Val, Name]).
diff --git a/src/ejabberd_acme.erl b/src/ejabberd_acme.erl
index bd4f22418..9e25ed4e6 100644
--- a/src/ejabberd_acme.erl
+++ b/src/ejabberd_acme.erl
@@ -25,6 +25,7 @@
-include("ejabberd_commands.hrl").
-include("ejabberd_acme.hrl").
-include_lib("public_key/include/public_key.hrl").
+-include("ejabberd_stacktrace.hrl").
-define(DEFAULT_CONFIG_CONTACT, <<"mailto:example-admin@example.com">>).
-define(DEFAULT_CONFIG_CA_URL, "https://acme-v01.api.letsencrypt.org").
@@ -100,10 +101,10 @@ is_valid_domain_opt(DomainString) ->
end.
-spec is_valid_revoke_cert(string()) -> boolean().
-is_valid_revoke_cert(DomainOrFile) ->
+is_valid_revoke_cert(DomainOrFile) ->
lists:prefix("file:", DomainOrFile) orelse
lists:prefix("domain:", DomainOrFile).
-
+
%% Commands
get_commands_spec() ->
[#ejabberd_commands{name = get_certificates, tags = [acme],
@@ -142,7 +143,7 @@ get_commands_spec() ->
%%
-spec get_certificates(domains_opt()) -> string() | {'error', _}.
get_certificates(Domains) ->
- case is_valid_domain_opt(Domains) of
+ case is_valid_domain_opt(Domains) of
true ->
try
CAUrl = get_config_ca_url(),
@@ -150,9 +151,8 @@ get_certificates(Domains) ->
catch
throw:Throw ->
Throw;
- E:R ->
- St = erlang:get_stacktrace(),
- ?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, St]),
+ ?EX_RULE(E, R, St) ->
+ ?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, ?EX_STACK(St)]),
{error, get_certificates}
end;
false ->
@@ -171,7 +171,7 @@ retrieve_or_create_account(CAUrl) ->
case read_account_persistent() of
none ->
create_save_new_account(CAUrl);
-
+
{ok, AccId, CAUrl, PrivateKey} ->
{ok, AccId, PrivateKey};
{ok, _AccId, _, _PrivateKey} ->
@@ -199,7 +199,7 @@ get_certificates2(CAUrl, PrivateKey, Hosts) ->
%% Format the result to send back to ejabberdctl
format_get_certificates_result(SavedCerts).
--spec format_get_certificates_result([{'ok', bitstring(), _} |
+-spec format_get_certificates_result([{'ok', bitstring(), _} |
{'error', bitstring(), _}]) ->
string().
format_get_certificates_result(Certs) ->
@@ -211,26 +211,26 @@ format_get_certificates_result(Certs) ->
case Cond of
true ->
Result = io_lib:format("Success:~n~s", [FormattedCerts]),
- lists:flatten(Result);
+ lists:flatten(Result);
_ ->
Result = io_lib:format("Error with one or more certificates~n~s", [FormattedCerts]),
lists:flatten(Result)
end.
--spec format_get_certificate({'ok', bitstring(), _} |
+-spec format_get_certificate({'ok', bitstring(), _} |
{'error', bitstring(), _}) ->
string().
-format_get_certificate({ok, Domain, saved}) ->
+format_get_certificate({ok, Domain, saved}) ->
io_lib:format(" Certificate for domain: \"~s\" acquired and saved", [Domain]);
-format_get_certificate({ok, Domain, not_found}) ->
+format_get_certificate({ok, Domain, not_found}) ->
io_lib:format(" Certificate for domain: \"~s\" not found, so it was not renewed", [Domain]);
format_get_certificate({ok, Domain, no_expire}) ->
io_lib:format(" Certificate for domain: \"~s\" is not close to expiring", [Domain]);
format_get_certificate({error, Domain, Reason}) ->
io_lib:format(" Error for domain: \"~s\", with reason: \'~s\'", [Domain, Reason]).
--spec get_certificate(url(), bitstring(), jose_jwk:key()) ->
- {'ok', bitstring(), pem()} |
+-spec get_certificate(url(), bitstring(), jose_jwk:key()) ->
+ {'ok', bitstring(), pem()} |
{'error', bitstring(), _}.
get_certificate(CAUrl, DomainName, PrivateKey) ->
try
@@ -243,9 +243,8 @@ get_certificate(CAUrl, DomainName, PrivateKey) ->
catch
throw:Throw ->
Throw;
- E:R ->
- St = erlang:get_stacktrace(),
- ?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, St]),
+ ?EX_RULE(E, R, St) ->
+ ?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, ?EX_STACK(St)]),
{error, DomainName, get_certificate}
end.
@@ -267,23 +266,23 @@ create_save_new_account(CAUrl) ->
%% TODO:
%% Find a way to ask the user if he accepts the TOS
--spec create_new_account(url(), bitstring(), jose_jwk:key()) -> {'ok', string()} |
+-spec create_new_account(url(), bitstring(), jose_jwk:key()) -> {'ok', string()} |
no_return().
create_new_account(CAUrl, Contact, PrivateKey) ->
try
{ok, Dirs, Nonce0} = ejabberd_acme_comm:directory(CAUrl),
Req0 = [{ <<"contact">>, [Contact]}],
- {ok, {TOS, Account}, Nonce1} =
+ {ok, {TOS, Account}, Nonce1} =
ejabberd_acme_comm:new_account(Dirs, PrivateKey, Req0, Nonce0),
{<<"id">>, AccIdInt} = lists:keyfind(<<"id">>, 1, Account),
AccId = integer_to_list(AccIdInt),
Req1 = [{ <<"agreement">>, list_to_bitstring(TOS)}],
- {ok, _Account2, _Nonce2} =
+ {ok, _Account2, _Nonce2} =
ejabberd_acme_comm:update_account({CAUrl, AccId}, PrivateKey, Req1, Nonce1),
{ok, AccId}
catch
E:R ->
- ?ERROR_MSG("Error: ~p creating an account for contact: ~p",
+ ?ERROR_MSG("Error: ~p creating an account for contact: ~p",
[{E,R}, Contact]),
throw({error,create_new_account})
end.
@@ -298,7 +297,7 @@ create_new_authorization(CAUrl, DomainName, PrivateKey) ->
{[{<<"type">>, <<"dns">>},
{<<"value">>, DomainName}]}},
{<<"existing">>, <<"accept">>}],
- {ok, {AuthzUrl, Authz}, Nonce1} =
+ {ok, {AuthzUrl, Authz}, Nonce1} =
ejabberd_acme_comm:new_authz(Dirs, PrivateKey, Req0, Nonce0),
{ok, AuthzId} = location_to_id(AuthzUrl),
@@ -321,7 +320,7 @@ create_new_authorization(CAUrl, DomainName, PrivateKey) ->
acme_challenge:unregister_hooks(DomainName)
end.
--spec create_new_certificate(url(), {bitstring(), [bitstring()]}, jose_jwk:key()) ->
+-spec create_new_certificate(url(), {bitstring(), [bitstring()]}, jose_jwk:key()) ->
{ok, bitstring(), pem()}.
create_new_certificate(CAUrl, {DomainName, AllSubDomains}, PrivateKey) ->
try
@@ -338,7 +337,7 @@ create_new_certificate(CAUrl, {DomainName, AllSubDomains}, PrivateKey) ->
{ok, {IssuerCertLink, Certificate}, _Nonce1} =
ejabberd_acme_comm:new_cert(Dirs, PrivateKey, Req, Nonce0),
- DecodedCert = public_key:pkix_decode_cert(list_to_binary(Certificate), plain),
+ DecodedCert = public_key:pkix_decode_cert(list_to_binary(Certificate), plain),
PemEntryCert = public_key:pem_entry_encode('Certificate', DecodedCert),
{ok, IssuerCert, _Nonce2} = ejabberd_acme_comm:get_issuer_cert(IssuerCertLink),
@@ -351,7 +350,7 @@ create_new_certificate(CAUrl, {DomainName, AllSubDomains}, PrivateKey) ->
PemCertKey = public_key:pem_encode([PemEntryKey, PemEntryCert, PemEntryIssuerCert]),
{ok, DomainName, PemCertKey}
- catch
+ catch
E:R ->
?ERROR_MSG("Error: ~p getting an authorization for domain: ~p~n",
[{E,R}, DomainName]),
@@ -383,9 +382,8 @@ renew_certificates() ->
catch
throw:Throw ->
Throw;
- E:R ->
- St = erlang:get_stacktrace(),
- ?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, St]),
+ ?EX_RULE(E, R, St) ->
+ ?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, ?EX_STACK(St)]),
{error, get_certificates}
end.
@@ -406,8 +404,8 @@ renew_certificates0(CAUrl) ->
%% Format the result to send back to ejabberdctl
format_get_certificates_result(SavedCerts).
--spec renew_certificate(url(), {bitstring(), data_cert()}, jose_jwk:key()) ->
- {'ok', bitstring(), _} |
+-spec renew_certificate(url(), {bitstring(), data_cert()}, jose_jwk:key()) ->
+ {'ok', bitstring(), _} |
{'error', bitstring(), _}.
renew_certificate(CAUrl, {DomainName, _} = Cert, PrivateKey) ->
case cert_to_expire(Cert) of
@@ -449,9 +447,8 @@ list_certificates(Verbose) ->
catch
throw:Throw ->
Throw;
- E:R ->
- St = erlang:get_stacktrace(),
- ?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, St]),
+ ?EX_RULE(E, R, St) ->
+ ?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, ?EX_STACK(St)]),
{error, list_certificates}
end;
false ->
@@ -492,34 +489,33 @@ format_certificate(DataCert, Verbose) ->
format_certificate_verbose(DomainName, SANs, NotAfter, PemCert)
end
catch
- E:R ->
- St = erlang:get_stacktrace(),
- ?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, St]),
+ ?EX_RULE(E, R, St) ->
+ ?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, ?EX_STACK(St)]),
fail_format_certificate(DomainName)
end.
--spec format_certificate_plain(bitstring(), [string()], {expired | ok, string()}, string())
+-spec format_certificate_plain(bitstring(), [string()], {expired | ok, string()}, string())
-> string().
format_certificate_plain(DomainName, SANs, NotAfter, Path) ->
Result = lists:flatten(io_lib:format(
- " Domain: ~s~n"
+ " Domain: ~s~n"
"~s"
- " ~s~n"
- " Path: ~s",
+ " ~s~n"
+ " Path: ~s",
[DomainName,
lists:flatten([io_lib:format(" SAN: ~s~n", [SAN]) || SAN <- SANs]),
format_validity(NotAfter), Path])),
Result.
--spec format_certificate_verbose(bitstring(), [string()], {expired | ok, string()}, bitstring())
+-spec format_certificate_verbose(bitstring(), [string()], {expired | ok, string()}, bitstring())
-> string().
format_certificate_verbose(DomainName, SANs, NotAfter, PemCert) ->
Result = lists:flatten(io_lib:format(
" Domain: ~s~n"
- "~s"
- " ~s~n"
- " Certificate In PEM format: ~n~s",
- [DomainName,
+ "~s"
+ " ~s~n"
+ " Certificate In PEM format: ~n~s",
+ [DomainName,
lists:flatten([io_lib:format(" SAN: ~s~n", [SAN]) || SAN <- SANs]),
format_validity(NotAfter), PemCert])),
Result.
@@ -533,8 +529,8 @@ format_validity({ok, NotAfter}) ->
-spec fail_format_certificate(bitstring()) -> string().
fail_format_certificate(DomainName) ->
Result = lists:flatten(io_lib:format(
- " Domain: ~s~n"
- " Failed to format Certificate",
+ " Domain: ~s~n"
+ " Failed to format Certificate",
[DomainName])),
Result.
@@ -542,7 +538,7 @@ fail_format_certificate(DomainName) ->
get_commonName(#'Certificate'{tbsCertificate = TbsCertificate}) ->
#'TBSCertificate'{
subject = {rdnSequence, SubjectList}
- } = TbsCertificate,
+ } = TbsCertificate,
%% TODO: Not the best way to find the commonName
ShallowSubjectList = [Attribute || [Attribute] <- SubjectList],
@@ -560,9 +556,9 @@ get_notAfter(Certificate) ->
true -> "19" ++ [Y1,Y2];
_ -> "20" ++ [Y1,Y2]
end,
- NotAfter = lists:flatten(io_lib:format("~s-~s-~s ~s:~s:~s",
+ NotAfter = lists:flatten(io_lib:format("~s-~s-~s ~s:~s:~s",
[YEAR, [MO1,MO2], [D1,D2],
- [H1,H2], [MI1,MI2], [S1,S2]])),
+ [H1,H2], [MI1,MI2], [S1,S2]])),
case close_to_expire(UtcTime, 0) of
true ->
@@ -577,7 +573,7 @@ get_subjectAltNames(#'Certificate'{tbsCertificate = TbsCertificate}) ->
extensions = Exts
} = TbsCertificate,
- EncodedSANs = [Val || #'Extension'{extnID = Oid, extnValue = Val} <- Exts,
+ EncodedSANs = [Val || #'Extension'{extnID = Oid, extnValue = Val} <- Exts,
Oid =:= attribute_oid(subjectAltName)],
lists:flatmap(
@@ -586,7 +582,7 @@ get_subjectAltNames(#'Certificate'{tbsCertificate = TbsCertificate}) ->
[Name || {dNSName, Name} <- SANs0]
end, EncodedSANs).
-
+
-spec get_utc_validity(#'Certificate'{}) -> string().
get_utc_validity(#'Certificate'{tbsCertificate = TbsCertificate}) ->
@@ -618,18 +614,17 @@ revoke_certificates(DomainOrFile) ->
catch
throw:Throw ->
Throw;
- E:R ->
- St = erlang:get_stacktrace(),
- ?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, St]),
+ ?EX_RULE(E, R, St) ->
+ ?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, ?EX_STACK(St)]),
{error, revoke_certificate}
- end.
+ end.
-spec revoke_certificate0(url(), string()) -> {ok, deleted}.
revoke_certificate0(CAUrl, DomainOrFile) ->
ParsedCert = parse_revoke_cert_argument(DomainOrFile),
revoke_certificate1(CAUrl, ParsedCert).
--spec revoke_certificate1(url(), {domain, bitstring()} | {file, file:filename()}) ->
+-spec revoke_certificate1(url(), {domain, bitstring()} | {file, file:filename()}) ->
{ok, deleted}.
revoke_certificate1(CAUrl, {domain, Domain}) ->
case domain_certificate_exists(Domain) of
@@ -650,7 +645,7 @@ revoke_certificate1(CAUrl, {file, File}) ->
?ERROR_MSG("Error: ~p reading pem certificate-key file: ~p", [Reason, File]),
throw({error, Reason})
end.
-
+
-spec revoke_certificate2(url(), pem()) -> ok.
revoke_certificate2(CAUrl, PemEncodedCert) ->
@@ -676,10 +671,10 @@ prepare_certificate_revoke(PemEncodedCert) ->
DerCert = public_key:der_encode('Certificate', PemCert),
Base64Cert = base64url:encode(DerCert),
- {ok, Key} = find_private_key_in_pem(PemEncodedCert),
+ {ok, Key} = find_private_key_in_pem(PemEncodedCert),
{Base64Cert, Key}.
--spec domain_certificate_exists(bitstring()) -> {bitstring(), data_cert()} | false.
+-spec domain_certificate_exists(bitstring()) -> {bitstring(), data_cert()} | false.
domain_certificate_exists(Domain) ->
Certs = read_certificates_persistent(),
lists:keyfind(Domain, 1, Certs).
@@ -693,7 +688,7 @@ domain_certificate_exists(Domain) ->
%% For now we accept only generating a key of
%% specific type for signing the csr
--spec make_csr(proplist(), [{dNSName, bitstring()}])
+-spec make_csr(proplist(), [{dNSName, bitstring()}])
-> {binary(), jose_jwk:key()}.
make_csr(Attributes, SANs) ->
Key = generate_key(),
@@ -749,9 +744,9 @@ extension(SANs) ->
extension_request(SANs) ->
#'AttributePKCS-10'{
type = ?'pkcs-9-at-extensionRequest',
- values = [{'asn1_OPENTYPE',
+ values = [{'asn1_OPENTYPE',
public_key:der_encode(
- 'ExtensionRequest',
+ 'ExtensionRequest',
[extension(SANs)])}]
}.
@@ -918,7 +913,7 @@ find_private_key_in_pem(Pem) ->
JoseKey = jose_jwk:from_key(Key),
{ok, JoseKey}
end.
-
+
-spec find_private_key_in_pem1([public_key:pki_asn1_type()],
[public_key:pem_entry()]) ->
@@ -948,10 +943,10 @@ private_key_types() ->
find_all_sub_domains(DomainName) ->
AllRoutes = ejabberd_router:get_all_routes(),
DomainLen = size(DomainName),
- [Route || Route <- AllRoutes,
- binary:longest_common_suffix([DomainName, Route])
+ [Route || Route <- AllRoutes,
+ binary:longest_common_suffix([DomainName, Route])
=:= DomainLen].
-
+
-spec is_error(_) -> boolean().
is_error({error, _}) -> true;
@@ -981,13 +976,13 @@ data_get_account(Data) ->
end.
-spec data_set_account(acme_data(), {list(), url(), jose_jwk:key()}) -> acme_data().
-data_set_account(Data, {AccId, CAUrl, PrivateKey}) ->
+data_set_account(Data, {AccId, CAUrl, PrivateKey}) ->
NewAcc = {account, #data_acc{id = AccId, ca_url = CAUrl, key = PrivateKey}},
lists:keystore(account, 1, Data, NewAcc).
%%
%% Certificates
-%%
+%%
-spec data_get_certificates(acme_data()) -> data_certs().
data_get_certificates(Data) ->
@@ -999,7 +994,7 @@ data_get_certificates(Data) ->
end.
-spec data_set_certificates(acme_data(), data_certs()) -> acme_data().
-data_set_certificates(Data, NewCerts) ->
+data_set_certificates(Data, NewCerts) ->
lists:keystore(certs, 1, Data, {certs, NewCerts}).
%% ATM we preserve one certificate for each domain
@@ -1053,7 +1048,7 @@ write_persistent(Data) ->
{error, Reason} ->
?ERROR_MSG("Error: ~p writing acme data file", [Reason]),
throw({error, Reason})
- end.
+ end.
-spec create_persistent() -> ok | no_return().
create_persistent() ->
@@ -1069,7 +1064,7 @@ create_persistent() ->
{error, Reason} ->
?ERROR_MSG("Error: ~p creating acme data file", [Reason]),
throw({error, Reason})
- end.
+ end.
-spec write_account_persistent({list(), url(), jose_jwk:key()}) -> ok | no_return().
write_account_persistent({AccId, CAUrl, PrivateKey}) ->
@@ -1099,7 +1094,7 @@ remove_certificate_persistent(DataCert) ->
NewData = data_remove_certificate(Data, DataCert),
ok = write_persistent(NewData).
--spec save_certificate({ok, bitstring(), binary()} | {error, _, _}) ->
+-spec save_certificate({ok, bitstring(), binary()} | {error, _, _}) ->
{ok, bitstring(), saved} | {error, bitstring(), _}.
save_certificate({error, _, _} = Error) ->
Error;
@@ -1123,13 +1118,12 @@ save_certificate({ok, DomainName, Cert}) ->
catch
throw:Throw ->
Throw;
- E:R ->
- St = erlang:get_stacktrace(),
- ?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, St]),
+ ?EX_RULE(E, R, St) ->
+ ?ERROR_MSG("Unknown ~p:~p, ~p", [E, R, ?EX_STACK(St)]),
{error, DomainName, saving}
end.
--spec save_renewed_certificate({ok, bitstring(), _} | {error, _, _}) ->
+-spec save_renewed_certificate({ok, bitstring(), _} | {error, _, _}) ->
{ok, bitstring(), _} | {error, bitstring(), _}.
save_renewed_certificate({error, _, _} = Error) ->
Error;
diff --git a/src/ejabberd_admin.erl b/src/ejabberd_admin.erl
index beaaaf562..4dbd0a0be 100644
--- a/src/ejabberd_admin.erl
+++ b/src/ejabberd_admin.erl
@@ -5,7 +5,7 @@
%%% Created : 7 May 2006 by Mickael Remond <mremond@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl
index 90c36a593..41e284de4 100644
--- a/src/ejabberd_app.erl
+++ b/src/ejabberd_app.erl
@@ -5,7 +5,7 @@
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -41,7 +41,7 @@ start(normal, _Args) ->
{T1, _} = statistics(wall_clock),
ejabberd_logger:start(),
write_pid_file(),
- start_apps(),
+ start_included_apps(),
start_elixir_application(),
ejabberd:check_app(ejabberd),
setup_if_elixir_conf_used(),
@@ -73,6 +73,19 @@ start(normal, _Args) ->
start(_, _) ->
{error, badarg}.
+start_included_apps() ->
+ {ok, Apps} = application:get_key(ejabberd, included_applications),
+ lists:foreach(
+ fun(mnesia) ->
+ ok;
+ (lager)->
+ ok;
+ (os_mon)->
+ ok;
+ (App) ->
+ application:ensure_all_started(App)
+ end, Apps).
+
%% Prepare the application for termination.
%% This function is called when an application is about to be stopped,
%% before shutting down the processes of the application.
@@ -148,18 +161,6 @@ file_queue_init() ->
end,
p1_queue:start(QueueDir).
-start_apps() ->
- crypto:start(),
- ejabberd:start_app(sasl),
- ejabberd:start_app(ssl),
- ejabberd:start_app(p1_utils),
- ejabberd:start_app(fast_yaml),
- ejabberd:start_app(fast_tls),
- ejabberd:start_app(pkix),
- ejabberd:start_app(xmpp),
- ejabberd:start_app(cache_tab),
- ejabberd:start_app(eimp).
-
setup_if_elixir_conf_used() ->
case ejabberd_config:is_using_elixir_config() of
true -> 'Elixir.Ejabberd.Config.Store':start_link();
diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl
index bc0211548..c27930140 100644
--- a/src/ejabberd_auth.erl
+++ b/src/ejabberd_auth.erl
@@ -5,7 +5,7 @@
%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_auth_anonymous.erl b/src/ejabberd_auth_anonymous.erl
index 3c4993cb0..21aecc341 100644
--- a/src/ejabberd_auth_anonymous.erl
+++ b/src/ejabberd_auth_anonymous.erl
@@ -5,7 +5,7 @@
%%% Created : 17 Feb 2006 by Mickael Remond <mremond@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_auth_external.erl b/src/ejabberd_auth_external.erl
index 3e300e3a0..6b2e2852e 100644
--- a/src/ejabberd_auth_external.erl
+++ b/src/ejabberd_auth_external.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_auth_ldap.erl b/src/ejabberd_auth_ldap.erl
index b23b1c340..06000c7f1 100644
--- a/src/ejabberd_auth_ldap.erl
+++ b/src/ejabberd_auth_ldap.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_auth_mnesia.erl b/src/ejabberd_auth_mnesia.erl
index 004e74996..1f75f686d 100644
--- a/src/ejabberd_auth_mnesia.erl
+++ b/src/ejabberd_auth_mnesia.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_auth_pam.erl b/src/ejabberd_auth_pam.erl
index 71b745df0..ffbab1f1f 100644
--- a/src/ejabberd_auth_pam.erl
+++ b/src/ejabberd_auth_pam.erl
@@ -5,7 +5,7 @@
%%% Created : 5 Jul 2007 by Evgeniy Khramtsov <xram@jabber.ru>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_auth_riak.erl b/src/ejabberd_auth_riak.erl
index 33c25424a..29da504c9 100644
--- a/src/ejabberd_auth_riak.erl
+++ b/src/ejabberd_auth_riak.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Nov 2012 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_auth_sql.erl b/src/ejabberd_auth_sql.erl
index cd9c02b91..f6f4f9efb 100644
--- a/src/ejabberd_auth_sql.erl
+++ b/src/ejabberd_auth_sql.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_backend_sup.erl b/src/ejabberd_backend_sup.erl
index dadb31f12..832c4e3e6 100644
--- a/src/ejabberd_backend_sup.erl
+++ b/src/ejabberd_backend_sup.erl
@@ -2,7 +2,7 @@
%%% Created : 24 Feb 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_bosh.erl b/src/ejabberd_bosh.erl
index e39a67132..cdfd59b8a 100644
--- a/src/ejabberd_bosh.erl
+++ b/src/ejabberd_bosh.erl
@@ -5,7 +5,7 @@
%%% Created : 20 Jul 2011 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index ba5b04af8..61284e3e6 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -2,7 +2,7 @@
%%% Created : 8 Dec 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -638,15 +638,16 @@ route_probe_reply(From, #{jid := To,
Subscription = get_subscription(To, From),
if IsAnotherResource orelse
Subscription == both orelse Subscription == from ->
- Packet = misc:add_delay_info(LastPres, To, TS),
- case privacy_check_packet(State, Packet, out) of
+ Packet = xmpp:set_from_to(LastPres, To, From),
+ Packet2 = misc:add_delay_info(Packet, To, TS),
+ case privacy_check_packet(State, Packet2, out) of
deny ->
ok;
allow ->
ejabberd_hooks:run(presence_probe_hook,
LServer,
[From, To, self()]),
- ejabberd_router:route(xmpp:set_from_to(Packet, To, From))
+ ejabberd_router:route(Packet2)
end;
true ->
ok
diff --git a/src/ejabberd_c2s_config.erl b/src/ejabberd_c2s_config.erl
index 0a183783d..d6782de4f 100644
--- a/src/ejabberd_c2s_config.erl
+++ b/src/ejabberd_c2s_config.erl
@@ -6,7 +6,7 @@
%%% Created : 2 Nov 2007 by Mickael Remond <mremond@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_captcha.erl b/src/ejabberd_captcha.erl
index 9f9d7b03f..91f0cb2da 100644
--- a/src/ejabberd_captcha.erl
+++ b/src/ejabberd_captcha.erl
@@ -5,7 +5,7 @@
%%% Created : 26 Apr 2008 by Evgeniy Khramtsov <xramtsov@gmail.com>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -105,12 +105,13 @@ create_captcha(SID, From, To, Lang, Limiter, Args) ->
"To unblock them, visit ~s">>, [JID, get_url(Id)]},
Body = xmpp:mk_text(BodyString, Lang),
OOB = #oob_x{url = get_url(Id)},
+ Hint = #hint{type = 'no-store'},
Tref = erlang:send_after(?CAPTCHA_LIFETIME, ?MODULE,
{remove_id, Id}),
ets:insert(captcha,
#captcha{id = Id, pid = self(), key = Key, tref = Tref,
args = Args}),
- {ok, Id, Body, [OOB, Captcha, Data]};
+ {ok, Id, Body, [Hint, OOB, Captcha, Data]};
Err -> Err
end.
diff --git a/src/ejabberd_cluster.erl b/src/ejabberd_cluster.erl
index 8fb9dde8e..10f945fe7 100644
--- a/src/ejabberd_cluster.erl
+++ b/src/ejabberd_cluster.erl
@@ -3,7 +3,7 @@
%%% Created : 5 Jul 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_cluster_mnesia.erl b/src/ejabberd_cluster_mnesia.erl
index 4889abd66..fb793cda8 100644
--- a/src/ejabberd_cluster_mnesia.erl
+++ b/src/ejabberd_cluster_mnesia.erl
@@ -5,7 +5,7 @@
%%% Created : 7 Oct 2015 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_commands.erl b/src/ejabberd_commands.erl
index 56a1518e4..921ed25c7 100644
--- a/src/ejabberd_commands.erl
+++ b/src/ejabberd_commands.erl
@@ -5,7 +5,7 @@
%%% Created : 20 May 2008 by Badlop <badlop@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -492,6 +492,7 @@ do_execute_command(Command, Arguments) ->
Module = Command#ejabberd_commands.module,
Function = Command#ejabberd_commands.function,
?DEBUG("Executing command ~p:~p with Args=~p", [Module, Function, Arguments]),
+ ejabberd_hooks:run(api_call, [Module, Function, Arguments]),
apply(Module, Function, Arguments).
-spec get_tags_commands() -> [{string(), [string()]}].
diff --git a/src/ejabberd_commands_doc.erl b/src/ejabberd_commands_doc.erl
index 590e06ea9..b62c4ca5b 100644
--- a/src/ejabberd_commands_doc.erl
+++ b/src/ejabberd_commands_doc.erl
@@ -5,7 +5,7 @@
%%% Created : 20 May 2008 by Badlop <badlop@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl
index 90bbed179..ed52c728b 100644
--- a/src/ejabberd_config.erl
+++ b/src/ejabberd_config.erl
@@ -5,7 +5,7 @@
%%% Created : 14 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -713,10 +713,16 @@ process_term(Term, State) ->
process_host_term(Term, Host, State, Action) ->
case Term of
- {modules, Modules} when Action == set ->
- set_option({modules, Host}, replace_modules(Modules), State);
- {modules, Modules} when Action == append ->
- append_option({modules, Host}, replace_modules(Modules), State);
+ {modules, Modules} ->
+ Modules1 = try (gen_mod:opt_type(modules))(Modules) of
+ _ -> replace_modules(Modules)
+ catch _:_ -> Modules
+ end,
+ if Action == set ->
+ set_option({modules, Host}, Modules1, State);
+ Action == append ->
+ append_option({modules, Host}, Modules1, State)
+ end;
{host, _} ->
State;
{hosts, _} ->
@@ -1449,7 +1455,7 @@ opt_type(hosts) ->
[iolist_to_binary(H) || H <- L]
end;
opt_type(language) ->
- fun iolist_to_binary/1;
+ fun xmpp_lang:check/1;
opt_type(max_fsm_queue) ->
fun (I) when is_integer(I), I > 0 -> I end;
opt_type(default_db) ->
diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl
index c71649562..73a98827c 100644
--- a/src/ejabberd_ctl.erl
+++ b/src/ejabberd_ctl.erl
@@ -5,7 +5,7 @@
%%% Created : 11 Jan 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -59,6 +59,7 @@
-include("ejabberd_ctl.hrl").
-include("ejabberd_commands.hrl").
-include("logger.hrl").
+-include("ejabberd_stacktrace.hrl").
-define(DEFAULT_VERSION, 1000000).
@@ -327,9 +328,9 @@ try_call_command(Args, Auth, AccessCommands, Version) ->
catch
throw:Error ->
{io_lib:format("~p", [Error]), ?STATUS_ERROR};
- A:Why ->
- Stack = erlang:get_stacktrace(),
- {io_lib:format("Problem '~p ~p' occurred executing the command.~nStacktrace: ~p", [A, Why, Stack]), ?STATUS_ERROR}
+ ?EX_RULE(A, Why, Stack) ->
+ {io_lib:format("Problem '~p ~p' occurred executing the command.~nStacktrace: ~p",
+ [A, Why, ?EX_STACK(Stack)]), ?STATUS_ERROR}
end.
%% @spec (Args::[string()], Auth, AccessCommands) -> string() | integer() | {string(), integer()} | {error, ErrorType}
diff --git a/src/ejabberd_hooks.erl b/src/ejabberd_hooks.erl
index bc67b4c67..28d994c4a 100644
--- a/src/ejabberd_hooks.erl
+++ b/src/ejabberd_hooks.erl
@@ -5,7 +5,7 @@
%%% Created : 8 Aug 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -57,6 +57,7 @@
terminate/2]).
-include("logger.hrl").
+-include("ejabberd_stacktrace.hrl").
-record(state, {}).
-type local_hook() :: { Seq :: integer(), Module :: atom(), Function :: atom()}.
@@ -129,14 +130,14 @@ delete_dist(Hook, Node, Module, Function, Seq) ->
delete_dist(Hook, Host, Node, Module, Function, Seq) ->
gen_server:call(ejabberd_hooks, {delete, Hook, Host, Node, Module, Function, Seq}).
--spec delete_all_hooks() -> true.
+-spec delete_all_hooks() -> true.
%% @doc Primarily for testing / instrumentation
delete_all_hooks() ->
gen_server:call(ejabberd_hooks, {delete_all}).
-spec get_handlers(atom(), binary() | global) -> [local_hook() | distributed_hook()].
-%% @doc Returns currently set handler for hook name
+%% @doc Returns currently set handler for hook name
get_handlers(Hookname, Host) ->
gen_server:call(ejabberd_hooks, {get_handlers, Hookname, Host}).
@@ -264,7 +265,7 @@ handle_delete(Hook, Host, El) ->
ok;
[] ->
ok
- end.
+ end.
%%----------------------------------------------------------------------
%% Func: handle_cast/2
@@ -379,15 +380,11 @@ safe_apply(Hook, Module, Function, Args) ->
true ->
apply(Module, Function, Args)
end
- catch E:R when E /= exit; R /= normal ->
- St = get_stacktrace(),
+ catch ?EX_RULE(E, R, St) when E /= exit; R /= normal ->
?ERROR_MSG("Hook ~p crashed when running ~p:~p/~p:~n"
"** Reason = ~p~n"
"** Arguments = ~p",
[Hook, Module, Function, length(Args),
- {E, R, St}, Args]),
+ {E, R, ?EX_STACK(St)}, Args]),
'EXIT'
end.
-
-get_stacktrace() ->
- [{Mod, Fun, Loc, Args} || {Mod, Fun, Args, Loc} <- erlang:get_stacktrace()].
diff --git a/src/ejabberd_http.erl b/src/ejabberd_http.erl
index 769577371..c226dba1c 100644
--- a/src/ejabberd_http.erl
+++ b/src/ejabberd_http.erl
@@ -5,7 +5,7 @@
%%% Created : 27 Feb 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -852,23 +852,23 @@ code_to_phrase(505) -> <<"HTTP Version Not Supported">>.
-spec parse_auth(binary()) -> {binary(), binary()} | {oauth, binary(), []} | undefined.
parse_auth(<<"Basic ", Auth64/binary>>) ->
- Auth = try base64:decode(Auth64)
- catch _:badarg -> <<>>
- end,
- %% Auth should be a string with the format: user@server:password
- %% Note that password can contain additional characters '@' and ':'
- case str:chr(Auth, $:) of
- 0 ->
- undefined;
- Pos ->
- {User, <<$:, Pass/binary>>} = erlang:split_binary(Auth, Pos-1),
- PassUtf8 = unicode:characters_to_binary(binary_to_list(Pass), utf8),
- {User, PassUtf8}
+ try base64:decode(Auth64) of
+ Auth ->
+ case binary:split(Auth, <<":">>) of
+ [User, Pass] ->
+ PassUtf8 = unicode:characters_to_binary(Pass, utf8),
+ {User, PassUtf8};
+ _ ->
+ invalid
+ end
+ catch _:_ ->
+ invalid
end;
parse_auth(<<"Bearer ", SToken/binary>>) ->
Token = str:strip(SToken),
{oauth, Token, []};
-parse_auth(<<_/binary>>) -> undefined.
+parse_auth(<<_/binary>>) ->
+ invalid.
parse_urlencoded(S) ->
parse_urlencoded(S, nokey, <<>>, key).
@@ -992,6 +992,8 @@ listen_opt_type(http_bind) ->
fun(B) when is_boolean(B) -> B end;
listen_opt_type(xmlrpc) ->
fun(B) when is_boolean(B) -> B end;
+listen_opt_type(tag) ->
+ fun(B) when is_binary(B) -> B end;
listen_opt_type(request_handlers) ->
fun(Hs) ->
Hs1 = lists:map(fun
@@ -1026,5 +1028,6 @@ listen_options() ->
{http_bind, false},
{xmlrpc, false},
{request_handlers, []},
+ {tag, <<>>},
{default_host, undefined},
{custom_headers, []}].
diff --git a/src/ejabberd_http_ws.erl b/src/ejabberd_http_ws.erl
index d10dbd108..4b54e67ec 100644
--- a/src/ejabberd_http_ws.erl
+++ b/src/ejabberd_http_ws.erl
@@ -5,7 +5,7 @@
%%% Created : 09-10-2010 by Eric Cestari <ecestari@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_iq.erl b/src/ejabberd_iq.erl
index adee25dbe..aeaffccde 100644
--- a/src/ejabberd_iq.erl
+++ b/src/ejabberd_iq.erl
@@ -5,7 +5,7 @@
%%% Created : 10 Nov 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -173,4 +173,8 @@ calc_checksum(Data) ->
callback(undefined, IQRes, Fun) ->
Fun(IQRes);
callback(Proc, IQRes, Ctx) ->
- Proc ! {iq_reply, IQRes, Ctx}.
+ try
+ Proc ! {iq_reply, IQRes, Ctx}
+ catch _:badarg ->
+ ok
+ end.
diff --git a/src/ejabberd_listener.erl b/src/ejabberd_listener.erl
index e8742413b..c32f5be86 100644
--- a/src/ejabberd_listener.erl
+++ b/src/ejabberd_listener.erl
@@ -5,7 +5,7 @@
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index d9ef97129..1384a2359 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -5,7 +5,7 @@
%%% Created : 30 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -48,6 +48,7 @@
-include("logger.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
-include("xmpp.hrl").
+-include("ejabberd_stacktrace.hrl").
-record(state, {}).
@@ -70,10 +71,9 @@ start_link() ->
-spec route(stanza()) -> any().
route(Packet) ->
try do_route(Packet)
- catch E:R ->
- St = erlang:get_stacktrace(),
+ catch ?EX_RULE(E, R, St) ->
?ERROR_MSG("failed to route packet:~n~s~nReason = ~p",
- [xmpp:pp(Packet), {E, {R, St}}])
+ [xmpp:pp(Packet), {E, {R, ?EX_STACK(St)}}])
end.
-spec route_iq(iq(), function()) -> ok.
diff --git a/src/ejabberd_logger.erl b/src/ejabberd_logger.erl
index c7845be2f..e35a769e5 100644
--- a/src/ejabberd_logger.erl
+++ b/src/ejabberd_logger.erl
@@ -5,7 +5,7 @@
%%% Created : 12 May 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2013-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2013-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_mnesia.erl b/src/ejabberd_mnesia.erl
index 48bc6db5c..3ccf6af89 100644
--- a/src/ejabberd_mnesia.erl
+++ b/src/ejabberd_mnesia.erl
@@ -5,7 +5,7 @@
%%% Created : 17 Nov 2016 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -43,6 +43,7 @@
-define(NEED_RESET, [local_content, type]).
-include("logger.hrl").
+-include("ejabberd_stacktrace.hrl").
-record(state, {tables = #{} :: map(),
schema = [] :: [{atom(), [{atom(), any()}]}]}).
@@ -385,8 +386,8 @@ do_transform(OldAttrs, Attrs, Old) ->
transform_fun(Module, Name) ->
fun(Obj) ->
try Module:transform(Obj)
- catch E:R ->
- StackTrace = erlang:get_stacktrace(),
+ catch ?EX_RULE(E, R, St) ->
+ StackTrace = ?EX_STACK(St),
?ERROR_MSG("Failed to transform Mnesia table ~s:~n"
"** Record: ~p~n"
"** Reason: ~p~n"
diff --git a/src/ejabberd_oauth.erl b/src/ejabberd_oauth.erl
index fbd311335..2913c8ef9 100644
--- a/src/ejabberd_oauth.erl
+++ b/src/ejabberd_oauth.erl
@@ -5,7 +5,7 @@
%%% Created : 20 Mar 2015 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_oauth_mnesia.erl b/src/ejabberd_oauth_mnesia.erl
index 04d5c9958..1c55877eb 100644
--- a/src/ejabberd_oauth_mnesia.erl
+++ b/src/ejabberd_oauth_mnesia.erl
@@ -5,7 +5,7 @@
%%% Created : 20 Jul 2016 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_oauth_rest.erl b/src/ejabberd_oauth_rest.erl
index 151946d30..215766d00 100644
--- a/src/ejabberd_oauth_rest.erl
+++ b/src/ejabberd_oauth_rest.erl
@@ -5,7 +5,7 @@
%%% Created : 26 Jul 2016 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_oauth_sql.erl b/src/ejabberd_oauth_sql.erl
index f8daa51bd..e86e5be9f 100644
--- a/src/ejabberd_oauth_sql.erl
+++ b/src/ejabberd_oauth_sql.erl
@@ -5,7 +5,7 @@
%%% Created : 27 Jul 2016 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_piefxis.erl b/src/ejabberd_piefxis.erl
index 541fcad8b..02b79ed4d 100644
--- a/src/ejabberd_piefxis.erl
+++ b/src/ejabberd_piefxis.erl
@@ -5,7 +5,7 @@
%%% Created : 17 Jul 2008 by Pablo Polvorin <pablo.polvorin@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -166,15 +166,10 @@ export_users([], _Server, _Fd) ->
export_user(User, Server, Fd) ->
Password = ejabberd_auth:get_password_s(User, Server),
LServer = jid:nameprep(Server),
- PasswordFormat = ejabberd_auth:password_format(LServer),
- Pass = case Password of
- {_,_,_,_} ->
- case PasswordFormat of
- scram -> format_scram_password(Password);
- _ -> <<"">>
- end;
- _ -> Password
- end,
+ Pass = case ejabberd_auth:password_format(LServer) of
+ scram -> format_scram_password(Password);
+ _ -> Password
+ end,
Els = get_offline(User, Server) ++
get_vcard(User, Server) ++
get_privacy(User, Server) ++
@@ -186,7 +181,8 @@ export_user(User, Server, Fd) ->
{<<"password">>, Pass}],
children = Els})).
-format_scram_password({StoredKey, ServerKey, Salt, IterationCount}) ->
+format_scram_password(#scram{storedkey = StoredKey, serverkey = ServerKey,
+ salt = Salt, iterationcount = IterationCount}) ->
StoredKeyB64 = base64:encode(StoredKey),
ServerKeyB64 = base64:encode(ServerKey),
SaltB64 = base64:encode(Salt),
diff --git a/src/ejabberd_pkix.erl b/src/ejabberd_pkix.erl
index 2005ffdfa..39b69d033 100644
--- a/src/ejabberd_pkix.erl
+++ b/src/ejabberd_pkix.erl
@@ -3,7 +3,7 @@
%%% Created : 4 Mar 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_rdbms.erl b/src/ejabberd_rdbms.erl
index 2b69258e5..c6f5536d7 100644
--- a/src/ejabberd_rdbms.erl
+++ b/src/ejabberd_rdbms.erl
@@ -5,7 +5,7 @@
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -98,7 +98,10 @@ stop_host(Host) ->
-spec reload_host(binary()) -> ok.
reload_host(Host) ->
- ejabberd_sql_sup:reload(Host).
+ case needs_sql(Host) of
+ {true, _} -> ejabberd_sql_sup:reload(Host);
+ false -> ok
+ end.
%% Returns {true, App} if we have configured sql for the given host
needs_sql(Host) ->
diff --git a/src/ejabberd_redis.erl b/src/ejabberd_redis.erl
index 857bece0e..3fa3f37d2 100644
--- a/src/ejabberd_redis.erl
+++ b/src/ejabberd_redis.erl
@@ -4,7 +4,7 @@
%%% Created : 8 May 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -50,6 +50,7 @@
-define(CALL_TIMEOUT, 60*1000). %% 60 seconds
-include("logger.hrl").
+-include("ejabberd_stacktrace.hrl").
-record(state, {connection :: pid() | undefined,
num :: pos_integer(),
@@ -106,9 +107,9 @@ multi(F) ->
{error, _} = Err -> Err;
Result -> get_result(Result)
end
- catch E:R ->
+ catch ?EX_RULE(E, R, St) ->
erlang:erase(?TR_STACK),
- erlang:raise(E, R, erlang:get_stacktrace())
+ erlang:raise(E, R, ?EX_STACK(St))
end;
_ ->
erlang:error(nested_transaction)
diff --git a/src/ejabberd_redis_sup.erl b/src/ejabberd_redis_sup.erl
index bbcd11449..f34a96655 100644
--- a/src/ejabberd_redis_sup.erl
+++ b/src/ejabberd_redis_sup.erl
@@ -3,7 +3,7 @@
%%% Created : 6 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_regexp.erl b/src/ejabberd_regexp.erl
index 284797529..c454835a9 100644
--- a/src/ejabberd_regexp.erl
+++ b/src/ejabberd_regexp.erl
@@ -5,7 +5,7 @@
%%% Created : 8 Dec 2011 by Badlop
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_riak.erl b/src/ejabberd_riak.erl
index 54c84d543..a86ac06d3 100644
--- a/src/ejabberd_riak.erl
+++ b/src/ejabberd_riak.erl
@@ -5,7 +5,7 @@
%%% Created : 29 Dec 2011 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_riak_sup.erl b/src/ejabberd_riak_sup.erl
index 950acbd9e..2598297b9 100644
--- a/src/ejabberd_riak_sup.erl
+++ b/src/ejabberd_riak_sup.erl
@@ -5,7 +5,7 @@
%%% Created : 29 Dec 2011 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl
index bd9a87ce2..12baed5ee 100644
--- a/src/ejabberd_router.erl
+++ b/src/ejabberd_router.erl
@@ -5,7 +5,7 @@
%%% Created : 27 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -71,6 +71,7 @@
-include("logger.hrl").
-include("ejabberd_router.hrl").
-include("xmpp.hrl").
+-include("ejabberd_stacktrace.hrl").
-callback init() -> any().
-callback register_route(binary(), binary(), local_hint(),
@@ -90,10 +91,9 @@ start_link() ->
-spec route(stanza()) -> ok.
route(Packet) ->
try do_route(Packet)
- catch E:R ->
- St = erlang:get_stacktrace(),
+ catch ?EX_RULE(E, R, St) ->
?ERROR_MSG("failed to route packet:~n~s~nReason = ~p",
- [xmpp:pp(Packet), {E, {R, St}}])
+ [xmpp:pp(Packet), {E, {R, ?EX_STACK(St)}}])
end.
-spec route(jid(), jid(), xmlel() | stanza()) -> ok.
diff --git a/src/ejabberd_router_mnesia.erl b/src/ejabberd_router_mnesia.erl
index a97874bcd..03fbe495f 100644
--- a/src/ejabberd_router_mnesia.erl
+++ b/src/ejabberd_router_mnesia.erl
@@ -2,7 +2,7 @@
%%% Created : 11 Jan 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_router_multicast.erl b/src/ejabberd_router_multicast.erl
index c95c18882..6dbaeb41a 100644
--- a/src/ejabberd_router_multicast.erl
+++ b/src/ejabberd_router_multicast.erl
@@ -5,7 +5,7 @@
%%% Created : 11 Aug 2007 by Badlop <badlop@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_router_redis.erl b/src/ejabberd_router_redis.erl
index 706a6b4fe..cafb05b13 100644
--- a/src/ejabberd_router_redis.erl
+++ b/src/ejabberd_router_redis.erl
@@ -3,7 +3,7 @@
%%% Created : 28 Mar 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_router_riak.erl b/src/ejabberd_router_riak.erl
index b330f201d..20346c369 100644
--- a/src/ejabberd_router_riak.erl
+++ b/src/ejabberd_router_riak.erl
@@ -3,7 +3,7 @@
%%% Created : 15 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_router_sql.erl b/src/ejabberd_router_sql.erl
index edf06dfe0..bc3ef52ef 100644
--- a/src/ejabberd_router_sql.erl
+++ b/src/ejabberd_router_sql.erl
@@ -3,7 +3,7 @@
%%% Created : 28 Mar 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -32,6 +32,7 @@
-include("logger.hrl").
-include("ejabberd_sql_pt.hrl").
-include("ejabberd_router.hrl").
+-include("ejabberd_stacktrace.hrl").
%%%===================================================================
%%% API
@@ -121,12 +122,11 @@ row_to_route(Domain, {ServerHost, NodeS, PidS, LocalHintS} = Row) ->
local_hint = dec_local_hint(LocalHintS)}]
catch _:{bad_node, _} ->
[];
- E:R ->
- St = erlang:get_stacktrace(),
+ ?EX_RULE(E, R, St) ->
?ERROR_MSG("failed to decode row from 'route' table:~n"
"Row = ~p~n"
"Domain = ~s~n"
"Reason = ~p",
- [Row, Domain, {E, {R, St}}]),
+ [Row, Domain, {E, {R, ?EX_STACK(St)}}]),
[]
end.
diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl
index a33d477e5..4b1881199 100644
--- a/src/ejabberd_s2s.erl
+++ b/src/ejabberd_s2s.erl
@@ -5,7 +5,7 @@
%%% Created : 7 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -55,12 +55,10 @@
transform_options/1, opt_type/1]).
-include("logger.hrl").
-
-include("xmpp.hrl").
-
-include("ejabberd_commands.hrl").
-
-include_lib("public_key/include/public_key.hrl").
+-include("ejabberd_stacktrace.hrl").
-define(PKIXEXPLICIT, 'OTP-PUB-KEY').
@@ -94,10 +92,9 @@ start_link() ->
route(Packet) ->
try do_route(Packet)
- catch E:R ->
- St = erlang:get_stacktrace(),
+ catch ?EX_RULE(E, R, St) ->
?ERROR_MSG("failed to route packet:~n~s~nReason = ~p",
- [xmpp:pp(Packet), {E, {R, St}}])
+ [xmpp:pp(Packet), {E, {R, ?EX_STACK(St)}}])
end.
clean_temporarily_blocked_table() ->
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index 3ceb9c058..db7655ef8 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -2,7 +2,7 @@
%%% Created : 12 Dec 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl
index db8f3d0a3..d940284ef 100644
--- a/src/ejabberd_s2s_out.erl
+++ b/src/ejabberd_s2s_out.erl
@@ -2,7 +2,7 @@
%%% Created : 16 Dec 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl
index 0f40822b7..c2fa2b8c0 100644
--- a/src/ejabberd_service.erl
+++ b/src/ejabberd_service.erl
@@ -2,7 +2,7 @@
%%% Created : 11 Dec 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_shaper.erl b/src/ejabberd_shaper.erl
index e42cb4121..cad04986c 100644
--- a/src/ejabberd_shaper.erl
+++ b/src/ejabberd_shaper.erl
@@ -5,7 +5,7 @@
%%% Created : 9 Feb 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_sip.erl b/src/ejabberd_sip.erl
index f9061edbe..8f6aed55c 100644
--- a/src/ejabberd_sip.erl
+++ b/src/ejabberd_sip.erl
@@ -5,7 +5,7 @@
%%% Created : 30 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2013-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2013-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index b8c85e9e8..165a750db 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -5,7 +5,7 @@
%%% Created : 24 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -91,6 +91,7 @@
-include("ejabberd_commands.hrl").
-include("ejabberd_sm.hrl").
+-include("ejabberd_stacktrace.hrl").
-callback init() -> ok | {error, any()}.
-callback set_session(#session{}) -> ok | {error, any()}.
@@ -141,11 +142,10 @@ route(Packet) ->
?DEBUG("hook dropped stanza:~n~s", [xmpp:pp(Packet)]);
Packet1 ->
try do_route(Packet1), ok
- catch E:R ->
- St = erlang:get_stacktrace(),
+ catch ?EX_RULE(E, R, St) ->
?ERROR_MSG("failed to route packet:~n~s~nReason = ~p",
[xmpp:pp(Packet1),
- {E, {R, St}}])
+ {E, {R, ?EX_STACK(St)}}])
end
end.
diff --git a/src/ejabberd_sm_mnesia.erl b/src/ejabberd_sm_mnesia.erl
index 43b49202e..5e36a3d8a 100644
--- a/src/ejabberd_sm_mnesia.erl
+++ b/src/ejabberd_sm_mnesia.erl
@@ -4,7 +4,7 @@
%%% Created : 9 Mar 2015 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_sm_redis.erl b/src/ejabberd_sm_redis.erl
index a93be86bb..e4bab3902 100644
--- a/src/ejabberd_sm_redis.erl
+++ b/src/ejabberd_sm_redis.erl
@@ -4,7 +4,7 @@
%%% Created : 11 Mar 2015 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_sm_riak.erl b/src/ejabberd_sm_riak.erl
index a8150d938..36c936976 100644
--- a/src/ejabberd_sm_riak.erl
+++ b/src/ejabberd_sm_riak.erl
@@ -3,7 +3,7 @@
%%% Created : 15 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_sm_sql.erl b/src/ejabberd_sm_sql.erl
index bdc32a27c..8c3efc9b3 100644
--- a/src/ejabberd_sm_sql.erl
+++ b/src/ejabberd_sm_sql.erl
@@ -4,7 +4,7 @@
%%% Created : 9 Mar 2015 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_sql.erl b/src/ejabberd_sql.erl
index 9e088f211..2d9c64187 100644
--- a/src/ejabberd_sql.erl
+++ b/src/ejabberd_sql.erl
@@ -5,7 +5,7 @@
%%% Created : 8 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -69,6 +69,7 @@
-include("logger.hrl").
-include("ejabberd_sql_pt.hrl").
+-include("ejabberd_stacktrace.hrl").
-record(state,
{db_ref = self() :: pid(),
@@ -516,24 +517,26 @@ outer_transaction(F, NRestarts, _Reason) ->
end,
sql_query_internal([<<"begin;">>]),
put(?NESTING_KEY, PreviousNestingLevel + 1),
- Result = (catch F()),
- put(?NESTING_KEY, PreviousNestingLevel),
- case Result of
- {aborted, Reason} when NRestarts > 0 ->
- sql_query_internal([<<"rollback;">>]),
- outer_transaction(F, NRestarts - 1, Reason);
- {aborted, Reason} when NRestarts =:= 0 ->
- ?ERROR_MSG("SQL transaction restarts exceeded~n** "
- "Restarts: ~p~n** Last abort reason: "
- "~p~n** Stacktrace: ~p~n** When State "
- "== ~p",
- [?MAX_TRANSACTION_RESTARTS, Reason,
- erlang:get_stacktrace(), get(?STATE_KEY)]),
- sql_query_internal([<<"rollback;">>]),
- {aborted, Reason};
- {'EXIT', Reason} ->
- sql_query_internal([<<"rollback;">>]), {aborted, Reason};
- Res -> sql_query_internal([<<"commit;">>]), {atomic, Res}
+ try F() of
+ Res ->
+ sql_query_internal([<<"commit;">>]),
+ {atomic, Res}
+ catch
+ ?EX_RULE(throw, {aborted, Reason}, _) when NRestarts > 0 ->
+ sql_query_internal([<<"rollback;">>]),
+ outer_transaction(F, NRestarts - 1, Reason);
+ ?EX_RULE(throw, {aborted, Reason}, Stack) when NRestarts =:= 0 ->
+ ?ERROR_MSG("SQL transaction restarts exceeded~n** "
+ "Restarts: ~p~n** Last abort reason: "
+ "~p~n** Stacktrace: ~p~n** When State "
+ "== ~p",
+ [?MAX_TRANSACTION_RESTARTS, Reason,
+ ?EX_STACK(Stack), get(?STATE_KEY)]),
+ sql_query_internal([<<"rollback;">>]),
+ {aborted, Reason};
+ ?EX_RULE(exit, Reason, _) ->
+ sql_query_internal([<<"rollback;">>]),
+ {aborted, Reason}
end.
execute_bloc(F) ->
@@ -599,10 +602,9 @@ sql_query_internal(#sql_query{} = Query) ->
{error, <<"killed">>};
exit:{normal, _} ->
{error, <<"terminated unexpectedly">>};
- Class:Reason ->
- ST = erlang:get_stacktrace(),
+ ?EX_RULE(Class, Reason, Stack) ->
?ERROR_MSG("Internal error while processing SQL query: ~p",
- [{Class, Reason, ST}]),
+ [{Class, Reason, ?EX_STACK(Stack)}]),
{error, <<"internal error">>}
end,
check_error(Res, Query);
@@ -737,12 +739,11 @@ sql_query_format_res({selected, _, Rows}, SQLQuery) ->
try
[(SQLQuery#sql_query.format_res)(Row)]
catch
- Class:Reason ->
- ST = erlang:get_stacktrace(),
+ ?EX_RULE(Class, Reason, Stack) ->
?ERROR_MSG("Error while processing "
"SQL query result: ~p~n"
"row: ~p",
- [{Class, Reason, ST}, Row]),
+ [{Class, Reason, ?EX_STACK(Stack)}, Row]),
[]
end
end, Rows),
@@ -1070,9 +1071,9 @@ init_mssql(Host) ->
case filelib:ensure_dir(freetds_config()) of
ok ->
try
- ok = file:write_file(freetds_config(), FreeTDS, [append]),
- ok = file:write_file(odbcinst_config(), ODBCINST),
- ok = file:write_file(odbc_config(), ODBCINI, [append]),
+ ok = write_file_if_new(freetds_config(), FreeTDS),
+ ok = write_file_if_new(odbcinst_config(), ODBCINST),
+ ok = write_file_if_new(odbc_config(), ODBCINI),
os:putenv("ODBCSYSINI", tmp_dir()),
os:putenv("FREETDS", freetds_config()),
os:putenv("FREETDSCONF", freetds_config()),
@@ -1088,6 +1089,12 @@ init_mssql(Host) ->
Err
end.
+write_file_if_new(File, Payload) ->
+ case filelib:is_file(File) of
+ true -> ok;
+ false -> file:write_file(File, Payload)
+ end.
+
tmp_dir() ->
case os:type() of
{win32, _} -> filename:join([os:getenv("HOME"), "conf"]);
diff --git a/src/ejabberd_sql_pt.erl b/src/ejabberd_sql_pt.erl
index 1f6134d07..0ae04c64d 100644
--- a/src/ejabberd_sql_pt.erl
+++ b/src/ejabberd_sql_pt.erl
@@ -5,7 +5,7 @@
%%% Created : 20 Jan 2016 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_sql_sup.erl b/src/ejabberd_sql_sup.erl
index ee889bd21..f16c23a00 100644
--- a/src/ejabberd_sql_sup.erl
+++ b/src/ejabberd_sql_sup.erl
@@ -5,7 +5,7 @@
%%% Created : 22 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_stun.erl b/src/ejabberd_stun.erl
index 1e00c85f5..24f3e696b 100644
--- a/src/ejabberd_stun.erl
+++ b/src/ejabberd_stun.erl
@@ -5,7 +5,7 @@
%%% Created : 8 May 2014 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2013-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2013-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_sup.erl b/src/ejabberd_sup.erl
index 86a14c78a..edf15e438 100644
--- a/src/ejabberd_sup.erl
+++ b/src/ejabberd_sup.erl
@@ -5,7 +5,7 @@
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_system_monitor.erl b/src/ejabberd_system_monitor.erl
index cf50209fb..59ba6f806 100644
--- a/src/ejabberd_system_monitor.erl
+++ b/src/ejabberd_system_monitor.erl
@@ -5,7 +5,7 @@
%%% Created : 21 Mar 2007 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_tmp_sup.erl b/src/ejabberd_tmp_sup.erl
index aa8a7e0f2..8f3e1f06c 100644
--- a/src/ejabberd_tmp_sup.erl
+++ b/src/ejabberd_tmp_sup.erl
@@ -5,7 +5,7 @@
%%% Created : 18 Jul 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_update.erl b/src/ejabberd_update.erl
index 4c360011f..c7aa652c1 100644
--- a/src/ejabberd_update.erl
+++ b/src/ejabberd_update.erl
@@ -5,7 +5,7 @@
%%% Created : 27 Jan 2006 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_web.erl b/src/ejabberd_web.erl
index a0291fc6f..3025dc146 100644
--- a/src/ejabberd_web.erl
+++ b/src/ejabberd_web.erl
@@ -6,7 +6,7 @@
%%% Created : 28 Feb 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_web_admin.erl b/src/ejabberd_web_admin.erl
index 03b11c9f6..4c4501436 100644
--- a/src/ejabberd_web_admin.erl
+++ b/src/ejabberd_web_admin.erl
@@ -5,7 +5,7 @@
%%% Created : 9 Apr 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -254,6 +254,7 @@ get_auth_admin(Auth, HostHTTP, RPath, Method) ->
catch _:{bad_jid, _} ->
{unauthorized, <<"badformed-jid">>}
end;
+ invalid -> {unauthorized, <<"no-auth-provided">>};
undefined -> {unauthorized, <<"no-auth-provided">>}
end.
@@ -305,7 +306,7 @@ make_xhtml(Els, Host, Node, Lang, JID) ->
#xmlel{name = <<"script">>,
attrs =
[{<<"src">>,
- <<Base/binary, "/additions.js">>},
+ <<Base/binary, "additions.js">>},
{<<"type">>, <<"text/javascript">>}],
children = [?C(<<" ">>)]},
#xmlel{name = <<"link">>,
@@ -337,7 +338,7 @@ make_xhtml(Els, Host, Node, Lang, JID) ->
[?XAE(<<"div">>, [{<<"id">>, <<"copyright">>}],
[?XE(<<"p">>,
[?AC(<<"https://www.ejabberd.im/">>, <<"ejabberd">>),
- ?C(<<" (c) 2002-2018 ">>),
+ ?C(<<" (c) 2002-2019 ">>),
?AC(<<"https://www.process-one.net/">>, <<"ProcessOne, leader in messaging and push solutions">>)]
)])])])]}}.
@@ -2380,10 +2381,13 @@ node_modules_parse_query(Host, Node, Modules, Query) ->
{ok, Tokens, _} =
erl_scan:string(binary_to_list(<<SOpts/binary, ".">>)),
{ok, Opts} = erl_parse:parse_term(Tokens),
+ NewMods = lists:keystore(Module, 1, ejabberd_config:get_option(modules), {Module, Opts}),
ejabberd_cluster:call(Node, gen_mod, stop_module,
[Host, Module]),
+ ejabberd_cluster:call(Node, ejabberd_config, add_option,
+ [modules, NewMods]),
ejabberd_cluster:call(Node, gen_mod, start_module,
- [Host, Module, Opts]),
+ [Host, Module]),
throw(submitted);
_ ->
case lists:keysearch(<<"stop", SModule/binary>>,
diff --git a/src/ejabberd_websocket.erl b/src/ejabberd_websocket.erl
index 5a329797b..506ff142b 100644
--- a/src/ejabberd_websocket.erl
+++ b/src/ejabberd_websocket.erl
@@ -33,7 +33,7 @@
%%% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
%%% POSSIBILITY OF SUCH DAMAGE.
%%% ==========================================================================================================
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%----------------------------------------------------------------------
-module(ejabberd_websocket).
diff --git a/src/ejabberd_xmlrpc.erl b/src/ejabberd_xmlrpc.erl
index 11da7f369..cda2864df 100644
--- a/src/ejabberd_xmlrpc.erl
+++ b/src/ejabberd_xmlrpc.erl
@@ -5,7 +5,7 @@
%%% Created : 21 Aug 2007 by Badlop <badlop@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejd2sql.erl b/src/ejd2sql.erl
index 40793f405..546b86879 100644
--- a/src/ejd2sql.erl
+++ b/src/ejd2sql.erl
@@ -5,7 +5,7 @@
%%% Created : 22 Aug 2005 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/eldap_filter.erl b/src/eldap_filter.erl
index 32cb85fd9..7ab634d95 100644
--- a/src/eldap_filter.erl
+++ b/src/eldap_filter.erl
@@ -6,7 +6,7 @@
%%% Author: Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/eldap_pool.erl b/src/eldap_pool.erl
index 3e8e35b84..b6421c230 100644
--- a/src/eldap_pool.erl
+++ b/src/eldap_pool.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Nov 2006 by Evgeniy Khramtsov <xram@jabber.ru>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/eldap_utils.erl b/src/eldap_utils.erl
index d757aa31b..47e18aac3 100644
--- a/src/eldap_utils.erl
+++ b/src/eldap_utils.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Oct 2006 by Mickael Remond <mremond@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/elixir_logger_backend.erl b/src/elixir_logger_backend.erl
index bbe43a2d3..16d7f954c 100644
--- a/src/elixir_logger_backend.erl
+++ b/src/elixir_logger_backend.erl
@@ -5,7 +5,7 @@
%%% Created : 9 March 2016 by Mickael Remond <mremond@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ext_mod.erl b/src/ext_mod.erl
index 02165bea8..0d734e08c 100644
--- a/src/ext_mod.erl
+++ b/src/ext_mod.erl
@@ -5,7 +5,7 @@
%%% Created : 19 Feb 2015 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2006-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2006-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/extauth.erl b/src/extauth.erl
index f77d3d2cc..ace340f72 100644
--- a/src/extauth.erl
+++ b/src/extauth.erl
@@ -2,7 +2,7 @@
%%% Created : 7 May 2018 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/extauth_sup.erl b/src/extauth_sup.erl
index c9dc0cdff..f4220fa81 100644
--- a/src/extauth_sup.erl
+++ b/src/extauth_sup.erl
@@ -2,7 +2,7 @@
%%% Created : 7 May 2018 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index f6a6744fd..38aa32e36 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -5,7 +5,7 @@
%%% Created : 22 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -40,6 +40,7 @@
-include("logger.hrl").
-include("xmpp.hrl").
-include("translate.hrl").
+-include("ejabberd_stacktrace.hrl").
-type component() :: ejabberd_sm | ejabberd_local.
@@ -113,10 +114,9 @@ process_iq(_Host, Module, Function, IQ) ->
ejabberd_router:route(ResIQ);
ignore ->
ok
- catch E:R ->
- St = erlang:get_stacktrace(),
+ catch ?EX_RULE(E, R, St) ->
?ERROR_MSG("failed to process iq:~n~s~nReason = ~p",
- [xmpp:pp(IQ), {E, {R, St}}]),
+ [xmpp:pp(IQ), {E, {R, ?EX_STACK(St)}}]),
Txt = <<"Module failed to handle the query">>,
Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang),
ejabberd_router:route_error(IQ, Err)
diff --git a/src/gen_mod.erl b/src/gen_mod.erl
index cf107f7b0..cec3ddb24 100644
--- a/src/gen_mod.erl
+++ b/src/gen_mod.erl
@@ -5,7 +5,7 @@
%%% Created : 24 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -58,6 +58,7 @@
-include("logger.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
+-include("ejabberd_stacktrace.hrl").
-record(ejabberd_module,
{module_host = {undefined, <<"">>} :: {atom(), binary()},
@@ -217,8 +218,8 @@ start_module(Host, Module, Opts0, Order, NeedValidation) ->
{ok, Pid} when is_pid(Pid) -> {ok, Pid};
Err -> erlang:error({bad_return, Module, Err})
end
- catch Class:Reason ->
- StackTrace = erlang:get_stacktrace(),
+ catch ?EX_RULE(Class, Reason, Stack) ->
+ StackTrace = ?EX_STACK(Stack),
ets:delete(ejabberd_modules, {Module, Host}),
ErrorText = format_module_error(
Module, start, 2,
@@ -282,8 +283,8 @@ reload_module(Host, Module, NewOpts, OldOpts, Order) ->
{ok, Pid} when is_pid(Pid) -> {ok, Pid};
Err -> erlang:error({bad_return, Module, Err})
end
- catch Class:Reason ->
- StackTrace = erlang:get_stacktrace(),
+ catch ?EX_RULE(Class, Reason, Stack) ->
+ StackTrace = ?EX_STACK(Stack),
ErrorText = format_module_error(
Module, reload, 3,
NewOpts, Class, Reason,
@@ -936,8 +937,12 @@ opt_type(modules) ->
fun(Mods) ->
lists:map(
fun({M, A}) when is_atom(M) ->
- true = is_opt_list(A),
- {M, A}
+ case is_opt_list(A) of
+ true -> {M, A};
+ false ->
+ ?ERROR_MSG("Malformed configuration format of module ~s", [M]),
+ erlang:error(badarg)
+ end
end, Mods)
end;
opt_type(_) -> [modules].
diff --git a/src/gen_pubsub_node.erl b/src/gen_pubsub_node.erl
index b54cc569b..624b2fd07 100644
--- a/src/gen_pubsub_node.erl
+++ b/src/gen_pubsub_node.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/gen_pubsub_nodetree.erl b/src/gen_pubsub_nodetree.erl
index bcf52855c..aba78a89a 100644
--- a/src/gen_pubsub_nodetree.erl
+++ b/src/gen_pubsub_nodetree.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/jd2ejd.erl b/src/jd2ejd.erl
index 394a5a471..0122a7f2d 100644
--- a/src/jd2ejd.erl
+++ b/src/jd2ejd.erl
@@ -5,7 +5,7 @@
%%% Created : 2 Feb 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/misc.erl b/src/misc.erl
index 5aa281565..3c5407cd0 100644
--- a/src/misc.erl
+++ b/src/misc.erl
@@ -8,7 +8,7 @@
%%% Created : 30 Mar 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl
index 9071ca817..c77d6a047 100644
--- a/src/mod_adhoc.erl
+++ b/src/mod_adhoc.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Nov 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl
index 367196a07..4655ac226 100644
--- a/src/mod_admin_extra.erl
+++ b/src/mod_admin_extra.erl
@@ -5,7 +5,7 @@
%%% Created : 10 Aug 2008 by Badlop <badlop@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -987,11 +987,15 @@ get_status_list(Host, Status_required) ->
apply(Fstatus, [Status, Status_required])].
connected_users_info() ->
- lists:map(
+ lists:filtermap(
fun({U, S, R}) ->
- Info = user_session_info(U, S, R),
- Jid = jid:encode(jid:make(U, S, R)),
- erlang:insert_element(1, Info, Jid)
+ case user_session_info(U, S, R) of
+ offline ->
+ false;
+ Info ->
+ Jid = jid:encode(jid:make(U, S, R)),
+ {true, erlang:insert_element(1, Info, Jid)}
+ end
end,
ejabberd_sm:dirty_get_sessions_list()).
@@ -1054,23 +1058,31 @@ set_presence(User, Host, Resource, Type, Show, Status, Priority0) ->
ejabberd_c2s:set_presence(Ref, Pres).
user_sessions_info(User, Host) ->
- [user_session_info(User, Host, Resource) ||
- Resource <- ejabberd_sm:get_user_resources(User, Host)].
+ lists:filtermap(fun(Resource) ->
+ case user_session_info(User, Host, Resource) of
+ offline -> false;
+ Info -> {true, Info}
+ end
+ end, ejabberd_sm:get_user_resources(User, Host)).
user_session_info(User, Host, Resource) ->
CurrentSec = calendar:datetime_to_gregorian_seconds({date(), time()}),
- Info = ejabberd_sm:get_user_info(User, Host, Resource),
- Now = proplists:get_value(ts, Info),
- Pid = proplists:get_value(pid, Info),
- {_U, _Resource, Status, StatusText} = get_presence(Pid),
- Priority = proplists:get_value(priority, Info),
- Conn = proplists:get_value(conn, Info),
- {Ip, Port} = proplists:get_value(ip, Info),
- IPS = inet_parse:ntoa(Ip),
- NodeS = atom_to_list(node(Pid)),
- Uptime = CurrentSec - calendar:datetime_to_gregorian_seconds(
- calendar:now_to_local_time(Now)),
- {atom_to_list(Conn), IPS, Port, num_prio(Priority), NodeS, Uptime, Status, Resource, StatusText}.
+ case ejabberd_sm:get_user_info(User, Host, Resource) of
+ offline ->
+ offline;
+ Info ->
+ Now = proplists:get_value(ts, Info),
+ Pid = proplists:get_value(pid, Info),
+ {_U, _Resource, Status, StatusText} = get_presence(Pid),
+ Priority = proplists:get_value(priority, Info),
+ Conn = proplists:get_value(conn, Info),
+ {Ip, Port} = proplists:get_value(ip, Info),
+ IPS = inet_parse:ntoa(Ip),
+ NodeS = atom_to_list(node(Pid)),
+ Uptime = CurrentSec - calendar:datetime_to_gregorian_seconds(
+ calendar:now_to_local_time(Now)),
+ {atom_to_list(Conn), IPS, Port, num_prio(Priority), NodeS, Uptime, Status, Resource, StatusText}
+ end.
%%%
diff --git a/src/mod_admin_update_sql.erl b/src/mod_admin_update_sql.erl
index 3c036f341..0212dab25 100644
--- a/src/mod_admin_update_sql.erl
+++ b/src/mod_admin_update_sql.erl
@@ -5,7 +5,7 @@
%%% Created : 9 Aug 2017 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_announce.erl b/src/mod_announce.erl
index b8ca970c9..c8d3e9e74 100644
--- a/src/mod_announce.erl
+++ b/src/mod_announce.erl
@@ -5,7 +5,7 @@
%%% Created : 11 Aug 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_announce_mnesia.erl b/src/mod_announce_mnesia.erl
index f3b8aef7c..ea7c54f36 100644
--- a/src/mod_announce_mnesia.erl
+++ b/src/mod_announce_mnesia.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_announce_riak.erl b/src/mod_announce_riak.erl
index 55959b58b..1d2435151 100644
--- a/src/mod_announce_riak.erl
+++ b/src/mod_announce_riak.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_announce_sql.erl b/src/mod_announce_sql.erl
index c4f1ba86f..60c3edcf6 100644
--- a/src/mod_announce_sql.erl
+++ b/src/mod_announce_sql.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_avatar.erl b/src/mod_avatar.erl
index d5f24e75d..e706a23c3 100644
--- a/src/mod_avatar.erl
+++ b/src/mod_avatar.erl
@@ -3,7 +3,7 @@
%%% Created : 13 Sep 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_block_strangers.erl b/src/mod_block_strangers.erl
index 0496245b0..486bea7fd 100644
--- a/src/mod_block_strangers.erl
+++ b/src/mod_block_strangers.erl
@@ -5,7 +5,7 @@
%%% Created : 25 Dec 2016 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_blocking.erl b/src/mod_blocking.erl
index d428e7d28..b1856c937 100644
--- a/src/mod_blocking.erl
+++ b/src/mod_blocking.erl
@@ -5,7 +5,7 @@
%%% Created : 24 Aug 2008 by Stephan Maka <stephan@spaceboyz.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_bosh.erl b/src/mod_bosh.erl
index a393597eb..03bdc6e15 100644
--- a/src/mod_bosh.erl
+++ b/src/mod_bosh.erl
@@ -7,7 +7,7 @@
%%% Created : 20 Jul 2011 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_bosh_mnesia.erl b/src/mod_bosh_mnesia.erl
index fdd7225ca..a0da1867f 100644
--- a/src/mod_bosh_mnesia.erl
+++ b/src/mod_bosh_mnesia.erl
@@ -2,7 +2,7 @@
%%% Created : 12 Jan 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_bosh_redis.erl b/src/mod_bosh_redis.erl
index 7c7cf6578..b94322194 100644
--- a/src/mod_bosh_redis.erl
+++ b/src/mod_bosh_redis.erl
@@ -5,7 +5,7 @@
%%% Created : 28 Mar 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2017-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2017-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_bosh_riak.erl b/src/mod_bosh_riak.erl
index df376f3d1..7ebd1bd6f 100644
--- a/src/mod_bosh_riak.erl
+++ b/src/mod_bosh_riak.erl
@@ -3,7 +3,7 @@
%%% Created : 15 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_bosh_sql.erl b/src/mod_bosh_sql.erl
index c32714c87..4ec65e779 100644
--- a/src/mod_bosh_sql.erl
+++ b/src/mod_bosh_sql.erl
@@ -5,7 +5,7 @@
%%% Created : 28 Mar 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2017-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2017-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_caps.erl b/src/mod_caps.erl
index 3d2b52dac..96b44cd68 100644
--- a/src/mod_caps.erl
+++ b/src/mod_caps.erl
@@ -5,7 +5,7 @@
%%% Created : 7 Oct 2006 by Magnus Henoch <henoch@dtek.chalmers.se>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_caps_mnesia.erl b/src/mod_caps_mnesia.erl
index c44834fc5..9855b1fc2 100644
--- a/src/mod_caps_mnesia.erl
+++ b/src/mod_caps_mnesia.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_caps_riak.erl b/src/mod_caps_riak.erl
index 1d94ceee4..37a29ff7f 100644
--- a/src/mod_caps_riak.erl
+++ b/src/mod_caps_riak.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_caps_sql.erl b/src/mod_caps_sql.erl
index 01da67158..b0829156e 100644
--- a/src/mod_caps_sql.erl
+++ b/src/mod_caps_sql.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl
index e1f82e872..72c098570 100644
--- a/src/mod_carboncopy.erl
+++ b/src/mod_carboncopy.erl
@@ -7,7 +7,7 @@
%%% {mod_carboncopy, []}
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_client_state.erl b/src/mod_client_state.erl
index 156fde726..162d47aa2 100644
--- a/src/mod_client_state.erl
+++ b/src/mod_client_state.erl
@@ -5,7 +5,7 @@
%%% Created : 11 Sep 2014 by Holger Weiss <holger@zedat.fu-berlin.de>
%%%
%%%
-%%% ejabberd, Copyright (C) 2014-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2014-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_configure.erl b/src/mod_configure.erl
index a52376504..aa431e285 100644
--- a/src/mod_configure.erl
+++ b/src/mod_configure.erl
@@ -5,7 +5,7 @@
%%% Created : 19 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_delegation.erl b/src/mod_delegation.erl
index 45e44c497..532463e3a 100644
--- a/src/mod_delegation.erl
+++ b/src/mod_delegation.erl
@@ -4,7 +4,7 @@
%%% Purpose : XEP-0355: Namespace Delegation
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_disco.erl b/src/mod_disco.erl
index 3b394b8dd..f0d23a0ca 100644
--- a/src/mod_disco.erl
+++ b/src/mod_disco.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_echo.erl b/src/mod_echo.erl
index 26cf60611..eaa630ac7 100644
--- a/src/mod_echo.erl
+++ b/src/mod_echo.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_fail2ban.erl b/src/mod_fail2ban.erl
index 11004efef..141462566 100644
--- a/src/mod_fail2ban.erl
+++ b/src/mod_fail2ban.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Aug 2014 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2014-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2014-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_http_api.erl b/src/mod_http_api.erl
index 3fb0d5981..8cc80982a 100644
--- a/src/mod_http_api.erl
+++ b/src/mod_http_api.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Sep 2014 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -80,6 +80,7 @@
-include("xmpp.hrl").
-include("logger.hrl").
-include("ejabberd_http.hrl").
+-include("ejabberd_stacktrace.hrl").
-define(DEFAULT_API_VERSION, 0).
@@ -136,39 +137,43 @@ depends(_Host, _Opts) ->
%% basic auth
%% ----------
-extract_auth(#request{auth = HTTPAuth, ip = {IP, _}}) ->
+extract_auth(#request{auth = HTTPAuth, ip = {IP, _}, opts = Opts}) ->
Info = case HTTPAuth of
- {SJID, Pass} ->
- try jid:decode(SJID) of
+ {SJID, Pass} ->
+ try jid:decode(SJID) of
#jid{luser = User, lserver = Server} ->
- case ejabberd_auth:check_password(User, <<"">>, Server, Pass) of
+ case ejabberd_auth:check_password(User, <<"">>, Server, Pass) of
true ->
#{usr => {User, Server, <<"">>}, caller_server => Server};
false ->
{error, invalid_auth}
- end
- catch _:{bad_jid, _} ->
- {error, invalid_auth}
- end;
- {oauth, Token, _} ->
+ end
+ catch _:{bad_jid, _} ->
+ {error, invalid_auth}
+ end;
+ {oauth, Token, _} ->
case ejabberd_oauth:check_token(Token) of
{ok, {U, S}, Scope} ->
#{usr => {U, S, <<"">>}, oauth_scope => Scope, caller_server => S};
{false, Reason} ->
{error, Reason}
- end;
- _ ->
+ end;
+ invalid ->
+ {error, invalid_auth};
+ _ ->
#{}
- end,
+ end,
case Info of
Map when is_map(Map) ->
- Map#{caller_module => ?MODULE, ip => IP};
+ Tag = proplists:get_value(tag, Opts, <<>>),
+ Map#{caller_module => ?MODULE, ip => IP, tag => Tag};
_ ->
?DEBUG("Invalid auth data: ~p", [Info]),
Info
end;
-extract_auth(#request{ip = IP}) ->
- #{ip => IP, caller_module => ?MODULE}.
+extract_auth(#request{ip = IP, opts = Opts}) ->
+ Tag = proplists:get_value(tag, Opts, <<>>),
+ #{ip => IP, caller_module => ?MODULE, tag => Tag}.
%% ------------------
%% command processing
@@ -192,9 +197,8 @@ process([Call], #request{method = 'POST', data = Data, ip = IPPort} = Req) ->
_:{error,{_,invalid_json}} = _Err ->
?DEBUG("Bad Request: ~p", [_Err]),
badrequest_response(<<"Invalid JSON input">>);
- _:_Error ->
- St = erlang:get_stacktrace(),
- ?DEBUG("Bad Request: ~p ~p", [_Error, St]),
+ ?EX_RULE(_Class, _Error, Stack) ->
+ ?DEBUG("Bad Request: ~p ~p", [_Error, ?EX_STACK(Stack)]),
badrequest_response()
end;
process([Call], #request{method = 'GET', q = Data, ip = {IP, _}} = Req) ->
@@ -210,9 +214,8 @@ process([Call], #request{method = 'GET', q = Data, ip = {IP, _}} = Req) ->
%% TODO We need to refactor to remove redundant error return formatting
throw:{error, unknown_command} ->
json_format({404, 44, <<"Command not found.">>});
- _:_Error ->
- St = erlang:get_stacktrace(),
- ?DEBUG("Bad Request: ~p ~p", [_Error, St]),
+ ?EX_RULE(_, _Error, Stack) ->
+ ?DEBUG("Bad Request: ~p ~p", [_Error, ?EX_STACK(Stack)]),
badrequest_response()
end;
process([_Call], #request{method = 'OPTIONS', data = <<>>}) ->
@@ -302,9 +305,8 @@ handle(Call, Auth, Args, Version) when is_atom(Call), is_list(Args) ->
{400, misc:atom_to_binary(Error)};
throw:Msg when is_list(Msg); is_binary(Msg) ->
{400, iolist_to_binary(Msg)};
- _Error ->
- St = erlang:get_stacktrace(),
- ?ERROR_MSG("REST API Error: ~p ~p", [_Error, St]),
+ ?EX_RULE(Class, Error, Stack) ->
+ ?ERROR_MSG("REST API Error: ~p:~p ~p", [Class, Error, ?EX_STACK(Stack)]),
{500, <<"internal_error">>}
end;
{error, Msg} ->
@@ -355,7 +357,10 @@ format_args(Args, ArgsFormat) ->
{Args, []}, ArgsFormat),
case ArgsRemaining of
[] -> R;
- L when is_list(L) -> exit({additional_unused_args, L})
+ L when is_list(L) ->
+ throw({invalid_parameter,
+ io_lib:format("Request have unknown arguments: ~w",
+ [[N || {N, _} <- L]])})
end.
format_arg({Elements},
diff --git a/src/mod_http_fileserver.erl b/src/mod_http_fileserver.erl
index 47cf31bce..d34d7193e 100644
--- a/src/mod_http_fileserver.erl
+++ b/src/mod_http_fileserver.erl
@@ -5,7 +5,7 @@
%%% Created :
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl
index fe3379f16..66df9f91d 100644
--- a/src/mod_http_upload.erl
+++ b/src/mod_http_upload.erl
@@ -5,7 +5,7 @@
%%% Created : 20 Aug 2015 by Holger Weiss <holger@zedat.fu-berlin.de>
%%%
%%%
-%%% ejabberd, Copyright (C) 2015-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2015-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_http_upload_quota.erl b/src/mod_http_upload_quota.erl
index f27c0222e..10f7831bd 100644
--- a/src/mod_http_upload_quota.erl
+++ b/src/mod_http_upload_quota.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Oct 2015 by Holger Weiss <holger@zedat.fu-berlin.de>
%%%
%%%
-%%% ejabberd, Copyright (C) 2015-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2015-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_last.erl b/src/mod_last.erl
index f0651b054..dcae1c27e 100644
--- a/src/mod_last.erl
+++ b/src/mod_last.erl
@@ -5,7 +5,7 @@
%%% Created : 24 Oct 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_last_mnesia.erl b/src/mod_last_mnesia.erl
index de5e448d3..d8d5296f3 100644
--- a/src/mod_last_mnesia.erl
+++ b/src/mod_last_mnesia.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_last_riak.erl b/src/mod_last_riak.erl
index ca41a6a06..cd5dd43d4 100644
--- a/src/mod_last_riak.erl
+++ b/src/mod_last_riak.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_last_sql.erl b/src/mod_last_sql.erl
index e8168f3f2..85f3e3895 100644
--- a/src/mod_last_sql.erl
+++ b/src/mod_last_sql.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_legacy_auth.erl b/src/mod_legacy_auth.erl
index 19b905ad8..c4614d74c 100644
--- a/src/mod_legacy_auth.erl
+++ b/src/mod_legacy_auth.erl
@@ -2,7 +2,7 @@
%%% Created : 11 Dec 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_mam.erl b/src/mod_mam.erl
index 32c13c875..f1f481260 100644
--- a/src/mod_mam.erl
+++ b/src/mod_mam.erl
@@ -5,7 +5,7 @@
%%% Created : 4 Jul 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2013-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2013-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -41,6 +41,7 @@
delete_old_messages/2, get_commands_spec/0, msg_to_el/4,
get_room_config/4, set_room_option/3, offline_message/1, export/1,
mod_options/1, remove_mam_for_user_with_peer/3, remove_mam_for_user/2,
+ is_empty_for_user/2, is_empty_for_room/3, check_create_room/4,
process_iq/3, store_mam_message/7, make_id/0]).
-include("xmpp.hrl").
@@ -53,6 +54,7 @@
-define(MAX_PAGE_SIZE, 250).
-type c2s_state() :: ejabberd_c2s:state().
+-type count() :: non_neg_integer() | undefined.
-callback init(binary(), gen_mod:opts()) -> any().
-callback remove_user(binary(), binary()) -> any().
@@ -64,13 +66,16 @@
-callback store(xmlel(), binary(), {binary(), binary()}, chat | groupchat,
jid(), binary(), recv | send, integer()) -> ok | any().
-callback write_prefs(binary(), binary(), #archive_prefs{}, binary()) -> ok | any().
--callback get_prefs(binary(), binary()) -> {ok, #archive_prefs{}} | error.
+-callback get_prefs(binary(), binary()) -> {ok, #archive_prefs{}} | error | {error, db_failure}.
-callback select(binary(), jid(), jid(), mam_query:result(),
#rsm_set{} | undefined, chat | groupchat) ->
- {[{binary(), non_neg_integer(), xmlel()}], boolean(), non_neg_integer()}.
+ {[{binary(), non_neg_integer(), xmlel()}], boolean(), count()} |
+ {error, db_failure}.
-callback use_cache(binary()) -> boolean().
-callback cache_nodes(binary()) -> [node()].
-callback remove_from_archive(binary(), binary(), jid() | none) -> ok | {error, any()}.
+-callback is_empty_for_user(binary(), binary()) -> boolean().
+-callback is_empty_for_room(binary(), binary(), binary()) -> boolean().
-optional_callbacks([use_cache/1, cache_nodes/1]).
@@ -90,44 +95,54 @@ start(Host, Opts) ->
ok
end,
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
- Mod:init(Host, Opts),
- init_cache(Mod, Host, Opts),
- register_iq_handlers(Host),
- ejabberd_hooks:add(sm_receive_packet, Host, ?MODULE,
- sm_receive_packet, 50),
- ejabberd_hooks:add(user_receive_packet, Host, ?MODULE,
- user_receive_packet, 88),
- ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
- user_send_packet, 88),
- ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
- user_send_packet_strip_tag, 500),
- ejabberd_hooks:add(offline_message_hook, Host, ?MODULE,
- offline_message, 50),
- ejabberd_hooks:add(muc_filter_message, Host, ?MODULE,
- muc_filter_message, 50),
- ejabberd_hooks:add(muc_process_iq, Host, ?MODULE,
- muc_process_iq, 50),
- ejabberd_hooks:add(disco_sm_features, Host, ?MODULE,
- disco_sm_features, 50),
- ejabberd_hooks:add(remove_user, Host, ?MODULE,
- remove_user, 50),
- ejabberd_hooks:add(remove_room, Host, ?MODULE,
- remove_room, 50),
- ejabberd_hooks:add(get_room_config, Host, ?MODULE,
- get_room_config, 50),
- ejabberd_hooks:add(set_room_option, Host, ?MODULE,
- set_room_option, 50),
- ejabberd_hooks:add(store_mam_message, Host, ?MODULE,
- store_mam_message, 100),
- case gen_mod:get_opt(assume_mam_usage, Opts) of
- true ->
- ejabberd_hooks:add(message_is_archived, Host, ?MODULE,
- message_is_archived, 50);
- false ->
- ok
- end,
- ejabberd_commands:register_commands(get_commands_spec()),
- ok.
+ case Mod:init(Host, Opts) of
+ ok ->
+ init_cache(Mod, Host, Opts),
+ register_iq_handlers(Host),
+ ejabberd_hooks:add(sm_receive_packet, Host, ?MODULE,
+ sm_receive_packet, 50),
+ ejabberd_hooks:add(user_receive_packet, Host, ?MODULE,
+ user_receive_packet, 88),
+ ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
+ user_send_packet, 88),
+ ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
+ user_send_packet_strip_tag, 500),
+ ejabberd_hooks:add(offline_message_hook, Host, ?MODULE,
+ offline_message, 50),
+ ejabberd_hooks:add(muc_filter_message, Host, ?MODULE,
+ muc_filter_message, 50),
+ ejabberd_hooks:add(muc_process_iq, Host, ?MODULE,
+ muc_process_iq, 50),
+ ejabberd_hooks:add(disco_sm_features, Host, ?MODULE,
+ disco_sm_features, 50),
+ ejabberd_hooks:add(remove_user, Host, ?MODULE,
+ remove_user, 50),
+ ejabberd_hooks:add(get_room_config, Host, ?MODULE,
+ get_room_config, 50),
+ ejabberd_hooks:add(set_room_option, Host, ?MODULE,
+ set_room_option, 50),
+ ejabberd_hooks:add(store_mam_message, Host, ?MODULE,
+ store_mam_message, 100),
+ case gen_mod:get_opt(assume_mam_usage, Opts) of
+ true ->
+ ejabberd_hooks:add(message_is_archived, Host, ?MODULE,
+ message_is_archived, 50);
+ false ->
+ ok
+ end,
+ case gen_mod:get_opt(clear_archive_on_room_destroy, Opts) of
+ true ->
+ ejabberd_hooks:add(remove_room, Host, ?MODULE,
+ remove_room, 50);
+ false ->
+ ejabberd_hooks:add(check_create_room, Host, ?MODULE,
+ check_create_room, 50)
+ end,
+ ejabberd_commands:register_commands(get_commands_spec()),
+ ok;
+ Err ->
+ Err
+ end.
use_cache(Mod, Host) ->
case erlang:function_exported(Mod, use_cache, 2) of
@@ -178,8 +193,6 @@ stop(Host) ->
disco_sm_features, 50),
ejabberd_hooks:delete(remove_user, Host, ?MODULE,
remove_user, 50),
- ejabberd_hooks:delete(remove_room, Host, ?MODULE,
- remove_room, 50),
ejabberd_hooks:delete(get_room_config, Host, ?MODULE,
get_room_config, 50),
ejabberd_hooks:delete(set_room_option, Host, ?MODULE,
@@ -193,6 +206,14 @@ stop(Host) ->
false ->
ok
end,
+ case gen_mod:get_module_opt(Host, ?MODULE, clear_archive_on_room_destroy) of
+ true ->
+ ejabberd_hooks:delete(remove_room, Host, ?MODULE,
+ remove_room, 50);
+ false ->
+ ejabberd_hooks:delete(check_create_room, Host, ?MODULE,
+ check_create_room, 50)
+ end,
case gen_mod:is_loaded_elsewhere(Host, ?MODULE) of
false ->
ejabberd_commands:unregister_commands(get_commands_spec());
@@ -563,6 +584,24 @@ export(LServer) ->
Mod = gen_mod:db_mod(LServer, ?MODULE),
Mod:export(LServer).
+-spec is_empty_for_user(binary(), binary()) -> boolean().
+is_empty_for_user(User, Server) ->
+ LUser = jid:nodeprep(User),
+ LServer = jid:nameprep(Server),
+ Mod = gen_mod:db_mod(LServer, ?MODULE),
+ Mod:is_empty_for_user(LUser, LServer).
+
+-spec is_empty_for_room(binary(), binary(), binary()) -> boolean().
+is_empty_for_room(LServer, Name, Host) ->
+ LName = jid:nodeprep(Name),
+ LHost = jid:nameprep(Host),
+ Mod = gen_mod:db_mod(LServer, ?MODULE),
+ Mod:is_empty_for_room(LServer, LName, LHost).
+
+-spec check_create_room(boolean(), binary(), binary(), binary()) -> boolean().
+check_create_room(Acc, ServerHost, RoomID, Host) ->
+ Acc and is_empty_for_room(ServerHost, RoomID, Host).
+
%%%===================================================================
%%% Internal functions
%%%===================================================================
@@ -603,37 +642,48 @@ process_iq(#iq{from = #jid{luser = LUser, lserver = LServer},
xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
end;
process_iq(#iq{from = #jid{luser = LUser, lserver = LServer},
- to = #jid{lserver = LServer},
+ to = #jid{lserver = LServer}, lang = Lang,
type = get, sub_els = [#mam_prefs{xmlns = NS}]} = IQ) ->
- Prefs = get_prefs(LUser, LServer),
- PrefsEl = prefs_el(Prefs#archive_prefs.default,
- Prefs#archive_prefs.always,
- Prefs#archive_prefs.never,
- NS),
- xmpp:make_iq_result(IQ, PrefsEl);
+ case get_prefs(LUser, LServer) of
+ {ok, Prefs} ->
+ PrefsEl = prefs_el(Prefs#archive_prefs.default,
+ Prefs#archive_prefs.always,
+ Prefs#archive_prefs.never,
+ NS),
+ xmpp:make_iq_result(IQ, PrefsEl);
+ {error, _} ->
+ Txt = <<"Database failure">>,
+ xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
+ end;
process_iq(IQ) ->
xmpp:make_error(IQ, xmpp:err_not_allowed()).
process_iq(LServer, #iq{from = #jid{luser = LUser}, lang = Lang,
sub_els = [SubEl]} = IQ, MsgType) ->
- case MsgType of
- chat ->
- maybe_activate_mam(LUser, LServer);
- _ ->
- ok
- end,
- case SubEl of
- #mam_query{rsm = #rsm_set{index = I}} when is_integer(I) ->
- Txt = <<"Unsupported <index/> element">>,
- xmpp:make_error(IQ, xmpp:err_feature_not_implemented(Txt, Lang));
- #mam_query{rsm = RSM, xmlns = NS} ->
- case parse_query(SubEl, Lang) of
- {ok, Query} ->
- NewRSM = limit_max(RSM, NS),
- select_and_send(LServer, Query, NewRSM, IQ, MsgType);
- {error, Err} ->
- xmpp:make_error(IQ, Err)
- end
+ Ret = case MsgType of
+ chat ->
+ maybe_activate_mam(LUser, LServer);
+ _ ->
+ ok
+ end,
+ case Ret of
+ ok ->
+ case SubEl of
+ #mam_query{rsm = #rsm_set{index = I}} when is_integer(I) ->
+ Txt = <<"Unsupported <index/> element">>,
+ xmpp:make_error(IQ, xmpp:err_feature_not_implemented(Txt, Lang));
+ #mam_query{rsm = RSM, xmlns = NS} ->
+ case parse_query(SubEl, Lang) of
+ {ok, Query} ->
+ NewRSM = limit_max(RSM, NS),
+ select_and_send(LServer, Query, NewRSM, IQ, MsgType);
+ {error, Err} ->
+ xmpp:make_error(IQ, Err)
+ end
+ end;
+ {error, _} ->
+ Txt = <<"Database failure">>,
+ xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
end.
-spec should_archive(message(), binary()) -> boolean().
@@ -827,17 +877,21 @@ may_enter_room(From, MUCState) ->
-spec store_msg(message(), binary(), binary(), jid(), send | recv)
-> ok | pass | any().
store_msg(Pkt, LUser, LServer, Peer, Dir) ->
- Prefs = get_prefs(LUser, LServer),
- case {should_archive_peer(LUser, LServer, Prefs, Peer), Pkt} of
- {true, #message{meta = #{sm_copy := true}}} ->
- ok; % Already stored.
- {true, _} ->
- case ejabberd_hooks:run_fold(store_mam_message, LServer, Pkt,
- [LUser, LServer, Peer, <<"">>, chat, Dir]) of
- #message{} -> ok;
- _ -> pass
+ case get_prefs(LUser, LServer) of
+ {ok, Prefs} ->
+ case {should_archive_peer(LUser, LServer, Prefs, Peer), Pkt} of
+ {true, #message{meta = #{sm_copy := true}}} ->
+ ok; % Already stored.
+ {true, _} ->
+ case ejabberd_hooks:run_fold(store_mam_message, LServer, Pkt,
+ [LUser, LServer, Peer, <<"">>, chat, Dir]) of
+ #message{} -> ok;
+ _ -> pass
+ end;
+ {false, _} ->
+ pass
end;
- {false, _} ->
+ {error, _} ->
pass
end.
@@ -896,18 +950,20 @@ get_prefs(LUser, LServer) ->
end,
case Res of
{ok, Prefs} ->
- Prefs;
+ {ok, Prefs};
+ {error, _} ->
+ {error, db_failure};
error ->
ActivateOpt = gen_mod:get_module_opt(
LServer, ?MODULE,
request_activates_archiving),
case ActivateOpt of
true ->
- #archive_prefs{us = {LUser, LServer}, default = never};
+ {ok, #archive_prefs{us = {LUser, LServer}, default = never}};
false ->
Default = gen_mod:get_module_opt(
LServer, ?MODULE, default),
- #archive_prefs{us = {LUser, LServer}, default = Default}
+ {ok, #archive_prefs{us = {LUser, LServer}, default = Default}}
end
end.
@@ -936,6 +992,8 @@ maybe_activate_mam(LUser, LServer) ->
case Res of
{ok, _Prefs} ->
ok;
+ {error, _} ->
+ {error, db_failure};
error ->
Default = gen_mod:get_module_opt(
LServer, ?MODULE, default),
@@ -946,15 +1004,21 @@ maybe_activate_mam(LUser, LServer) ->
end.
select_and_send(LServer, Query, RSM, #iq{from = From, to = To} = IQ, MsgType) ->
- {Msgs, IsComplete, Count} =
- case MsgType of
- chat ->
- select(LServer, From, From, Query, RSM, MsgType);
- _ ->
- select(LServer, From, To, Query, RSM, MsgType)
- end,
- SortedMsgs = lists:keysort(2, Msgs),
- send(SortedMsgs, Count, IsComplete, IQ).
+ Ret = case MsgType of
+ chat ->
+ select(LServer, From, From, Query, RSM, MsgType);
+ _ ->
+ select(LServer, From, To, Query, RSM, MsgType)
+ end,
+ case Ret of
+ {Msgs, IsComplete, Count} ->
+ SortedMsgs = lists:keysort(2, Msgs),
+ send(SortedMsgs, Count, IsComplete, IQ);
+ {error, _} ->
+ Txt = <<"Database failure">>,
+ Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang),
+ xmpp:make_error(IQ, Err)
+ end.
select(_LServer, JidRequestor, JidArchive, Query, RSM,
{groupchat, _Role, #state{config = #config{mam = false},
@@ -1055,7 +1119,7 @@ maybe_update_from_to(Pkt, _JidRequestor, _JidArchive, _Peer, _MsgType, _Nick) ->
Pkt.
-spec send([{binary(), integer(), xmlel()}],
- non_neg_integer(), boolean(), iq()) -> iq() | ignore.
+ count(), boolean(), iq()) -> iq() | ignore.
send(Msgs, Count, IsComplete,
#iq{from = From, to = To,
sub_els = [#mam_query{id = QID, xmlns = NS}]} = IQ) ->
@@ -1093,7 +1157,7 @@ send(Msgs, Count, IsComplete,
ignore
end.
--spec make_rsm_out([{binary(), integer(), xmlel()}], non_neg_integer()) -> rsm_set().
+-spec make_rsm_out([{binary(), integer(), xmlel()}], count()) -> rsm_set().
make_rsm_out([], Count) ->
#rsm_set{count = Count};
make_rsm_out([{FirstID, _, _}|_] = Msgs, Count) ->
@@ -1191,6 +1255,8 @@ mod_opt_type(default) ->
(roster) -> roster
end;
mod_opt_type(request_activates_archiving) ->
+ fun (B) when is_boolean(B) -> B end;
+mod_opt_type(clear_archive_on_room_destroy) ->
fun (B) when is_boolean(B) -> B end.
mod_options(Host) ->
@@ -1198,6 +1264,7 @@ mod_options(Host) ->
{default, never},
{request_activates_archiving, false},
{compress_xml, false},
+ {clear_archive_on_room_destroy, true},
{db_type, ejabberd_config:default_db(Host, ?MODULE)},
{use_cache, ejabberd_config:use_cache(Host)},
{cache_size, ejabberd_config:cache_size(Host)},
diff --git a/src/mod_mam_mnesia.erl b/src/mod_mam_mnesia.erl
index 55154f6bb..f94dd2e49 100644
--- a/src/mod_mam_mnesia.erl
+++ b/src/mod_mam_mnesia.erl
@@ -4,7 +4,7 @@
%%% Created : 15 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -28,7 +28,8 @@
%% API
-export([init/2, remove_user/2, remove_room/3, delete_old_messages/3,
- extended_fields/0, store/8, write_prefs/4, get_prefs/2, select/6, remove_from_archive/3]).
+ extended_fields/0, store/8, write_prefs/4, get_prefs/2, select/6, remove_from_archive/3,
+ is_empty_for_user/2, is_empty_for_room/3]).
-include_lib("stdlib/include/ms_transform.hrl").
-include("xmpp.hrl").
@@ -48,13 +49,20 @@
%%% API
%%%===================================================================
init(_Host, _Opts) ->
- ejabberd_mnesia:create(?MODULE, archive_msg,
+ try
+ {atomic, _} = ejabberd_mnesia:create(
+ ?MODULE, archive_msg,
[{disc_only_copies, [node()]},
{type, bag},
{attributes, record_info(fields, archive_msg)}]),
- ejabberd_mnesia:create(?MODULE, archive_prefs,
+ {atomic, _} = ejabberd_mnesia:create(
+ ?MODULE, archive_prefs,
[{disc_only_copies, [node()]},
- {attributes, record_info(fields, archive_prefs)}]).
+ {attributes, record_info(fields, archive_prefs)}]),
+ ok
+ catch _:{badmatch, _} ->
+ {error, db_failure}
+ end.
remove_user(LUser, LServer) ->
US = {LUser, LServer},
@@ -191,6 +199,13 @@ select(_LServer, JidRequestor,
erlang:garbage_collect(),
Result.
+is_empty_for_user(LUser, LServer) ->
+ not lists:member({LUser, LServer},
+ mnesia:dirty_all_keys(archive_msg)).
+
+is_empty_for_room(_LServer, LName, LHost) ->
+ is_empty_for_user(LName, LHost).
+
%%%===================================================================
%%% Internal functions
%%%===================================================================
diff --git a/src/mod_mam_sql.erl b/src/mod_mam_sql.erl
index 4fac259bc..48112842c 100644
--- a/src/mod_mam_sql.erl
+++ b/src/mod_mam_sql.erl
@@ -4,7 +4,7 @@
%%% Created : 15 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -30,7 +30,8 @@
%% API
-export([init/2, remove_user/2, remove_room/3, delete_old_messages/3,
- extended_fields/0, store/8, write_prefs/4, get_prefs/2, select/6, export/1, remove_from_archive/3]).
+ extended_fields/0, store/8, write_prefs/4, get_prefs/2, select/6, export/1, remove_from_archive/3,
+ is_empty_for_user/2, is_empty_for_room/3]).
-include_lib("stdlib/include/ms_transform.hrl").
-include("xmpp.hrl").
@@ -264,6 +265,23 @@ export(_Server) ->
[]
end}].
+is_empty_for_user(LUser, LServer) ->
+ case ejabberd_sql:sql_query(
+ LServer,
+ ?SQL("select @(count(*))d from archive"
+ " where username=%(LUser)s and %(LServer)H")) of
+ {selected, [{Res}]} ->
+ case Res of
+ 0 -> true;
+ _ -> false
+ end;
+ _ -> false
+ end.
+
+is_empty_for_room(LServer, LName, LHost) ->
+ LUser = jid:encode({LName, LHost, <<>>}),
+ is_empty_for_user(LUser, LServer).
+
%%%===================================================================
%%% Internal functions
%%%===================================================================
diff --git a/src/mod_metrics.erl b/src/mod_metrics.erl
index 282dca7ef..a84d92b9c 100644
--- a/src/mod_metrics.erl
+++ b/src/mod_metrics.erl
@@ -5,7 +5,7 @@
%%% Created : 22 Oct 2015 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_muc.erl b/src/mod_muc.erl
index 8a80e3012..ae3c6f9f7 100644
--- a/src/mod_muc.erl
+++ b/src/mod_muc.erl
@@ -5,7 +5,7 @@
%%% Created : 19 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -65,7 +65,8 @@
iq_set_register_info/5,
count_online_rooms_by_user/3,
get_online_rooms_by_user/3,
- can_use_nick/4]).
+ can_use_nick/4,
+ check_create_room/4]).
-export([init/1, handle_call/3, handle_cast/2,
handle_info/2, terminate/2, code_change/3,
@@ -112,10 +113,14 @@
%% API
%%====================================================================
start(Host, Opts) ->
+ ejabberd_hooks:add(check_create_room, Host, ?MODULE,
+ check_create_room, 50),
gen_mod:start_child(?MODULE, Host, Opts).
stop(Host) ->
Rooms = shutdown_rooms(Host),
+ ejabberd_hooks:delete(check_create_room, Host, ?MODULE,
+ check_create_room, 50),
gen_mod:stop_child(?MODULE, Host),
{wait, Rooms}.
@@ -354,6 +359,7 @@ init_state(Host, Opts) ->
AccessCreate = gen_mod:get_opt(access_create, Opts),
AccessAdmin = gen_mod:get_opt(access_admin, Opts),
AccessPersistent = gen_mod:get_opt(access_persistent, Opts),
+ AccessMam = gen_mod:get_opt(access_mam, Opts),
HistorySize = gen_mod:get_opt(history_size, Opts),
MaxRoomsDiscoItems = gen_mod:get_opt(max_rooms_discoitems, Opts),
DefRoomOpts = gen_mod:get_opt(default_room_options, Opts),
@@ -361,7 +367,7 @@ init_state(Host, Opts) ->
RoomShaper = gen_mod:get_opt(room_shaper, Opts),
#state{hosts = MyHosts,
server_host = Host,
- access = {Access, AccessCreate, AccessAdmin, AccessPersistent},
+ access = {Access, AccessCreate, AccessAdmin, AccessPersistent, AccessMam},
default_room_opts = DefRoomOpts,
queue_type = QueueType,
history_size = HistorySize,
@@ -392,7 +398,7 @@ unregister_iq_handlers(Host) ->
do_route(Host, ServerHost, Access, HistorySize, RoomShaper,
From, To, Packet, DefRoomOpts, _MaxRoomsDiscoItems, QueueType) ->
- {AccessRoute, _AccessCreate, _AccessAdmin, _AccessPersistent} = Access,
+ {AccessRoute, _AccessCreate, _AccessAdmin, _AccessPersistent, _AccessMam} = Access,
case acl:match_rule(ServerHost, AccessRoute, From) of
allow ->
do_route1(Host, ServerHost, Access, HistorySize, RoomShaper,
@@ -411,7 +417,7 @@ do_route1(_Host, _ServerHost, _Access, _HistorySize, _RoomShaper,
do_route1(Host, ServerHost, Access, _HistorySize, _RoomShaper,
From, #jid{luser = <<"">>, lresource = <<"">>} = _To,
#message{lang = Lang, body = Body, type = Type} = Packet, _, _) ->
- {_AccessRoute, _AccessCreate, AccessAdmin, _AccessPersistent} = Access,
+ {_AccessRoute, _AccessCreate, AccessAdmin, _AccessPersistent, _AccessMam} = Access,
if Type == error ->
ok;
true ->
@@ -432,7 +438,7 @@ do_route1(_Host, _ServerHost, _Access, _HistorySize, _RoomShaper,
ejabberd_router:route_error(Packet, Err);
do_route1(Host, ServerHost, Access, HistorySize, RoomShaper,
From, To, Packet, DefRoomOpts, QueueType) ->
- {_AccessRoute, AccessCreate, _AccessAdmin, _AccessPersistent} = Access,
+ {_AccessRoute, AccessCreate, _AccessAdmin, _AccessPersistent, _AccessMam} = Access,
{Room, _, Nick} = jid:tolower(To),
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
case RMod:find_online_room(ServerHost, Room, Host) of
@@ -441,7 +447,9 @@ do_route1(Host, ServerHost, Access, HistorySize, RoomShaper,
true ->
case check_user_can_create_room(
ServerHost, AccessCreate, From, Room) and
- check_create_roomid(ServerHost, Room) of
+ ejabberd_hooks:run_fold(check_create_room,
+ ServerHost, true,
+ [ServerHost, Room, Host]) of
true ->
{ok, Pid} = start_new_room(
Host, ServerHost, Access,
@@ -610,9 +618,10 @@ check_user_can_create_room(ServerHost, AccessCreate,
_ -> false
end.
-check_create_roomid(ServerHost, RoomID) ->
+check_create_room(Acc, ServerHost, RoomID, _Host) ->
Max = gen_mod:get_module_opt(ServerHost, ?MODULE, max_room_id),
Regexp = gen_mod:get_module_opt(ServerHost, ?MODULE, regexp_room_id),
+ Acc and
(byte_size(RoomID) =< Max) and
(re:run(RoomID, Regexp, [unicode, {capture, none}]) == match).
@@ -884,6 +893,8 @@ mod_opt_type(access_create) ->
fun acl:access_rules_validator/1;
mod_opt_type(access_persistent) ->
fun acl:access_rules_validator/1;
+mod_opt_type(access_mam) ->
+ fun acl:access_rules_validator/1;
mod_opt_type(access_register) ->
fun acl:access_rules_validator/1;
mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
@@ -985,13 +996,14 @@ mod_opt_type({default_room_options, presence_broadcast}) ->
end, L)
end;
mod_opt_type({default_room_options, lang}) ->
- fun iolist_to_binary/1.
+ fun xmpp_lang:check/1.
mod_options(Host) ->
[{access, all},
{access_admin, none},
{access_create, all},
{access_persistent, all},
+ {access_mam, all},
{access_register, all},
{db_type, ejabberd_config:default_db(Host, ?MODULE)},
{ram_db_type, ejabberd_config:default_ram_db(Host, ?MODULE)},
diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl
index c050d4fc2..494a4ef3f 100644
--- a/src/mod_muc_admin.erl
+++ b/src/mod_muc_admin.erl
@@ -5,7 +5,7 @@
%%% Created : 8 Sep 2007 by Badlop <badlop@ono.com>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -34,6 +34,7 @@
create_room_with_opts/4, create_room/3, destroy_room/2,
create_rooms_file/1, destroy_rooms_file/1,
rooms_unused_list/2, rooms_unused_destroy/2,
+ rooms_empty_list/1, rooms_empty_destroy/1,
get_user_rooms/2, get_room_occupants/2,
get_room_occupants_number/2, send_direct_invitation/5,
change_room_option/4, get_room_options/2,
@@ -116,14 +117,14 @@ get_commands_spec() ->
module = ?MODULE, function = muc_register_nick,
args_desc = ["Nick", "User JID", "Server Host"],
args_example = [<<"Tim">>, <<"tim@example.org">>, <<"example.org">>],
- args = [{nick, binary}, {jid, binary}, {serverhost, binary}],
+ args = [{nick, binary}, {jid, binary}, {host, binary}],
result = {res, rescode}},
#ejabberd_commands{name = muc_unregister_nick, tags = [muc],
desc = "Unregister the nick registered by that account in the MUC service",
module = ?MODULE, function = muc_unregister_nick,
args_desc = ["User JID", "MUC service"],
args_example = [<<"tim@example.org">>, <<"example.org">>],
- args = [{jid, binary}, {serverhost, binary}],
+ args = [{jid, binary}, {host, binary}],
result = {res, rescode}},
#ejabberd_commands{name = create_room, tags = [muc_room],
@@ -173,6 +174,8 @@ get_commands_spec() ->
result = {res, rescode}},
#ejabberd_commands{name = rooms_unused_list, tags = [muc],
desc = "List the rooms that are unused for many days in host",
+ longdesc = "The room recent history is used, so it's recommended "
+ " to wait a few days after service start before running this.",
module = ?MODULE, function = rooms_unused_list,
args_desc = ["Server host", "Number of days"],
args_example = ["example.com", 31],
@@ -182,6 +185,8 @@ get_commands_spec() ->
result = {rooms, {list, {room, string}}}},
#ejabberd_commands{name = rooms_unused_destroy, tags = [muc],
desc = "Destroy the rooms that are unused for many days in host",
+ longdesc = "The room recent history is used, so it's recommended "
+ " to wait a few days after service start before running this.",
module = ?MODULE, function = rooms_unused_destroy,
args_desc = ["Server host", "Number of days"],
args_example = ["example.com", 31],
@@ -190,6 +195,25 @@ get_commands_spec() ->
args = [{host, binary}, {days, integer}],
result = {rooms, {list, {room, string}}}},
+ #ejabberd_commands{name = rooms_empty_list, tags = [muc],
+ desc = "List the rooms that have no messages in archive",
+ module = ?MODULE, function = rooms_empty_list,
+ args_desc = ["Server host"],
+ args_example = ["example.com"],
+ result_desc = "List of empty rooms",
+ result_example = ["room1@muc.example.com", "room2@muc.example.com"],
+ args = [{host, binary}],
+ result = {rooms, {list, {room, string}}}},
+ #ejabberd_commands{name = rooms_empty_destroy, tags = [muc],
+ desc = "Destroy the rooms that have no messages in archive",
+ module = ?MODULE, function = rooms_empty_destroy,
+ args_desc = ["Server host"],
+ args_example = ["example.com"],
+ result_desc = "List of empty rooms that have been destroyed",
+ result_example = ["room1@muc.example.com", "room2@muc.example.com"],
+ args = [{host, binary}],
+ result = {rooms, {list, {room, string}}}},
+
#ejabberd_commands{name = get_user_rooms, tags = [muc],
desc = "Get the list of rooms where this user is occupant",
module = ?MODULE, function = get_user_rooms,
@@ -263,9 +287,9 @@ get_commands_spec() ->
#ejabberd_commands{name = subscribe_room, tags = [muc_room],
desc = "Subscribe to a MUC conference",
module = ?MODULE, function = subscribe_room,
- args_desc = ["Full JID, including some resource", "a user's nick",
+ args_desc = ["User JID", "a user's nick",
"the room to subscribe", "nodes separated by commas: ,"],
- args_example = ["tom@localhost/dummy", "Tom", "room1@conference.localhost",
+ args_example = ["tom@localhost", "Tom", "room1@conference.localhost",
"urn:xmpp:mucsub:nodes:messages,urn:xmpp:mucsub:nodes:affiliations"],
result_desc = "The list of nodes that has subscribed",
result_example = ["urn:xmpp:mucsub:nodes:messages",
@@ -604,6 +628,7 @@ create_room_with_opts(Name1, Host1, ServerHost, CustomRoomOpts) ->
AcCreate = gen_mod:get_module_opt(ServerHost, mod_muc, access_create),
AcAdmin = gen_mod:get_module_opt(ServerHost, mod_muc, access_admin),
AcPer = gen_mod:get_module_opt(ServerHost, mod_muc, access_persistent),
+ AcMam = gen_mod:get_module_opt(ServerHost, mod_muc, access_mam),
HistorySize = gen_mod:get_module_opt(ServerHost, mod_muc, history_size),
RoomShaper = gen_mod:get_module_opt(ServerHost, mod_muc, room_shaper),
QueueType = gen_mod:get_module_opt(ServerHost, mod_muc, queue_type),
@@ -615,7 +640,7 @@ create_room_with_opts(Name1, Host1, ServerHost, CustomRoomOpts) ->
{ok, Pid} = mod_muc_room:start(
Host,
ServerHost,
- {Access, AcCreate, AcAdmin, AcPer},
+ {Access, AcCreate, AcAdmin, AcPer, AcMam},
Name,
HistorySize,
RoomShaper,
@@ -713,35 +738,41 @@ create_rooms_file(Filename) ->
ok.
-%%----------------------------
-%% List/Delete Unused Rooms
-%%----------------------------
+%%---------------------------------
+%% List/Delete Unused/Empty Rooms
+%%---------------------------------
%%---------------
%% Control
rooms_unused_list(ServerHost, Days) ->
- rooms_unused_report(list, ServerHost, Days).
+ rooms_report(unused, list, ServerHost, Days).
rooms_unused_destroy(ServerHost, Days) ->
- rooms_unused_report(destroy, ServerHost, Days).
+ rooms_report(unused, destroy, ServerHost, Days).
+
+rooms_empty_list(ServerHost) ->
+ rooms_report(empty, list, ServerHost, 0).
+rooms_empty_destroy(ServerHost) ->
+ rooms_report(empty, destroy, ServerHost, 0).
-rooms_unused_report(Action, ServerHost, Days) ->
- {NA, NP, RP} = muc_unused(Action, ServerHost, Days),
- io:format("Unused rooms: ~p out of ~p~n", [NP, NA]),
+
+rooms_report(Method, Action, ServerHost, Days) ->
+ {NA, NP, RP} = muc_unused(Method, Action, ServerHost, Days),
+ io:format("rooms ~s: ~p out of ~p~n", [Method, NP, NA]),
[<<R/binary, "@", H/binary>> || {R, H, _P} <- RP].
-muc_unused(Action, ServerHost, Last_allowed) ->
+muc_unused(Method, Action, ServerHost, Last_allowed) ->
%% Get all required info about all existing rooms
Rooms_all = get_rooms(ServerHost),
%% Decide which ones pass the requirements
- Rooms_pass = decide_rooms(Rooms_all, Last_allowed),
+ Rooms_pass = decide_rooms(Method, Rooms_all, ServerHost, Last_allowed),
Num_rooms_all = length(Rooms_all),
Num_rooms_pass = length(Rooms_pass),
%% Perform the desired action for matching rooms
- act_on_rooms(Action, Rooms_pass, ServerHost),
+ act_on_rooms(Method, Action, Rooms_pass, ServerHost),
{Num_rooms_all, Num_rooms_pass, Rooms_pass}.
@@ -766,11 +797,11 @@ get_room_state(Room_pid) ->
%%---------------
%% Decide
-decide_rooms(Rooms, Last_allowed) ->
- Decide = fun(R) -> decide_room(R, Last_allowed) end,
+decide_rooms(Method, Rooms, ServerHost, Last_allowed) ->
+ Decide = fun(R) -> decide_room(Method, R, ServerHost, Last_allowed) end,
lists:filter(Decide, Rooms).
-decide_room({_Room_name, _Host, Room_pid}, Last_allowed) ->
+decide_room(unused, {_Room_name, _Host, Room_pid}, ServerHost, Last_allowed) ->
C = get_room_config(Room_pid),
Persistent = C#config.persistent,
@@ -782,10 +813,15 @@ decide_room({_Room_name, _Host, Room_pid}, Last_allowed) ->
History = (S#state.history)#lqueue.queue,
Ts_now = calendar:universal_time(),
- Ts_uptime = uptime_seconds(),
+ HistorySize = gen_mod:get_module_opt(ServerHost, mod_muc, history_size),
+ JustCreated = S#state.just_created,
{Has_hist, Last} = case p1_queue:is_empty(History) of
+ true when (HistorySize == 0) or (JustCreated == true) ->
+ {false, 0};
true ->
- {false, Ts_uptime};
+ Ts_diff = (misc:now_to_usec(now())
+ - S#state.just_created) div 1000000,
+ {false, Ts_diff};
false ->
Last_message = get_queue_last(History),
Ts_last = calendar:now_to_universal_time(
@@ -795,13 +831,19 @@ decide_room({_Room_name, _Host, Room_pid}, Last_allowed) ->
- calendar:datetime_to_gregorian_seconds(Ts_last),
{true, Ts_diff}
end,
-
case {Persistent, Just_created, Num_users, Has_hist, seconds_to_days(Last)} of
- {_true, false, 0, _, Last_days}
- when Last_days >= Last_allowed ->
+ {_true, JC, 0, _, Last_days}
+ when (Last_days >= Last_allowed) and (JC /= true) ->
true;
_ ->
false
+ end;
+decide_room(empty, {Room_name, Host, _Room_pid}, ServerHost, _Last_allowed) ->
+ case gen_mod:is_loaded(ServerHost, mod_mam) of
+ true ->
+ mod_mam:is_empty_for_room(ServerHost, Room_name, Host);
+ _ ->
+ false
end.
seconds_to_days(S) ->
@@ -810,7 +852,7 @@ seconds_to_days(S) ->
%%---------------
%% Act
-act_on_rooms(Action, Rooms, ServerHost) ->
+act_on_rooms(Method, Action, Rooms, ServerHost) ->
ServerHosts = [ {A, find_host(A)} || A <- ejabberd_config:get_myhosts() ],
Delete = fun({_N, H, _Pid} = Room) ->
SH = case ServerHost of
@@ -818,7 +860,7 @@ act_on_rooms(Action, Rooms, ServerHost) ->
O -> O
end,
- act_on_room(Action, Room, SH)
+ act_on_room(Method, Action, Room, SH)
end,
lists:foreach(Delete, Rooms).
@@ -826,13 +868,15 @@ find_serverhost(Host, ServerHosts) ->
{value, {ServerHost, Host}} = lists:keysearch(Host, 2, ServerHosts),
ServerHost.
-act_on_room(destroy, {N, H, Pid}, SH) ->
+act_on_room(Method, destroy, {N, H, Pid}, SH) ->
+ Message = iolist_to_binary(io_lib:format(
+ <<"Room destroyed by rooms_~s_destroy.">>, [Method])),
p1_fsm:send_all_state_event(
- Pid, {destroy, <<"Room destroyed by rooms_unused_destroy.">>}),
+ Pid, {destroy, Message}),
mod_muc:room_destroyed(H, N, Pid, SH),
mod_muc:forget_room(SH, H, N);
-act_on_room(list, _, _) ->
+act_on_room(_Method, list, _, _) ->
ok.
@@ -1104,9 +1148,8 @@ subscribe_room(User, Nick, Room, Nodes) ->
try jid:decode(Room) of
#jid{luser = Name, lserver = Host} when Name /= <<"">> ->
try jid:decode(User) of
- #jid{lresource = <<"">>} ->
- throw({error, "User's JID should have a resource"});
- UserJID ->
+ UserJID1 ->
+ UserJID = jid:replace_resource(UserJID1, <<"modmucadmin">>),
case get_room_pid(Name, Host) of
Pid when is_pid(Pid) ->
case p1_fsm:sync_send_all_state_event(
@@ -1215,9 +1258,6 @@ make_opts(StateData) ->
%% Utils
%%----------------------------
-uptime_seconds() ->
- trunc(element(1, erlang:statistics(wall_clock))/1000).
-
find_host(global) ->
global;
find_host("global") ->
diff --git a/src/mod_muc_log.erl b/src/mod_muc_log.erl
index a847a3874..42a9cc0a5 100644
--- a/src/mod_muc_log.erl
+++ b/src/mod_muc_log.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Mar 2006 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_muc_mnesia.erl b/src/mod_muc_mnesia.erl
index 43cf1aa01..32006256e 100644
--- a/src/mod_muc_mnesia.erl
+++ b/src/mod_muc_mnesia.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_muc_riak.erl b/src/mod_muc_riak.erl
index d9e0732db..a5d02fd1a 100644
--- a/src/mod_muc_riak.erl
+++ b/src/mod_muc_riak.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl
index 39f727111..a8818aca4 100644
--- a/src/mod_muc_room.erl
+++ b/src/mod_muc_room.erl
@@ -5,7 +5,7 @@
%%% Created : 19 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -54,6 +54,7 @@
-include("xmpp.hrl").
-include("translate.hrl").
-include("mod_muc_room.hrl").
+-include("ejabberd_stacktrace.hrl").
-define(MAX_USERS_DEFAULT_LIST,
[5, 10, 20, 30, 50, 100, 200, 500, 1000, 2000, 5000]).
@@ -339,7 +340,7 @@ normal_state({route, <<"">>, #iq{} = IQ}, StateData) ->
ejabberd_router:route_error(IQ, Err),
case StateData#state.just_created of
true -> {stop, normal, StateData};
- false -> {next_state, normal_state, StateData}
+ _ -> {next_state, normal_state, StateData}
end;
normal_state({route, Nick, #presence{from = From} = Packet}, StateData) ->
Activity = get_user_activity(From, StateData),
@@ -698,36 +699,42 @@ handle_info(_Info, StateName, StateData) ->
{next_state, StateName, StateData}.
terminate(Reason, _StateName, StateData) ->
- ?INFO_MSG("Stopping MUC room ~s@~s",
- [StateData#state.room, StateData#state.host]),
- ReasonT = case Reason of
- shutdown ->
- <<"You are being removed from the room "
- "because of a system shutdown">>;
- _ -> <<"Room terminates">>
- end,
- Packet = #presence{
- type = unavailable,
- sub_els = [#muc_user{items = [#muc_item{affiliation = none,
- reason = ReasonT,
- role = none}],
- status_codes = [332,110]}]},
- maps:fold(
- fun(LJID, Info, _) ->
- Nick = Info#user.nick,
- case Reason of
- shutdown ->
- send_wrapped(jid:replace_resource(StateData#state.jid, Nick),
- Info#user.jid, Packet,
- ?NS_MUCSUB_NODES_PARTICIPANTS,
- StateData);
- _ -> ok
- end,
- tab_remove_online_user(LJID, StateData)
- end, [], get_users_and_subscribers(StateData)),
- add_to_log(room_existence, stopped, StateData),
- mod_muc:room_destroyed(StateData#state.host, StateData#state.room, self(),
- StateData#state.server_host),
+ try
+ ?INFO_MSG("Stopping MUC room ~s@~s",
+ [StateData#state.room, StateData#state.host]),
+ ReasonT = case Reason of
+ shutdown ->
+ <<"You are being removed from the room "
+ "because of a system shutdown">>;
+ _ -> <<"Room terminates">>
+ end,
+ Packet = #presence{
+ type = unavailable,
+ sub_els = [#muc_user{items = [#muc_item{affiliation = none,
+ reason = ReasonT,
+ role = none}],
+ status_codes = [332,110]}]},
+ maps:fold(
+ fun(LJID, Info, _) ->
+ Nick = Info#user.nick,
+ case Reason of
+ shutdown ->
+ send_wrapped(jid:replace_resource(StateData#state.jid, Nick),
+ Info#user.jid, Packet,
+ ?NS_MUCSUB_NODES_PARTICIPANTS,
+ StateData);
+ _ -> ok
+ end,
+ tab_remove_online_user(LJID, StateData)
+ end, [], get_users_and_subscribers(StateData)),
+ add_to_log(room_existence, stopped, StateData),
+ mod_muc:room_destroyed(StateData#state.host, StateData#state.room, self(),
+ StateData#state.server_host)
+ catch ?EX_RULE(E, R, St) ->
+ mod_muc:room_destroyed(StateData#state.host, StateData#state.room, self(),
+ StateData#state.server_host),
+ ?ERROR_MSG("Got exception on room termination: ~p", [{E, {R, ?EX_STACK(St)}}])
+ end,
ok.
%%%----------------------------------------------------------------------
@@ -1408,7 +1415,7 @@ get_affiliations_callback(StateData) ->
-spec get_service_affiliation(jid(), state()) -> owner | none.
get_service_affiliation(JID, StateData) ->
{_AccessRoute, _AccessCreate, AccessAdmin,
- _AccessPersistent} =
+ _AccessPersistent, _AccessMam} =
StateData#state.access,
case acl:match_rule(StateData#state.server_host,
AccessAdmin, JID)
@@ -1953,8 +1960,8 @@ add_new_user(From, Nick, Packet, StateData) ->
ResultState =
case NewStateData#state.just_created of
true ->
- NewStateData#state{just_created = false};
- false ->
+ NewStateData#state{just_created = misc:now_to_usec(now())};
+ _ ->
Robots = maps:remove(From, StateData#state.robots),
NewStateData#state{robots = Robots}
end,
@@ -2142,15 +2149,15 @@ presence_broadcast_allowed(JID, StateData) ->
-spec send_initial_presences_and_messages(
jid(), binary(), presence(), state(), state()) -> ok.
send_initial_presences_and_messages(From, Nick, Presence, NewState, OldState) ->
- send_self_presence(From, NewState),
+ advertise_entity_capabilities(From, NewState),
send_existing_presences(From, NewState),
- send_initial_presence(From, NewState, OldState),
+ send_self_presence(From, NewState, OldState),
History = get_history(Nick, Presence, NewState),
send_history(From, History, NewState),
send_subject(From, OldState).
--spec send_self_presence(jid(), state()) -> ok.
-send_self_presence(JID, State) ->
+-spec advertise_entity_capabilities(jid(), state()) -> ok.
+advertise_entity_capabilities(JID, State) ->
AvatarHash = (State#state.config)#config.vcard_xupdate,
DiscoInfo = make_disco_info(JID, State),
Extras = iq_disco_info_extras(<<"en">>, State, true),
@@ -2168,8 +2175,8 @@ send_self_presence(JID, State) ->
id = p1_rand:get_string(),
sub_els = Els2}).
--spec send_initial_presence(jid(), state(), state()) -> ok.
-send_initial_presence(NJID, StateData, OldStateData) ->
+-spec send_self_presence(jid(), state(), state()) -> ok.
+send_self_presence(NJID, StateData, OldStateData) ->
send_new_presence(NJID, <<"">>, true, StateData, OldStateData).
-spec send_update_presence(jid(), state(), state()) -> ok.
@@ -2468,7 +2475,7 @@ status_codes(IsInitialPresence, _IsSelfPresence = true, StateData) ->
true ->
S1 = case StateData#state.just_created of
true -> [201|S0];
- false -> S0
+ _ -> S0
end,
S2 = case (StateData#state.config)#config.anonymous of
true -> S1;
@@ -2765,7 +2772,7 @@ process_item_change(Item, SD, UJID) ->
maybe_send_affiliation(JID, A, SD1),
SD1
end
- catch E:R ->
+ catch ?EX_RULE(E, R, St) ->
FromSuffix = case UJID of
#jid{} ->
JidString = jid:encode(UJID),
@@ -2773,9 +2780,8 @@ process_item_change(Item, SD, UJID) ->
undefined ->
<<"">>
end,
- St = erlang:get_stacktrace(),
?ERROR_MSG("failed to set item ~p~s: ~p",
- [Item, FromSuffix, {E, {R, St}}]),
+ [Item, FromSuffix, {E, {R, ?EX_STACK(St)}}]),
{error, xmpp:err_internal_server_error()}
end.
@@ -3170,6 +3176,7 @@ process_iq_owner(From, #iq{type = set, lang = Lang,
Options ->
case is_allowed_log_change(Options, StateData, From) andalso
is_allowed_persistent_change(Options, StateData, From) andalso
+ is_allowed_mam_change(Options, StateData, From) andalso
is_allowed_room_name_desc_limits(Options, StateData) andalso
is_password_settings_correct(Options, StateData) of
true ->
@@ -3234,13 +3241,26 @@ is_allowed_persistent_change(Options, StateData, From) ->
false -> true;
true ->
{_AccessRoute, _AccessCreate, _AccessAdmin,
- AccessPersistent} =
+ AccessPersistent, _AccessMam} =
StateData#state.access,
allow ==
acl:match_rule(StateData#state.server_host,
AccessPersistent, From)
end.
+-spec is_allowed_mam_change(muc_roomconfig:result(), state(), jid()) -> boolean().
+is_allowed_mam_change(Options, StateData, From) ->
+ case proplists:is_defined(mam, Options) of
+ false -> true;
+ true ->
+ {_AccessRoute, _AccessCreate, _AccessAdmin,
+ _AccessPersistent, AccessMam} =
+ StateData#state.access,
+ allow ==
+ acl:match_rule(StateData#state.server_host,
+ AccessMam, From)
+ end.
+
%% Check if the Room Name and Room Description defined in the Data Form
%% are conformant to the configured limits
-spec is_allowed_room_name_desc_limits(muc_roomconfig:result(), state()) -> boolean().
@@ -3283,7 +3303,7 @@ get_default_room_maxusers(RoomState) ->
-spec get_config(binary(), state(), jid()) -> xdata().
get_config(Lang, StateData, From) ->
- {_AccessRoute, _AccessCreate, _AccessAdmin, AccessPersistent} =
+ {_AccessRoute, _AccessCreate, _AccessAdmin, AccessPersistent, _AccessMam} =
StateData#state.access,
ServiceMaxUsers = get_service_max_users(StateData),
DefaultRoomMaxUsers = get_default_room_maxusers(StateData),
@@ -3493,7 +3513,7 @@ send_config_change_info(New, #state{config = Old} = StateData) ->
if Codes /= [] ->
maps:fold(
fun(_LJID, #user{jid = JID}, _) ->
- send_self_presence(JID, StateData#state{config = New})
+ advertise_entity_capabilities(JID, StateData#state{config = New})
end, ok, StateData#state.users),
Message = #message{type = groupchat,
id = p1_rand:get_string(),
@@ -3963,7 +3983,7 @@ process_iq_vcard(From, #iq{type = set, lang = Lang, sub_els = [Pkt]},
{ignore, state()}.
process_iq_mucsub(_From, #iq{type = set, lang = Lang,
sub_els = [#muc_subscribe{}]},
- #state{just_created = false, config = #config{allow_subscription = false}}) ->
+ #state{just_created = Just, config = #config{allow_subscription = false}}) when Just /= true ->
{error, xmpp:err_not_allowed(<<"Subscriptions are not allowed">>, Lang)};
process_iq_mucsub(From,
#iq{type = set, lang = Lang,
@@ -4345,7 +4365,7 @@ send_subscriptions_change_notifications(From, Nick, Type, State) ->
items = [#ps_item{
id = p1_rand:get_string(),
sub_els = [Payload]}]}}]},
- ejabberd_router:route(xmpp:set_from_to(Packet, From, JID));
+ ejabberd_router:route(xmpp:set_from_to(Packet, State#state.jid, JID));
false ->
ok
end
diff --git a/src/mod_muc_sql.erl b/src/mod_muc_sql.erl
index e92b4bc54..12487e628 100644
--- a/src/mod_muc_sql.erl
+++ b/src/mod_muc_sql.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_multicast.erl b/src/mod_multicast.erl
index 72c177b80..509fe8893 100644
--- a/src/mod_multicast.erl
+++ b/src/mod_multicast.erl
@@ -5,7 +5,7 @@
%%% Created : 29 May 2007 by Badlop <badlop@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_offline.erl b/src/mod_offline.erl
index 53e437020..2582a7c98 100644
--- a/src/mod_offline.erl
+++ b/src/mod_offline.erl
@@ -5,7 +5,7 @@
%%% Created : 5 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -101,6 +101,8 @@
-callback remove_all_messages(binary(), binary()) -> {atomic, any()}.
-callback count_messages(binary(), binary()) -> non_neg_integer().
+-optional_callbacks([remove_expired_messages/1, remove_old_messages/2]).
+
depends(_Host, _Opts) ->
[].
@@ -365,7 +367,6 @@ remove_msg_by_node(To, Seq) ->
-spec need_to_store(binary(), message()) -> boolean().
need_to_store(_LServer, #message{type = error}) -> false;
-need_to_store(_LServer, #message{type = groupchat}) -> false;
need_to_store(LServer, #message{type = Type} = Packet) ->
case xmpp:has_subtag(Packet, #offline{}) of
false ->
@@ -374,16 +375,25 @@ need_to_store(LServer, #message{type = Type} = Packet) ->
true;
no_store ->
false;
- none when Type == headline ->
- false;
none ->
- case gen_mod:get_module_opt(
- LServer, ?MODULE, store_empty_body) of
- true ->
+ Store = case Type of
+ groupchat ->
+ gen_mod:get_module_opt(
+ LServer, ?MODULE, store_groupchat);
+ headline ->
+ false;
+ _ ->
+ true
+ end,
+ case {Store, gen_mod:get_module_opt(
+ LServer, ?MODULE, store_empty_body)} of
+ {false, _} ->
+ false;
+ {_, true} ->
true;
- false ->
+ {_, false} ->
Packet#message.body /= [];
- unless_chat_state ->
+ {_, unless_chat_state} ->
not misc:is_standalone_chat_state(Packet)
end
end;
@@ -543,12 +553,18 @@ privacy_check_packet(#{lserver := LServer} = State, Pkt, Dir) ->
remove_expired_messages(Server) ->
LServer = jid:nameprep(Server),
Mod = gen_mod:db_mod(LServer, ?MODULE),
- Mod:remove_expired_messages(LServer).
+ case erlang:function_exported(Mod, remove_expired_messages, 1) of
+ true -> Mod:remove_expired_messages(LServer);
+ false -> erlang:error(not_implemented)
+ end.
remove_old_messages(Days, Server) ->
LServer = jid:nameprep(Server),
Mod = gen_mod:db_mod(LServer, ?MODULE),
- Mod:remove_old_messages(Days, LServer).
+ case erlang:function_exported(Mod, remove_old_messages, 2) of
+ true -> Mod:remove_old_messages(Days, LServer);
+ false -> erlang:error(not_implemented)
+ end.
-spec remove_user(binary(), binary()) -> ok.
remove_user(User, Server) ->
@@ -837,6 +853,8 @@ import(LServer, {sql, _}, DBType, <<"spool">>,
mod_opt_type(access_max_user_messages) ->
fun acl:shaper_rules_validator/1;
mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
+mod_opt_type(store_groupchat) ->
+ fun(V) when is_boolean(V) -> V end;
mod_opt_type(store_empty_body) ->
fun (V) when is_boolean(V) -> V;
(unless_chat_state) -> unless_chat_state
@@ -845,4 +863,5 @@ mod_opt_type(store_empty_body) ->
mod_options(Host) ->
[{db_type, ejabberd_config:default_db(Host, ?MODULE)},
{access_max_user_messages, max_user_offline_messages},
- {store_empty_body, unless_chat_state}].
+ {store_empty_body, unless_chat_state},
+ {store_groupchat, false}].
diff --git a/src/mod_offline_mnesia.erl b/src/mod_offline_mnesia.erl
index a7f0cd02f..77c5b2e44 100644
--- a/src/mod_offline_mnesia.erl
+++ b/src/mod_offline_mnesia.erl
@@ -4,7 +4,7 @@
%%% Created : 15 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_offline_riak.erl b/src/mod_offline_riak.erl
index 2c03df366..db86767ce 100644
--- a/src/mod_offline_riak.erl
+++ b/src/mod_offline_riak.erl
@@ -4,7 +4,7 @@
%%% Created : 15 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_offline_sql.erl b/src/mod_offline_sql.erl
index f2cc682d6..cb0efa51e 100644
--- a/src/mod_offline_sql.erl
+++ b/src/mod_offline_sql.erl
@@ -4,7 +4,7 @@
%%% Created : 15 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_ping.erl b/src/mod_ping.erl
index e0b4a36a9..25d2b60ed 100644
--- a/src/mod_ping.erl
+++ b/src/mod_ping.erl
@@ -5,7 +5,7 @@
%%% Created : 11 Jul 2009 by Brian Cully <bjc@kublai.com>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -122,30 +122,31 @@ handle_cast({start_ping, JID}, State) ->
handle_cast({stop_ping, JID}, State) ->
Timers = del_timer(JID, State#state.timers),
{noreply, State#state{timers = Timers}};
-handle_cast({iq_reply, timeout, JID}, State) ->
- ejabberd_hooks:run(user_ping_timeout, State#state.host,
- [JID]),
- Timers = case State#state.timeout_action of
- kill ->
- #jid{user = User, server = Server,
- resource = Resource} =
- JID,
- case ejabberd_sm:get_session_pid(User, Server, Resource)
- of
- Pid when is_pid(Pid) -> ejabberd_c2s:close(Pid, ping_timeout);
- _ -> ok
- end,
- del_timer(JID, State#state.timers);
- _ ->
- State#state.timers
- end,
- {noreply, State#state{timers = Timers}};
-handle_cast({iq_reply, #iq{}, _JID}, State) ->
- {noreply, State};
handle_cast(Msg, State) ->
?WARNING_MSG("unexpected cast: ~p", [Msg]),
{noreply, State}.
+handle_info({iq_reply, #iq{type = error}, JID}, State) ->
+ handle_info({iq_reply, timeout, JID}, State);
+handle_info({iq_reply, #iq{}, _JID}, State) ->
+ {noreply, State};
+handle_info({iq_reply, timeout, JID}, State) ->
+ Timers = del_timer(JID, State#state.timers),
+ ejabberd_hooks:run(user_ping_timeout, State#state.host,
+ [JID]),
+ case State#state.timeout_action of
+ kill ->
+ #jid{user = User, server = Server,
+ resource = Resource} =
+ JID,
+ case ejabberd_sm:get_session_pid(User, Server, Resource)
+ of
+ Pid when is_pid(Pid) -> ejabberd_c2s:close(Pid, ping_timeout);
+ _ -> ok
+ end;
+ _ -> ok
+ end,
+ {noreply, State#state{timers = Timers}};
handle_info({timeout, _TRef, {ping, JID}}, State) ->
Host = State#state.host,
From = jid:remove_resource(JID),
diff --git a/src/mod_pres_counter.erl b/src/mod_pres_counter.erl
index 6c58d2641..c1473e344 100644
--- a/src/mod_pres_counter.erl
+++ b/src/mod_pres_counter.erl
@@ -5,7 +5,7 @@
%%% Created : 23 Sep 2010 by Ahmed Omar
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl
index 6cb573439..0b534d272 100644
--- a/src/mod_privacy.erl
+++ b/src/mod_privacy.erl
@@ -5,7 +5,7 @@
%%% Created : 21 Jul 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_privacy_mnesia.erl b/src/mod_privacy_mnesia.erl
index a28910c0f..1be9912fb 100644
--- a/src/mod_privacy_mnesia.erl
+++ b/src/mod_privacy_mnesia.erl
@@ -4,7 +4,7 @@
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_privacy_riak.erl b/src/mod_privacy_riak.erl
index 71d744c8a..51caaafe7 100644
--- a/src/mod_privacy_riak.erl
+++ b/src/mod_privacy_riak.erl
@@ -4,7 +4,7 @@
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_privacy_sql.erl b/src/mod_privacy_sql.erl
index 4ee0984a8..e5a97c96b 100644
--- a/src/mod_privacy_sql.erl
+++ b/src/mod_privacy_sql.erl
@@ -4,7 +4,7 @@
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_private.erl b/src/mod_private.erl
index b32fff98e..f69f2cc96 100644
--- a/src/mod_private.erl
+++ b/src/mod_private.erl
@@ -5,7 +5,7 @@
%%% Created : 16 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -255,7 +255,7 @@ publish_data(JID, Data) ->
{access_model, whitelist}],
case mod_pubsub:publish_item(
LBJID, LServer, ?NS_STORAGE_BOOKMARKS, JID,
- <<>>, [El], PubOpts, all) of
+ <<"current">>, [El], PubOpts, all) of
{result, _} -> ok;
{error, _} = Err -> Err
end
diff --git a/src/mod_private_mnesia.erl b/src/mod_private_mnesia.erl
index b981a803a..03d98b1ca 100644
--- a/src/mod_private_mnesia.erl
+++ b/src/mod_private_mnesia.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_private_riak.erl b/src/mod_private_riak.erl
index 6ddf9cc10..c0a225a14 100644
--- a/src/mod_private_riak.erl
+++ b/src/mod_private_riak.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_private_sql.erl b/src/mod_private_sql.erl
index a0ec03c6a..1fa91a9d4 100644
--- a/src/mod_private_sql.erl
+++ b/src/mod_private_sql.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_privilege.erl b/src/mod_privilege.erl
index 5f2fa3297..abb38456a 100644
--- a/src/mod_privilege.erl
+++ b/src/mod_privilege.erl
@@ -4,7 +4,7 @@
%%% Purpose : XEP-0356: Privileged Entity
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_proxy65.erl b/src/mod_proxy65.erl
index c911dd7aa..0fca1cdcb 100644
--- a/src/mod_proxy65.erl
+++ b/src/mod_proxy65.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_proxy65_lib.erl b/src/mod_proxy65_lib.erl
index 23e1108ad..70a762413 100644
--- a/src/mod_proxy65_lib.erl
+++ b/src/mod_proxy65_lib.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_proxy65_mnesia.erl b/src/mod_proxy65_mnesia.erl
index 7423697c1..89dd24800 100644
--- a/src/mod_proxy65_mnesia.erl
+++ b/src/mod_proxy65_mnesia.erl
@@ -2,7 +2,7 @@
%%% Created : 16 Jan 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_proxy65_redis.erl b/src/mod_proxy65_redis.erl
index 99eda70bd..a3f7bb5a7 100644
--- a/src/mod_proxy65_redis.erl
+++ b/src/mod_proxy65_redis.erl
@@ -3,7 +3,7 @@
%%% Created : 31 Mar 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_proxy65_riak.erl b/src/mod_proxy65_riak.erl
index 543015654..ec1015772 100644
--- a/src/mod_proxy65_riak.erl
+++ b/src/mod_proxy65_riak.erl
@@ -3,7 +3,7 @@
%%% Created : 15 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_proxy65_service.erl b/src/mod_proxy65_service.erl
index 9510ff4b2..433371240 100644
--- a/src/mod_proxy65_service.erl
+++ b/src/mod_proxy65_service.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_proxy65_sql.erl b/src/mod_proxy65_sql.erl
index 0f51adb55..20fed2209 100644
--- a/src/mod_proxy65_sql.erl
+++ b/src/mod_proxy65_sql.erl
@@ -3,7 +3,7 @@
%%% Created : 30 Mar 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_proxy65_stream.erl b/src/mod_proxy65_stream.erl
index 668817868..7e5c180ae 100644
--- a/src/mod_proxy65_stream.erl
+++ b/src/mod_proxy65_stream.erl
@@ -4,7 +4,7 @@
%%% Purpose : Bytestream process.
%%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru>
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl
index 72edea9ce..b332dd321 100644
--- a/src/mod_pubsub.erl
+++ b/src/mod_pubsub.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_push.erl b/src/mod_push.erl
index 5e75e0f9d..1a12f6029 100644
--- a/src/mod_push.erl
+++ b/src/mod_push.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Jul 2017 by Holger Weiss <holger@zedat.fu-berlin.de>
%%%
%%%
-%%% ejabberd, Copyright (C) 2017-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2017-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -441,14 +441,32 @@ notify(#{jid := #jid{luser = LUser, lserver = LServer},
notify(LUser, LServer, Clients, Pkt, Dir) ->
lists:foreach(
fun({TS, PushLJID, Node, XData}) ->
- HandleResponse = fun(#iq{type = result}) ->
- ok;
- (#iq{type = error}) ->
- spawn(?MODULE, delete_session,
- [LUser, LServer, TS]);
- (timeout) ->
- ok % Hmm.
- end,
+ HandleResponse =
+ fun(#iq{type = result}) ->
+ ?DEBUG("~s accepted notification for ~s@~s (~s)",
+ [jid:encode(PushLJID), LUser, LServer, Node]);
+ (#iq{type = error} = IQ) ->
+ case inspect_error(IQ) of
+ {wait, Reason} ->
+ ?INFO_MSG("~s rejected notification for "
+ "~s@~s (~s) temporarily: ~s",
+ [jid:encode(PushLJID), LUser,
+ LServer, Node, Reason]);
+ {Type, Reason} ->
+ spawn(?MODULE, delete_session,
+ [LUser, LServer, TS]),
+ ?WARNING_MSG("~s rejected notification for "
+ "~s@~s (~s), disabling push: ~s "
+ "(~s)",
+ [jid:encode(PushLJID), LUser,
+ LServer, Node, Reason, Type])
+ end;
+ (timeout) ->
+ ?DEBUG("Timeout sending notification for ~s@~s (~s) "
+ "to ~s",
+ [LUser, LServer, Node, jid:encode(PushLJID)]),
+ ok % Hmm.
+ end,
notify(LServer, PushLJID, Node, XData, Pkt, Dir, HandleResponse)
end, Clients).
@@ -667,6 +685,15 @@ get_body_text(#message{body = Body} = Msg) ->
body_is_encrypted(#message{sub_els = SubEls}) ->
lists:keyfind(<<"encrypted">>, #xmlel.name, SubEls) /= false.
+-spec inspect_error(iq()) -> {atom(), binary()}.
+inspect_error(IQ) ->
+ case xmpp:get_error(IQ) of
+ #stanza_error{type = Type} = Err ->
+ {Type, xmpp:format_stanza_error(Err)};
+ undefined ->
+ {undefined, <<"unrecognized error">>}
+ end.
+
%%--------------------------------------------------------------------
%% Caching.
%%--------------------------------------------------------------------
diff --git a/src/mod_push_keepalive.erl b/src/mod_push_keepalive.erl
index 779fd0006..a7a7d8c92 100644
--- a/src/mod_push_keepalive.erl
+++ b/src/mod_push_keepalive.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Jul 2017 by Holger Weiss <holger@zedat.fu-berlin.de>
%%%
%%%
-%%% ejabberd, Copyright (C) 2017-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2017-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_push_mnesia.erl b/src/mod_push_mnesia.erl
index 3b7f9aae4..ee3891e07 100644
--- a/src/mod_push_mnesia.erl
+++ b/src/mod_push_mnesia.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Jul 2017 by Holger Weiss <holger@zedat.fu-berlin.de>
%%%
%%%
-%%% ejabberd, Copyright (C) 2017-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2017-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_push_sql.erl b/src/mod_push_sql.erl
index 5879e163a..50ad30684 100644
--- a/src/mod_push_sql.erl
+++ b/src/mod_push_sql.erl
@@ -5,7 +5,7 @@
%%% Created : 26 Oct 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2017-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2017-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_register.erl b/src/mod_register.erl
index 3785c9c00..841053a43 100644
--- a/src/mod_register.erl
+++ b/src/mod_register.erl
@@ -5,7 +5,7 @@
%%% Created : 8 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_register_web.erl b/src/mod_register_web.erl
index ae659ddc8..1e188d333 100644
--- a/src/mod_register_web.erl
+++ b/src/mod_register_web.erl
@@ -5,7 +5,7 @@
%%% Created : 4 May 2008 by Badlop <badlop@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index 1f42b69e0..c67f5bb32 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -5,7 +5,7 @@
%%% Created : 11 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -53,14 +53,11 @@
depends/2]).
-include("logger.hrl").
-
-include("xmpp.hrl").
-
-include("mod_roster.hrl").
-
-include("ejabberd_http.hrl").
-
-include("ejabberd_web_admin.hrl").
+-include("ejabberd_stacktrace.hrl").
-define(ROSTER_CACHE, roster_cache).
-define(ROSTER_ITEM_CACHE, roster_item_cache).
@@ -231,7 +228,7 @@ roster_version(LServer, LUser) ->
case roster_version_on_db(LServer) of
true ->
case read_roster_version(LUser, LServer) of
- error -> not_found;
+ error -> undefined;
{ok, V} -> V
end;
false ->
@@ -320,10 +317,9 @@ process_iq_get(#iq{to = To, lang = Lang,
#roster_query{items = Items,
ver = Version}
end)
- catch E:R ->
- St = erlang:get_stacktrace(),
+ catch ?EX_RULE(E, R, St) ->
?ERROR_MSG("failed to process roster get for ~s: ~p",
- [jid:encode(To), {E, {R, St}}]),
+ [jid:encode(To), {E, {R, ?EX_STACK(St)}}]),
Txt = <<"Roster module has failed">>,
xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
end.
@@ -481,7 +477,8 @@ push_item(To, OldItem, NewItem) ->
#jid{luser = LUser, lserver = LServer} = To,
Ver = case roster_versioning_enabled(LServer) of
true -> roster_version(LServer, LUser);
- false -> undefined
+ false -> undefined;
+ undefined -> undefined
end,
lists:foreach(
fun(Resource) ->
diff --git a/src/mod_roster_mnesia.erl b/src/mod_roster_mnesia.erl
index 01e671b43..c67d7d5e4 100644
--- a/src/mod_roster_mnesia.erl
+++ b/src/mod_roster_mnesia.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_roster_riak.erl b/src/mod_roster_riak.erl
index 1f65d384c..d267856c3 100644
--- a/src/mod_roster_riak.erl
+++ b/src/mod_roster_riak.erl
@@ -4,7 +4,7 @@
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_roster_sql.erl b/src/mod_roster_sql.erl
index 85019e21d..91242f610 100644
--- a/src/mod_roster_sql.erl
+++ b/src/mod_roster_sql.erl
@@ -4,7 +4,7 @@
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_s2s_dialback.erl b/src/mod_s2s_dialback.erl
index ff4174ebf..55854a82b 100644
--- a/src/mod_s2s_dialback.erl
+++ b/src/mod_s2s_dialback.erl
@@ -2,7 +2,7 @@
%%% Created : 16 Dec 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_service_log.erl b/src/mod_service_log.erl
index d8c9c565e..62b5e289f 100644
--- a/src/mod_service_log.erl
+++ b/src/mod_service_log.erl
@@ -5,7 +5,7 @@
%%% Created : 24 Aug 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl
index 79b782e17..d80258db7 100644
--- a/src/mod_shared_roster.erl
+++ b/src/mod_shared_roster.erl
@@ -5,7 +5,7 @@
%%% Created : 5 Mar 2005 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -303,10 +303,10 @@ get_jid_info({Subscription, Ask, Groups}, User, Server,
US1 = {U1, S1},
DisplayedGroups = get_user_displayed_groups(US),
SRUsers = lists:foldl(fun (Group, Acc1) ->
+ GroupName = get_group_name(LServer, Group),
lists:foldl(fun (User1, Acc2) ->
dict:append(User1,
- get_group_name(LServer,
- Group),
+ GroupName,
Acc2)
end,
Acc1,
@@ -451,18 +451,24 @@ get_group_name(Host1, Group1) ->
%% Get list of names of groups that have @all@/@online@/etc in the memberlist
get_special_users_groups(Host) ->
- lists:filter(fun (Group) ->
- get_group_opt(Host, Group, all_users, false) orelse
- get_group_opt(Host, Group, online_users, false)
- end,
- list_groups(Host)).
+ lists:filtermap(fun ({Group, Opts}) ->
+ case proplists:get_value(all_users, Opts, false) orelse
+ proplists:get_value(online_users, Opts, false) of
+ true -> {true, Group};
+ false -> false
+ end
+ end,
+ groups_with_opts(Host)).
%% Get list of names of groups that have @online@ in the memberlist
get_special_users_groups_online(Host) ->
- lists:filter(fun (Group) ->
- get_group_opt(Host, Group, online_users, false)
- end,
- list_groups(Host)).
+ lists:filtermap(fun ({Group, Opts}) ->
+ case proplists:get_value(online_users, Opts, false) of
+ true -> {true, Group};
+ false -> false
+ end
+ end,
+ groups_with_opts(Host)).
%% Given two lists of groupnames and their options,
%% return the list of displayed groups to the second list
@@ -656,8 +662,13 @@ push_user_to_group(LUser, LServer, Group, Host,
when (U == LUser) and (S == LServer) ->
ok;
({U, S}) ->
- push_roster_item(U, S, LUser, LServer, GroupName,
- Subscription)
+ case lists:member(S, ejabberd_config:get_myhosts()) of
+ true ->
+ push_roster_item(U, S, LUser, LServer, GroupName,
+ Subscription);
+ _ ->
+ ok
+ end
end,
get_group_users(Host, Group)).
diff --git a/src/mod_shared_roster_ldap.erl b/src/mod_shared_roster_ldap.erl
index b50ad93d0..327ec0a9d 100644
--- a/src/mod_shared_roster_ldap.erl
+++ b/src/mod_shared_roster_ldap.erl
@@ -7,7 +7,7 @@
%%% Created : 5 Mar 2005 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_shared_roster_mnesia.erl b/src/mod_shared_roster_mnesia.erl
index 2995c2230..a54b9687f 100644
--- a/src/mod_shared_roster_mnesia.erl
+++ b/src/mod_shared_roster_mnesia.erl
@@ -4,7 +4,7 @@
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_shared_roster_riak.erl b/src/mod_shared_roster_riak.erl
index 94ed737ec..87bdd80c1 100644
--- a/src/mod_shared_roster_riak.erl
+++ b/src/mod_shared_roster_riak.erl
@@ -4,7 +4,7 @@
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_shared_roster_sql.erl b/src/mod_shared_roster_sql.erl
index 00714fca9..39ca9fb0d 100644
--- a/src/mod_shared_roster_sql.erl
+++ b/src/mod_shared_roster_sql.erl
@@ -4,7 +4,7 @@
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_sic.erl b/src/mod_sic.erl
index 765b9adcd..3ca8e6da9 100644
--- a/src/mod_sic.erl
+++ b/src/mod_sic.erl
@@ -5,7 +5,7 @@
%%% Created : 6 Mar 2010 by Karim Gemayel <karim.gemayel@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_sip.erl b/src/mod_sip.erl
index 814b9df6f..3cb2ac13e 100644
--- a/src/mod_sip.erl
+++ b/src/mod_sip.erl
@@ -5,7 +5,7 @@
%%% Created : 21 Apr 2014 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2014-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2014-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_sip_proxy.erl b/src/mod_sip_proxy.erl
index 3ee0a6fee..5efc238e0 100644
--- a/src/mod_sip_proxy.erl
+++ b/src/mod_sip_proxy.erl
@@ -5,7 +5,7 @@
%%% Created : 21 Apr 2014 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2014-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2014-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_sip_registrar.erl b/src/mod_sip_registrar.erl
index dfb9a50f0..787ec0cb8 100644
--- a/src/mod_sip_registrar.erl
+++ b/src/mod_sip_registrar.erl
@@ -5,7 +5,7 @@
%%% Created : 23 Apr 2014 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2014-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2014-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_stats.erl b/src/mod_stats.erl
index 706c22a70..772d51098 100644
--- a/src/mod_stats.erl
+++ b/src/mod_stats.erl
@@ -5,7 +5,7 @@
%%% Created : 11 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_stream_mgmt.erl b/src/mod_stream_mgmt.erl
index 5adeaf8c2..4c38b87af 100644
--- a/src/mod_stream_mgmt.erl
+++ b/src/mod_stream_mgmt.erl
@@ -3,7 +3,7 @@
%%% Created : 25 Dec 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_time.erl b/src/mod_time.erl
index 78c75f8af..6c4a0bae5 100644
--- a/src/mod_time.erl
+++ b/src/mod_time.erl
@@ -6,7 +6,7 @@
%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
index 39da3472e..5caecae50 100644
--- a/src/mod_vcard.erl
+++ b/src/mod_vcard.erl
@@ -5,7 +5,7 @@
%%% Created : 2 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl
index acfd0a052..2d00d4465 100644
--- a/src/mod_vcard_ldap.erl
+++ b/src/mod_vcard_ldap.erl
@@ -4,7 +4,7 @@
%%% Created : 29 Jul 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_vcard_mnesia.erl b/src/mod_vcard_mnesia.erl
index af361dbb3..31e9f6d43 100644
--- a/src/mod_vcard_mnesia.erl
+++ b/src/mod_vcard_mnesia.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_vcard_riak.erl b/src/mod_vcard_riak.erl
index 49a303c88..ec43cc8d1 100644
--- a/src/mod_vcard_riak.erl
+++ b/src/mod_vcard_riak.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_vcard_sql.erl b/src/mod_vcard_sql.erl
index 57d2052a0..93ef2e948 100644
--- a/src/mod_vcard_sql.erl
+++ b/src/mod_vcard_sql.erl
@@ -4,7 +4,7 @@
%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_vcard_xupdate.erl b/src/mod_vcard_xupdate.erl
index 2f3853357..a674598b8 100644
--- a/src/mod_vcard_xupdate.erl
+++ b/src/mod_vcard_xupdate.erl
@@ -5,7 +5,7 @@
%%% Created : 9 Mar 2007 by Igor Goryachev <igor@goryachev.org>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_version.erl b/src/mod_version.erl
index da0f736eb..7c1f28aea 100644
--- a/src/mod_version.erl
+++ b/src/mod_version.erl
@@ -5,7 +5,7 @@
%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_buddy.erl b/src/node_buddy.erl
index 485675253..a975cb3eb 100644
--- a/src/node_buddy.erl
+++ b/src/node_buddy.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_club.erl b/src/node_club.erl
index 8aa8380a2..953aca117 100644
--- a/src/node_club.erl
+++ b/src/node_club.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_dag.erl b/src/node_dag.erl
index 9d84c484e..d1d8ccd8e 100644
--- a/src/node_dag.erl
+++ b/src/node_dag.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Jun 2009 by Brian Cully <bjc@kublai.com>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_dispatch.erl b/src/node_dispatch.erl
index 1cc96c22a..d0c1b6165 100644
--- a/src/node_dispatch.erl
+++ b/src/node_dispatch.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_flat.erl b/src/node_flat.erl
index 11e0785c0..2c0d7869a 100644
--- a/src/node_flat.erl
+++ b/src/node_flat.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_flat_sql.erl b/src/node_flat_sql.erl
index ebe164a15..cdf7fe3a9 100644
--- a/src/node_flat_sql.erl
+++ b/src/node_flat_sql.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_hometree.erl b/src/node_hometree.erl
index 1e4bc0cf7..c55c696f4 100644
--- a/src/node_hometree.erl
+++ b/src/node_hometree.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_hometree_sql.erl b/src/node_hometree_sql.erl
index c2776e126..8e0a8f281 100644
--- a/src/node_hometree_sql.erl
+++ b/src/node_hometree_sql.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_mb.erl b/src/node_mb.erl
index 615ccadec..9042f27cf 100644
--- a/src/node_mb.erl
+++ b/src/node_mb.erl
@@ -5,7 +5,7 @@
%%% Created : 25 Sep 2008 by Eric Cestari <ecestari@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_mb_sql.erl b/src/node_mb_sql.erl
index 78122b72d..bc06be24d 100644
--- a/src/node_mb_sql.erl
+++ b/src/node_mb_sql.erl
@@ -5,7 +5,7 @@
%%% Created : 6 Sep 2016 by Holger Weiss <holger@zedat.fu-berlin.de>
%%%
%%%
-%%% ejabberd, Copyright (C) 2016-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2016-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_mix.erl b/src/node_mix.erl
index 0cd6f84e9..4d2741a5e 100644
--- a/src/node_mix.erl
+++ b/src/node_mix.erl
@@ -4,7 +4,7 @@
%%% Created : 8 Mar 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_mix_sql.erl b/src/node_mix_sql.erl
index 4ac01c62e..961d34da8 100644
--- a/src/node_mix_sql.erl
+++ b/src/node_mix_sql.erl
@@ -4,7 +4,7 @@
%%% Created : 8 Mar 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_online.erl b/src/node_online.erl
index a9a39be3b..0bdcb60c3 100644
--- a/src/node_online.erl
+++ b/src/node_online.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Dec 2015 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_pep.erl b/src/node_pep.erl
index e98cde81b..3baafc10d 100644
--- a/src/node_pep.erl
+++ b/src/node_pep.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_pep_sql.erl b/src/node_pep_sql.erl
index e5ceb1e8c..4e6dd4872 100644
--- a/src/node_pep_sql.erl
+++ b/src/node_pep_sql.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_private.erl b/src/node_private.erl
index 22f966dbd..d98669372 100644
--- a/src/node_private.erl
+++ b/src/node_private.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/node_public.erl b/src/node_public.erl
index 63468dbf3..28dafa791 100644
--- a/src/node_public.erl
+++ b/src/node_public.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/nodetree_dag.erl b/src/nodetree_dag.erl
index 93f414f31..1185ed817 100644
--- a/src/nodetree_dag.erl
+++ b/src/nodetree_dag.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Jun 2009 by Brian Cully <bjc@kublai.com>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/nodetree_tree.erl b/src/nodetree_tree.erl
index c0da117b0..084fa322a 100644
--- a/src/nodetree_tree.erl
+++ b/src/nodetree_tree.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/nodetree_tree_sql.erl b/src/nodetree_tree_sql.erl
index c311ea3ab..311bbbf07 100644
--- a/src/nodetree_tree_sql.erl
+++ b/src/nodetree_tree_sql.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/nodetree_virtual.erl b/src/nodetree_virtual.erl
index 4d0485eff..c27efe44b 100644
--- a/src/nodetree_virtual.erl
+++ b/src/nodetree_virtual.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Dec 2007 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/prosody2ejabberd.erl b/src/prosody2ejabberd.erl
index b8d9f4da1..3fc3cc8b5 100644
--- a/src/prosody2ejabberd.erl
+++ b/src/prosody2ejabberd.erl
@@ -4,7 +4,7 @@
%%% Created : 20 Jan 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -189,7 +189,11 @@ convert_data(Host, "vcard", User, [Data]) ->
ok
end;
convert_data(_Host, "config", _User, [Data]) ->
- RoomJID = jid:decode(proplists:get_value(<<"jid">>, Data, <<"">>)),
+ RoomJID1 = case proplists:get_value(<<"jid">>, Data, not_found) of
+ not_found -> proplists:get_value(<<"_jid">>, Data, room_jid_not_found);
+ A when is_binary(A) -> A
+ end,
+ RoomJID = jid:decode(RoomJID1),
Config = proplists:get_value(<<"_data">>, Data, []),
RoomCfg = convert_room_config(Data),
case proplists:get_bool(<<"persistent">>, Config) of
@@ -303,22 +307,24 @@ convert_roster_item(LUser, LServer, JIDstring, LuaList) ->
InitR = #roster{usj = {LUser, LServer, LJID},
us = {LUser, LServer},
jid = LJID},
- Roster =
- lists:foldl(
- fun({<<"groups">>, Val}, R) ->
+ lists:foldl(
+ fun({<<"groups">>, Val}, [R]) ->
Gs = lists:flatmap(
fun({G, true}) -> [G];
(_) -> []
end, Val),
- R#roster{groups = Gs};
- ({<<"subscription">>, Sub}, R) ->
- R#roster{subscription = misc:binary_to_atom(Sub)};
- ({<<"ask">>, <<"subscribe">>}, R) ->
- R#roster{ask = out};
- ({<<"name">>, Name}, R) ->
- R#roster{name = Name}
- end, InitR, LuaList),
- [Roster]
+ [R#roster{groups = Gs}];
+ ({<<"subscription">>, Sub}, [R]) ->
+ [R#roster{subscription = misc:binary_to_atom(Sub)}];
+ ({<<"ask">>, <<"subscribe">>}, [R]) ->
+ [R#roster{ask = out}];
+ ({<<"name">>, Name}, [R]) ->
+ [R#roster{name = Name}];
+ ({<<"persist">>, false}, _) ->
+ [];
+ (_, []) ->
+ []
+ end, [InitR], LuaList)
catch _:{bad_jid, _} ->
[]
end.
@@ -358,9 +364,11 @@ convert_room_config(Data) ->
end,
[{affiliations, convert_room_affiliations(Data)},
{allow_change_subj, proplists:get_bool(<<"changesubject">>, Config)},
+ {mam, proplists:get_bool(<<"archiving">>, Config)},
{description, proplists:get_value(<<"description">>, Config, <<"">>)},
{members_only, proplists:get_bool(<<"members_only">>, Config)},
{moderated, proplists:get_bool(<<"moderated">>, Config)},
+ {persistent, proplists:get_bool(<<"persistent">>, Config)},
{anonymous, Anonymous}] ++ Pass ++ Subj.
convert_privacy_item({_, Item}) ->
@@ -517,6 +525,11 @@ el_to_offline_msg(LUser, LServer, #xmlel{attrs = Attrs} = El) ->
deserialize(L) ->
deserialize(L, #xmlel{}, []).
+deserialize([{Other, _}|T], El, Acc)
+ when (Other == <<"key">>)
+ or (Other == <<"when">>)
+ or (Other == <<"with">>) ->
+ deserialize(T, El, Acc);
deserialize([{<<"attr">>, Attrs}|T], El, Acc) ->
deserialize(T, El#xmlel{attrs = Attrs ++ El#xmlel.attrs}, Acc);
deserialize([{<<"name">>, Name}|T], El, Acc) ->
diff --git a/src/proxy_protocol.erl b/src/proxy_protocol.erl
index 2103a4004..5c33b130d 100644
--- a/src/proxy_protocol.erl
+++ b/src/proxy_protocol.erl
@@ -5,7 +5,7 @@
%%% Created : 27 Nov 2018 by Paweł Chmielowski <pawel@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/pubsub_db_sql.erl b/src/pubsub_db_sql.erl
index 6a13054a8..a709ce8b2 100644
--- a/src/pubsub_db_sql.erl
+++ b/src/pubsub_db_sql.erl
@@ -5,7 +5,7 @@
%%% Created : 7 Aug 2009 by Pablo Polvorin <pablo.polvorin@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/pubsub_index.erl b/src/pubsub_index.erl
index 9c80e265f..de71b6395 100644
--- a/src/pubsub_index.erl
+++ b/src/pubsub_index.erl
@@ -5,7 +5,7 @@
%%% Created : 30 Apr 2009 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/pubsub_migrate.erl b/src/pubsub_migrate.erl
index 0728da765..da7d5b997 100644
--- a/src/pubsub_migrate.erl
+++ b/src/pubsub_migrate.erl
@@ -5,7 +5,7 @@
%%% Created : 26 Jul 2014 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/pubsub_subscription.erl b/src/pubsub_subscription.erl
index 615ab322f..88a19c3c6 100644
--- a/src/pubsub_subscription.erl
+++ b/src/pubsub_subscription.erl
@@ -5,7 +5,7 @@
%%% Created : 29 May 2009 by Brian Cully <bjc@kublai.com>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/pubsub_subscription_sql.erl b/src/pubsub_subscription_sql.erl
index 2fcfb0f19..194b2676a 100644
--- a/src/pubsub_subscription_sql.erl
+++ b/src/pubsub_subscription_sql.erl
@@ -6,7 +6,7 @@
%%% Created : 7 Aug 2009 by Pablo Polvorin <pablo.polvorin@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/rest.erl b/src/rest.erl
index 16fa20eb0..8aab0a5ae 100644
--- a/src/rest.erl
+++ b/src/rest.erl
@@ -5,7 +5,7 @@
%%% Created : 16 Oct 2014 by Christophe Romain <christophe.romain@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/str.erl b/src/str.erl
index b314acf5b..bbf0d6a6e 100644
--- a/src/str.erl
+++ b/src/str.erl
@@ -5,7 +5,7 @@
%%% Created : 23 Feb 2012 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/translate.erl b/src/translate.erl
index 5a1e13e82..b2c3e4481 100644
--- a/src/translate.erl
+++ b/src/translate.erl
@@ -5,7 +5,7 @@
%%% Created : 6 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/win32_dns.erl b/src/win32_dns.erl
index fe1ba5395..dcb1d34eb 100644
--- a/src/win32_dns.erl
+++ b/src/win32_dns.erl
@@ -5,7 +5,7 @@
%%% Created : 5 Mar 2009 by Geoff Cant
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/xml_compress.erl b/src/xml_compress.erl
index 673b25c14..a85ec56b2 100644
--- a/src/xml_compress.erl
+++ b/src/xml_compress.erl
@@ -506,8 +506,8 @@ decode_child(<<2:8, Rest/binary>>, PNs, J1, J2) ->
{Children, Rest4} = decode_children(Rest3, PNs, J1, J2),
{{xmlel, Name, Attrs, Children}, Rest4};
decode_child(<<3:8, Rest/binary>>, PNs, J1, J2) ->
- {Name, Rest2} = decode_string(Rest),
- {Ns, Rest3} = decode_string(Rest2),
+ {Ns, Rest2} = decode_string(Rest),
+ {Name, Rest3} = decode_string(Rest2),
{Attrs, Rest4} = decode_attrs(Rest3),
{Children, Rest5} = decode_children(Rest4, Ns, J1, J2),
{{xmlel, Name, add_ns(PNs, Ns, Attrs), Children}, Rest5};
diff --git a/test/acl_test.exs b/test/acl_test.exs
deleted file mode 100644
index ee2b37ab9..000000000
--- a/test/acl_test.exs
+++ /dev/null
@@ -1,389 +0,0 @@
-# ----------------------------------------------------------------------
-#
-# ejabberd, Copyright (C) 2002-2017 ProcessOne
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# ----------------------------------------------------------------------
-
-defmodule ACLTest do
- @author "mremond@process-one.net"
-
- use ExUnit.Case, async: false
-
- setup_all do
- :ok = :mnesia.start
- :ejabberd_mnesia.start
- :jid.start
- :ejabberd_hooks.start_link
- :stringprep.start
- :ok = :ejabberd_config.start(["domain1", "domain2"], [])
- {:ok, _} = :acl.start_link
- :ok
- end
-
- setup do
- :acl.clear
- end
-
- test "access rule match with user part ACL" do
- :acl.add(:global, :basic_acl_1, {:user, "test1"})
- :acl.add(:global, :basic_acl_1, {:user, "test2"})
- :acl.add_access(:global, :basic_rule_1, [{:allow, [{:acl, :basic_acl_1}]}])
- # JID can only be passes as jid record.
- # => TODO: Support passing JID as binary.
- assert :acl.match_rule(:global, :basic_rule_1, :jid.from_string("test1@domain1")) == :allow
- assert :acl.match_rule(:global, :basic_rule_1, :jid.from_string("test1@domain2")) == :allow
- assert :acl.match_rule(:global, :basic_rule_1, :jid.from_string("test2@domain1")) == :allow
- assert :acl.match_rule(:global, :basic_rule_1, :jid.from_string("test2@domain2")) == :allow
- # We match on user part only for local domain. As an implicit rule remote domain are not matched
- assert :acl.match_rule(:global, :basic_rule_1, :jid.from_string("test1@otherdomain")) == :deny
- assert :acl.match_rule(:global, :basic_rule_1, :jid.from_string("test2@otherdomain")) == :deny
- assert :acl.match_rule(:global, :basic_rule_1, :jid.from_string("test11@domain1")) == :deny
-
- :acl.add(:global, :basic_acl_2, {:user, {"test2", "domain1"}})
- :acl.add_access(:global, :basic_rule_2, [{:allow, [{:acl, :basic_acl_2}]}])
- assert :acl.match_rule(:global, :basic_rule_2, :jid.from_string("test2@domain1")) == :allow
- assert :acl.match_rule(:global, :basic_rule_2, :jid.from_string("test2@domain2")) == :deny
- assert :acl.match_rule(:global, :basic_rule_2, :jid.from_string("test2@otherdomain")) == :deny
- assert :acl.match_rule(:global, :basic_rule_2, {127,0,0,1}) == :deny
- end
-
- test "IP based ACL" do
- :acl.add(:global, :ip_acl_1, {:ip, "127.0.0.0/24"})
- :acl.add_access(:global, :ip_rule_1, [{:allow, [{:acl, :ip_acl_1}]}])
- # IP must be expressed as a tuple when calling match rule
- assert :acl.match_rule(:global, :ip_rule_1, {127,0,0,1}) == :allow
- assert :acl.match_rule(:global, :ip_rule_1, {127,0,1,1}) == :deny
- assert :acl.match_rule(:global, :ip_rule_1, :jid.from_string("test1@domain1")) == :deny
- end
-
- test "Access rule are evaluated sequentially" do
- :acl.add(:global, :user_acl_1, {:user, {"test1", "domain2"}})
- :acl.add(:global, :user_acl_2, {:user, "test1"})
- :acl.add_access(:global, :user_rule_1, [{:deny, [{:acl, :user_acl_1}]}, {:allow, [{:acl, :user_acl_2}]}])
- assert :acl.match_rule(:global, :user_rule_1, :jid.from_string("test1@domain1")) == :allow
- assert :acl.match_rule(:global, :user_rule_1, :jid.from_string("test1@domain2")) == :deny
- end
-
- # Access rules are sometimes used to provide values (i.e.: max_s2s_connections, max_user_sessions)
- test "Access rules providing values" do
- :acl.add(:global, :user_acl, {:user_regexp, ""})
- :acl.add(:global, :admin_acl, {:user, "admin"})
- :acl.add_access(:global, :value_rule_1, [{10, [{:acl, :admin_acl}]}, {5, [{:acl, :user_acl}]}])
- assert :acl.match_rule(:global, :value_rule_1, :jid.from_string("test1@domain1")) == 5
- assert :acl.match_rule(:global, :value_rule_1, :jid.from_string("admin@domain1")) == 10
-
- # If we have no match, :deny is still the default value
- # => TODO maybe we should have a match rule which allow passing custom default value ?
- assert :acl.match_rule(:global, :value_rule_1, :jid.from_string("user@otherdomain")) == :deny
- end
-
-
- # At the moment IP and user rules to no go well together: There is
- # no way to combine IP and user restrictions.
- # => TODO we need to implement access rules that implement both and will deny the access
- # if either IP or user returns deny
- test "mixing IP and user access rules" do
- :acl.add(:global, :user_acl_1, {:user, "test1"})
- :acl.add(:global, :ip_acl_1, {:ip, "127.0.0.0/24"})
- :acl.add_access(:global, :mixed_rule_1, [{:allow, [{:acl, :user_acl_1}]}, {:allow, [{:acl, :ip_acl_1}]}])
- assert :acl.match_rule(:global, :mixed_rule_1, :jid.from_string("test1@domain1")) == :allow
- assert :acl.match_rule(:global, :mixed_rule_1, {127,0,0,1}) == :allow
-
- :acl.add_access(:global, :mixed_rule_2, [{:deny, [{:acl, :user_acl_1}]}, {:allow, [{:acl, :ip_acl_1}]}])
- assert :acl.match_rule(:global, :mixed_rule_2, :jid.from_string("test1@domain1")) == :deny
- assert :acl.match_rule(:global, :mixed_rule_2, {127,0,0,1}) == :allow
- end
-
- test "access_matches works with predefined access rules" do
- :acl.add(:global, :user_acl_2, {:user, "user"})
- :acl.add_access(:global, :user_rule_2, [{:allow, [{:acl, :user_acl_2}]}, {:deny, [:all]}])
-
- assert :acl.access_matches(:user_rule_2, %{usr: {"user", "domain1", ""}, ip: {127,0,0,1}}, :global) == :allow
- assert :acl.access_matches(:user_rule_2, %{usr: {"user2", "domain1", ""}, ip: {127,0,0,1}}, :global) == :deny
- end
-
- test "access_matches rule all always matches" do
- assert :acl.access_matches(:all, %{}, :global) == :allow
- assert :acl.access_matches(:all, %{usr: {"user", "domain1", ""}, ip: {127,0,0,1}}, :global) == :allow
- end
-
- test "access_matches rule none never matches" do
- assert :acl.access_matches(:none, %{}, :global) == :deny
- assert :acl.access_matches(:none, %{usr: {"user", "domain1", ""}, ip: {127,0,0,1}}, :global) == :deny
- end
-
- test "access_matches with not existing rule never matches" do
- assert :acl.access_matches(:bleble, %{}, :global) == :deny
- assert :acl.access_matches(:bleble, %{usr: {"user", "domain1", ""}, ip: {127,0,0,1}}, :global) == :deny
- end
-
- test "access_matches works with inlined access rules" do
- :acl.add(:global, :user_acl_3, {:user, "user"})
-
- assert :acl.access_matches([{:allow, [{:acl, :user_acl_3}]}, {:deny, [:all]}],
- %{usr: {"user", "domain1", ""}, ip: {127,0,0,1}}, :global) == :allow
- assert :acl.access_matches([{:allow, [{:acl, :user_acl_3}]}, {:deny, [:all]}],
- %{usr: {"user2", "domain1", ""}, ip: {127,0,0,1}}, :global) == :deny
- end
-
- test "access_matches allow to have acl rules inlined" do
- assert :acl.access_matches([{:allow, [{:user, "user"}]}, {:deny, [:all]}],
- %{usr: {"user", "domain1", ""}, ip: {127,0,0,1}}, :global) == :allow
- assert :acl.access_matches([{:allow, [{:user, "user"}]}, {:deny, [:all]}],
- %{usr: {"user2", "domain1", ""}, ip: {127,0,0,1}}, :global) == :deny
- end
-
- test "access_matches test have implicit deny at end" do
- assert :acl.access_matches([{:allow, [{:user, "user"}]}],
- %{usr: {"user", "domain1", ""}, ip: {127,0,0,1}}, :global) == :allow
- assert :acl.access_matches([{:allow, [{:user, "user"}]}],
- %{usr: {"user2", "domain1", ""}, ip: {127,0,0,1}}, :global) == :deny
- end
-
- test "access_matches requires that all subrules match" do
- rules = [{:allow, [{:user, "user"}, {:ip, {{127,0,0,1}, 32}}]}]
- assert :acl.access_matches(rules, %{usr: {"user", "domain1", ""}, ip: {127,0,0,1}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user", "domain1", ""}, ip: {127,0,0,2}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user2", "domain1", ""}, ip: {127,0,0,1}}, :global) == :deny
- end
-
- test "access_matches rules are matched in order" do
- rules = [{:allow, [{:user, "user"}]}, {:deny, [{:user, "user2"}]}, {:allow, [{:user_regexp, "user"}]}]
- assert :acl.access_matches(rules, %{usr: {"user", "domain1", ""}, ip: {127,0,0,1}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user2", "domain1", ""}, ip: {127,0,0,1}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user22", "domain1", ""}, ip: {127,0,0,1}}, :global) == :allow
- end
-
- test "access_matches rules that require ip but no one is provided don't crash" do
- rules = [{:allow, [{:ip, {{127,0,0,1}, 32}}]},
- {:allow, [{:user, "user"}]},
- {:allow, [{:user, "user2"}, {:ip, {{127,0,0,1}, 32}}]}]
- assert :acl.access_matches(rules, %{usr: {"user", "domain1", ""}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user2", "domain1", ""}}, :global) == :deny
- end
-
- test "access_matches rules that require usr but no one is provided don't crash" do
- rules = [{:allow, [{:ip, {{127,0,0,1}, 32}}]},
- {:allow, [{:user, "user"}]},
- {:allow, [{:user, "user2"}, {:ip, {{127,0,0,2}, 32}}]}]
- assert :acl.access_matches(rules, %{ip: {127,0,0,1}}, :global) == :allow
- assert :acl.access_matches(rules, %{ip: {127,0,0,2}}, :global) == :deny
- end
-
- test "access_matches rules with all always matches" do
- rules = [{:allow, [:all]}, {:deny, {:user, "user"}}]
- assert :acl.access_matches(rules, %{}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user", "domain1", ""}, ip: {127,0,0,1}}, :global) == :allow
- end
-
- test "access_matches rules with {acl, all} always matches" do
- rules = [{:allow, [{:acl, :all}]}, {:deny, {:user, "user"}}]
- assert :acl.access_matches(rules, %{}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user", "domain1", ""}, ip: {127,0,0,1}}, :global) == :allow
- end
-
- test "access_matches rules with none never matches" do
- rules = [{:allow, [:none]}, {:deny, [:all]}]
- assert :acl.access_matches(rules, %{}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user", "domain1", ""}, ip: {127,0,0,1}}, :global) == :deny
- end
-
- test "access_matches with no rules never matches" do
- assert :acl.access_matches([], %{}, :global) == :deny
- assert :acl.access_matches([], %{usr: {"user", "domain1", ""}, ip: {127,0,0,1}}, :global) == :deny
- end
-
- test "access_matches ip rule accepts {ip, port}" do
- rules = [{:allow, [{:ip, {{127,0,0,1}, 32}}]}]
- assert :acl.access_matches(rules, %{ip: {{127,0,0,1}, 5000}}, :global) == :allow
- assert :acl.access_matches(rules, %{ip: {{127,0,0,2}, 5000}}, :global) == :deny
- end
-
- test "access_matches user rule works" do
- rules = [{:allow, [{:user, "user1"}]}]
- assert :acl.access_matches(rules, %{usr: {"user1", "domain1", ""}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user2", "domain1", ""}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user1", "domain3", ""}}, :global) == :deny
- end
-
- test "access_matches 2 arg user rule works" do
- rules = [{:allow, [{:user, {"user1", "server1"}}]}]
- assert :acl.access_matches(rules, %{usr: {"user1", "server1", ""}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user1", "server2", ""}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user2", "server1", ""}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user2", "server2", ""}}, :global) == :deny
- end
-
- test "access_matches server rule works" do
- rules = [{:allow, [{:server, "server1"}]}]
- assert :acl.access_matches(rules, %{usr: {"user", "server1", ""}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user", "server2", ""}}, :global) == :deny
- end
-
- test "access_matches resource rule works" do
- rules = [{:allow, [{:resource, "res1"}]}]
- assert :acl.access_matches(rules, %{usr: {"user", "domain1", "res1"}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user", "domain1", "res2"}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user", "domain3", "res1"}}, :global) == :allow
- end
-
- test "access_matches user_regexp rule works" do
- rules = [{:allow, [{:user_regexp, "user[0-9]"}]}]
- assert :acl.access_matches(rules, %{usr: {"user1", "domain1", "res1"}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"userA", "domain1", "res1"}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user1", "domain3", "res1"}}, :global) == :deny
- end
-
- test "access_matches 2 arg user_regexp rule works" do
- rules = [{:allow, [{:user_regexp, {"user[0-9]", "server1"}}]}]
- assert :acl.access_matches(rules, %{usr: {"user1", "server1", "res1"}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"userA", "server1", "res1"}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user1", "server2", "res1"}}, :global) == :deny
- end
-
- test "access_matches server_regexp rule works" do
- rules = [{:allow, [{:server_regexp, "server[0-9]"}]}]
- assert :acl.access_matches(rules, %{usr: {"user", "server1", ""}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user", "serverA", ""}}, :global) == :deny
- end
-
- test "access_matches resource_regexp rule works" do
- rules = [{:allow, [{:resource_regexp, "res[0-9]"}]}]
- assert :acl.access_matches(rules, %{usr: {"user", "domain1", "res1"}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user", "domain1", "resA"}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user", "domain3", "res1"}}, :global) == :allow
- end
-
- test "access_matches node_regexp rule works" do
- rules = [{:allow, [{:node_regexp, {"user[0-9]", "server[0-9]"}}]}]
- assert :acl.access_matches(rules, %{usr: {"user1", "server1", "res1"}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"userA", "server1", "res1"}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user1", "serverA", "res1"}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"userA", "serverA", "res1"}}, :global) == :deny
- end
-
- test "access_matches user_glob rule works" do
- rules = [{:allow, [{:user_glob, "user?"}]}]
- assert :acl.access_matches(rules, %{usr: {"user1", "domain1", "res1"}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user11", "domain1", "res1"}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user1", "domain3", "res1"}}, :global) == :deny
- end
-
- test "access_matches 2 arg user_glob rule works" do
- rules = [{:allow, [{:user_glob, {"user?", "server1"}}]}]
- assert :acl.access_matches(rules, %{usr: {"user1", "server1", "res1"}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user11", "server1", "res1"}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user1", "server2", "res1"}}, :global) == :deny
- end
-
- test "access_matches server_glob rule works" do
- rules = [{:allow, [{:server_glob, "server?"}]}]
- assert :acl.access_matches(rules, %{usr: {"user", "server1", ""}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user", "server11", ""}}, :global) == :deny
- end
-
- test "access_matches resource_glob rule works" do
- rules = [{:allow, [{:resource_glob, "res?"}]}]
- assert :acl.access_matches(rules, %{usr: {"user", "domain1", "res1"}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user", "domain1", "res11"}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user", "domain3", "res1"}}, :global) == :allow
- end
-
- test "access_matches node_glob rule works" do
- rules = [{:allow, [{:node_glob, {"user?", "server?"}}]}]
- assert :acl.access_matches(rules, %{usr: {"user1", "server1", "res1"}}, :global) == :allow
- assert :acl.access_matches(rules, %{usr: {"user11", "server1", "res1"}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user1", "server11", "res1"}}, :global) == :deny
- assert :acl.access_matches(rules, %{usr: {"user11", "server11", "res1"}}, :global) == :deny
- end
-
- test "transform_access_rules_config expands allow rule" do
- assert :acl.transform_access_rules_config([:allow]) == [{:allow, [:all]}]
- end
-
- test "transform_access_rules_config expands deny rule" do
- assert :acl.transform_access_rules_config([:deny]) == [{:deny, [:all]}]
- end
-
- test "transform_access_rules_config expands <integer> rule" do
- assert :acl.transform_access_rules_config([100]) == [{100, [:all]}]
- end
-
- test "transform_access_rules_config expands <shaper_name> rule" do
- assert :acl.transform_access_rules_config([:fast]) == [{:fast, [:all]}]
- end
-
- test "transform_access_rules_config expands allow: <acl_name> rule" do
- assert :acl.transform_access_rules_config([{:allow, :test1}]) == [{:allow, [{:acl, :test1}]}]
- end
-
- test "transform_access_rules_config expands deny: <acl_name> rule" do
- assert :acl.transform_access_rules_config([{:deny, :test1}]) == [{:deny, [{:acl, :test1}]}]
- end
-
- test "transform_access_rules_config expands integer: <acl_name> rule" do
- assert :acl.transform_access_rules_config([{100, :test1}]) == [{100, [{:acl, :test1}]}]
- end
-
- test "transform_access_rules_config expands <shaper_name>: <acl_name> rule" do
- assert :acl.transform_access_rules_config([{:fast, :test1}]) == [{:fast, [{:acl, :test1}]}]
- end
-
- test "transform_access_rules_config expands allow rule (no list)" do
- assert :acl.transform_access_rules_config(:allow) == [{:allow, [:all]}]
- end
-
- test "transform_access_rules_config expands deny rule (no list)" do
- assert :acl.transform_access_rules_config(:deny) == [{:deny, [:all]}]
- end
-
- test "transform_access_rules_config expands <integer> rule (no list)" do
- assert :acl.transform_access_rules_config(100) == [{100, [:all]}]
- end
-
- test "transform_access_rules_config expands <shaper_name> rule (no list)" do
- assert :acl.transform_access_rules_config(:fast) == [{:fast, [:all]}]
- end
-
- test "access_rules_validator works with <AccessName>" do
- assert :acl.access_rules_validator(:my_access) == :my_access
- end
-
- test "shapes_rules_validator works with <AccessName>" do
- assert :acl.shaper_rules_validator(:my_access) == :my_access
- end
-
- ## Checking ACL on both user pattern and IP
- ## ========================================
-
- # Typical example is mod_register
-
- # Deprecated approach
- test "module can test both IP and user through two independent :acl.match_rule check (deprecated)" do
- :acl.add(:global, :user_acl, {:user, {"test1", "domain1"}})
- :acl.add(:global, :ip_acl, {:ip, "127.0.0.0/24"})
- :acl.add_access(:global, :user_rule, [{:allow, [{:acl, :user_acl}]}])
- :acl.add_access(:global, :ip_rule, [{:allow, [{:acl, :ip_acl}]}])
-
- # acl module in 16.03 is not able to provide a function for compound result:
- assert :acl.match_rule(:global, :user_rule, :jid.from_string("test1@domain1")) == :allow
- assert :acl.match_rule(:global, :ip_rule, {127,0,0,1}) == :allow
- assert :acl.match_rule(:global, :user_rule, :jid.from_string("test2@domain1")) == :deny
- assert :acl.match_rule(:global, :ip_rule, {127,0,1,1}) == :deny
- end
-
-end
diff --git a/test/announce_tests.erl b/test/announce_tests.erl
index 7b621a3d1..1a08f317f 100644
--- a/test/announce_tests.erl
+++ b/test/announce_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 16 Nov 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/carbons_tests.erl b/test/carbons_tests.erl
index 55bbc9270..5142346c1 100644
--- a/test/carbons_tests.erl
+++ b/test/carbons_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 16 Nov 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/csi_tests.erl b/test/csi_tests.erl
index 2b346e275..027cd66c0 100644
--- a/test/csi_tests.erl
+++ b/test/csi_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 16 Nov 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/ejabberd_SUITE.erl b/test/ejabberd_SUITE.erl
index 1d8de7b8e..77e6ebdfb 100644
--- a/test/ejabberd_SUITE.erl
+++ b/test/ejabberd_SUITE.erl
@@ -3,7 +3,7 @@
%%% Created : 2 Jun 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -65,13 +65,13 @@ init_per_suite(Config) ->
start_ejabberd(Config) ->
case proplists:get_value(backends, Config) of
all ->
- ok = application:start(ejabberd, transient);
+ {ok, _} = application:ensure_all_started(ejabberd, transient);
Backends when is_list(Backends) ->
Hosts = lists:map(fun(Backend) -> Backend ++ ".localhost" end, Backends),
application:load(ejabberd),
AllHosts = Hosts ++ ["localhost"], %% We always need localhost for the generic no_db tests
application:set_env(ejabberd, hosts, AllHosts),
- ok = application:start(ejabberd, transient)
+ {ok, _} = application:ensure_all_started(ejabberd, transient)
end.
end_per_suite(_Config) ->
diff --git a/test/ejabberd_admin_test.exs b/test/ejabberd_admin_test.exs
deleted file mode 100644
index 1090eff17..000000000
--- a/test/ejabberd_admin_test.exs
+++ /dev/null
@@ -1,88 +0,0 @@
-# ----------------------------------------------------------------------
-#
-# ejabberd, Copyright (C) 2002-2017 ProcessOne
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# ----------------------------------------------------------------------
-
-defmodule EjabberdAdminTest do
- use ExUnit.Case, async: false
-
- @author "jsautret@process-one.net"
-
- setup_all do
- :mnesia.start
- :ejabberd_mnesia.start
- # For some myterious reason, :ejabberd_commands.init mays
- # sometimes fails if module is not loaded before
- :ejabberd_config.start(["domain"], [])
- {:module, :ejabberd_commands} = Code.ensure_loaded(:ejabberd_commands)
- :ejabberd_hooks.start_link
- {:ok, _} = :acl.start_link
- {:ok, _} = :ejabberd_access_permissions.start_link()
- :ejabberd_commands.start_link
- :ejabberd_admin.start_link
- :ok
- end
-
- setup do
- :ok
- end
-
- test "Logvel can be set and retrieved" do
- :ejabberd_logger.start()
-
- assert :lager == call_command(:set_loglevel, [1])
- assert {1, :critical, 'Critical'} ==
- call_command(:get_loglevel, [])
-
- assert :lager == call_command(:set_loglevel, [2])
- assert {2, :error, 'Error'} ==
- call_command(:get_loglevel, [])
-
- assert :lager == call_command(:set_loglevel, [3])
- assert {3, :warning, 'Warning'} ==
- call_command(:get_loglevel, [])
-
-# assert {:wrong_loglevel, 6} ==
-# catch_throw call_command(:set_loglevel, [6])
-# assert {3, :warning, 'Warning'} ==
-# call_command(:get_loglevel, [])
-
- assert :lager == call_command(:set_loglevel, [4])
- assert {4, :info, 'Info'} ==
- call_command(:get_loglevel, [])
-
- assert :lager == call_command(:set_loglevel, [5])
- assert {5, :debug, 'Debug'} ==
- call_command(:get_loglevel, [])
-
- assert :lager == call_command(:set_loglevel, [0])
- assert {0, :no_log, 'No log'} ==
- call_command(:get_loglevel, [])
-
- end
-
- defp call_command(name, args) do
- :ejabberd_commands.execute_command2(name, args, %{:caller_module => :ejabberd_ctl})
- end
-
- test "command status works with ejabberd stopped" do
- assert :ejabberd_not_running ==
- elem(call_command(:status, []), 0)
- end
-
-end
diff --git a/test/ejabberd_auth_mock.exs b/test/ejabberd_auth_mock.exs
deleted file mode 100644
index 10daf03dc..000000000
--- a/test/ejabberd_auth_mock.exs
+++ /dev/null
@@ -1,74 +0,0 @@
-# ----------------------------------------------------------------------
-#
-# ejabberd, Copyright (C) 2002-2017 ProcessOne
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# ----------------------------------------------------------------------
-
-defmodule EjabberdAuthMock do
-
- @author "jsautret@process-one.net"
- @agent __MODULE__
-
- def init do
- try do
- Agent.stop(@agent)
- catch
- :exit, _e -> :ok
- end
-
- {:ok, _pid} = Agent.start_link(fn -> %{} end, name: @agent)
-
- mock(:ejabberd_auth, :user_exists,
- fn (user, domain) ->
- Agent.get(@agent, fn users -> Map.get(users, {user, domain}) end) != nil
- end)
- mock(:ejabberd_auth, :get_password_s,
- fn (user, domain) ->
- Agent.get(@agent, fn users -> Map.get(users, {user, domain}, "") end )
- end)
- mock(:ejabberd_auth, :check_password,
- fn (user, _authzid, domain, password) ->
- Agent.get(@agent, fn users ->
- Map.get(users, {user, domain}) end) == password
- end)
- mock(:ejabberd_auth, :set_password,
- fn (user, domain, password) ->
- Agent.update(@agent, fn users ->
- Map.put(users, {user, domain}, password) end)
- end)
- end
-
- def create_user(user, domain, password) do
- Agent.update(@agent, fn users -> Map.put(users, {user, domain}, password) end)
- end
-
- ####################################################################
- # Helpers
- ####################################################################
-
- # TODO refactor: Move to ejabberd_test_mock
- def mock(module, function, fun) do
- try do
- :meck.new(module)
- catch
- :error, {:already_started, _pid} -> :ok
- end
-
- :meck.expect(module, function, fun)
- end
-
-end
diff --git a/test/ejabberd_hooks_test.exs b/test/ejabberd_hooks_test.exs
deleted file mode 100644
index 90624147c..000000000
--- a/test/ejabberd_hooks_test.exs
+++ /dev/null
@@ -1,203 +0,0 @@
-# ----------------------------------------------------------------------
-#
-# ejabberd, Copyright (C) 2002-2017 ProcessOne
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# ----------------------------------------------------------------------
-
-# Notes on the tests:
-#
-# This test suite will print out errors in logs for tests:
-#
-# test "Error in run_fold is ignored"
-# test "Throw in run_fold is ignored"
-# test "Exit in run_fold is ignored"
-#
-# Those tests are not failing and we can safely ignore those errors in
-# log as we are exercising hook handler recovery from that situation.
-
-defmodule EjabberdHooksTest do
- use ExUnit.Case, async: false
-
- @author "mremond@process-one.net"
- @host <<"domain.net">>
- @self __MODULE__
-
- setup_all do
- {:ok, _pid} = :ejabberd_hooks.start_link
- :ok
- end
-
- setup do
- :meck.unload
- :true = :ejabberd_hooks.delete_all_hooks
- :ok
- end
-
- test "An anonymous function can be added as a hook" do
- hookname = :test_fun_hook
- :ok = :ejabberd_hooks.add(hookname, @host, fn _ -> :ok end, 50)
- [{50, :undefined, _}] = :ejabberd_hooks.get_handlers(hookname, @host)
- end
-
- test "A module function can be added as a hook" do
- hookname = :test_mod_hook
- callback = :hook_callback
- :ok = :ejabberd_hooks.add(hookname, @host, @self, callback, 40)
- [{40, @self, _callback}] = :ejabberd_hooks.get_handlers(hookname, @host)
- end
-
- test "An anonymous function can be removed from hook handlers" do
- hookname = :test_fun_hook
- anon_fun = fn _ -> :ok end
- :ok = :ejabberd_hooks.add(hookname, @host, anon_fun, 50)
- :ok = :ejabberd_hooks.delete(hookname, @host, anon_fun, 50)
- [] = :ejabberd_hooks.get_handlers(hookname, @host)
- end
-
- test "An module function can be removed from hook handlers" do
- hookname = :test_mod_hook
- callback = :hook_callback
- :ok = :ejabberd_hooks.add(hookname, @host, @self, callback, 40)
- :ok = :ejabberd_hooks.delete(hookname, @host, @self, callback, 40)
- [] = :ejabberd_hooks.get_handlers(hookname, @host)
- # TODO: Check that removed function is not call anymore
- end
-
- test "'Run hook' call registered handler once" do
- test_result = :hook_result
- run_hook([], fn -> test_result end, test_result)
- end
-
- test "'Run hook' can call registered handler with parameters" do
- test_result = :hook_result_with_params
- run_hook([:hook_params], fn _ -> test_result end, test_result)
- end
-
- # TODO test "Several handlers are run in order by hook"
-
- test "Hook run chain is stopped when handler return 'stop'" do
- # setup test
- hookname = :test_mod_hook
- modulename = :hook_module
- mock(modulename, :hook_callback1, fn _ -> :stop end)
- mock(modulename, :hook_callback2, fn _ -> :end_result end)
-
- :ok = :ejabberd_hooks.add(hookname, @host, modulename, :hook_callback1, 40)
- :ok = :ejabberd_hooks.add(hookname, @host, modulename, :hook_callback1, 50)
-
- :ok = :ejabberd_hooks.run(hookname, @host, [:hook_params])
- # callback2 is never run:
- [{_pid, {^modulename, _callback, [:hook_params]}, :stop}] = :meck.history(modulename)
- end
-
- test "Run fold hooks accumulate state in correct order through handlers" do
- # setup test
- hookname = :test_mod_hook
- modulename = :hook_module
- mock(modulename, :hook_callback1, fn(list, user) -> [user|list] end)
- mock(modulename, :hook_callback2, fn(list, _user) -> ["jid2"|list] end)
-
- :ok = :ejabberd_hooks.add(hookname, @host, modulename, :hook_callback1, 40)
- :ok = :ejabberd_hooks.add(hookname, @host, modulename, :hook_callback2, 50)
-
- ["jid2", "jid1"] = :ejabberd_hooks.run_fold(hookname, @host, [], ["jid1"])
- end
-
- test "Hook run_fold are executed based on priority order, not registration order" do
- # setup test
- hookname = :test_mod_hook
- modulename = :hook_module
- mock(modulename, :hook_callback1, fn(_acc) -> :first end)
- mock(modulename, :hook_callback2, fn(_acc) -> :second end)
-
- :ok = :ejabberd_hooks.add(hookname, @host, modulename, :hook_callback2, 50)
- :ok = :ejabberd_hooks.add(hookname, @host, modulename, :hook_callback1, 40)
-
- :second = :ejabberd_hooks.run_fold(hookname, @host, :started, [])
- # Both module have been called:
- 2 = length(:meck.history(modulename))
- end
-
- # TODO: Test with ability to stop and return a value
- test "Hook run_fold chain is stopped when handler return 'stop'" do
- # setup test
- hookname = :test_mod_hook
- modulename = :hook_module
- mock(modulename, :hook_callback1, fn(_acc) -> :stop end)
- mock(modulename, :hook_callback2, fn(_acc) -> :executed end)
-
- :ok = :ejabberd_hooks.add(hookname, @host, modulename, :hook_callback1, 40)
- :ok = :ejabberd_hooks.add(hookname, @host, modulename, :hook_callback2, 50)
-
- :stopped = :ejabberd_hooks.run_fold(hookname, @host, :started, [])
- # Only one module has been called
- [{_pid, {^modulename, :hook_callback1, [:started]}, :stop}] = :meck.history(modulename)
- end
-
- test "Error in run_fold is ignored" do
- run_fold_crash(fn(_acc) -> raise "crashed" end)
- end
-
- test "Throw in run_fold is ignored" do
- run_fold_crash(fn(_acc) -> throw :crashed end)
- end
-
- test "Exit in run_fold is ignored" do
- run_fold_crash(fn(_acc) -> exit :crashed end)
- end
-
- # test for run hook with various number of params
- def run_hook(params, fun, result) do
- # setup test
- hookname = :test_mod_hook
- modulename = :hook_module
- callback = :hook_callback
- mock(modulename, callback, fun)
-
- # Then check
- :ok = :ejabberd_hooks.add(hookname, @host, modulename, callback, 40)
- :ok = :ejabberd_hooks.run(hookname, @host, params)
- [{_pid, {^modulename, ^callback, ^params}, ^result}] = :meck.history(modulename)
- end
-
- def run_fold_crash(crash_fun) do
- # setup test
- hookname = :test_mod_hook
- modulename = :hook_module
- mock(modulename, :hook_callback1, crash_fun)
- mock(modulename, :hook_callback2, fn(_acc) -> :final end)
-
- :ok = :ejabberd_hooks.add(hookname, @host, modulename, :hook_callback1, 40)
- :ok = :ejabberd_hooks.add(hookname, @host, modulename, :hook_callback2, 50)
-
- :final = :ejabberd_hooks.run_fold(hookname, @host, :started, [])
- # Both handlers were called
- 2 = length(:meck.history(modulename))
- end
-
- # TODO refactor: Move to ejabberd_test_mock
- def mock(module, function, fun) do
- try do
- :meck.new(module, [:non_strict])
- catch
- :error, {:already_started, _pid} -> :ok
- end
-
- :meck.expect(module, function, fun)
- end
-
-end
diff --git a/test/ejabberd_oauth_mock.exs b/test/ejabberd_oauth_mock.exs
deleted file mode 100644
index 8f1f11843..000000000
--- a/test/ejabberd_oauth_mock.exs
+++ /dev/null
@@ -1,50 +0,0 @@
-# ----------------------------------------------------------------------
-#
-# ejabberd, Copyright (C) 2002-2017 ProcessOne
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# ----------------------------------------------------------------------
-
-defmodule EjabberdOauthMock do
-
- @author "jsautret@process-one.net"
-
- def init() do
- :mnesia.start
- :mnesia.create_table(:oauth_token,
- [ram_copies: [node],
- attributes: [:oauth_token, :us, :scope, :expire]])
- :application.start(:cache_tab)
- :cache_tab.new(:oauth_token,
- [{:max_size, 1000}, {:life_time, 3600}])
- end
-
- def get_token(user, domain, command, expiration \\ 3600) do
- now = {megasecs, secs, _} = :os.timestamp
- expire = 1000000 * megasecs + secs + expiration
- :random.seed now
- token = to_string :random.uniform(100000000)
-
- {:ok, _} = :ejabberd_oauth.associate_access_token(token,
- [{"resource_owner",
- {:user, user, domain}},
- {"scope", [to_string command]},
- {"expiry_time", expire}],
- [])
- token
- end
-
-end
diff --git a/test/ejabberd_sm_mock.exs b/test/ejabberd_sm_mock.exs
deleted file mode 100644
index 9ac739ba5..000000000
--- a/test/ejabberd_sm_mock.exs
+++ /dev/null
@@ -1,121 +0,0 @@
-# ----------------------------------------------------------------------
-#
-# ejabberd, Copyright (C) 2002-2017 ProcessOne
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# ----------------------------------------------------------------------
-
-defmodule EjabberdSmMock do
- @author "jsautret@process-one.net"
-
- require Record
- Record.defrecord :session, Record.extract(:session, from_lib: "ejabberd/include/ejabberd_sm.hrl")
- Record.defrecord :jid, Record.extract(:jid, from_lib: "xmpp/include/jid.hrl")
-
- @agent __MODULE__
-
- def init do
- ModLastMock.init
-
- try do
- Agent.stop(@agent)
- catch
- :exit, _e -> :ok
- end
-
- {:ok, _pid} = Agent.start_link(fn -> [] end, name: @agent)
-
- mock(:ejabberd_sm, :get_user_resources,
- fn (user, domain) -> for s <- get_sessions(user, domain), do: s.resource end)
-
- mock(:ejabberd_sm, :route,
- fn (to, {:exit, _reason}) ->
- user = jid(to, :user)
- domain = jid(to, :server)
- resource = jid(to, :resource)
- disconnect_resource(user, domain, resource)
- :ok
- (_, _) -> :ok
- end)
-
- end
-
- def connect_resource(user, domain, resource,
- opts \\ [priority: 1, conn: :c2s]) do
- Agent.update(@agent, fn sessions ->
- session = %{user: user, domain: domain, resource: resource,
- timestamp: :os.timestamp, pid: self, node: node,
- auth_module: :ejabberd_auth, ip: :undefined,
- priority: opts[:priority], conn: opts[:conn]}
- [session | sessions]
- end)
- end
-
- def disconnect_resource(user, domain, resource) do
- disconnect_resource(user, domain, resource, ModLastMock.now)
- end
-
- def disconnect_resource(user, domain, resource, timestamp) do
- Agent.update(@agent, fn sessions ->
- for s <- sessions,
- s.user != user or s.domain != domain or s.resource != resource, do: s
- end)
- ModLastMock.set_last user, domain, "", timestamp
- end
-
- def get_sessions() do
- Agent.get(@agent, fn sessions -> sessions end)
- end
-
- def get_sessions(user, domain) do
- Agent.get(@agent, fn sessions ->
- for s <- sessions, s.user == user, s.domain == domain, do: s
- end)
- end
-
- def get_session(user, domain, resource) do
- Agent.get(@agent, fn sessions ->
- for s <- sessions,
- s.user == user, s.domain == domain, s.resource == resource, do: s
- end)
- end
-
- def to_record(s) do
- session(usr: {s.user, s.domain, s.ressource},
- us: {s.user, s.domain},
- sid: {s.timestamp, s.pid},
- priority: s.priority,
- info: [conn: s.conn, ip: s.ip, node: s.node,
- oor: false, auth_module: s.auth_module])
- end
-
- ####################################################################
- # Helpers
- ####################################################################
-
-
- # TODO refactor: Move to ejabberd_test_mock
- def mock(module, function, fun) do
- try do
- :meck.new(module)
- catch
- :error, {:already_started, _pid} -> :ok
- end
-
- :meck.expect(module, function, fun)
- end
-
-end
diff --git a/test/elixir_SUITE.erl b/test/elixir_SUITE.erl
deleted file mode 100644
index b869e00f7..000000000
--- a/test/elixir_SUITE.erl
+++ /dev/null
@@ -1,119 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% Author : Mickael Remond <mremond@process-one.net>
-%%% Created : 19 Feb 2015 by Mickael Remond <mremond@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License along
-%%% with this program; if not, write to the Free Software Foundation, Inc.,
-%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-%%%
-%%%----------------------------------------------------------------------
-
-%%% This is a common test wrapper to run our ejabberd tests written in
-%%% Elixir from standard common test code.
-%%%
-%%% Example: Is run with:
-%%% ./rebar skip_deps=true ct suites=elixir
-%%% or from ejabber overall test suite:
-%%% make quicktest
-
--module(elixir_SUITE).
-
--compile(export_all).
-
-init_per_suite(Config) ->
- suite:setup_ejabberd_lib_path(Config),
- check_meck(),
- code:add_pathz(filename:join(test_dir(), "../include")),
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_testcase(_TestCase, Config) ->
- process_flag(error_handler, ?MODULE),
- Config.
-
-all() ->
- case is_elixir_available() of
- true ->
- Dir = test_dir(),
- filelib:fold_files(Dir, ".*test\.exs$", false,
- fun(Filename, Acc) -> [list_to_atom(filename:basename(Filename)) | Acc] end,
- []);
- false ->
- []
- end.
-
-check_meck() ->
- case catch meck:module_info(module) of
- meck ->
- ok;
- {'EXIT',{undef, _}} ->
- ct:print("meck is not available. Please make sure you configured ejabberd with --enable-elixir --enable-tools"),
- ok
- end.
-
-is_elixir_available() ->
- case catch elixir:module_info() of
- {'EXIT',{undef,_}} ->
- ct:print("ejabberd has not been build with Elixir support, skipping Elixir tests."),
- false;
- ModInfo when is_list(ModInfo) ->
- true
- end.
-
-undefined_function(?MODULE, Func, Args) ->
- case lists:suffix(".exs", atom_to_list(Func)) of
- true ->
- run_elixir_test(Func);
- false ->
- error_handler:undefined_function(?MODULE, Func, Args)
- end;
-undefined_function(Module, Func, Args) ->
- error_handler:undefined_function(Module, Func,Args).
-
-run_elixir_test(Func) ->
- %% Elixir tests can be tagged as follow to be ignored (place before test start)
- %% @tag pending: true
- 'Elixir.ExUnit':start([{exclude, [{pending, true}]},
- {formatters,
- ['Elixir.ExUnit.CLIFormatter',
- 'Elixir.ExUnit.CTFormatter']},
- {autorun, false}]),
-
- filelib:fold_files(test_dir(), ".*mock\.exs\$", true,
- fun (File, N) ->
- 'Elixir.Code':load_file(list_to_binary(File)),
- N+1
- end, 0),
-
- 'Elixir.Code':load_file(list_to_binary(filename:join(test_dir(), atom_to_list(Func)))),
- %% I did not use map syntax, so that this file can still be build under R16
- catch 'Elixir.ExUnit.Server':cases_loaded(),
- ResultMap = 'Elixir.ExUnit':run(),
- case maps:find(failures, ResultMap) of
- {ok, 0} ->
- %% Zero failures
- ok;
- {ok, Failures} ->
- ct:print("Tests failed in module '~s': ~.10B failures.~nSee logs for details", [Func, Failures]),
- ct:fail(elixir_test_failure),
- error
- end.
-
-test_dir() ->
- {ok, CWD} = file:get_cwd(),
- filename:join(CWD, "../../test").
diff --git a/test/example_tests.erl b/test/example_tests.erl
index 61b84cc2d..b93e0ccbb 100644
--- a/test/example_tests.erl
+++ b/test/example_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 16 Nov 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/jid_test.exs b/test/jid_test.exs
deleted file mode 100644
index aa3563bea..000000000
--- a/test/jid_test.exs
+++ /dev/null
@@ -1,45 +0,0 @@
-# ----------------------------------------------------------------------
-#
-# ejabberd, Copyright (C) 2002-2017 ProcessOne
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# ----------------------------------------------------------------------
-
-defmodule JidTest do
- @author "mremond@process-one.net"
-
- use ExUnit.Case, async: true
-
- require Record
- Record.defrecord :jid, Record.extract(:jid, from_lib: "xmpp/include/jid.hrl")
-
- setup_all do
- :stringprep.start
- :jid.start
- :ok
- end
-
- test "create a jid from a binary" do
- jid = :jid.from_string("test@localhost/resource")
- assert jid(jid, :user) == "test"
- assert jid(jid, :server) == "localhost"
- assert jid(jid, :resource) == "resource"
- end
-
- test "Check that sending a list to from_string/1 does not crash the jid process" do
- {:error, :need_jid_as_binary} = :jid.from_string('test@localhost/resource')
- end
-end
diff --git a/test/ldap_srv.erl b/test/ldap_srv.erl
index f601827c4..8ac5a7b89 100644
--- a/test/ldap_srv.erl
+++ b/test/ldap_srv.erl
@@ -3,7 +3,7 @@
%%% Created : 21 Jun 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/mam_tests.erl b/test/mam_tests.erl
index e46a13ff0..128df2fe8 100644
--- a/test/mam_tests.erl
+++ b/test/mam_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 14 Nov 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -377,7 +377,7 @@ recv_fin(Config, I, QueryID, NS, IsComplete) when NS == ?NS_MAM_1; NS == ?NS_MAM
complete = Complete,
rsm = RSM}]} = recv_iq(Config),
ct:comment("Checking if complete is ~s", [IsComplete]),
- Complete = IsComplete,
+ ?match(IsComplete, Complete),
RSM;
recv_fin(Config, I, QueryID, ?NS_MAM_TMP = NS, _IsComplete) ->
ct:comment("Receiving fin iq for namespace '~s'", [NS]),
@@ -394,7 +394,7 @@ recv_fin(Config, _, QueryID, ?NS_MAM_0 = NS, IsComplete) ->
complete = Complete,
rsm = RSM} = xmpp:get_subtag(FinMsg, #mam_fin{xmlns = NS}),
ct:comment("Checking if complete is ~s", [IsComplete]),
- Complete = IsComplete,
+ ?match(IsComplete, Complete),
RSM.
send_messages_to_room(Config, Range) ->
@@ -417,7 +417,6 @@ recv_messages_from_room(Config, Range) ->
MyNickJID = jid:replace_resource(Room, MyNick),
MyJID = my_jid(Config),
QID = p1_rand:get_string(),
- Count = length(Range),
I = send(Config, #iq{type = set, to = Room,
sub_els = [#mam_query{xmlns = ?NS_MAM_2, id = QID}]}),
lists:foreach(
@@ -440,8 +439,9 @@ recv_messages_from_room(Config, Range) ->
#iq{from = Room, id = I, type = result,
sub_els = [#mam_fin{xmlns = ?NS_MAM_2,
id = QID,
- rsm = #rsm_set{count = Count},
- complete = true}]} = recv_iq(Config).
+ rsm = RSM,
+ complete = true}]} = recv_iq(Config),
+ match_rsm_count(RSM, length(Range)).
query_all(Config, From, To) ->
lists:foreach(
@@ -454,7 +454,8 @@ query_all(Config, From, To, NS) ->
Range = lists:seq(1, 5),
ID = send_query(Config, #mam_query{xmlns = NS, id = QID}),
recv_archived_messages(Config, From, To, QID, Range),
- #rsm_set{count = 5} = recv_fin(Config, ID, QID, NS, _Complete = true).
+ RSM = recv_fin(Config, ID, QID, NS, _Complete = true),
+ match_rsm_count(RSM, 5).
query_with(Config, From, To) ->
lists:foreach(
@@ -480,7 +481,8 @@ query_with(Config, From, To, NS) ->
end,
ID = send_query(Config, Query),
recv_archived_messages(Config, From, To, QID, Range),
- #rsm_set{count = 5} = recv_fin(Config, ID, QID, NS, true)
+ RSM = recv_fin(Config, ID, QID, NS, true),
+ match_rsm_count(RSM, 5)
end, [Peer, BarePeer]).
query_rsm_max(Config, From, To) ->
@@ -498,7 +500,8 @@ query_rsm_max(Config, From, To, NS) ->
ID = send_query(Config, Query),
recv_archived_messages(Config, From, To, QID, Range),
IsComplete = Max >= 5,
- #rsm_set{count = 5} = recv_fin(Config, ID, QID, NS, IsComplete)
+ RSM = recv_fin(Config, ID, QID, NS, IsComplete),
+ match_rsm_count(RSM, 5)
end, lists:seq(0, 6)).
query_rsm_after(Config, From, To) ->
@@ -517,8 +520,9 @@ query_rsm_after(Config, From, To, NS) ->
rsm = #rsm_set{'after' = After}},
ID = send_query(Config, Query),
recv_archived_messages(Config, From, To, QID, Range),
- #rsm_set{count = 5, first = First} =
+ RSM = #rsm_set{first = First} =
recv_fin(Config, ID, QID, NS, true),
+ match_rsm_count(RSM, 5),
First
end, #rsm_first{data = undefined},
[lists:seq(N, 5) || N <- lists:seq(1, 6)]).
@@ -539,7 +543,15 @@ query_rsm_before(Config, From, To, NS) ->
rsm = #rsm_set{before = Before}},
ID = send_query(Config, Query),
recv_archived_messages(Config, From, To, QID, Range),
- #rsm_set{count = 5, last = Last} =
+ RSM = #rsm_set{last = Last} =
recv_fin(Config, ID, QID, NS, true),
+ match_rsm_count(RSM, 5),
Last
end, <<"">>, lists:reverse([lists:seq(1, N) || N <- lists:seq(0, 5)])).
+
+match_rsm_count(#rsm_set{count = undefined}, _) ->
+ %% The backend doesn't support counting
+ ok;
+match_rsm_count(#rsm_set{count = Count1}, Count2) ->
+ ct:comment("Checking if RSM 'count' is ~p", [Count2]),
+ ?match(Count2, Count1).
diff --git a/test/mix_tests.erl b/test/mix_tests.erl
deleted file mode 100644
index 864150661..000000000
--- a/test/mix_tests.erl
+++ /dev/null
@@ -1,154 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
-%%% Created : 16 Nov 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License along
-%%% with this program; if not, write to the Free Software Foundation, Inc.,
-%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-%%%
-%%%----------------------------------------------------------------------
-
--module(mix_tests).
-
-%% API
--compile(export_all).
--import(suite, [mix_jid/1, mix_room_jid/1, my_jid/1, is_feature_advertised/3,
- disconnect/1, send_recv/2, recv_message/1, send/2,
- put_event/2, get_event/1]).
--include("suite.hrl").
-
-%%%===================================================================
-%%% API
-%%%===================================================================
-%%%===================================================================
-%%% Single user tests
-%%%===================================================================
-single_cases() ->
- {mix_single, [sequence],
- [single_test(feature_enabled)]}.
-
-feature_enabled(Config) ->
- MIX = mix_jid(Config),
- ct:comment("Checking if ~s is set", [?NS_MIX_0]),
- true = is_feature_advertised(Config, ?NS_MIX_0, MIX),
- disconnect(Config).
-
-%%%===================================================================
-%%% Master-slave tests
-%%%===================================================================
-master_slave_cases() ->
- {mix_master_slave, [sequence],
- [master_slave_test(all)]}.
-
-all_master(Config) ->
- MIX = mix_jid(Config),
- Room = mix_room_jid(Config),
- MyJID = my_jid(Config),
- MyBareJID = jid:remove_resource(MyJID),
- #iq{type = result,
- sub_els =
- [#disco_info{
- identities = [#identity{category = <<"conference">>,
- type = <<"text">>}],
- xdata = [#xdata{type = result, fields = XFields}]}]} =
- send_recv(Config, #iq{type = get, to = MIX, sub_els = [#disco_info{}]}),
- true = lists:any(
- fun(#xdata_field{var = <<"FORM_TYPE">>,
- values = [?NS_MIX_SERVICEINFO_0]}) -> true;
- (_) -> false
- end, XFields),
- %% Joining
- Nodes = [?NS_MIX_NODES_MESSAGES, ?NS_MIX_NODES_PRESENCE,
- ?NS_MIX_NODES_PARTICIPANTS, ?NS_MIX_NODES_SUBJECT,
- ?NS_MIX_NODES_CONFIG],
- #iq{type = result,
- sub_els = [#mix_join{subscribe = Nodes, jid = MyBareJID}]} =
- send_recv(Config, #iq{type = set, to = Room,
- sub_els = [#mix_join{subscribe = Nodes}]}),
- #message{from = Room,
- sub_els =
- [#ps_event{
- items = #ps_items{
- node = ?NS_MIX_NODES_PARTICIPANTS,
- items = [#ps_item{
- id = ParticipantID,
- sub_els = [PXML]}]}}]} =
- recv_message(Config),
- #mix_participant{jid = MyBareJID} = xmpp:decode(PXML),
- %% Coming online
- PresenceID = p1_rand:get_string(),
- Presence = xmpp:encode(#presence{}),
- #iq{type = result,
- sub_els =
- [#pubsub{
- publish = #ps_publish{
- node = ?NS_MIX_NODES_PRESENCE,
- items = [#ps_item{id = PresenceID}]}}]} =
- send_recv(
- Config,
- #iq{type = set, to = Room,
- sub_els =
- [#pubsub{
- publish = #ps_publish{
- node = ?NS_MIX_NODES_PRESENCE,
- items = [#ps_item{
- id = PresenceID,
- sub_els = [Presence]}]}}]}),
- #message{from = Room,
- sub_els =
- [#ps_event{
- items = #ps_items{
- node = ?NS_MIX_NODES_PRESENCE,
- items = [#ps_item{
- id = PresenceID,
- sub_els = [Presence]}]}}]} =
- recv_message(Config),
- %% Coming offline
- send(Config, #presence{type = unavailable, to = Room}),
- %% Receiving presence retract event
- #message{from = Room,
- sub_els = [#ps_event{
- items = #ps_items{
- node = ?NS_MIX_NODES_PRESENCE,
- retract = PresenceID}}]} =
- recv_message(Config),
- %% Leaving
- #iq{type = result, sub_els = []} =
- send_recv(Config, #iq{type = set, to = Room, sub_els = [#mix_leave{}]}),
- #message{from = Room,
- sub_els =
- [#ps_event{
- items = #ps_items{
- node = ?NS_MIX_NODES_PARTICIPANTS,
- retract = ParticipantID}}]} =
- recv_message(Config),
- put_event(Config, disconnect),
- disconnect(Config).
-
-all_slave(Config) ->
- disconnect = get_event(Config),
- disconnect(Config).
-
-%%%===================================================================
-%%% Internal functions
-%%%===================================================================
-single_test(T) ->
- list_to_atom("mix_" ++ atom_to_list(T)).
-
-master_slave_test(T) ->
- {list_to_atom("mix_" ++ atom_to_list(T)), [parallel],
- [list_to_atom("mix_" ++ atom_to_list(T) ++ "_master"),
- list_to_atom("mix_" ++ atom_to_list(T) ++ "_slave")]}.
diff --git a/test/mod_admin_extra_test.exs b/test/mod_admin_extra_test.exs
deleted file mode 100644
index 7b1bc21de..000000000
--- a/test/mod_admin_extra_test.exs
+++ /dev/null
@@ -1,374 +0,0 @@
-# ----------------------------------------------------------------------
-#
-# ejabberd, Copyright (C) 2002-2017 ProcessOne
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# ----------------------------------------------------------------------
-
-defmodule EjabberdModAdminExtraTest do
- use ExUnit.Case, async: false
-
- require EjabberdAuthMock
- require EjabberdSmMock
- require ModLastMock
- require ModRosterMock
-
- @author "jsautret@process-one.net"
-
- @user "user"
- @domain "domain"
- @password "password"
- @resource "resource"
-
- require Record
- Record.defrecord :jid, Record.extract(:jid, from_lib: "xmpp/include/jid.hrl")
-
- setup_all do
- try do
- :jid.start
- :stringprep.start
- :mnesia.start
- :ejabberd_mnesia.start
- :p1_sha.load_nif
- :ejabberd_hooks.start_link
- rescue
- _ -> :ok
- end
- :ok = :ejabberd_config.start(["domain"], [])
- :gen_mod.start_link
- :acl.start_link
- :ejabberd_access_permissions.start_link()
- :ejabberd_commands.start_link
- :mod_admin_extra.start(@domain, [])
- :ejabberd_hooks.start_link
- :ok
- end
-
- setup do
- :meck.unload
- EjabberdAuthMock.init
- EjabberdSmMock.init
- ModRosterMock.init(@domain, :mod_admin_extra)
- :ok
- end
-
- ###################### Accounts
- test "check_account works" do
- EjabberdAuthMock.create_user @user, @domain, @password
-
- assert call_command(:check_account, [@user, @domain])
- refute call_command(:check_account, [@user, "bad_domain"])
- refute call_command(:check_account, ["bad_user", @domain])
-
- assert :meck.validate :ejabberd_auth
- end
-
- test "check_password works" do
-
- EjabberdAuthMock.create_user @user, @domain, @password
-
- assert call_command(:check_password,
- [@user, @domain, @password])
- refute call_command(:check_password,
- [@user, @domain, "bad_password"])
- refute call_command(:check_password,
- [@user, "bad_domain", @password])
- refute call_command(:check_password,
- ["bad_user", @domain, @password])
-
- assert :meck.validate :ejabberd_auth
-
- end
-
- test "check_password_hash works" do
-
- EjabberdAuthMock.create_user @user, @domain, @password
- hash = "5F4DCC3B5AA765D61D8327DEB882CF99" # echo -n password|md5
-
- assert call_command(:check_password_hash,
- [@user, @domain, hash, "md5"])
- refute call_command(:check_password_hash,
- [@user, @domain, "bad_hash", "md5"])
- refute call_command(:check_password_hash,
- [@user, "bad_domain", hash, "md5"])
- refute call_command(:check_password_hash,
- ["bad_user", @domain, hash, "md5"])
-
- hash = "5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8" # echo -n password|shasum
- assert call_command(:check_password_hash,
- [@user, @domain, hash, "sha"])
-
- assert :unkown_hash_method ==
- catch_throw call_command(:check_password_hash,
- [@user, @domain, hash, "bad_method"])
-
- assert :meck.validate :ejabberd_auth
-
- end
-
- test "set_password works" do
- EjabberdAuthMock.create_user @user, @domain, @password
-
- assert call_command(:change_password,
- [@user, @domain, "new_password"])
- refute call_command(:check_password,
- [@user, @domain, @password])
- assert call_command(:check_password,
- [@user, @domain, "new_password"])
- assert {:not_found, 'unknown_user'} ==
- catch_throw call_command(:change_password,
- ["bad_user", @domain,
- @password])
- assert :meck.validate :ejabberd_auth
- end
-
- ###################### Sessions
-
- test "num_resources works" do
- assert 0 == call_command(:num_resources,
- [@user, @domain])
-
- EjabberdSmMock.connect_resource @user, @domain, @resource
- assert 1 == call_command(:num_resources,
- [@user, @domain])
-
- EjabberdSmMock.connect_resource @user, @domain, @resource<>"2"
- assert 2 == call_command(:num_resources,
- [@user, @domain])
-
- EjabberdSmMock.connect_resource @user<>"1", @domain, @resource
- assert 2 == call_command(:num_resources,
- [@user, @domain])
-
- EjabberdSmMock.disconnect_resource @user, @domain, @resource
- assert 1 == call_command(:num_resources,
- [@user, @domain])
-
- assert :meck.validate :ejabberd_sm
- end
-
- test "resource_num works" do
- EjabberdSmMock.connect_resource @user, @domain, @resource<>"3"
- EjabberdSmMock.connect_resource @user, @domain, @resource<>"2"
- EjabberdSmMock.connect_resource @user, @domain, @resource<>"1"
-
- assert :bad_argument ==
- elem(catch_throw(call_command(:resource_num,
- [@user, @domain, 0])), 0)
- assert @resource<>"1" ==
- call_command(:resource_num, [@user, @domain, 1])
- assert @resource<>"3" ==
- call_command(:resource_num, [@user, @domain, 3])
- assert :bad_argument ==
- elem(catch_throw(call_command(:resource_num,
- [@user, @domain, 4])), 0)
- assert :meck.validate :ejabberd_sm
- end
-
- test "kick_session works" do
- EjabberdSmMock.connect_resource @user, @domain, @resource<>"1"
- EjabberdSmMock.connect_resource @user, @domain, @resource<>"2"
- EjabberdSmMock.connect_resource @user, @domain, @resource<>"3"
-
- assert 3 == length EjabberdSmMock.get_sessions @user, @domain
- assert 1 == length EjabberdSmMock.get_session @user, @domain, @resource<>"2"
-
- assert :ok ==
- call_command(:kick_session,
- [@user, @domain,
- @resource<>"2", "kick"])
-
- assert 2 == length EjabberdSmMock.get_sessions @user, @domain
- assert 0 == length EjabberdSmMock.get_session @user, @domain, @resource<>"2"
-
- assert :meck.validate :ejabberd_sm
- end
-
- ###################### Last
-
- test "get_last works" do
-
- assert {_, 'NOT FOUND'} =
- call_command(:get_last, [@user, @domain])
-
- EjabberdSmMock.connect_resource @user, @domain, @resource<>"1"
- EjabberdSmMock.connect_resource @user, @domain, @resource<>"2"
-
- assert {_, 'ONLINE'} =
- call_command(:get_last, [@user, @domain])
-
- EjabberdSmMock.disconnect_resource @user, @domain, @resource<>"1"
-
- assert {_, 'ONLINE'} =
- call_command(:get_last, [@user, @domain])
-
- now = {megasecs, secs, _microsecs} = :os.timestamp
- timestamp = megasecs * 1000000 + secs
- EjabberdSmMock.disconnect_resource(@user, @domain, @resource<>"2",
- timestamp)
- {{year, month, day}, {hour, minute, second}} = :calendar.now_to_universal_time now
- result = IO.iodata_to_binary(:io_lib.format(
- "~w-~.2.0w-~.2.0wT~.2.0w:~.2.0w:~.2.0wZ",
- [year, month, day, hour, minute, second]))
- assert {result, ""} ==
- call_command(:get_last, [@user, @domain])
-
- assert :meck.validate :mod_last
- end
-
- ###################### Roster
-
- @tag :skip
- test "add_rosteritem and delete_rosteritem work" do
- # Connect user
- # Add user1 & user2 to user's roster
- # Remove user1 & user2 from user's roster
-
- EjabberdSmMock.connect_resource @user, @domain, @resource
-
- assert [] == ModRosterMock.get_roster(@user, @domain)
-
- assert :ok ==
- call_command(:add_rosteritem, [@user, @domain,
- @user<>"1", @domain,
- "nick1",
- "group1",
- "both"])
- # Check that user1 is the only item of the user's roster
- result = ModRosterMock.get_roster(@user, @domain)
- assert 1 == length result
- [{{@user, @domain, jid}, opts}] = result
- assert @user<>"1@"<>@domain == jid
- assert "nick1" == opts.nick
- assert ["group1"] == opts.groups
- assert :both == opts.subs
-
- # Check that the item roster user1 was pushed with subscription
- # 'both' to user online ressource
- jid = :jlib.make_jid(@user, @domain, @resource)
- assert 1 ==
- :meck.num_calls(:ejabberd_sm, :route,
- [jid,
- {:item, {@user<>"1", @domain, ""}, :both}])
-
- assert :ok ==
- call_command(:add_rosteritem, [@user, @domain,
- @user<>"2", @domain,
- "nick2",
- "group2",
- "both"])
- result = ModRosterMock.get_roster(@user, @domain)
- assert 2 == length result
-
-
- # Check that the item roster user2 was pushed with subscription
- # 'both' to user online ressource
- assert 1 ==
- :meck.num_calls(:ejabberd_sm, :route,
- [jid,
- {:item, {@user<>"2", @domain, ""}, :both}])
-
-
- call_command(:delete_rosteritem, [@user, @domain,
- @user<>"1", @domain])
- result = ModRosterMock.get_roster(@user, @domain)
- assert 1 == length result
- [{{@user, @domain, jid}, opts}] = result
- assert @user<>"2@"<>@domain == jid
- assert "nick2" == opts.nick
- assert ["group2"] == opts.groups
- assert :both == opts.subs
-
- # Check that the item roster user1 was pushed with subscription
- # 'none' to user online ressource
- jid = :jlib.make_jid(@user, @domain, @resource)
- assert 1 ==
- :meck.num_calls(:ejabberd_sm, :route,
- [jid,
- {:item, {@user<>"1", @domain, ""}, :none}])
-
- call_command(:delete_rosteritem, [@user, @domain,
- @user<>"2", @domain])
-
- # Check that the item roster user2 was pushed with subscription
- # 'none' to user online ressource
- assert 1 ==
- :meck.num_calls(:ejabberd_sm, :route,
- [jid,
- {:item, {@user<>"2", @domain, ""}, :none}])
-
- # Check that nothing else was pushed to user resource
- jid = jid(user: @user, server: @domain, resource: :_,
- luser: @user, lserver: @domain, lresource: :_)
- assert 4 ==
- :meck.num_calls(:ejabberd_sm, :route,
- [jid,
- {:item, :_, :_}])
-
- assert [] == ModRosterMock.get_roster(@user, @domain)
- assert :meck.validate :ejabberd_sm
-
- end
-
- @tag :skip
- test "get_roster works" do
- assert [] == ModRosterMock.get_roster(@user, @domain)
- assert [] == call_command(:get_roster, [@user, @domain],
- :admin)
-
- assert :ok ==
- call_command(:add_rosteritem, [@user, @domain,
- @user<>"1", @domain,
- "nick1",
- "group1",
- "both"])
- assert [{@user<>"1@"<>@domain, "", 'both', 'none', "group1"}] ==
- call_command(:get_roster, [@user, @domain], :admin)
- assert :ok ==
- call_command(:add_rosteritem, [@user, @domain,
- @user<>"2", @domain,
- "nick2",
- "group2",
- "none"])
- result = call_command(:get_roster, [@user, @domain], :admin)
- assert 2 == length result
- assert Enum.member?(result, {@user<>"1@"<>@domain, "", 'both', 'none', "group1"})
- assert Enum.member?(result, {@user<>"2@"<>@domain, "", 'none', 'none', "group2"})
-
- end
-
- defp call_command(name, args) do
- :ejabberd_commands.execute_command2(name, args, %{:caller_module => :ejabberd_ctl})
- end
-
- defp call_command(name, args, mode) do
- call_command(name, args)
- end
-
-# kick_user command is defined in ejabberd_sm, move to extra?
-# test "kick_user works" do
-# assert 0 == call_command(:num_resources,
-# [@user, @domain])
-# EjabberdSmMock.connect_resource(@user, @domain, @resource<>"1")
-# EjabberdSmMock.connect_resource(@user, @domain, @resource<>"2")
-# assert 2 ==
-# call_command(:kick_user, [@user, @domain])
-# assert 0 == call_command(:num_resources,
-# [@user, @domain])
-# assert :meck.validate :ejabberd_sm
-# end
-
-end
diff --git a/test/mod_http_api_mock_test.exs b/test/mod_http_api_mock_test.exs
deleted file mode 100644
index ceda2bb0f..000000000
--- a/test/mod_http_api_mock_test.exs
+++ /dev/null
@@ -1,270 +0,0 @@
-# ----------------------------------------------------------------------
-#
-# ejabberd, Copyright (C) 2002-2017 ProcessOne
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# ----------------------------------------------------------------------
-
-defmodule ModHttpApiMockTest do
- use ExUnit.Case, async: false
-
- @author "jsautret@process-one.net"
-
- # Admin user
- @admin "admin"
- @adminpass "adminpass"
- # Non admin user
- @user "user"
- @userpass "userpass"
- # XMPP domain
- @domain "domain"
- # mocked command
- @command "command_test"
- @acommand String.to_atom(@command)
- # default API version
- @version 0
-
- require Record
- Record.defrecord :request, Record.extract(:request, from_lib: "ejabberd/include/ejabberd_http.hrl")
-
- setup_all do
- try do
- :jid.start
- :mnesia.start
- :ejabberd_mnesia.start
- :stringprep.start
- :ejabberd_hooks.start_link
- :ejabberd_config.start([@domain], [])
- {:ok, _} = :ejabberd_access_permissions.start_link()
- :ejabberd_commands.start_link
- rescue
- _ -> :ok
- end
- :mod_http_api.start(@domain, [])
- EjabberdOauthMock.init
- :ok
- end
-
- setup do
- :meck.unload
- :meck.new :ejabberd_commands
- :meck.new(:acl, [:passthrough]) # Need to fake acl to allow oauth
- EjabberdAuthMock.init
- :ok
- end
-
- test "HTTP GET simple command call with Basic Auth" do
- EjabberdAuthMock.create_user @user, @domain, @userpass
-
- # Mock a simple command() -> :ok
- :meck.expect(:ejabberd_commands, :get_command_format,
- fn (@acommand, %{usr: {@user, @domain, _}}, @version) ->
- {[], {:res, :rescode}}
- end)
- :meck.expect(:ejabberd_commands, :get_exposed_commands,
- fn () -> [@acommand] end)
- :meck.expect(:ejabberd_commands, :execute_command2,
- fn (@acommand, [], %{usr: {@user, @domain, _}}, @version) ->
- :ok
- end)
-
- :ejabberd_config.add_local_option(:commands, [[{:add_commands, [@acommand]}]])
-
- # Correct Basic Auth call
- req = request(method: :GET,
- path: ["api", @command],
- q: [nokey: ""],
- # Basic auth
- auth: {@user<>"@"<>@domain, @userpass},
- ip: {{127,0,0,1},60000},
- host: @domain)
- result = :mod_http_api.process([@command], req)
-
- # history = :meck.history(:ejabberd_commands)
-
- assert 200 == elem(result, 0) # HTTP code
- assert "0" == elem(result, 2) # command result
-
- # Bad password
- req = request(method: :GET,
- path: ["api", @command],
- q: [nokey: ""],
- # Basic auth
- auth: {@user<>"@"<>@domain, @userpass<>"bad"},
- ip: {{127,0,0,1},60000},
- host: @domain)
- result = :mod_http_api.process([@command], req)
- assert 401 == elem(result, 0) # HTTP code
-
- # Check that the command was executed only once
- assert 1 ==
- :meck.num_calls(:ejabberd_commands, :execute_command2, :_)
-
- assert :meck.validate :ejabberd_auth
- assert :meck.validate :ejabberd_commands
- end
-
- test "HTTP GET simple command call with OAuth" do
- EjabberdAuthMock.create_user @user, @domain, @userpass
-
- # Mock a simple command() -> :ok
- :meck.expect(:ejabberd_commands, :get_command_format,
- fn (@acommand, %{usr: {@user, @domain, _}}, @version) ->
- {[], {:res, :rescode}}
- end)
- :meck.expect(:ejabberd_commands, :get_exposed_commands,
- fn () -> [@acommand] end)
- :meck.expect(:ejabberd_commands, :execute_command2,
- fn (@acommand, [], %{usr: {@user, @domain, _}, oauth_scope: ["ejabberd:user"]}, @version) ->
- :ok
- (@acommand, [], %{usr: {@user, @domain, _}, oauth_scope: [@command]}, @version) ->
- :ok
- (@acommand, [], %{usr: {@user, @domain, _}, oauth_scope: _}, @version) ->
- throw({:error, :access_rules_unauthorized})
- end)
-
-
- # Correct OAuth call using specific scope
- token = EjabberdOauthMock.get_token @user, @domain, @command
- req = request(method: :GET,
- path: ["api", @command],
- q: [nokey: ""],
- # OAuth
- auth: {:oauth, token, []},
- ip: {{127,0,0,1},60000},
- host: @domain)
- result = :mod_http_api.process([@command], req)
- assert 200 == elem(result, 0) # HTTP code
- assert "0" == elem(result, 2) # command result
-
- # Correct OAuth call using specific ejabberd:user scope
- token = EjabberdOauthMock.get_token @user, @domain, "ejabberd:user"
- req = request(method: :GET,
- path: ["api", @command],
- q: [nokey: ""],
- # OAuth
- auth: {:oauth, token, []},
- ip: {{127,0,0,1},60000},
- host: @domain)
- result = :mod_http_api.process([@command], req)
- assert 200 == elem(result, 0) # HTTP code
- assert "0" == elem(result, 2) # command result
-
- # Wrong OAuth token
- req = request(method: :GET,
- path: ["api", @command],
- q: [nokey: ""],
- # OAuth
- auth: {:oauth, "bad"<>token, []},
- ip: {{127,0,0,1},60000},
- host: @domain)
- result = :mod_http_api.process([@command], req)
- assert 401 == elem(result, 0) # HTTP code
-
- # Expired OAuth token
- token = EjabberdOauthMock.get_token @user, @domain, @command, 1
- :timer.sleep 1500
- req = request(method: :GET,
- path: ["api", @command],
- q: [nokey: ""],
- # OAuth
- auth: {:oauth, token, []},
- ip: {{127,0,0,1},60000},
- host: @domain)
- result = :mod_http_api.process([@command], req)
- assert 401 == elem(result, 0) # HTTP code
-
- # Wrong OAuth scope
- token = EjabberdOauthMock.get_token @user, @domain, "bad_command"
- :timer.sleep 1500
- req = request(method: :GET,
- path: ["api", @command],
- q: [nokey: ""],
- # OAuth
- auth: {:oauth, token, []},
- ip: {{127,0,0,1},60000},
- host: @domain)
- result = :mod_http_api.process([@command], req)
- assert 403 == elem(result, 0) # HTTP code
-
- # Check that the command was executed twice
- assert 3 ==
- :meck.num_calls(:ejabberd_commands, :execute_command2, :_)
-
- assert :meck.validate :ejabberd_auth
- #assert :meck.validate :ejabberd_commands
- #assert :ok = :meck.history(:ejabberd_commands)
- end
-
- test "Request oauth token, resource owner password credentials" do
- EjabberdAuthMock.create_user @user, @domain, @userpass
- :application.set_env(:oauth2, :backend, :ejabberd_oauth)
- :application.start(:oauth2)
-
- # Mock a simple command() -> :ok
- :meck.expect(:ejabberd_commands, :get_command_format,
- fn (@acommand, {@user, @domain, {:oauth, _token}, false}, @version) ->
- {[], {:res, :rescode}}
- end)
- :meck.expect(:ejabberd_commands, :get_exposed_commands,
- fn () -> [@acommand] end)
-
- #Mock acl to allow oauth authorizations
- :meck.expect(:acl, :match_rule, fn(_Server, _Access, _Jid) -> :allow end)
-
-
- # Correct password
- req = request(method: :POST,
- path: ["oauth", "token"],
- q: [{"grant_type", "password"}, {"scope", @command}, {"username", @user<>"@"<>@domain}, {"ttl", "4000"}, {"password", @userpass}],
- ip: {{127,0,0,1},60000},
- host: @domain)
- result = :ejabberd_oauth.process([], req)
- assert 200 = elem(result, 0) #http code
- {kv} = :jiffy.decode(elem(result,2))
- assert {_, "bearer"} = List.keyfind(kv, "token_type", 0)
- assert {_, @command} = List.keyfind(kv, "scope", 0)
- assert {_, 4000} = List.keyfind(kv, "expires_in", 0)
- {"access_token", _token} = List.keyfind(kv, "access_token", 0)
-
- #missing grant_type
- req = request(method: :POST,
- path: ["oauth", "token"],
- q: [{"scope", @command}, {"username", @user<>"@"<>@domain}, {"password", @userpass}],
- ip: {{127,0,0,1},60000},
- host: @domain)
- result = :ejabberd_oauth.process([], req)
- assert 400 = elem(result, 0) #http code
- {kv} = :jiffy.decode(elem(result,2))
- assert {_, "unsupported_grant_type"} = List.keyfind(kv, "error", 0)
-
-
- # incorrect user/pass
- req = request(method: :POST,
- path: ["oauth", "token"],
- q: [{"grant_type", "password"}, {"scope", @command}, {"username", @user<>"@"<>@domain}, {"password", @userpass<>"aa"}],
- ip: {{127,0,0,1},60000},
- host: @domain)
- result = :ejabberd_oauth.process([], req)
- assert 400 = elem(result, 0) #http code
- {kv} = :jiffy.decode(elem(result,2))
- assert {_, "invalid_grant"} = List.keyfind(kv, "error", 0)
-
- assert :meck.validate :ejabberd_auth
- assert :meck.validate :ejabberd_commands
- end
-
-end
diff --git a/test/mod_http_api_test.exs b/test/mod_http_api_test.exs
deleted file mode 100644
index f7abbc004..000000000
--- a/test/mod_http_api_test.exs
+++ /dev/null
@@ -1,127 +0,0 @@
-# ----------------------------------------------------------------------
-#
-# ejabberd, Copyright (C) 2002-2017 ProcessOne
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# ----------------------------------------------------------------------
-
-defmodule ModHttpApiTest do
- @author "mremond@process-one.net"
-
- use ExUnit.Case, async: true
-
- require Record
- Record.defrecord :request, Record.extract(:request, from_lib: "ejabberd/include/ejabberd_http.hrl")
- Record.defrecord :ejabberd_commands, Record.extract(:ejabberd_commands, from_lib: "ejabberd/include/ejabberd_commands.hrl")
-
- setup_all do
- :ok = :mnesia.start
- :ejabberd_mnesia.start
- :stringprep.start
- :ejabberd_hooks.start_link
- :ok = :ejabberd_config.start(["localhost"], [])
- :acl.start_link
- {:ok, _} = :ejabberd_access_permissions.start_link()
- {:ok, _} = :ejabberd_commands.start_link
- :ok = :ejabberd_commands.register_commands(cmds)
- on_exit fn ->
- :meck.unload
- unregister_commands(cmds) end
- end
-
- test "We can expose several commands to API at a time" do
- setup_mocks()
- assert :ok == :ejabberd_commands.expose_commands([:open_cmd, :user_cmd])
- commands = :ejabberd_commands.get_exposed_commands()
- assert Enum.member?(commands, :open_cmd)
- assert Enum.member?(commands, :user_cmd)
- end
-
-# test "We can call open commands without authentication" do
-# setup_mocks()
-# :ejabberd_commands.expose_commands([:open_cmd])
-# request = request(method: :POST, ip: {{127,0,0,1},50000}, data: "[]")
-# {200, _, _} = :mod_http_api.process(["open_cmd"], request)
-# end
-
- # This related to the commands config file option
- test "Attempting to access a command that is not exposed as HTTP API returns 403" do
- setup_mocks()
- assert :ok == :ejabberd_commands.expose_commands([])
- request = request(method: :POST, ip: {{127,0,0,1},50000}, data: "{}")
- {403, _, _} = :mod_http_api.process(["open_cmd"], request)
- end
-
- test "Call to user, admin or restricted commands without authentication are rejected" do
- setup_mocks()
- assert :ok == :ejabberd_commands.expose_commands([:user_cmd, :admin_cmd, :restricted])
- request = request(method: :POST, ip: {{127,0,0,1},50000}, data: "{}")
- {400, _, _} = :mod_http_api.process(["user_cmd"], request)
- {403, _, _} = :mod_http_api.process(["admin_cmd"], request)
- {403, _, _} = :mod_http_api.process(["restricted_cmd"], request)
- end
-
- @tag pending: true
- test "If admin_ip_access is enabled, we can call restricted API without authentication from that IP" do
- setup_mocks()
- end
-
- # Define a set of test commands that we expose through API
- # We define one for each policy type
- defp cmds do
- [:open, :user, :admin, :restricted]
- |> Enum.map(&({&1, String.to_atom(to_string(&1) <> "_cmd")}))
- |> Enum.map(fn({cmd_type, cmd}) ->
- ejabberd_commands(name: cmd, tags: [:test],
- policy: cmd_type,
- module: __MODULE__,
- function: cmd,
- args: [],
- result: {:res, :rescode})
- end)
- end
-
- def open_cmd, do: :ok
- def user_cmd(_, _), do: :ok
- def admin_cmd, do: :ok
- def restricted_cmd, do: :ok
-
- defp setup_mocks() do
- :meck.unload
- mock(:gen_mod, :get_module_opt,
- fn (_server, :mod_http_api, _admin_ip_access, _, _) ->
- [{:allow, [{:ip, {{127,0,0,2}, 32}}]}]
- end)
- end
-
- defp mock(module, function, fun) do
- try do
- :meck.new(module)
- catch
- :error, {:already_started, _pid} -> :ok
- end
- :meck.expect(module, function, fun)
- end
-
- defp unregister_commands(commands) do
- try do
- :ejabberd_commands.unregister_commands(commands)
- catch
- _,_ -> :ok
- end
- end
-
-end
diff --git a/test/mod_last_mock.exs b/test/mod_last_mock.exs
deleted file mode 100644
index 25f2bd473..000000000
--- a/test/mod_last_mock.exs
+++ /dev/null
@@ -1,79 +0,0 @@
-# ----------------------------------------------------------------------
-#
-# ejabberd, Copyright (C) 2002-2017 ProcessOne
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# ----------------------------------------------------------------------
-
-defmodule ModLastMock do
-
- require Record
- Record.defrecord :session, Record.extract(:session, from_lib: "ejabberd/include/ejabberd_sm.hrl")
- Record.defrecord :jid, Record.extract(:jid, from_lib: "xmpp/include/jid.hrl")
-
- @author "jsautret@process-one.net"
- @agent __MODULE__
-
- def init do
- try do
- Agent.stop(@agent)
- catch
- :exit, _e -> :ok
- end
-
- {:ok, _pid} = Agent.start_link(fn -> %{} end, name: @agent)
-
- mock(:mod_last, :get_last_info,
- fn (user, domain) ->
- Agent.get(@agent, fn last ->
- case Map.get(last, {user, domain}, :not_found) do
- {ts, status} -> {:ok, ts, status}
- result -> result
- end
- end)
- end)
- end
-
- def set_last(user, domain, status) do
- set_last(user, domain, status, now)
- end
-
- def set_last(user, domain, status, timestamp) do
- Agent.update(@agent, fn last ->
- Map.put(last, {user, domain}, {timestamp, status})
- end)
- end
-
- ####################################################################
- # Helpers
- ####################################################################
- def now() do
- {megasecs, secs, _microsecs} = :os.timestamp
- megasecs * 1000000 + secs
- end
-
- # TODO refactor: Move to ejabberd_test_mock
- def mock(module, function, fun) do
- try do
- :meck.new(module)
- catch
- :error, {:already_started, _pid} -> :ok
- end
-
- :meck.expect(module, function, fun)
- end
-
-end
diff --git a/test/mod_roster_mock.exs b/test/mod_roster_mock.exs
deleted file mode 100644
index 70f273898..000000000
--- a/test/mod_roster_mock.exs
+++ /dev/null
@@ -1,159 +0,0 @@
-# ----------------------------------------------------------------------
-#
-# ejabberd, Copyright (C) 2002-2017 ProcessOne
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# ----------------------------------------------------------------------
-
-defmodule ModRosterMock do
- @author "jsautret@process-one.net"
-
- require Record
- Record.defrecord :roster, Record.extract(:roster, from_lib: "ejabberd/include/mod_roster.hrl")
- Record.defrecord :roster_version, Record.extract(:roster_version, from_lib: "ejabberd/include/mod_roster.hrl")
-
- @agent __MODULE__
-
- def init(domain, module) do
- try do
- Agent.stop(@agent)
- catch
- :exit, _e -> :ok
- end
-
- {:ok, _pid} = Agent.start_link(fn -> %{} end, name: @agent)
-
- mock_with_meck
-
- :ejabberd_mnesia.create(:mod_roster_mnesia, :roster,
- [ram_copies: [node()],
- attributes: Keyword.keys(roster(roster())),
- index: [:us]])
- :ejabberd_mnesia.create(:mod_roster_mnesia, :roster_version,
- [ram_copies: [node()],
- attributes: Keyword.keys(roster_version(roster_version()))])
- #:mod_roster.stop(domain)
- :gen_mod.start_module(domain, :mod_roster)
- end
-
- def mock_with_meck do
-# mock(:gen_mod, :db_type,
-# fn (_server, :mod_roster_mnesia) ->
-# :mnesia
-# end)
-#
-# mock(:mnesia, :transaction,
-# fn (_server, function) ->
-# {:atomic, function.()}
-# end)
-#
-# mock(:mnesia, :write,
-# fn (Item) ->
-# throw Item
-# {:atomic, :ok}
-# end)
-
- mock(:mod_roster_mnesia, :init,
- fn (_server, _opts) ->
- :ok
- end)
- mock(:mod_roster_mnesia, :transaction,
- fn (_server, function) ->
- {:atomic, function.()}
- end)
-
- mock(:mod_roster_mnesia, :update_roster_t,
- fn (user, domain, {u, d, _r}, item) ->
- add_roster_item(user, domain, u<>"@"<>d,
- roster(item, :name),
- roster(item, :subscription),
- roster(item, :groups),
- roster(item, :ask),
- roster(item, :askmessage))
- end)
-
- mock(:mod_roster_mnesia, :invalidate_roster_cache,
- fn (_user, _server) ->
- :ok
- end)
-
- end
-
- def add_roster_item(user, domain, jid, nick, subs \\ :none, groups \\ [],
- ask \\ :none, askmessage \\ "")
- when is_binary(user) and byte_size(user) > 0
- and is_binary(domain) and byte_size(domain) > 0
- and is_binary(jid) and byte_size(jid) > 0
- and is_binary(nick)
- and is_atom(subs)
- and is_list(groups)
- and is_atom(ask)
- and is_binary(askmessage)
- do
- Agent.update(@agent, fn roster ->
- Map.put(roster, {user, domain, jid}, %{nick: nick,
- subs: subs, groups: groups,
- ask: ask, askmessage: askmessage})
- end)
- end
-
- def remove_roster_item(user, domain, jid) do
- Agent.update(@agent, fn roster ->
- Map.delete(roster, {user, domain, jid})
- end)
- end
-
- def get_rosters() do
- Agent.get(@agent, fn roster -> roster end)
- end
-
- def get_roster(user, domain) do
- Agent.get(@agent, fn roster ->
- for {u, d, jid} <- Map.keys(roster), u == user, d == domain,
- do: {{u, d, jid}, Map.fetch!(roster, {u, d, jid})}
- end)
- end
-
- def to_record({{user, domain, jid}, r}) do
- roster(usj: {user, domain, jid},
- us: {user, domain},
- jid: :jid.from_string(jid),
- subscription: r.subs,
- ask: r.ask,
- groups: r.groups,
- askmessage: r.askmessage
- )
- end
- def to_records(rosters) do
- for item <- rosters, do: to_record(item)
- end
-
-####################################################################
-# Helpers
-####################################################################
-
- # TODO refactor: Move to ejabberd_test_mock
- def mock(module, function, fun) do
- try do
- :meck.new(module, [:non_strict, :passthrough, :unstick])
- catch
- :error, {:already_started, _pid} -> :ok
- end
-
- :meck.expect(module, function, fun)
- end
-
-end
diff --git a/test/muc_tests.erl b/test/muc_tests.erl
index 617ca8dd2..e744e3fc9 100644
--- a/test/muc_tests.erl
+++ b/test/muc_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 15 Oct 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/offline_tests.erl b/test/offline_tests.erl
index 4b91f818b..fbf1fbf74 100644
--- a/test/offline_tests.erl
+++ b/test/offline_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 7 Nov 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/privacy_tests.erl b/test/privacy_tests.erl
index 8cd99f513..f27a08b82 100644
--- a/test/privacy_tests.erl
+++ b/test/privacy_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 18 Oct 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/private_tests.erl b/test/private_tests.erl
index 506608670..5ae832b36 100644
--- a/test/private_tests.erl
+++ b/test/private_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 23 Nov 2018 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -24,7 +24,7 @@
%% API
-compile(export_all).
--import(suite, [my_jid/1, is_feature_advertised/3,
+-import(suite, [my_jid/1, server_jid/1, is_feature_advertised/3,
send_recv/2, disconnect/1]).
-include("suite.hrl").
@@ -43,9 +43,15 @@ single_cases() ->
single_test(test_published)]}.
test_features(Config) ->
+ Server = jid:encode(server_jid(Config)),
MyJID = my_jid(Config),
- true = is_feature_advertised(Config, ?NS_BOOKMARKS_CONVERSION_0,
- jid:remove_resource(MyJID)),
+ case gen_mod:is_loaded(Server, mod_pubsub) of
+ true ->
+ true = is_feature_advertised(Config, ?NS_BOOKMARKS_CONVERSION_0,
+ jid:remove_resource(MyJID));
+ false ->
+ ok
+ end,
disconnect(Config).
test_no_namespace(Config) ->
@@ -73,20 +79,26 @@ test_set_get(Config) ->
disconnect(Config).
test_published(Config) ->
- Storage = bookmark_storage(),
- Node = xmpp:get_ns(Storage),
- #iq{type = result,
- sub_els = [#pubsub{items = #ps_items{node = Node, items = Items}}]} =
- send_recv(
- Config,
- #iq{type = get,
- sub_els = [#pubsub{items = #ps_items{node = Node}}]}),
- [#ps_item{sub_els = [StorageXMLIn]}] = Items,
- Storage = xmpp:decode(StorageXMLIn),
- #iq{type = result, sub_els = []} =
- send_recv(Config,
- #iq{type = set,
- sub_els = [#pubsub_owner{delete = {Node, <<>>}}]}),
+ Server = jid:encode(server_jid(Config)),
+ case gen_mod:is_loaded(Server, mod_pubsub) of
+ true ->
+ Storage = bookmark_storage(),
+ Node = xmpp:get_ns(Storage),
+ #iq{type = result,
+ sub_els = [#pubsub{items = #ps_items{node = Node, items = Items}}]} =
+ send_recv(
+ Config,
+ #iq{type = get,
+ sub_els = [#pubsub{items = #ps_items{node = Node}}]}),
+ [#ps_item{sub_els = [StorageXMLIn]}] = Items,
+ Storage = xmpp:decode(StorageXMLIn),
+ #iq{type = result, sub_els = []} =
+ send_recv(Config,
+ #iq{type = set,
+ sub_els = [#pubsub_owner{delete = {Node, <<>>}}]});
+ false ->
+ ok
+ end,
disconnect(Config).
%%%===================================================================
diff --git a/test/proxy65_tests.erl b/test/proxy65_tests.erl
index 5f308e744..be3c92cd4 100644
--- a/test/proxy65_tests.erl
+++ b/test/proxy65_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 16 Nov 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/pubsub_tests.erl b/test/pubsub_tests.erl
index ca468f779..b4950ef33 100644
--- a/test/pubsub_tests.erl
+++ b/test/pubsub_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 16 Nov 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/push_tests.erl b/test/push_tests.erl
index 505aa90f5..436f94d55 100644
--- a/test/push_tests.erl
+++ b/test/push_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 15 Jul 2017 by Holger Weiss <holger@zedat.fu-berlin.de>
%%%
%%%
-%%% ejabberd, Copyright (C) 2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/replaced_tests.erl b/test/replaced_tests.erl
index 6141abd16..884852c3e 100644
--- a/test/replaced_tests.erl
+++ b/test/replaced_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 16 Nov 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/roster_tests.erl b/test/roster_tests.erl
index 8ef206470..38420abb7 100644
--- a/test/roster_tests.erl
+++ b/test/roster_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 22 Oct 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/sm_tests.erl b/test/sm_tests.erl
index 134a2f951..3eb2bf214 100644
--- a/test/sm_tests.erl
+++ b/test/sm_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 16 Nov 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/suite.erl b/test/suite.erl
index 62c394a55..b466bd02a 100644
--- a/test/suite.erl
+++ b/test/suite.erl
@@ -3,7 +3,7 @@
%%% Created : 27 Jun 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/test_helper.exs b/test/test_helper.exs
deleted file mode 100644
index 454f2338a..000000000
--- a/test/test_helper.exs
+++ /dev/null
@@ -1,7 +0,0 @@
-Code.require_file "ejabberd_auth_mock.exs", __DIR__
-Code.require_file "ejabberd_oauth_mock.exs", __DIR__
-Code.require_file "ejabberd_sm_mock.exs", __DIR__
-Code.require_file "mod_last_mock.exs", __DIR__
-Code.require_file "mod_roster_mock.exs", __DIR__
-
-ExUnit.start
diff --git a/test/upload_tests.erl b/test/upload_tests.erl
index ed1e90845..0234a8847 100644
--- a/test/upload_tests.erl
+++ b/test/upload_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 17 May 2018 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/test/vcard_tests.erl b/test/vcard_tests.erl
index 6f935e39b..0ee2e5459 100644
--- a/test/vcard_tests.erl
+++ b/test/vcard_tests.erl
@@ -3,7 +3,7 @@
%%% Created : 16 Nov 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/tools/xml_compress_gen.erl b/tools/xml_compress_gen.erl
index 4dad71a43..f19bcfdbd 100644
--- a/tools/xml_compress_gen.erl
+++ b/tools/xml_compress_gen.erl
@@ -4,7 +4,7 @@
%% Created : 14 Sep 2018 Pawel Chmielowski
%%
%%
-%% ejabberd, Copyright (C) 2002-2018 ProcessOne
+%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%
%% This program is free software; you can redistribute it and/or
%% modify it under the terms of the GNU General Public License as
@@ -117,8 +117,8 @@ gen_decode(Dev, Data, VerId) ->
" {Children, Rest4} = decode_children(Rest3, PNs, J1, J2),~n"
" {{xmlel, Name, Attrs, Children}, Rest4};~n", []),
io:format(Dev, "decode_child(<<3:8, Rest/binary>>, PNs, J1, J2) ->~n"
- " {Name, Rest2} = decode_string(Rest),~n"
- " {Ns, Rest3} = decode_string(Rest2),~n"
+ " {Ns, Rest2} = decode_string(Rest),~n"
+ " {Name, Rest3} = decode_string(Rest2),~n"
" {Attrs, Rest4} = decode_attrs(Rest3),~n"
" {Children, Rest5} = decode_children(Rest4, Ns, J1, J2),~n"
" {{xmlel, Name, add_ns(PNs, Ns, Attrs), Children}, Rest5};~n", []),
diff --git a/vars.config.in b/vars.config.in
index 9878ee2b4..045c0874d 100644
--- a/vars.config.in
+++ b/vars.config.in
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2019 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -39,7 +39,6 @@
{riak, @riak@}.
{redis, @redis@}.
{elixir, @elixir@}.
-{iconv, @iconv@}.
{stun, @stun@}.
{sip, @sip@}.