import logging import smtplib import socket from django.contrib import admin from django import forms from django.core.exceptions import ValidationError from api.models import MailProvider _logger = logging.getLogger(__name__) class MailProviderForm(forms.ModelForm): host_password = forms.CharField(widget=forms.PasswordInput(render_value=True)) class Meta: model = MailProvider fields = "__all__" def clean(self): cleaned_data = super().clean() host = cleaned_data.get("host") port = cleaned_data.get("port") user = cleaned_data.get("host_user") password = cleaned_data.get("host_password") use_tls = cleaned_data.get("use_tls") if host: try: socket.gethostbyname(host) except socket.gaierror: raise ValidationError( "Invalid mail server hostname. Could not resolve host." ) if host and port and user and password: try: if port == 465: connection = smtplib.SMTP_SSL(host, port, timeout=10) else: connection = smtplib.SMTP(host, port, timeout=10) if use_tls and port == 465: raise ValidationError( "Port 465 should not be used with STARTTLS. Use SMTP_SSL instead or change to port 587." ) if use_tls: connection.starttls() connection.login(user, password) connection.quit() except Exception as e: raise ValidationError(f'Could not connect to the mail server: {e}') return cleaned_data @admin.register(MailProvider) class MailProviderAdmin(admin.ModelAdmin): form = MailProviderForm list_display = ("from_email", "host", "port", "use_tls") search_fields = ("from_email", "host_user", "host") list_filter = ("use_tls",) fieldsets = ( (None, { "fields": ("from_email", "host", "port", "use_tls") }), ("Authentication", { "fields": ("host_user", "host_password") }), )