SMTP Configuration view and form

This commit is contained in:
Eduardo Silva 2025-02-27 23:26:44 -03:00
parent dc85a76715
commit 95a0695392
6 changed files with 124 additions and 3 deletions

View File

@ -4,6 +4,7 @@ from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Row, Column, Submit, HTML from crispy_forms.layout import Layout, Row, Column, Submit, HTML
from crispy_forms.templatetags.crispy_forms_field import css_class from crispy_forms.templatetags.crispy_forms_field import css_class
from .models import InviteSettings from .models import InviteSettings
from wireguard_tools.models import EmailSettings
class InviteSettingsForm(forms.ModelForm): class InviteSettingsForm(forms.ModelForm):
@ -253,3 +254,81 @@ class InviteSettingsForm(forms.ModelForm):
self.add_error(field, "The template must include the placeholder '{invite_url}'.") self.add_error(field, "The template must include the placeholder '{invite_url}'.")
return cleaned_data return cleaned_data
class EmailSettingsForm(forms.ModelForm):
class Meta:
model = EmailSettings
fields = [
'smtp_username',
'smtp_password',
'smtp_host',
'smtp_port',
'smtp_encryption',
'smtp_from_address',
'enabled',
]
def __init__(self, *args, **kwargs):
super(EmailSettingsForm, self).__init__(*args, **kwargs)
# Set custom labels for form fields
self.fields['smtp_username'].label = 'Username'
self.fields['smtp_password'].label = 'Password'
self.fields['smtp_host'].label = 'Host'
self.fields['smtp_port'].label = 'Port'
self.fields['smtp_encryption'].label = 'Encryption'
self.fields['smtp_from_address'].label = 'From Address'
self.fields['smtp_password'].required = True
self.fields['smtp_host'].required = True
self.fields['smtp_port'].required = True
self.fields['smtp_encryption'].required = True
self.fields['smtp_from_address'].required = True
self.fields['smtp_username'].required = True
# Use PasswordInput widget to hide the password
self.fields['smtp_password'].widget = forms.PasswordInput(render_value=False)
# Ensure that during edit the saved password is not displayed
if self.instance and self.instance.pk:
self.fields['smtp_password'].initial = ''
self.helper = FormHelper()
self.helper.form_method = 'post'
self.helper.layout = Layout(
HTML("<h3>SMTP Settings</h3>"),
Row(
Column('smtp_username', css_class='form-group col-md-4 mb-0'),
Column('smtp_password', css_class='form-group col-md-4 mb-0'),
Column('smtp_from_address', css_class='form-group col-md-4 mb-0'),
css_class='form-row'
),
Row(
Column('smtp_host', css_class='form-group col-md-4 mb-0'),
Column('smtp_port', css_class='form-group col-md-4 mb-0'),
Column('smtp_encryption', css_class='form-group col-md-4 mb-0'),
css_class='form-row'
),
Row(
Column('enabled', css_class='form-group col-md-4 mb-0'),
css_class='form-row'
),
Row(
Column(
Submit('submit', 'Save', css_class='btn btn-success'),
HTML(' <a class="btn btn-secondary" href="/vpn_invite/">Back</a> '),
css_class='col-md-12'
),
css_class='form-row'
)
)
def clean(self):
cleaned_data = super().clean()
smtp_port = cleaned_data.get('smtp_port')
if smtp_port is not None and smtp_port <= 0:
self.add_error('smtp_port', "SMTP port must be a positive integer.")
return cleaned_data

View File

@ -4,8 +4,9 @@ from user_manager.models import UserAcl
from .models import InviteSettings, PeerInvite from .models import InviteSettings, PeerInvite
from django.conf import settings from django.conf import settings
from django.utils import timezone from django.utils import timezone
from .forms import InviteSettingsForm from .forms import InviteSettingsForm, EmailSettingsForm
from django.contrib import messages from django.contrib import messages
from wireguard_tools.models import EmailSettings
@login_required @login_required
@ -56,3 +57,23 @@ def view_vpn_invite_settings(request):
'form_size': 'col-lg-12' 'form_size': 'col-lg-12'
} }
return render(request, 'generic_form.html', context=data) return render(request, 'generic_form.html', context=data)
@login_required
def view_email_settings(request):
if not UserAcl.objects.filter(user=request.user).filter(user_level__gte=50).exists():
return render(request, 'access_denied.html', {'page_title': 'Access Denied'})
email_settings, _ = EmailSettings.objects.get_or_create(name='email_settings')
form = EmailSettingsForm(request.POST or None, instance=email_settings)
if form.is_valid():
form.save()
messages.success(request, 'Email Settings|Settings saved successfully.')
return redirect('/vpn_invite/')
data = {
'email_settings': email_settings,
'page_title': 'Email Settings',
'form': form,
'form_size': 'col-lg-12'
}
return render(request, 'generic_form.html', context=data)

View File

@ -1,3 +1,4 @@
from django.contrib import admin from django.contrib import admin
from .models import EmailSettings
# Register your models here. # Register your models here.
admin.site.register(EmailSettings)

View File

@ -0,0 +1,18 @@
# Generated by Django 5.1.5 on 2025-02-28 02:09
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wireguard_tools', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='emailsettings',
name='enabled',
field=models.BooleanField(default=True),
),
]

View File

@ -10,6 +10,7 @@ class EmailSettings(models.Model):
smtp_port = models.IntegerField(default=587) smtp_port = models.IntegerField(default=587)
smtp_encryption = models.CharField(default='tls', choices=(('ssl', 'SSL'), ('tls', 'TLS')), max_length=3) smtp_encryption = models.CharField(default='tls', choices=(('ssl', 'SSL'), ('tls', 'TLS')), max_length=3)
smtp_from_address = models.EmailField(blank=True, null=True) smtp_from_address = models.EmailField(blank=True, null=True)
enabled = models.BooleanField(default=True)
uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)

View File

@ -27,7 +27,7 @@ from api.views import wireguard_status, cron_check_updates, cron_update_peer_lat
from firewall.views import view_redirect_rule_list, manage_redirect_rule, view_firewall_rule_list, manage_firewall_rule, view_manage_firewall_settings, view_generate_iptables_script, view_reset_firewall, view_firewall_migration_required from firewall.views import view_redirect_rule_list, manage_redirect_rule, view_firewall_rule_list, manage_firewall_rule, view_manage_firewall_settings, view_generate_iptables_script, view_reset_firewall, view_firewall_migration_required
from dns.views import view_static_host_list, view_manage_static_host, view_manage_dns_settings, view_apply_dns_config from dns.views import view_static_host_list, view_manage_static_host, view_manage_dns_settings, view_apply_dns_config
from wgrrd.views import view_rrd_graph from wgrrd.views import view_rrd_graph
from vpn_invite.views import view_vpn_invite_list, view_vpn_invite_settings from vpn_invite.views import view_vpn_invite_list, view_vpn_invite_settings, view_email_settings
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
@ -70,4 +70,5 @@ urlpatterns = [
path('firewall/migration_required/', view_firewall_migration_required, name='firewall_migration_required'), path('firewall/migration_required/', view_firewall_migration_required, name='firewall_migration_required'),
path('vpn_invite/', view_vpn_invite_list, name='vpn_invite_list'), path('vpn_invite/', view_vpn_invite_list, name='vpn_invite_list'),
path('vpn_invite/settings/', view_vpn_invite_settings, name='vpn_invite_settings'), path('vpn_invite/settings/', view_vpn_invite_settings, name='vpn_invite_settings'),
path('vpn_invite/smtp_settings/', view_email_settings, name='email_settings'),
] ]