mirror of
https://github.com/eduardogsilva/wireguard_webadmin.git
synced 2025-04-19 00:45:16 +00:00
User toggle for webconsole and enhanced filter
This commit is contained in:
parent
64cd174639
commit
10e456b202
@ -1,13 +1,19 @@
|
|||||||
from wireguard.models import WireGuardInstance
|
from wireguard.models import WireGuardInstance
|
||||||
from wgwadmlibrary.tools import is_valid_ip_or_hostname
|
from wgwadmlibrary.tools import is_valid_ip_or_hostname
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render, get_object_or_404
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from user_manager.models import UserAcl
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def view_console(request):
|
def view_console(request):
|
||||||
page_title = 'Console'
|
page_title = 'Console'
|
||||||
|
user_acl = get_object_or_404(UserAcl, user=request.user)
|
||||||
|
|
||||||
|
if not user_acl.enable_console:
|
||||||
|
return render(request, 'access_denied.html', {'page_title': 'Access Denied'})
|
||||||
|
|
||||||
wireguard_instances = WireGuardInstance.objects.all().order_by('instance_id')
|
wireguard_instances = WireGuardInstance.objects.all().order_by('instance_id')
|
||||||
if wireguard_instances.filter(pending_changes=True).exists():
|
if wireguard_instances.filter(pending_changes=True).exists():
|
||||||
pending_changes_warning = True
|
pending_changes_warning = True
|
||||||
@ -60,13 +66,18 @@ def view_console(request):
|
|||||||
bash_command = None
|
bash_command = None
|
||||||
command_success = False
|
command_success = False
|
||||||
|
|
||||||
if bash_command:
|
if user_acl.enable_enhanced_filter and requested_command == 'wgshow':
|
||||||
try:
|
command_output = 'Enhanced filter is enabled. This command is not available.'
|
||||||
command_output = subprocess.check_output(bash_command, stderr=subprocess.STDOUT).decode('utf-8')
|
bash_command = None
|
||||||
command_success = True
|
command_success = False
|
||||||
except subprocess.CalledProcessError as e:
|
else:
|
||||||
command_output = e.output.decode('utf-8')
|
if bash_command:
|
||||||
command_success = False
|
try:
|
||||||
|
command_output = subprocess.check_output(bash_command, stderr=subprocess.STDOUT).decode('utf-8')
|
||||||
|
command_success = True
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
command_output = e.output.decode('utf-8')
|
||||||
|
command_success = False
|
||||||
|
|
||||||
context = {'page_title': page_title, 'command_output': command_output, 'command_success': command_success, 'pending_changes_warning': pending_changes_warning}
|
context = {'page_title': page_title, 'command_output': command_output, 'command_success': command_success, 'pending_changes_warning': pending_changes_warning}
|
||||||
return render(request, 'console/console.html', context)
|
return render(request, 'console/console.html', context)
|
@ -8,6 +8,8 @@
|
|||||||
<th>User Level</th>
|
<th>User Level</th>
|
||||||
<th>Peer Groups</th>
|
<th>Peer Groups</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -24,6 +26,16 @@
|
|||||||
Any
|
Any
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
<td style="width: 1%; white-space: nowrap;">
|
||||||
|
{% if user_acl.enable_console %}
|
||||||
|
<i class="fas fa-terminal" title="Console Enabled"></i>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td style="width: 1%; white-space: nowrap;">
|
||||||
|
{% if user_acl.enable_enhanced_filter %}
|
||||||
|
<i class="fas fa-eye-slash" title="Enhanced Filter Enabled"></i>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
<td style="width: 1%; white-space: nowrap;">
|
<td style="width: 1%; white-space: nowrap;">
|
||||||
<a href="/user/manage/?uuid={{ user_acl.uuid }}" ><i class="far fa-edit"></i></a>
|
<a href="/user/manage/?uuid={{ user_acl.uuid }}" ><i class="far fa-edit"></i></a>
|
||||||
</td>
|
</td>
|
||||||
|
@ -2,5 +2,3 @@
|
|||||||
<a href="/user/list/" class="btn {% if request.path == '/user/list/' %}btn-outline-primary{% else %}btn-primary{% endif %}">List Users</a>
|
<a href="/user/list/" class="btn {% if request.path == '/user/list/' %}btn-outline-primary{% else %}btn-primary{% endif %}">List Users</a>
|
||||||
<a href="/user/peer-group/list/" class="btn {% if request.path == '/user/peer-group/list/' %}btn-outline-primary{% else %}btn-primary{% endif %}">List Peer Groups</a>
|
<a href="/user/peer-group/list/" class="btn {% if request.path == '/user/peer-group/list/' %}btn-outline-primary{% else %}btn-primary{% endif %}">List Peer Groups</a>
|
||||||
<a href="/user/peer-group/manage/" class="btn btn-primary">Add Peer Group</a>
|
<a href="/user/peer-group/manage/" class="btn btn-primary">Add Peer Group</a>
|
||||||
<br><br><br><h5>Warning:</h5>
|
|
||||||
<p>The limitation of Peer Groups for users is implemented. However, in some places, information about other peers may still leak, such as in Console -> wg show or through the endpoint /api/wireguard_status/. In the next version, we will add a fix for this.</p>
|
|
@ -12,6 +12,8 @@ class UserAclForm(forms.Form):
|
|||||||
username = forms.CharField(max_length=150)
|
username = forms.CharField(max_length=150)
|
||||||
password1 = forms.CharField(widget=forms.PasswordInput, required=False, label="Password")
|
password1 = forms.CharField(widget=forms.PasswordInput, required=False, label="Password")
|
||||||
password2 = forms.CharField(widget=forms.PasswordInput, required=False, label="Password confirmation")
|
password2 = forms.CharField(widget=forms.PasswordInput, required=False, label="Password confirmation")
|
||||||
|
enable_console = forms.BooleanField(required=False, label="Enable Console")
|
||||||
|
enable_enhanced_filter = forms.BooleanField(required=False, label="Enable Enhanced Filter")
|
||||||
user_level = forms.ChoiceField(choices=UserAcl.user_level.field.choices, required=True, label="User Level")
|
user_level = forms.ChoiceField(choices=UserAcl.user_level.field.choices, required=True, label="User Level")
|
||||||
peer_groups = forms.ModelMultipleChoiceField(
|
peer_groups = forms.ModelMultipleChoiceField(
|
||||||
queryset=PeerGroup.objects.all(),
|
queryset=PeerGroup.objects.all(),
|
||||||
@ -27,9 +29,16 @@ class UserAclForm(forms.Form):
|
|||||||
self.fields['username'].initial = self.instance.username
|
self.fields['username'].initial = self.instance.username
|
||||||
self.fields['username'].widget.attrs['readonly'] = True
|
self.fields['username'].widget.attrs['readonly'] = True
|
||||||
self.fields['peer_groups'].initial = self.instance.useracl.peer_groups.all()
|
self.fields['peer_groups'].initial = self.instance.useracl.peer_groups.all()
|
||||||
|
self.fields['enable_console'].initial = self.instance.useracl.enable_console
|
||||||
|
self.fields['enable_enhanced_filter'].initial = self.instance.useracl.enable_enhanced_filter
|
||||||
else:
|
else:
|
||||||
self.fields['password1'].required = True
|
self.fields['password1'].required = True
|
||||||
self.fields['password2'].required = True
|
self.fields['password2'].required = True
|
||||||
|
self.fields['enable_console'].initial = True
|
||||||
|
self.fields['enable_enhanced_filter'].initial = False
|
||||||
|
|
||||||
|
self.fields['enable_console'].label = "Console"
|
||||||
|
self.fields['enable_enhanced_filter'].label = "Enhanced Filter"
|
||||||
|
|
||||||
self.helper = FormHelper()
|
self.helper = FormHelper()
|
||||||
self.helper.form_method = 'post'
|
self.helper.form_method = 'post'
|
||||||
@ -60,6 +69,14 @@ class UserAclForm(forms.Form):
|
|||||||
Column('peer_groups', css_class='form-group col-md-12 mb-0'),
|
Column('peer_groups', css_class='form-group col-md-12 mb-0'),
|
||||||
css_class='form-row'
|
css_class='form-row'
|
||||||
),
|
),
|
||||||
|
Row(
|
||||||
|
Column('enable_console', css_class='form-group col-md-12 mb-0'),
|
||||||
|
css_class='form-row'
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
Column('enable_enhanced_filter', css_class='form-group col-md-12 mb-0'),
|
||||||
|
css_class='form-row'
|
||||||
|
),
|
||||||
Row(
|
Row(
|
||||||
Column(
|
Column(
|
||||||
Submit('submit', 'Save', css_class='btn btn-success'),
|
Submit('submit', 'Save', css_class='btn btn-success'),
|
||||||
@ -100,6 +117,8 @@ class UserAclForm(forms.Form):
|
|||||||
password = self.cleaned_data.get('password1')
|
password = self.cleaned_data.get('password1')
|
||||||
user_level = self.cleaned_data['user_level']
|
user_level = self.cleaned_data['user_level']
|
||||||
peer_groups = self.cleaned_data.get('peer_groups', [])
|
peer_groups = self.cleaned_data.get('peer_groups', [])
|
||||||
|
enable_console = self.cleaned_data.get('enable_console', False)
|
||||||
|
enable_enhanced_filter = self.cleaned_data.get('enable_enhanced_filter', False)
|
||||||
|
|
||||||
if self.instance:
|
if self.instance:
|
||||||
user = self.instance
|
user = self.instance
|
||||||
@ -115,7 +134,9 @@ class UserAclForm(forms.Form):
|
|||||||
user_acl, created = UserAcl.objects.update_or_create(
|
user_acl, created = UserAcl.objects.update_or_create(
|
||||||
user=user,
|
user=user,
|
||||||
defaults={
|
defaults={
|
||||||
'user_level': user_level
|
'user_level': user_level,
|
||||||
|
'enable_console': enable_console,
|
||||||
|
'enable_enhanced_filter': enable_enhanced_filter
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 5.1.5 on 2025-01-21 15:06
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('user_manager', '0004_useracl_peer_groups'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='useracl',
|
||||||
|
name='enable_console',
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='useracl',
|
||||||
|
name='enable_enhanced_filter',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
@ -14,6 +14,8 @@ class UserAcl(models.Model):
|
|||||||
(50, 'Administrator'),
|
(50, 'Administrator'),
|
||||||
))
|
))
|
||||||
peer_groups = models.ManyToManyField(PeerGroup, blank=True)
|
peer_groups = models.ManyToManyField(PeerGroup, blank=True)
|
||||||
|
enable_console = models.BooleanField(default=True)
|
||||||
|
enable_enhanced_filter = models.BooleanField(default=False)
|
||||||
|
|
||||||
created = models.DateTimeField(auto_now_add=True)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
updated = models.DateTimeField(auto_now=True)
|
updated = models.DateTimeField(auto_now=True)
|
||||||
|
@ -156,6 +156,12 @@ def view_manage_user(request):
|
|||||||
<h4>Peer Groups</h4>
|
<h4>Peer Groups</h4>
|
||||||
<p>Select which peer groups this user can access. If no peer groups are selected, the user will have access to all peers.</p>
|
<p>Select which peer groups this user can access. If no peer groups are selected, the user will have access to all peers.</p>
|
||||||
|
|
||||||
|
<h4>Console</h4>
|
||||||
|
<p>Enable or disable web console access for this user.</p>
|
||||||
|
|
||||||
|
<h4>Enhanced Filter</h4>
|
||||||
|
<p>This option filters the API status response to include only peers that the user has access to. Depending on the size of your environment, enabling this option may impact performance. To mitigate this, consider increasing the "Web Refresh Interval" to reduce the number of requests.</p>
|
||||||
|
|
||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,19 +78,25 @@ def view_welcome(request):
|
|||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def view_wireguard_status(request):
|
def view_wireguard_status(request):
|
||||||
|
user_acl = get_object_or_404(UserAcl, user=request.user)
|
||||||
page_title = 'WireGuard Status'
|
page_title = 'WireGuard Status'
|
||||||
wireguard_instances = WireGuardInstance.objects.all().order_by('instance_id')
|
wireguard_instances = WireGuardInstance.objects.all().order_by('instance_id')
|
||||||
if wireguard_instances.filter(pending_changes=True).exists():
|
if wireguard_instances.filter(pending_changes=True).exists():
|
||||||
pending_changes_warning = True
|
pending_changes_warning = True
|
||||||
else:
|
else:
|
||||||
pending_changes_warning = False
|
pending_changes_warning = False
|
||||||
bash_command = ['bash', '-c', 'wg show']
|
|
||||||
try:
|
if user_acl.enable_enhanced_filter:
|
||||||
command_output = subprocess.check_output(bash_command, stderr=subprocess.STDOUT).decode('utf-8')
|
command_output = 'Enhanced filter is enabled. This command is not available.'
|
||||||
command_success = True
|
command_success = True
|
||||||
except subprocess.CalledProcessError as e:
|
else:
|
||||||
command_output = e.output.decode('utf-8')
|
bash_command = ['bash', '-c', 'wg show']
|
||||||
command_success = False
|
try:
|
||||||
|
command_output = subprocess.check_output(bash_command, stderr=subprocess.STDOUT).decode('utf-8')
|
||||||
|
command_success = True
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
command_output = e.output.decode('utf-8')
|
||||||
|
command_success = False
|
||||||
|
|
||||||
context = {'page_title': page_title, 'command_output': command_output, 'command_success': command_success, 'pending_changes_warning': pending_changes_warning, 'wireguard_instances': wireguard_instances}
|
context = {'page_title': page_title, 'command_output': command_output, 'command_success': command_success, 'pending_changes_warning': pending_changes_warning, 'wireguard_instances': wireguard_instances}
|
||||||
return render(request, 'wireguard/wireguard_status.html', context)
|
return render(request, 'wireguard/wireguard_status.html', context)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user