Routerfleet integration

This commit is contained in:
Eduardo Silva 2024-04-03 15:19:01 -03:00
parent 6ffa1abb15
commit 31fc3a1098
6 changed files with 127 additions and 5 deletions

View File

@ -1,6 +1,9 @@
from django.shortcuts import render, Http404, redirect from django.shortcuts import render, Http404, redirect
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib import auth from django.contrib import auth
from django.contrib import messages
from api.views import get_api_key
from .forms import CreateUserForm, LoginForm from .forms import CreateUserForm, LoginForm
from django.http import HttpResponse from django.http import HttpResponse
from user_manager.models import UserAcl from user_manager.models import UserAcl
@ -25,6 +28,11 @@ def view_create_first_user(request):
def view_login(request): def view_login(request):
if not User.objects.filter().all(): if not User.objects.filter().all():
return redirect('/accounts/create_first_user/') return redirect('/accounts/create_first_user/')
if get_api_key('routerfleet'):
messages.warning(request, 'Login disabled|Login form is disabled. Check integration settings.')
return redirect('/accounts/logout/')
if request.method == 'POST': if request.method == 'POST':
form = LoginForm(request.POST) form = LoginForm(request.POST)
if form.is_valid(): if form.is_valid():

View File

@ -1,9 +1,14 @@
from django.contrib.auth.models import User
from django.contrib import auth
from django.http import JsonResponse from django.http import JsonResponse
from django.shortcuts import get_object_or_404, redirect
from django.views.decorators.http import require_http_methods from django.views.decorators.http import require_http_methods
from django.http import HttpResponseForbidden from django.http import HttpResponseForbidden
from django.conf import settings from django.conf import settings
from django.utils import timezone from django.utils import timezone
from user_manager.models import UserAcl, AuthenticationToken
from wireguard.models import WebadminSettings, Peer, PeerStatus from wireguard.models import WebadminSettings, Peer, PeerStatus
import requests import requests
import subprocess import subprocess
@ -13,9 +18,14 @@ import os
import uuid import uuid
def get_api_key(): def get_api_key(api_name):
api_file_path = '/etc/wireguard/api_key'
api_key = None api_key = None
if api_name == 'api':
api_file_path = '/etc/wireguard/api_key'
elif api_name == 'routerfleet':
api_file_path = '/etc/wireguard/routerfleet_key'
else:
return api_key
if os.path.exists(api_file_path) and os.path.isfile(api_file_path): if os.path.exists(api_file_path) and os.path.isfile(api_file_path):
with open(api_file_path, 'r') as api_file: with open(api_file_path, 'r') as api_file:
@ -31,12 +41,80 @@ def get_api_key():
return api_key return api_key
def routerfleet_authenticate_session(request):
AuthenticationToken.objects.filter(created__lt=timezone.now() - timezone.timedelta(minutes=1)).delete()
authentication_token = get_object_or_404(AuthenticationToken, uuid=request.GET.get('token'))
auth.login(request, authentication_token.user)
authentication_token.delete()
return redirect('/')
@require_http_methods(["GET"])
def routerfleet_get_user_token(request):
data = {'status': '', 'message': '', 'authentication_token': ''}
if request.GET.get('key'):
api_key = get_api_key('routerfleet')
if api_key and api_key == request.GET.get('key'):
pass
else:
return HttpResponseForbidden()
else:
return HttpResponseForbidden()
try:
default_user_level = int(request.GET.get('default_user_level'))
if default_user_level not in [10, 20, 30, 40, 50]:
default_user_level = 0
except:
default_user_level = 0
if request.GET.get('username'):
user = User.objects.filter(username=request.GET.get('username')).first()
if request.GET.get('action') == 'test':
if UserAcl.objects.filter(user=user, user_level__gte=50).exists():
data['status'] = 'success'
data['message'] = 'User exists and is an administrator'
else:
data['status'] = 'error'
data['message'] = f'Administrator with username {request.GET.get("username")} not found at wireguard_webadmin.'
elif request.GET.get('action') == 'login':
if user:
user_acl = UserAcl.objects.filter(user=user).first()
else:
if default_user_level == 0:
data['status'] = 'error'
data['message'] = 'User not found'
else:
user = User.objects.create_user(username=request.GET.get('username'), password=str(uuid.uuid4()))
user_acl = UserAcl.objects.create(user=user, user_level=default_user_level)
if user and user_acl:
authentication_token = AuthenticationToken.objects.create(user=user)
data['status'] = 'success'
data['message'] = 'User authenticated successfully'
data['authentication_token'] = str(authentication_token.uuid)
else:
data['status'] = 'error'
data['message'] = 'Invalid action'
else:
data['status'] = 'error'
data['message'] = 'No username provided'
if data['status'] == 'error':
return JsonResponse(data, status=400)
else:
return JsonResponse(data)
@require_http_methods(["GET"]) @require_http_methods(["GET"])
def wireguard_status(request): def wireguard_status(request):
if request.user.is_authenticated: if request.user.is_authenticated:
pass pass
elif request.GET.get('key'): elif request.GET.get('key'):
api_key = get_api_key() api_key = get_api_key('api')
if api_key and api_key == request.GET.get('key'): if api_key and api_key == request.GET.get('key'):
pass pass
else: else:

