VPN Invite list view/delete

This commit is contained in:
Eduardo Silva 2025-02-27 13:24:09 -03:00
parent 07b7a24c40
commit aea86c3a82
6 changed files with 118 additions and 8 deletions

View File

@ -165,10 +165,10 @@
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="/vpn_invite/settings/" class="nav-link {% if '/vpn_invite/' in request.path %}active{% endif %}"> <a href="/vpn_invite/" class="nav-link {% if '/vpn_invite/' in request.path %}active{% endif %}">
<i class="fas fa-share-square nav-icon"></i> <i class="fas fa-share-square nav-icon"></i>
<p> <p>
Invite Settings VPN Invite
</p> </p>
</a> </a>
</li> </li>

View File

@ -0,0 +1,56 @@
{% extends 'base.html' %}
{% block content %}
<div class='row'>
<div class='col-xl-8'>
<div class="card card-primary card-outline">
<div class="card-header">
<h3 class="card-title">{{ page_title }}</h3>
</div>
<div class="card-body">
<div class="row">
<div class="col-lg-12">
<table class="table table-hover">
<thead>
<tr>
<th>Peer</th>
<th>Expiration</th>
<th>Password</th>
<th></th>
</tr>
</thead>
<tbody>
{% if peer_invite_list %}
{% for invite in peer_invite_list %}
<tr>
<td>{{ invite.peer }}</td>
<td>{{ invite.invite_expiration }}</td>
<td>{{ invite.invite_password }}</td>
<td class="min-width">
<a href="/vpn_invite/?invite={{ invite.uuid }}&action=delete" onclick="return confirm('Remove VPN invitation for peer {{ invite.peer }}?')"><i class="fas fa-trash-alt"></i></a>
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="4"></td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<a href="/vpn_invite/smtp_settings/" class="btn btn-primary">SMTP Settings</a>
<a href="/vpn_invite/settings/" class="btn btn-primary">Invite Settings</a>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,3 +1,12 @@
from django.contrib import admin from django.contrib import admin
from .models import InviteSettings, PeerInvite
# Register your models here.
class PeerInviteAdmin(admin.ModelAdmin):
list_display = ('peer', 'invite_expiration', 'created', 'updated', 'uuid')
admin.site.register(PeerInvite, PeerInviteAdmin)
class InviteSettingsAdmin(admin.ModelAdmin):
list_display = ('name', 'uuid', 'created', 'updated')
admin.site.register(InviteSettings, InviteSettingsAdmin)

View File

@ -7,6 +7,9 @@ class InviteSettings(models.Model):
name = models.CharField(max_length=16, default='default_settings', unique=True) name = models.CharField(max_length=16, default='default_settings', unique=True)
default_password = models.CharField(max_length=32, default='', blank=True, null=True) default_password = models.CharField(max_length=32, default='', blank=True, null=True)
enforce_random_password = models.BooleanField(default=True) enforce_random_password = models.BooleanField(default=True)
required_user_level = models.PositiveIntegerField(default=50, choices=(
(20, 'View Only User'), (30, 'Peer Manager'), (40, 'Wireguard Manager'), (50, 'Administrator'),
))
random_password_length = models.IntegerField(default=6) random_password_length = models.IntegerField(default=6)
random_password_complexity = models.CharField( random_password_complexity = models.CharField(
max_length=22, default='letters_digits', choices=( max_length=22, default='letters_digits', choices=(
@ -38,11 +41,14 @@ class InviteSettings(models.Model):
download_instructions = models.TextField(default='Download the WireGuard app for your device using one of the links below. After installation, you can scan the QR code or download the configuration file to import on your device.') download_instructions = models.TextField(default='Download the WireGuard app for your device using one of the links below. After installation, you can scan the QR code or download the configuration file to import on your device.')
invite_url = models.URLField(default='') invite_url = models.URLField(default='')
invite_text_body = models.TextField(default='Here is your WireGuard VPN invite link: {invite_url}. The link expires in {expire_minutes} minutes.')
invite_email_subject = models.CharField(max_length=64, default='WireGuard VPN Invite', blank=True, null=True) invite_email_subject = models.CharField(max_length=64, default='WireGuard VPN Invite', blank=True, null=True)
invite_email_body = models.TextField(default='Here is your WireGuard VPN invite link: {invite_url}', blank=True, null=True) invite_email_body = models.TextField(default='Here is your WireGuard VPN invite link: {invite_url}. The link expires in {expire_minutes} minutes.')
invite_email_enabled = models.BooleanField(default=True) invite_email_enabled = models.BooleanField(default=True)
invite_whatsapp_body = models.TextField(default='Here is your WireGuard VPN invite link: {invite_url}', blank=True, null=True) invite_whatsapp_body = models.TextField(default='Here is your WireGuard VPN invite link: {invite_url}. The link expires in {expire_minutes} minutes.')
invite_whatsapp_enabled = models.BooleanField(default=True) invite_whatsapp_enabled = models.BooleanField(default=True)
uuid = models.UUIDField(default=uuid.uuid4, editable=False) uuid = models.UUIDField(default=uuid.uuid4, editable=False)

View File

@ -1,3 +1,40 @@
from django.shortcuts import render from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from user_manager.models import UserAcl
from .models import InviteSettings, PeerInvite
from django.conf import settings
from django.utils import timezone
# Create your views here.
@login_required
def view_vpn_invite_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'})
if request.GET.get('invite') and request.GET.get('action') == 'delete':
PeerInvite.objects.filter(uuid=request.GET.get('invite')).delete()
return redirect('/vpn_invite/')
try:
default_invite_url = f'{settings.CSRF_TRUSTED_ORIGINS[1]}/invite/'
except:
default_invite_url = 'https://wireguard-webadmin.example.com/invite/'
invite_settings, _ = InviteSettings.objects.get_or_create(
name='default_settings', defaults={'invite_url': default_invite_url,}
)
if invite_settings.invite_url.startswith('http://'):
invite_settings.invite_url = invite_settings.invite_url.replace('http://', 'https://')
invite_settings.save()
peer_invite_list = PeerInvite.objects.all().order_by('invite_expiration')
peer_invite_list.filter(invite_expiration__lt=timezone.now()).delete()
data = {
'page_title': 'VPN Invite',
'peer_invite_list': peer_invite_list,
}
return render(request, 'vpn_invite/invite_settings.html', context=data)

View File

@ -27,6 +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_settings
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
@ -66,5 +67,6 @@ urlpatterns = [
path('firewall/firewall_settings/', view_manage_firewall_settings, name='firewall_settings'), path('firewall/firewall_settings/', view_manage_firewall_settings, name='firewall_settings'),
path('firewall/generate_firewall_script/', view_generate_iptables_script, name='generate_iptables_script'), path('firewall/generate_firewall_script/', view_generate_iptables_script, name='generate_iptables_script'),
path('firewall/reset_to_default/', view_reset_firewall, name='reset_firewall'), path('firewall/reset_to_default/', view_reset_firewall, name='reset_firewall'),
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_settings, name='vpn_invite_settings'),
] ]