Changeset - ef35c565bb0a
[Not reviewed]
0 7 0
Branko Majic (branko) - 1 month ago 2025-02-13 22:37:03
branko@majic.rs
MAR-242: Added role parameters for xmpp_server role to configure HTTP file upload limits (XEP-0363):

- Refactor the daily quota tests to be a bit more flexible.
7 files changed with 52 insertions and 24 deletions:
0 comments (0 inline, 0 general) First comment
docs/rolereference.rst
Show inline comments
 
@@ -900,8 +900,17 @@ Prosody is configured as follows:
 
  service is set-up, with FQDN set to ``conference.DOMAIN``.
 
* For each domain specified, a dedicated file proxy service will be set-up, with
 
  FQDN set to ``proxy.DOMAIN``.
 
* For each domain specified, a dedicated http file share service will be set-up,
 
  with FQDN set to ``upload.DOMAIN``.
 
* For each domain specified, a dedicated http file share service is
 
  set-up, with FQDN set to ``upload.DOMAIN``. Service is configured
 
  with maximum upload file size limit, as well as per-user daily
 
  quota. This allows clients to use `XEP-0363: HTTP File Upload
 
  <https://xmpp.org/extensions/xep-0363.html>`_ for exchanging files.
 

	
 
  .. warning::
 
     Due to `bug related to global quotas
 
     <https://issues.prosody.im/1891>`_, the role currently does not
 
     configure global quotas in any way. This might change in the
 
     future.
 

	
 
Prosody expects a specific directory structure in LDAP when doing look-ups:
 

	
 
@@ -968,6 +977,15 @@ Parameters
 
  Fully qualified domain name, hostname, or IP address of the LDAP server used
 
  for user authentication and listing.
 

	
 
**xmpp_http_file_share_daily_quota** (integer, optional, ``104857600``)
 
  Daily quota for individual users - maximum file size in bytes that a
 
  particular user can upload per day (`XEP-0363: HTTP File Upload
 
  <https://xmpp.org/extensions/xep-0363.html>`_).
 

	
 
**xmpp_http_file_share_size_limit** (integer, optional, ``10485760``)
 
  Maximum file size in bytes to allow for upload (`XEP-0363: HTTP File
 
  Upload <https://xmpp.org/extensions/xep-0363.html>`_).
 

	
 