View File

@ -0,0 +1,27 @@
# Generated by Django 5.0.2 on 2024-04-03 16:45
import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('user_manager', '0002_remove_useracl_id_useracl_created_useracl_updated_and_more'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='AuthenticationToken',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(auto_now_add=True)),
('updated', models.DateTimeField(auto_now=True)),
('uuid', models.UUIDField(default=uuid.uuid4, editable=False)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -19,3 +19,10 @@ class UserAcl(models.Model):
def __str__(self): def __str__(self):
return self.user.username return self.user.username
class AuthenticationToken(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
uuid = models.UUIDField(editable=False, default=uuid.uuid4)

View File

@ -129,6 +129,6 @@ STATICFILES_DIRS = [
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
WIREGUARD_WEBADMIN_VERSION = 9604 WIREGUARD_WEBADMIN_VERSION = 9605
from wireguard_webadmin.production_settings import * from wireguard_webadmin.production_settings import *

View File

@ -22,7 +22,7 @@ from console.views import view_console
from user_manager.views import view_user_list, view_manage_user from user_manager.views import view_user_list, view_manage_user
from accounts.views import view_create_first_user, view_login, view_logout from accounts.views import view_create_first_user, view_login, view_logout
from wireguard_tools.views import export_wireguard_configs, download_config_or_qrcode, restart_wireguard_interfaces from wireguard_tools.views import export_wireguard_configs, download_config_or_qrcode, restart_wireguard_interfaces
from api.views import wireguard_status, cron_check_updates, cron_update_peer_latest_handshake from api.views import wireguard_status, cron_check_updates, cron_update_peer_latest_handshake, routerfleet_get_user_token, routerfleet_authenticate_session
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
@ -43,6 +43,8 @@ urlpatterns = [
path('accounts/create_first_user/', view_create_first_user, name='create_first_user'), path('accounts/create_first_user/', view_create_first_user, name='create_first_user'),
path('accounts/login/', view_login, name='login'), path('accounts/login/', view_login, name='login'),
path('accounts/logout/', view_logout, name='logout'), path('accounts/logout/', view_logout, name='logout'),
path('accounts/routerfleet_authenticate_session/', routerfleet_authenticate_session, name='routerfleet_authenticate_session'),
path('api/routerfleet_get_user_token/', routerfleet_get_user_token, name='routerfleet_get_user_token'),
path('api/wireguard_status/', wireguard_status, name='api_wireguard_status'), path('api/wireguard_status/', wireguard_status, name='api_wireguard_status'),
path('api/cron_check_updates/', cron_check_updates, name='cron_check_updates'), path('api/cron_check_updates/', cron_check_updates, name='cron_check_updates'),
path('api/cron_update_peer_latest_handshake/', cron_update_peer_latest_handshake, name='cron_update_peer_latest_handshake'), path('api/cron_update_peer_latest_handshake/', cron_update_peer_latest_handshake, name='cron_update_peer_latest_handshake'),