diff --git a/vpn_invite/forms.py b/vpn_invite/forms.py
index 378e877..4cb6226 100644
--- a/vpn_invite/forms.py
+++ b/vpn_invite/forms.py
@@ -4,6 +4,7 @@ from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Row, Column, Submit, HTML
from crispy_forms.templatetags.crispy_forms_field import css_class
from .models import InviteSettings
+from wireguard_tools.models import EmailSettings
class InviteSettingsForm(forms.ModelForm):
@@ -253,3 +254,81 @@ class InviteSettingsForm(forms.ModelForm):
self.add_error(field, "The template must include the placeholder '{invite_url}'.")
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("
SMTP Settings
"),
+ 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(' Back '),
+ 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
+
diff --git a/vpn_invite/views.py b/vpn_invite/views.py
index f03d801..b4fc329 100644
--- a/vpn_invite/views.py
+++ b/vpn_invite/views.py
@@ -4,8 +4,9 @@ from user_manager.models import UserAcl
from .models import InviteSettings, PeerInvite
from django.conf import settings
from django.utils import timezone
-from .forms import InviteSettingsForm
+from .forms import InviteSettingsForm, EmailSettingsForm
from django.contrib import messages
+from wireguard_tools.models import EmailSettings
@login_required
@@ -56,3 +57,23 @@ def view_vpn_invite_settings(request):
'form_size': 'col-lg-12'
}
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)
diff --git a/wireguard_tools/admin.py b/wireguard_tools/admin.py
index 8c38f3f..b341834 100644
--- a/wireguard_tools/admin.py
+++ b/wireguard_tools/admin.py
@@ -1,3 +1,4 @@
from django.contrib import admin
-
+from .models import EmailSettings
# Register your models here.
+admin.site.register(EmailSettings)
\ No newline at end of file
diff --git a/wireguard_tools/migrations/0002_emailsettings_enabled.py b/wireguard_tools/migrations/0002_emailsettings_enabled.py
new file mode 100644
index 0000000..4d554bd
--- /dev/null
+++ b/wireguard_tools/migrations/0002_emailsettings_enabled.py
@@ -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),
+ ),
+ ]
diff --git a/wireguard_tools/models.py b/wireguard_tools/models.py
index 3239918..c63cf4a 100644
--- a/wireguard_tools/models.py
+++ b/wireguard_tools/models.py
@@ -10,6 +10,7 @@ class EmailSettings(models.Model):
smtp_port = models.IntegerField(default=587)
smtp_encryption = models.CharField(default='tls', choices=(('ssl', 'SSL'), ('tls', 'TLS')), max_length=3)
smtp_from_address = models.EmailField(blank=True, null=True)
+ enabled = models.BooleanField(default=True)
uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
created = models.DateTimeField(auto_now_add=True)
diff --git a/wireguard_webadmin/urls.py b/wireguard_webadmin/urls.py
index bfe9782..806bc58 100644
--- a/wireguard_webadmin/urls.py
+++ b/wireguard_webadmin/urls.py
@@ -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 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 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 = [
path('admin/', admin.site.urls),
@@ -70,4 +70,5 @@ urlpatterns = [
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/settings/', view_vpn_invite_settings, name='vpn_invite_settings'),
+ path('vpn_invite/smtp_settings/', view_email_settings, name='email_settings'),
]