**xmpp_server_archive_expiration** (string, optional, ``never``)
 
  Expiration period for messages stored server-side using `XEP-0313:
 
  Message Archive Management
roles/xmpp_server/defaults/main.yml
Show inline comments
 
---
 

	
 
enable_backup: false
 
xmpp_http_file_share_daily_quota: 104857600  # 100MiB
 
xmpp_http_file_share_size_limit: 10485760  # 10MiB
 
xmpp_server_archive_expiration: "never"
 
xmpp_server_tls_protocol: "tlsv1_2+"
 

	
roles/xmpp_server/molecule/default/group_vars/parameters-optional.yml
Show inline comments
 
@@ -6,6 +6,8 @@ xmpp_administrators:
 
xmpp_domains:
 
  - domain2
 
  - domain3
 
xmpp_http_file_share_daily_quota: 73400320  # 70MiB
 
xmpp_http_file_share_size_limit: 20971520  # 20MiB
 
xmpp_ldap_base_dn: dc=local
 
xmpp_ldap_password: prosodypassword
 
xmpp_ldap_server: ldap-server
roles/xmpp_server/molecule/default/tests/test_client.py
Show inline comments
 
@@ -145,19 +145,17 @@ def test_http_file_upload(host, server_host, username, password, domain):
 
        assert uploaded_file.content_string == expected_content
 

	
 

	
 
@pytest.mark.parametrize("username, password, domain, server", [
 
    ["john.doe", "johnpassword", "domain1", "parameters-mandatory"],
 
    ["jane.doe", "janepassword", "domain2", "parameters-optional"],
 
    ["mick.doe", "mickpassword", "domain3", "parameters-optional"],
 
@pytest.mark.parametrize("username, password, domain, server, file_size_limit", [
 
    ["john.doe", "johnpassword", "domain1", "parameters-mandatory", 10 * 1024 * 1024],
 
    ["jane.doe", "janepassword", "domain2", "parameters-optional", 20 * 1024 * 1024],
 
    ["mick.doe", "mickpassword", "domain3", "parameters-optional", 20 * 1024 * 1024],
 
])
 
@pytest.mark.usefixtures("server_clean_domain_uploads")
 
def test_http_file_share_size_limit(host, username, password, domain):
 
def test_http_file_share_size_limit(host, username, password, domain, file_size_limit):
 
    """
 
    Tests the maximum file size for files uploaded via XEP-0363.
 
    """
 

	
 
    file_size_limit = 10 * 1024 * 1024
 

	
 
    # Test exact size limit.
 
    create_sample_file = host.run("dd if=/dev/zero of=/tmp/http_file_upload_sample.txt bs=%sB count=1", str(file_size_limit))
 
    assert create_sample_file.rc == 0
 
@@ -177,30 +175,30 @@ def test_http_file_share_size_limit(host, username, password, domain):
 
    assert "file-too-large" in send.stderr
 

	
 

	
 
@pytest.mark.parametrize("username, password, domain, server", [
 
    ["john.doe", "johnpassword", "domain1", "parameters-mandatory"],
 
    ["jane.doe", "janepassword", "domain2", "parameters-optional"],
 
    ["mick.doe", "mickpassword", "domain3", "parameters-optional"],
 
@pytest.mark.parametrize("username, password, domain, server, file_size_limit, user_daily_quota", [
 
    ["john.doe", "johnpassword", "domain1", "parameters-mandatory", 10 * 1024 * 1024, 100 * 1024 * 1024],
 
    ["jane.doe", "janepassword", "domain2", "parameters-optional", 20 * 1024 * 1024, 70 * 1024 * 1024],
 
    ["mick.doe", "mickpassword", "domain3", "parameters-optional", 20 * 1024 * 1024, 70 * 1024 * 1024],
 
])
 
@pytest.mark.usefixtures("server_clean_domain_uploads")
 
def test_http_file_share_daily_quota(host, username, password, domain):
 
def test_http_file_share_daily_quota(host, username, password, domain, file_size_limit, user_daily_quota):
 
    """
 
    Tests the user's daily quota for files uploaded via XEP-0363.
 
    """
 

	
 
    # Equivalent of 100MiB.
 
    file_size_limit = 10 * 1024 * 1024
 
    file_count = 10
 
    remaining_quota = user_daily_quota
 
    while remaining_quota > 0:
 
        file_size = file_size_limit if file_size_limit < remaining_quota else remaining_quota
 
        create_sample_file = host.run("dd if=/dev/zero of=/tmp/http_file_upload_sample.txt bs=%sB count=1", str(file_size))
 
        assert create_sample_file.rc == 0
 

	
 
    # Fill-up the daily quota.
 
    create_sample_file = host.run("dd if=/dev/zero of=/tmp/http_file_upload_sample.txt bs=%sB count=1", str(file_size_limit))
 
    assert create_sample_file.rc == 0
 
    for _ in range(file_count):
 
        send = host.run(f"go-sendxmpp --debug --username {username}@{domain} --password {password} --jserver {domain}:5222 "
 
                        f"--http-upload /tmp/http_file_upload_sample.txt "
 
                        f"{username}@{domain}")
 
        assert send.rc == 0
 

	
 
        remaining_quota -= file_size
 

	
 
    # Test exceeded daily quota.
 
    create_sample_file = host.run("dd if=/dev/zero of=/tmp/http_file_upload_sample.txt bs=1B count=1")
 
    assert create_sample_file.rc == 0
roles/xmpp_server/molecule/default/tests/test_mandatory.py
Show inline comments
 
@@ -38,7 +38,9 @@ Component "conference.domain1" "muc"
 
Component "proxy.domain1" "proxy65"
 
  proxy65_acl = { "domain1" }
 
Component "upload.domain1" "http_file_share"
 
  http_file_share_access = { "domain1" }""" in config.content_string
 
  http_file_share_access = { "domain1" }
 
  http_file_share_size_limit = 10485760
 
  http_file_share_daily_quota = 104857600""" in config.content_string
 

	
 

	
 
def test_xmpp_server_uses_correct_dh_parameters(host):
roles/xmpp_server/molecule/default/tests/test_optional.py
Show inline comments
 
@@ -38,7 +38,9 @@ Component "conference.domain2" "muc"
 
Component "proxy.domain2" "proxy65"
 
  proxy65_acl = { "domain2" }
 
Component "upload.domain2" "http_file_share"
 
  http_file_share_access = { "domain2" }""" in config.content_string
 
  http_file_share_access = { "domain2" }
 
  http_file_share_size_limit = 20971520
 
  http_file_share_daily_quota = 73400320""" in config.content_string
 

	
 
        assert """VirtualHost "domain3"
 
Component "conference.domain3" "muc"
 
@@ -46,7 +48,9 @@ Component "conference.domain3" "muc"
 
Component "proxy.domain3" "proxy65"
 
  proxy65_acl = { "domain3" }
 
Component "upload.domain3" "http_file_share"
 
  http_file_share_access = { "domain3" }""" in config.content_string
 
  http_file_share_access = { "domain3" }
 
  http_file_share_size_limit = 20971520
 
  http_file_share_daily_quota = 73400320""" in config.content_string
 

	
 

	
 
@pytest.mark.parametrize("port", [
roles/xmpp_server/templates/prosody.cfg.lua.j2
Show inline comments
 
@@ -112,4 +112,6 @@ Component "proxy.{{ domain }}" "proxy65"
 
  proxy65_acl = { "{{ domain }}" }
 
Component "upload.{{ domain }}" "http_file_share"
 
  http_file_share_access = { "{{ domain }}" }
 
  http_file_share_size_limit = {{ xmpp_http_file_share_size_limit }}
 
  http_file_share_daily_quota = {{ xmpp_http_file_share_daily_quota }}
 
{% endfor -%}
0 comments (0 inline, 0 general) First comment
You need to be logged in to comment. Login now