Переглянути джерело

Add jinja2 filters urlencode and escape_quotes

FreddleSpl0it 3 місяців тому
батько
коміт
744aa5d137

+ 24 - 10
data/Dockerfiles/bootstrap/modules/BootstrapBase.py

@@ -13,6 +13,7 @@ import hashlib
 import json
 import psutil
 import signal
+from urllib.parse import quote
 from pathlib import Path
 import dns.resolver
 import mysql.connector
@@ -89,17 +90,19 @@ class BootstrapBase:
 
   def prepare_template_vars(self, overwrite_path, extra_vars = None):
     """
-    Loads and merges environment variables for Jinja2 templates from multiple sources.
+    Loads and merges environment variables for Jinja2 templates from multiple sources, and registers custom template filters.
 
-    This method combines:
+    This method combines variables from:
       1. System environment variables
-      2. Key/value pairs from the MySQL `service_settings` table
-      3. An optional dictionary of extra_vars
-      4. A JSON file with overrides (if the file exists)
+      2. The MySQL `service_settings` table (filtered by service type if defined)
+      3. An optional `extra_vars` dictionary
+      4. A JSON overwrite file (if it exists at the given path)
+
+    Also registers custom Jinja2 filters.
 
     Args:
         overwrite_path (str or Path): Path to a JSON file containing key-value overrides.
-        extra_vars (dict, optional): A dictionary of additional variables to include.
+        extra_vars (dict, optional): Additional variables to merge into the environment.
 
     Returns:
         dict: A dictionary containing all resolved template variables.
@@ -108,10 +111,15 @@ class BootstrapBase:
         Prints errors if database fetch or JSON parsing fails, but does not raise exceptions.
     """
 
-    # 1. Load env vars
+    # 1. setup filters
+    self.env.filters['sha1'] = self.sha1_filter
+    self.env.filters['urlencode'] = self.urlencode_filter
+    self.env.filters['escape_quotes'] = self.escape_quotes_filter
+
+    # 2. Load env vars
     env_vars = dict(os.environ)
 
-    # 2. Load from MySQL
+    # 3. Load from MySQL
     try:
       cursor = self.mysql_conn.cursor()
 
@@ -129,11 +137,11 @@ class BootstrapBase:
     except Exception as e:
       print(f"Failed to fetch DB service settings: {e}")
 
-    # 3. Load extra vars
+    # 4. Load extra vars
     if extra_vars:
       env_vars.update(extra_vars)
 
-    # 4. Load overwrites
+    # 5. Load overwrites
     overwrite_path = Path(overwrite_path)
     if overwrite_path.exists():
       try:
@@ -810,3 +818,9 @@ class BootstrapBase:
 
   def sha1_filter(self, value):
     return hashlib.sha1(value.encode()).hexdigest()
+
+  def urlencode_filter(self, value):
+    return quote(value, safe='')
+
+  def escape_quotes_filter(self, value):
+    return value.replace('"', r'\"')

+ 0 - 4
data/Dockerfiles/bootstrap/modules/BootstrapDovecot.py

@@ -45,10 +45,6 @@ class BootstrapDovecot(BootstrapBase):
       "ENV_VARS": dict(os.environ)
     }
     self.env_vars = self.prepare_template_vars('/service_config/overwrites.json', extra_vars)
-    # Escape DBPASS
-    self.env_vars['DBPASS'] = self.env_vars['DBPASS'].replace('"', r'\"')
-    # Set custom filters
-    self.env.filters['sha1'] = self.sha1_filter
 
     print("Set Timezone")
     self.set_timezone()

+ 1 - 1
data/conf/dovecot/config_templates/dovecot-dict-sql-quota.conf.j2

@@ -1,5 +1,5 @@
 {% set QUOTA_TABLE = "quota2" if MASTER|lower in ["y", "yes"] else "quota2replica" %}
-connect = "host=/var/run/mysqld/mysqld.sock dbname={{ DBNAME }} user={{ DBUSER }} password={{ DBPASS }}"
+connect = "host=/var/run/mysqld/mysqld.sock dbname={{ DBNAME }} user={{ DBUSER }} password={{ DBPASS | escape_quotes }}"
 map {
   pattern = priv/quota/storage
   table = {{ QUOTA_TABLE }}

+ 1 - 1
data/conf/dovecot/config_templates/dovecot-dict-sql-sieve_after.conf.j2

@@ -1,4 +1,4 @@
-connect = "host=/var/run/mysqld/mysqld.sock dbname={{ DBNAME }} user={{ DBUSER }} password={{ DBPASS }}"
+connect = "host=/var/run/mysqld/mysqld.sock dbname={{ DBNAME }} user={{ DBUSER }} password={{ DBPASS | escape_quotes }}"
 map {
   pattern = priv/sieve/name/$script_name
   table = sieve_after

+ 1 - 1
data/conf/dovecot/config_templates/dovecot-dict-sql-sieve_before.conf.j2

@@ -1,4 +1,4 @@
-connect = "host=/var/run/mysqld/mysqld.sock dbname={{ DBNAME }} user={{ DBUSER }} password={{ DBPASS }}"
+connect = "host=/var/run/mysqld/mysqld.sock dbname={{ DBNAME }} user={{ DBUSER }} password={{ DBPASS | escape_quotes }}"
 map {
   pattern = priv/sieve/name/$script_name
   table = sieve_before

+ 1 - 1
data/conf/dovecot/config_templates/dovecot-dict-sql-userdb.conf.j2

@@ -1,4 +1,4 @@
 driver = mysql
-connect = "host=/var/run/mysqld/mysqld.sock dbname={{ DBNAME }} user={{ DBUSER }} password={{ DBPASS }}"
+connect = "host=/var/run/mysqld/mysqld.sock dbname={{ DBNAME }} user={{ DBUSER }} password={{ DBPASS | escape_quotes }}"
 user_query = SELECT CONCAT(JSON_UNQUOTE(JSON_VALUE(attributes, '$.mailbox_format')), mailbox_path_prefix, '%d/%n/{{ MAILDIR_SUB }}:VOLATILEDIR=/var/volatile/%u:INDEX=/var/vmail_index/%u') AS mail, '%s' AS protocol, 5000 AS uid, 5000 AS gid, concat('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND (active = '1' OR active = '2')
 iterate_query = SELECT username FROM mailbox WHERE active = '1' OR active = '2';

+ 9 - 9
data/conf/sogo/config_templates/sogod.plist.j2

@@ -3,7 +3,7 @@
 <plist version="0.9">
 <dict>
     <key>OCSAclURL</key>
-    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST }}/{{ DBNAME }}/sogo_acl</string>
+    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST | urlencode }}/{{ DBNAME }}/sogo_acl</string>
     <key>SOGoIMAPServer</key>
     <string>imap://{{ DOVECOT_HOST }}:143/?TLS=YES&amp;tlsVerifyMode=none</string>
     <key>SOGoSieveServer</key>
