mirror of
https://github.com/dat515-2025/Group-8.git
synced 2026-03-22 23:20:56 +01:00
Merge pull request #49 from dat515-2025/merge/email_sender
feat(infrastructure): add email sender
This commit is contained in:
16
.github/workflows/deploy-prod.yaml
vendored
16
.github/workflows/deploy-prod.yaml
vendored
@@ -92,6 +92,13 @@ jobs:
|
|||||||
CSAS_CLIENT_ID: ${{ secrets.CSAS_CLIENT_ID }}
|
CSAS_CLIENT_ID: ${{ secrets.CSAS_CLIENT_ID }}
|
||||||
CSAS_CLIENT_SECRET: ${{ secrets.CSAS_CLIENT_SECRET }}
|
CSAS_CLIENT_SECRET: ${{ secrets.CSAS_CLIENT_SECRET }}
|
||||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||||
|
SMTP_HOST: ${{ secrets.SMTP_HOST }}
|
||||||
|
SMTP_PORT: ${{ secrets.SMTP_PORT }}
|
||||||
|
SMTP_USERNAME: ${{ secrets.SMTP_USERNAME }}
|
||||||
|
SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }}
|
||||||
|
SMTP_USE_TLS: ${{ secrets.SMTP_USE_TLS }}
|
||||||
|
SMTP_USE_SSL: ${{ secrets.SMTP_USE_SSL }}
|
||||||
|
SMTP_FROM: ${{ secrets.SMTP_FROM }}
|
||||||
run: |
|
run: |
|
||||||
helm upgrade --install myapp ./7project/charts/myapp-chart \
|
helm upgrade --install myapp ./7project/charts/myapp-chart \
|
||||||
-n prod --create-namespace \
|
-n prod --create-namespace \
|
||||||
@@ -111,4 +118,11 @@ jobs:
|
|||||||
--set-string oauth.csas.clientId="$CSAS_CLIENT_ID" \
|
--set-string oauth.csas.clientId="$CSAS_CLIENT_ID" \
|
||||||
--set-string oauth.csas.clientSecret="$CSAS_CLIENT_SECRET" \
|
--set-string oauth.csas.clientSecret="$CSAS_CLIENT_SECRET" \
|
||||||
--set-string sentry_dsn="$SENTRY_DSN" \
|
--set-string sentry_dsn="$SENTRY_DSN" \
|
||||||
--set-string database.encryptionSecret="${{ secrets.PROD_DB_ENCRYPTION_KEY }}"
|
--set-string database.encryptionSecret="${{ secrets.PROD_DB_ENCRYPTION_KEY }}" \
|
||||||
|
--set-string smtp.host="$SMTP_HOST" \
|
||||||
|
--set smtp.port="$SMTP_PORT" \
|
||||||
|
--set-string smtp.username="$SMTP_USERNAME" \
|
||||||
|
--set-string smtp.password="$SMTP_PASSWORD" \
|
||||||
|
--set-string smtp.tls="$SMTP_USE_TLS" \
|
||||||
|
--set-string smtp.ssl="$SMTP_USE_SSL" \
|
||||||
|
--set-string smtp.from="$SMTP_FROM"
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import os
|
||||||
|
import smtplib
|
||||||
|
from email.message import EmailMessage
|
||||||
|
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
|
|
||||||
@@ -84,8 +87,45 @@ def send_email(to: str, subject: str, body: str) -> None:
|
|||||||
logger.error("Email task missing fields. to=%r subject=%r body_len=%r", to, subject, len(body) if body else 0)
|
logger.error("Email task missing fields. to=%r subject=%r body_len=%r", to, subject, len(body) if body else 0)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Placeholder for real email sending logic
|
host = os.getenv("SMTP_HOST")
|
||||||
|
if not host:
|
||||||
|
logger.error("SMTP_HOST is not configured; cannot send email")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
port = int(os.getenv("SMTP_PORT", "25"))
|
||||||
|
username = os.getenv("SMTP_USERNAME")
|
||||||
|
password = os.getenv("SMTP_PASSWORD")
|
||||||
|
use_tls = os.getenv("SMTP_USE_TLS", "0").lower() in {"1", "true", "yes"}
|
||||||
|
use_ssl = os.getenv("SMTP_USE_SSL", "0").lower() in {"1", "true", "yes"}
|
||||||
|
timeout = int(os.getenv("SMTP_TIMEOUT", "10"))
|
||||||
|
mail_from = os.getenv("SMTP_FROM") or username or "noreply@localhost"
|
||||||
|
|
||||||
|
# Build message
|
||||||
|
msg = EmailMessage()
|
||||||
|
msg["To"] = to
|
||||||
|
msg["From"] = mail_from
|
||||||
|
msg["Subject"] = subject
|
||||||
|
msg.set_content(body)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if use_ssl:
|
||||||
|
with smtplib.SMTP_SSL(host=host, port=port, timeout=timeout) as smtp:
|
||||||
|
if username and password:
|
||||||
|
smtp.login(username, password)
|
||||||
|
smtp.send_message(msg)
|
||||||
|
else:
|
||||||
|
with smtplib.SMTP(host=host, port=port, timeout=timeout) as smtp:
|
||||||
|
# STARTTLS if requested
|
||||||
|
if use_tls:
|
||||||
|
smtp.starttls()
|
||||||
|
if username and password:
|
||||||
|
smtp.login(username, password)
|
||||||
|
smtp.send_message(msg)
|
||||||
logger.info("[Celery] Email sent | to=%s | subject=%s | body_len=%d", to, subject, len(body))
|
logger.info("[Celery] Email sent | to=%s | subject=%s | body_len=%d", to, subject, len(body))
|
||||||
|
except Exception:
|
||||||
|
logger.exception("Failed to send email via SMTP to=%s subject=%s host=%s port=%s tls=%s ssl=%s", to, subject,
|
||||||
|
host, port, use_tls, use_ssl)
|
||||||
|
|
||||||
|
|
||||||
@shared_task(name="workers.load_transactions")
|
@shared_task(name="workers.load_transactions")
|
||||||
|
|||||||
@@ -19,3 +19,10 @@ stringData:
|
|||||||
RABBITMQ_USERNAME: {{ .Values.rabbitmq.username | quote }}
|
RABBITMQ_USERNAME: {{ .Values.rabbitmq.username | quote }}
|
||||||
SENTRY_DSN: {{ .Values.sentry_dsn | quote }}
|
SENTRY_DSN: {{ .Values.sentry_dsn | quote }}
|
||||||
DB_ENCRYPTION_KEY: {{ required "Set .Values.database.encryptionSecret" .Values.database.encryptionSecret | quote }}
|
DB_ENCRYPTION_KEY: {{ required "Set .Values.database.encryptionSecret" .Values.database.encryptionSecret | quote }}
|
||||||
|
SMTP_HOST: {{ .Values.smtp.host | default "" | quote }}
|
||||||
|
SMTP_PORT: {{ .Values.smtp.port | default 587 | quote }}
|
||||||
|
SMTP_USERNAME: {{ .Values.smtp.username | default "" | quote }}
|
||||||
|
SMTP_PASSWORD: {{ .Values.smtp.password | default "" | quote }}
|
||||||
|
SMTP_USE_TLS: {{ .Values.smtp.tls | default false | quote }}
|
||||||
|
SMTP_USE_SSL: {{ .Values.smtp.ssl | default false | quote }}
|
||||||
|
SMTP_FROM: {{ .Values.smtp.from | default "" | quote }}
|
||||||
|
|||||||
@@ -85,3 +85,38 @@ spec:
|
|||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: prod
|
name: prod
|
||||||
key: DB_ENCRYPTION_KEY
|
key: DB_ENCRYPTION_KEY
|
||||||
|
- name: SMTP_HOST
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: prod
|
||||||
|
key: SMTP_HOST
|
||||||
|
- name: SMTP_PORT
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: prod
|
||||||
|
key: SMTP_PORT
|
||||||
|
- name: SMTP_USERNAME
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: prod
|
||||||
|
key: SMTP_USERNAME
|
||||||
|
- name: SMTP_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: prod
|
||||||
|
key: SMTP_PASSWORD
|
||||||
|
- name: SMTP_USE_TLS
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: prod
|
||||||
|
key: SMTP_USE_TLS
|
||||||
|
- name: SMTP_USE_SSL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: prod
|
||||||
|
key: SMTP_USE_SSL
|
||||||
|
- name: SMTP_FROM
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: prod
|
||||||
|
key: SMTP_FROM
|
||||||
|
|||||||
@@ -42,6 +42,16 @@ cron:
|
|||||||
endpoint: "/_cron"
|
endpoint: "/_cron"
|
||||||
concurrencyPolicy: "Forbid"
|
concurrencyPolicy: "Forbid"
|
||||||
|
|
||||||
|
smtp:
|
||||||
|
host:
|
||||||
|
port: 587
|
||||||
|
username: ""
|
||||||
|
password: ""
|
||||||
|
tls: false
|
||||||
|
ssl: false
|
||||||
|
from: ""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
service:
|
service:
|
||||||
port: 80
|
port: 80
|
||||||
|
|||||||
Reference in New Issue
Block a user