mirror of
https://github.com/langgenius/dify.git
synced 2026-04-23 12:16:11 +08:00
feat: Add SMTP OAuth 2.0 support for Microsoft Exchange
Add comprehensive OAuth 2.0 authentication support for SMTP to address Microsoft's Basic Authentication retirement in September 2025. Key features: - OAuth 2.0 SASL XOAUTH2 authentication mechanism - Microsoft Azure AD integration with client credentials flow - Backward compatible with existing basic authentication - Comprehensive configuration options in .env.example files - Enhanced SMTP client with dependency injection for better testability - Complete test coverage with proper mocking Configuration: - SMTP_AUTH_TYPE: Choose between 'basic' and 'oauth2' authentication - Microsoft OAuth 2.0 settings for Azure AD integration - Automatic token acquisition using client credentials flow Files changed: - Enhanced SMTP client with OAuth 2.0 support - New mail module structure under libs/mail/ - Updated configuration system with OAuth settings - Comprehensive documentation and setup instructions - Complete test suite for OAuth functionality This change ensures compatibility with Microsoft Exchange Online after Basic Authentication retirement.
This commit is contained in:
@ -16,7 +16,7 @@ class Mail:
|
||||
def is_inited(self) -> bool:
|
||||
return self._client is not None
|
||||
|
||||
def init_app(self, app: Flask):
|
||||
def init_app(self, _: Flask):
|
||||
mail_type = dify_config.MAIL_TYPE
|
||||
if not mail_type:
|
||||
logger.warning("MAIL_TYPE is not set")
|
||||
@ -40,20 +40,36 @@ class Mail:
|
||||
resend.api_key = api_key
|
||||
self._client = resend.Emails
|
||||
case "smtp":
|
||||
from libs.smtp import SMTPClient
|
||||
from libs.mail import SMTPClient
|
||||
|
||||
if not dify_config.SMTP_SERVER or not dify_config.SMTP_PORT:
|
||||
raise ValueError("SMTP_SERVER and SMTP_PORT are required for smtp mail type")
|
||||
if not dify_config.SMTP_USE_TLS and dify_config.SMTP_OPPORTUNISTIC_TLS:
|
||||
raise ValueError("SMTP_OPPORTUNISTIC_TLS is not supported without enabling SMTP_USE_TLS")
|
||||
|
||||
# Validate OAuth 2.0 configuration if auth_type is oauth2
|
||||
oauth_access_token = None
|
||||
|
||||
if dify_config.SMTP_AUTH_TYPE == "oauth2":
|
||||
oauth_access_token = dify_config.MICROSOFT_OAUTH2_ACCESS_TOKEN
|
||||
if not oauth_access_token:
|
||||
# Try to get token using client credentials flow
|
||||
if dify_config.MICROSOFT_OAUTH2_CLIENT_ID and dify_config.MICROSOFT_OAUTH2_CLIENT_SECRET:
|
||||
oauth_access_token = self._get_oauth_token()
|
||||
|
||||
if not oauth_access_token:
|
||||
raise ValueError("OAuth 2.0 access token is required for oauth2 auth_type")
|
||||
|
||||
self._client = SMTPClient(
|
||||
server=dify_config.SMTP_SERVER,
|
||||
port=dify_config.SMTP_PORT,
|
||||
username=dify_config.SMTP_USERNAME or "",
|
||||
password=dify_config.SMTP_PASSWORD or "",
|
||||
_from=dify_config.MAIL_DEFAULT_SEND_FROM or "",
|
||||
from_addr=dify_config.MAIL_DEFAULT_SEND_FROM or "",
|
||||
use_tls=dify_config.SMTP_USE_TLS,
|
||||
opportunistic_tls=dify_config.SMTP_OPPORTUNISTIC_TLS,
|
||||
oauth_access_token=oauth_access_token,
|
||||
auth_type=dify_config.SMTP_AUTH_TYPE,
|
||||
)
|
||||
case "sendgrid":
|
||||
from libs.sendgrid import SendGridClient
|
||||
|
||||
Reference in New Issue
Block a user