@@ -15,19 +15,19 @@
     <key>SOGoEncryptionKey</key>
     <string>{{RAND_PASS}}</string>
     <key>OCSAdminURL</key>
-    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST }}/{{ DBNAME }}/sogo_admin</string>
+    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST | urlencode }}/{{ DBNAME }}/sogo_admin</string>
     <key>OCSCacheFolderURL</key>
-    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST }}/{{ DBNAME }}/sogo_cache_folder</string>
+    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST | urlencode }}/{{ DBNAME }}/sogo_cache_folder</string>
     <key>OCSEMailAlarmsFolderURL</key>
-    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST }}/{{ DBNAME }}/sogo_alarms_folder</string>
+    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST | urlencode }}/{{ DBNAME }}/sogo_alarms_folder</string>
     <key>OCSFolderInfoURL</key>
-    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST }}/{{ DBNAME }}/sogo_folder_info</string>
+    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST | urlencode }}/{{ DBNAME }}/sogo_folder_info</string>
     <key>OCSSessionsFolderURL</key>
-    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST }}/{{ DBNAME }}/sogo_sessions_folder</string>
+    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST | urlencode }}/{{ DBNAME }}/sogo_sessions_folder</string>
     <key>OCSStoreURL</key>
-    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST }}/{{ DBNAME }}/sogo_store</string>
+    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST | urlencode }}/{{ DBNAME }}/sogo_store</string>
     <key>SOGoProfileURL</key>
-    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST }}/{{ DBNAME }}/sogo_user_profile</string>
+    <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST | urlencode }}/{{ DBNAME }}/sogo_user_profile</string>
     <key>SOGoTimeZone</key>
     <string>{{TZ}}</string>
     <key>domains</key>
@@ -69,7 +69,7 @@
           <key>prependPasswordScheme</key>
           <string>YES</string>
           <key>viewURL</key>
-          <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST }}/{{ DBNAME }}/_sogo_static_view</string>
+          <string>mysql://{{ DBUSER }}:{{ DBPASS }}@{{ DB_HOST | urlencode }}/{{ DBNAME }}/_sogo_static_view</string>
         </dict>
         {% if IAM_SETTINGS.authsource == "ldap" and domain.ldap_gal %}
         <dict>

+ 3 - 5
docker-compose.yml

@@ -233,7 +233,7 @@ services:
         - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
         - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
         - REDISPASS=${REDISPASS}
-        - DB_HOST=${DB_HOST:-%2Fvar%2Frun%2Fmysqld%2Fmysqld.sock}
+        - DB_HOST=${DB_HOST:-/var/run/mysqld/mysqld.sock}
         - SOGO_HOST=${SOGO_HOST:-172.22.1.248}
         - DOVECOT_HOST=${DOVECOT_HOST:-172.22.1.250}
         - POSTFIX_HOST=${POSTFIX_HOST:-172.22.1.253}
@@ -243,8 +243,7 @@ services:
       volumes:
         - ./data/hooks/sogo:/hooks:Z
         - ./data/conf/sogo:/service_config:z
-        - ./data/conf/sogo/cron.creds:/etc/sogo/cron.creds:z
-        - ./data/conf/sogo/sieve.creds:/etc/sogo/sieve.creds:z
+        - ./data/conf/sogo:/etc/sogo:z
         - ./data/web/inc/init_db.inc.php:/init_db.inc.php:z
         - ./data/conf/sogo/custom-favicon.ico:/usr/lib/GNUstep/SOGo/WebServerResources/img/sogo.ico:z
         - ./data/conf/sogo/custom-shortlogo.svg:/usr/lib/GNUstep/SOGo/WebServerResources/img/sogo-compact.svg:z
@@ -373,8 +372,7 @@ services:
       volumes:
         - ./data/hooks/postfix:/hooks:Z
         - ./data/conf/postfix:/service_config:z
-        - ./data/conf/postfix/postscreen_access.cidr:/opt/postfix/conf/postscreen_access.cidr:z
-        - ./data/conf/postfix/extra.cf:/opt/postfix/conf/extra.cf:z
+        - ./data/conf/postfix:/opt/postfix/conf:z
         - ./data/assets/ssl:/etc/ssl/mail/:ro,z
         - postfix-vol-1:/var/spool/postfix
         - crypt-vol-1:/var/lib/zeyple