Compare commits
2 Commits
38fcf8c4d8
...
6fccc0b2f9
| Author | SHA1 | Date |
|---|---|---|
|
|
6fccc0b2f9 | |
|
|
1d66485068 |
|
|
@ -77,7 +77,8 @@ class RulesProcessor:
|
||||||
forwards,
|
forwards,
|
||||||
domain,
|
domain,
|
||||||
worker_name,
|
worker_name,
|
||||||
metrics_callback
|
metrics_callback,
|
||||||
|
rule=rule
|
||||||
)
|
)
|
||||||
|
|
||||||
def _handle_ooo(
|
def _handle_ooo(
|
||||||
|
|
@ -141,34 +142,104 @@ class RulesProcessor:
|
||||||
forwards: list,
|
forwards: list,
|
||||||
domain: str,
|
domain: str,
|
||||||
worker_name: str,
|
worker_name: str,
|
||||||
metrics_callback=None
|
metrics_callback=None,
|
||||||
|
rule: dict = None # NEU
|
||||||
):
|
):
|
||||||
"""Handle email forwarding"""
|
"""Handle email forwarding"""
|
||||||
|
# NEU: SMTP Override aus Rule lesen
|
||||||
|
smtp_override = None
|
||||||
|
if rule:
|
||||||
|
smtp_override = rule.get('forward_smtp_override')
|
||||||
|
|
||||||
for forward_to in forwards:
|
for forward_to in forwards:
|
||||||
try:
|
try:
|
||||||
fwd_msg = self._create_forward_message(parsed, recipient, forward_to, original_from)
|
fwd_msg = self._create_forward_message(
|
||||||
|
parsed, recipient, forward_to, original_from
|
||||||
|
)
|
||||||
fwd_bytes = fwd_msg.as_bytes()
|
fwd_bytes = fwd_msg.as_bytes()
|
||||||
|
|
||||||
# Distinguish: Internal (Port 2525) vs External (SES)
|
# NEU: Legacy SMTP Override (Migration)
|
||||||
if is_internal_address(forward_to):
|
if smtp_override:
|
||||||
# Internal address → direct via Port 2525 (no loop!)
|
success = self._send_via_legacy_smtp(
|
||||||
success = self._send_internal_email(recipient, forward_to, fwd_bytes, worker_name)
|
recipient, forward_to, fwd_bytes,
|
||||||
|
smtp_override, worker_name
|
||||||
|
)
|
||||||
if success:
|
if success:
|
||||||
log(f"✓ Forwarded internally to {forward_to}", 'SUCCESS', worker_name)
|
log(f"✓ Forwarded via legacy SMTP to {forward_to} "
|
||||||
|
f"({smtp_override.get('host', '?')})",
|
||||||
|
'SUCCESS', worker_name)
|
||||||
else:
|
else:
|
||||||
log(f"⚠ Internal forward failed to {forward_to}", 'WARNING', worker_name)
|
log(f"⚠ Legacy SMTP forward failed to {forward_to}",
|
||||||
else:
|
'WARNING', worker_name)
|
||||||
# External address → via SES
|
|
||||||
success = self.ses.send_raw_email(recipient, forward_to, fwd_bytes, worker_name)
|
elif is_internal_address(forward_to):
|
||||||
|
success = self._send_internal_email(
|
||||||
|
recipient, forward_to, fwd_bytes, worker_name
|
||||||
|
)
|
||||||
if success:
|
if success:
|
||||||
log(f"✓ Forwarded externally to {forward_to} via SES", 'SUCCESS', worker_name)
|
log(f"✓ Forwarded internally to {forward_to}",
|
||||||
|
'SUCCESS', worker_name)
|
||||||
|
else:
|
||||||
|
log(f"⚠ Internal forward failed to {forward_to}",
|
||||||
|
'WARNING', worker_name)
|
||||||
|
else:
|
||||||
|
success = self.ses.send_raw_email(
|
||||||
|
recipient, forward_to, fwd_bytes, worker_name
|
||||||
|
)
|
||||||
|
if success:
|
||||||
|
log(f"✓ Forwarded externally to {forward_to} via SES",
|
||||||
|
'SUCCESS', worker_name)
|
||||||
|
|
||||||
if metrics_callback:
|
if metrics_callback:
|
||||||
metrics_callback('forward', domain)
|
metrics_callback('forward', domain)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log(f"⚠ Forward failed to {forward_to}: {e}", 'ERROR', worker_name)
|
log(f"⚠ Forward failed to {forward_to}: {e}",
|
||||||
|
'ERROR', worker_name)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _send_via_legacy_smtp(
|
||||||
|
from_addr: str,
|
||||||
|
to_addr: str,
|
||||||
|
raw_message: bytes,
|
||||||
|
smtp_config: dict,
|
||||||
|
worker_name: str
|
||||||
|
) -> bool:
|
||||||
|
"""
|
||||||
|
Send email directly to a legacy SMTP server (for migration).
|
||||||
|
Bypasses SES completely to avoid mail loops.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
host = smtp_config.get('host', '')
|
||||||
|
|
||||||
|
# DynamoDB speichert Zahlen als Decimal, daher int()
|
||||||
|
port = int(smtp_config.get('port', 25))
|
||||||
|
use_tls = smtp_config.get('tls', False)
|
||||||
|
username = smtp_config.get('username')
|
||||||
|
password = smtp_config.get('password')
|
||||||
|
|
||||||
|
if not host:
|
||||||
|
log(f" ✗ Legacy SMTP: no host configured", 'ERROR', worker_name)
|
||||||
|
return False
|
||||||
|
|
||||||
|
with smtplib.SMTP(host, port, timeout=30) as conn:
|
||||||
|
conn.ehlo()
|
||||||
|
if use_tls:
|
||||||
|
conn.starttls()
|
||||||
|
conn.ehlo()
|
||||||
|
if username and password:
|
||||||
|
conn.login(username, password)
|
||||||
|
conn.sendmail(from_addr, [to_addr], raw_message)
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
log(
|
||||||
|
f" ✗ Legacy SMTP failed ({smtp_config.get('host', '?')}:"
|
||||||
|
f"{smtp_config.get('port', '?')}): {e}",
|
||||||
|
'ERROR', worker_name
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _send_internal_email(from_addr: str, to_addr: str, raw_message: bytes, worker_name: str) -> bool:
|
def _send_internal_email(from_addr: str, to_addr: str, raw_message: bytes, worker_name: str) -> bool:
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue