fix + test api with resl client

This commit is contained in:
2025-02-06 15:10:51 +01:00
parent 2d172a3620
commit 861a0e58e5
20 changed files with 376 additions and 254 deletions

View File

@@ -1,8 +1,8 @@
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.http import JsonResponse, HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required, permission_required
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.contrib.auth.decorators import login_required
import json
import paho.mqtt.client as mqtt
@@ -16,13 +16,51 @@ from .mqtt_service import MosquittoDynamicSecurity
config = dotenv_values(".env")
# authenticate(config['MASTER_PASSWORD'])
@csrf_exempt
def list_sites_api(request):
if request.method == 'POST':
data = json.loads(request.body)
master_password = data.get('master_password')
if not authenticate(master_password):
return JsonResponse({"error": "Master password errata"}, status=403)
sites = PasswordEntry.objects.values_list('site', flat=True)
return JsonResponse({"sites": list(sites)})
return JsonResponse({"error": "Richiesta non valida"}, status=400)
@csrf_exempt
def get_password_api(request):
if request.method == 'POST':
data = json.loads(request.body)
master_password = data.get('master_password')
site = data.get('site')
if not authenticate(master_password):
return JsonResponse({"error": "Master password errata"}, status=403)
key = derive_key(master_password)
try:
entry = PasswordEntry.objects.get(site=site)
decrypted_password = decrypt_password(entry.password, key)
return JsonResponse({
"site": entry.site,
"username": entry.username,
"password": decrypted_password,
"client_id": entry.client_id,
"topic": entry.topic
})
except PasswordEntry.DoesNotExist:
return JsonResponse({"error": "Sito non trovato"}, status=404)
return JsonResponse({"error": "Richiesta non valida"}, status=400)
@login_required
def home_view(request):
return redirect('list_users') # Reindirizza alla lista degli utenti
#return render(request, 'home.html')
@csrf_exempt
@login_required
def publish_message(request):
request_data = json.loads(request.body)
publish.single(topic=request_data['topic'],
@@ -58,6 +96,57 @@ def create_user(request):
"username": username,
"password": password
}
],
"commands": [
{
"command": "createRole",
"rolename": f'{username}_role',
"textname": "",
"textdescription": "",
"acls": [
{ "acltype": "publishClientSend", "topic": topic, "priority": 0, "allow": True }
]
},
{
"command": "createRole",
"rolename": f'{username}_ase_role',
"textname": "",
"textdescription": "",
"acls": [
{ "acltype": "publishClientSend", "topic": topic, "priority": 0, "allow": True },
{ "acltype": "publishClientReceive", "topic": topic, "priority": 0, "allow": True },
{ "acltype": "subscribeLiteral", "topic": topic, "priority": 0, "allow": True },
{ "acltype": "subscribePattern", "topic": topic, "priority": 0, "allow": True },
{ "acltype": "unsubscribeLiteral", "topic": topic, "priority": 0, "allow": True },
{ "acltype": "unsubscribePattern", "topic": topic, "priority": 0, "allow": True }
]
},
{
"command": "createClient",
"username": username,
"password": password,
"clientid": client_id,
"textname": f'{username} subscriber',
"textdescription": f'{username} subscriber',
"groups": [
],
"roles": [
{ "rolename": f'{username}_role', "priority": 0 }
]
},
{
"command": "createClient",
"username": f'{username}_ase',
"password": f'{password}{config["MQTT_PWDX"]}',
"clientid": f'{client_id}_ase',
"textname": f'{username} ASE subscriber',
"textdescription": f'{username} ASE subscriber',
"groups": [
],
"roles": [
{ "rolename": f'{username}_ase_role', "priority": 0 }
]
}
]
}
@@ -68,6 +157,7 @@ def create_user(request):
key = derive_key(config['MASTER_PASSWORD'])
encrypted_password = encrypt_password(password, key)
encrypted_password_ase = encrypt_password(f'{password}_ase', key)
PasswordEntry.objects.create(
site=site,
@@ -78,6 +168,15 @@ def create_user(request):
status='enabled'
)
PasswordEntry.objects.create(
site=f'{site}_ase',
username=f'{username}_ase',
password=encrypted_password_ase,
client_id=f'{client_id}_ase',
topic=topic,
status='enabled'
)
messages.success(request, 'Utente creato con successo!') # Messaggio di successo
return redirect('list_users') # Reindirizza alla lista degli utenti
else:
@@ -96,9 +195,39 @@ def edit_user(request, slug):
user = PasswordEntry.objects.filter(slug=slug).first()
return render(request, 'wallet_api/edit_user.html', {'user': user})
else:
messages.success(request, 'Non hai i permessi per creare utenti MQTT!') # Messaggio di successo
messages.success(request, 'Non hai i permessi per cancellare utenti MQTT!') # Messaggio di successo
return redirect('list_users') # Reindirizza alla lista degli utenti
@login_required
def delete_user(request, slug):
if request.user.groups.filter(name='ase_admin').exists():
user = PasswordEntry.objects.filter(slug=slug).first()
command = {
"commands":
[
{
"command": "deleteClient",
"username": user.username
},
{
"command": "deleteRole",
"rolename": f'{user.username}_role'
}
]
}
# Invia il comando a Mosquitto
mqtt_service = MosquittoDynamicSecurity()
response = mqtt_service.send_command(command)
if "error" not in response["responses"][0]:
result = PasswordEntry.objects.filter(id=user.id).delete()
print(result)
messages.success(request, f'Utente {user.username} eliminato!') # Messaggio di successo
return redirect('list_users') # Reindirizza alla lista degli utenti
else:
messages.success(request, 'Non hai i permessi per cancellare utenti MQTT!') # Messaggio di successo
return redirect('list_users') # Reindirizza alla lista degli utenti
@login_required
def disable_user(request, slug):
if request.user.groups.filter(name='ase_admin').exists():
@@ -164,43 +293,9 @@ def enable_user(request, slug):
messages.success(request, 'Non hai i permessi per disabilitare utenti MQTT!') # Messaggio di successo
return redirect('list_users') # Reindirizza alla lista degli utenti
@login_required
def view_role(request, role):
return render(request, 'wallet_api/role_info.html', {'role': role })
@csrf_exempt
def get_password_api(request):
if request.method == 'POST':
data = json.loads(request.body)
master_password = data.get('master_password')
site = data.get('site')
if not authenticate(master_password):
return JsonResponse({"error": "Master password errata"}, status=403)
key = derive_key(master_password)
try:
entry = PasswordEntry.objects.get(site=site)
decrypted_password = decrypt_password(entry.password, key)
return JsonResponse({
"site": entry.site,
"username": entry.username,
"password": decrypted_password,
"client_id": entry.client_id,
"topic": entry.topic
})
except PasswordEntry.DoesNotExist:
return JsonResponse({"error": "Sito non trovato"}, status=404)
return JsonResponse({"error": "Richiesta non valida"}, status=400)
@csrf_exempt
def list_sites_api(request):
if request.method == 'POST':
data = json.loads(request.body)
master_password = data.get('master_password')
if not authenticate(master_password):
return JsonResponse({"error": "Master password errata"}, status=403)
sites = PasswordEntry.objects.values_list('site', flat=True)
return JsonResponse({"sites": list(sites)})
return JsonResponse({"error": "Richiesta non valida"}, status=400)