Browse Source

feat: opportunistic tls flag for smtp (#4794)

Charles Zhou 10 months ago
parent
commit
a325a294bd
5 changed files with 24 additions and 10 deletions
  1. 3 2
      api/.env.example
  2. 1 0
      api/config.py
  3. 4 1
      api/extensions/ext_mail.py
  4. 12 5
      api/libs/smtp.py
  5. 4 2
      docker/docker-compose.yaml

+ 3 - 2
api/.env.example

@@ -127,10 +127,11 @@ RESEND_API_KEY=
 RESEND_API_URL=https://api.resend.com
 # smtp configuration
 SMTP_SERVER=smtp.gmail.com
-SMTP_PORT=587
+SMTP_PORT=465
 SMTP_USERNAME=123
 SMTP_PASSWORD=abc
-SMTP_USE_TLS=false
+SMTP_USE_TLS=true
+SMTP_OPPORTUNISTIC_TLS=false
 
 # Sentry configuration
 SENTRY_DSN=

+ 1 - 0
api/config.py

@@ -295,6 +295,7 @@ class Config:
         self.SMTP_USERNAME = get_env('SMTP_USERNAME')
         self.SMTP_PASSWORD = get_env('SMTP_PASSWORD')
         self.SMTP_USE_TLS = get_bool_env('SMTP_USE_TLS')
+        self.SMTP_OPPORTUNISTIC_TLS = get_bool_env('SMTP_OPPORTUNISTIC_TLS')
 
         # ------------------------
         # Workspace Configurations.

+ 4 - 1
api/extensions/ext_mail.py

@@ -33,13 +33,16 @@ class Mail:
                 from libs.smtp import SMTPClient
                 if not app.config.get('SMTP_SERVER') or not app.config.get('SMTP_PORT'):
                     raise ValueError('SMTP_SERVER and SMTP_PORT are required for smtp mail type')
+                if not app.config.get('SMTP_USE_TLS') and app.config.get('SMTP_OPPORTUNISTIC_TLS'):
+                    raise ValueError('SMTP_OPPORTUNISTIC_TLS is not supported without enabling SMTP_USE_TLS')
                 self._client = SMTPClient(
                     server=app.config.get('SMTP_SERVER'),
                     port=app.config.get('SMTP_PORT'),
                     username=app.config.get('SMTP_USERNAME'),
                     password=app.config.get('SMTP_PASSWORD'),
                     _from=app.config.get('MAIL_DEFAULT_SEND_FROM'),
-                    use_tls=app.config.get('SMTP_USE_TLS')
+                    use_tls=app.config.get('SMTP_USE_TLS'),
+                    opportunistic_tls=app.config.get('SMTP_OPPORTUNISTIC_TLS')
                 )
             else:
                 raise ValueError('Unsupported mail type {}'.format(app.config.get('MAIL_TYPE')))

+ 12 - 5
api/libs/smtp.py

@@ -5,20 +5,27 @@ from email.mime.text import MIMEText
 
 
 class SMTPClient:
-    def __init__(self, server: str, port: int, username: str, password: str, _from: str, use_tls=False):
+    def __init__(self, server: str, port: int, username: str, password: str, _from: str, use_tls=False, opportunistic_tls=False):
         self.server = server
         self.port = port
         self._from = _from
         self.username = username
         self.password = password
-        self._use_tls = use_tls
+        self.use_tls = use_tls
+        self.opportunistic_tls = opportunistic_tls
 
     def send(self, mail: dict):
         smtp = None
         try:
-            smtp = smtplib.SMTP(self.server, self.port, timeout=10)
-            if self._use_tls:
-                smtp.starttls()
+            if self.use_tls:
+                if self.opportunistic_tls:
+                    smtp = smtplib.SMTP(self.server, self.port, timeout=10)
+                    smtp.starttls()
+                else:
+                    smtp = smtplib.SMTP_SSL(self.server, self.port, timeout=10)
+            else:
+                smtp = smtplib.SMTP(self.server, self.port, timeout=10)
+                
             if self.username and self.password:
                 smtp.login(self.username, self.password)
 

+ 4 - 2
docker/docker-compose.yaml

@@ -139,10 +139,11 @@ services:
       # default send from email address, if not specified
       MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
       SMTP_SERVER: ''
-      SMTP_PORT: 587
+      SMTP_PORT: 465
       SMTP_USERNAME: ''
       SMTP_PASSWORD: ''
       SMTP_USE_TLS: 'true'
+      SMTP_OPPORTUNISTIC_TLS: 'false'
       # the api-key for resend (https://resend.com)
       RESEND_API_KEY: ''
       RESEND_API_URL: https://api.resend.com
@@ -268,10 +269,11 @@ services:
       # default send from email address, if not specified
       MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
       SMTP_SERVER: ''
-      SMTP_PORT: 587
+      SMTP_PORT: 465
       SMTP_USERNAME: ''
       SMTP_PASSWORD: ''
       SMTP_USE_TLS: 'true'
+      SMTP_OPPORTUNISTIC_TLS: 'false'
       # the api-key for resend (https://resend.com)
       RESEND_API_KEY: ''
       RESEND_API_URL: https://api.resend.com