set master pwd al primo lancio - ruoli
This commit is contained in:
7
.env
7
.env
@@ -1,9 +1,11 @@
|
||||
MASTER_PASSWORD=pipperepettenuse
|
||||
|
||||
DB_NAME=wallet
|
||||
DB_USER=postgres
|
||||
DB_PASSWORD=BatManu#171017
|
||||
DB_HOST=10.211.114.101
|
||||
DB_PORT=5432
|
||||
MASTER_PASSWORD=pipperepettenuse
|
||||
|
||||
MQTT_HOST=10.211.114.214
|
||||
MQTT_PORT=1883
|
||||
MQTT_KEEPALIVE=60
|
||||
@@ -11,3 +13,6 @@ MQTT_USER=alex
|
||||
MQTT_PASSWORD=batt1l0
|
||||
MQTT_DS_TOPIC="$CONTROL/dynamic-security/v1"
|
||||
MQTT_DS_RESP_TOPIC="$CONTROL/dynamic-security/v1/response"
|
||||
|
||||
GMAIL_USER=alessandro.battilani@gmail.com
|
||||
GMAIL_PASSWORD=batmanu#171017
|
||||
BIN
avatars/ape1.jpg
Normal file
BIN
avatars/ape1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
BIN
avatars/ape2_hSVw8me.jpg
Normal file
BIN
avatars/ape2_hSVw8me.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 112 KiB |
@@ -7,7 +7,7 @@
|
||||
{% block content %}
|
||||
<h1 class="mb-4">{% trans "Sign In" %}</h1>
|
||||
<p class="mb-4">
|
||||
If you have not created an account yet, then please
|
||||
{% trans "If you have not created an account yet, then please" %}
|
||||
<a
|
||||
href="{% url 'account_signup' %}?next={% url 'profile-onboarding' %}"
|
||||
class="text-decoration-none"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load static %}
|
||||
{% load django_htmx %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@@ -23,10 +23,11 @@
|
||||
</style>
|
||||
</head>
|
||||
<body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
|
||||
{% include 'includes/messages.html' %}
|
||||
|
||||
{% include 'includes/header.html' %}
|
||||
|
||||
{% include 'includes/messages.html' %}
|
||||
|
||||
{% block layout %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{% load static %}
|
||||
<header class="d-flex align-items-center justify-content-between bg-dark text-white py-3 px-4 sticky-top z-40">
|
||||
<header class="d-flex align-items-center justify-content-between bg-secondary text-white py-1 px-4 sticky-top z-40">
|
||||
<div>
|
||||
<a class="d-flex align-items-center gap-2 text-decoration-none text-white" href="/">
|
||||
<img class="h-6" src="{% static 'images/ase-logo.png' %}" alt="ASE" height="40"/>
|
||||
<img class="h-6" src="{% static 'images/ase-logo.png' %}" alt="ASE" height="30"/>
|
||||
<span class="text-lg fw-bold">MQTT User Management</span>
|
||||
</a>
|
||||
</div>
|
||||
@@ -14,13 +14,17 @@
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle d-flex align-items-center gap-2 text-white" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<img class="h-8 w-8 rounded-circle object-cover" src="{{ request.user.profile.avatar }}" alt="Avatar" height="40"/>
|
||||
<img class="h-8 w-8 rounded-circle object-cover" src="{{ request.user.profile.avatar }}" alt="Avatar" height="30"/>
|
||||
{{ request.user.profile.name }}
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end shadow-lg" style="min-width: 200px;">
|
||||
<li><a class="dropdown-item" href="{% url 'profile' %}">My Profile</a></li>
|
||||
<li><a class="dropdown-item" href="{% url 'profile-edit' %}">Edit Profile</a></li>
|
||||
<li><a class="dropdown-item" href="{% url 'profile-settings' %}">Settings</a></li>
|
||||
{% if request.user.is_superuser %}
|
||||
<li><hr class="dropdown-divider" /></li>
|
||||
<li><a class="dropdown-item" href="{% url 'admin:index' %}">Site Admin</a></li>
|
||||
{% endif %}
|
||||
<li><hr class="dropdown-divider" /></li>
|
||||
<li><a class="dropdown-item" href="{% url 'account_logout' %}">Log Out</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div>
|
||||
{% for message in messages %}
|
||||
<div
|
||||
class="position-fixed top-0 start-50 translate-middle-x mt-3 z-50"
|
||||
class="position-fixed top-10 start-50 translate-middle-x mt-3 z-30"
|
||||
style="width: 100%; max-width: 576px"
|
||||
>
|
||||
<div
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends 'base.html' %} {% block layout %}
|
||||
<div class="container">
|
||||
<div class="container" style="margin-top: 20px;">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-md-8 col-lg-6">
|
||||
<div class="bg-white rounded-3 p-4 p-md-5 shadow-lg">
|
||||
|
||||
@@ -1,18 +1,5 @@
|
||||
{% extends 'layouts/blank.html' %} {% block content %}
|
||||
|
||||
<!-- Mostra i messaggi di errore o successo -->
|
||||
{% if messages %}
|
||||
<div>
|
||||
{% for message in messages %}
|
||||
<div class="alert {% if message.tags %}alert-{{ message.tags }}{% endif %}">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Form per la creazione dell'utente -->
|
||||
|
||||
<h1>Add User</h1>
|
||||
<form method="post" hx-post="/create_user" hx-target="#content">
|
||||
{% csrf_token %}
|
||||
|
||||
@@ -1,16 +1,5 @@
|
||||
{% extends 'layouts/blank.html' %} {% block content %}
|
||||
|
||||
<!-- Mostra i messaggi di errore o successo -->
|
||||
{% if messages %}
|
||||
<div>
|
||||
{% for message in messages %}
|
||||
<div class="alert {% if message.tags %}alert-{{ message.tags }}{% endif %}">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h1>Add User</h1>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
|
||||
@@ -1,20 +1,12 @@
|
||||
{% extends 'layouts/blank.html' %} {% block content %}
|
||||
|
||||
<!-- Mostra i messaggi di errore o successo -->
|
||||
{% if messages %}
|
||||
<div>
|
||||
{% for message in messages %}
|
||||
<div class="alert {% if message.tags %}alert-{{ message.tags }}{% endif %}">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h1>List Mosquitto Users</h1>
|
||||
<a href="{% url 'create_user' %}">
|
||||
<button class="btn btn-primary mb-3">Add User</button>
|
||||
</a>
|
||||
{% if ase_adm_group %}
|
||||
<a href="{% url 'create_user' %}">
|
||||
<button class="btn btn-primary mb-3">Add User</button>
|
||||
|
||||
</a>
|
||||
{% endif %}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -29,20 +21,35 @@
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td>{{user.site}}</td>
|
||||
<td>
|
||||
<a href="{% url 'edit_user' user.slug %}">{{user.username}}</a
|
||||
>
|
||||
<td>{% if ase_adm_group %}
|
||||
<a href="{% url 'edit_user' user.slug %}">
|
||||
{% endif %}
|
||||
{{user.username}}</a>
|
||||
</td>
|
||||
<td>{{user.client_id}}</td>
|
||||
<td>{{user.topic}}</td>
|
||||
<td id="user-status">
|
||||
{% if user.status == "enabled" %}
|
||||
<a href="{% url 'disable_user' user.slug %}">
|
||||
<button class="btn btn-danger btn-sm">Disable</button>
|
||||
<a
|
||||
{% if ase_adm_group %}
|
||||
href="{% url 'disable_user' user.slug %}"
|
||||
{% endif %}>
|
||||
<button class="btn btn-danger btn-sm"
|
||||
{% if not ase_adm_group %}
|
||||
disabled
|
||||
{% endif %}
|
||||
>Disable</button>
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{% url 'enable_user' user.slug %}">
|
||||
<button class="btn btn-warning btn-sm">Enable</button>
|
||||
<a
|
||||
{% if ase_adm_group %}
|
||||
href="{% url 'enable_user' user.slug %}"
|
||||
{% endif %}>
|
||||
<button class="btn btn-warning btn-sm"
|
||||
{% if not ase_adm_group %}
|
||||
disabled
|
||||
{% endif %}
|
||||
>Enable</button>
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
@@ -157,3 +157,13 @@ ACCOUNT_SIGNUP_REDIRECT_URL = "{% url 'account_signup' %}?next={% url 'profile-o
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
ACCOUNT_AUTHENTICATION_METHOD = 'email'
|
||||
ACCOUNT_EMAIL_REQUIRED = True
|
||||
|
||||
'''
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
EMAIL_HOST = 'smtp.gmail.com'
|
||||
EMAIL_PORT = 587
|
||||
EMAIL_USE_TLS = True
|
||||
EMAIL_HOST_USER = 'tuo_indirizzo@gmail.com'
|
||||
EMAIL_HOST_PASSWORD = 'tua_password_gmail'
|
||||
DEFAULT_FROM_EMAIL = 'tuo_indirizzo@gmail.com'
|
||||
'''
|
||||
@@ -1,6 +1,8 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class WalletApiConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'wallet_api'
|
||||
|
||||
def ready(self):
|
||||
import wallet_api.signals
|
||||
|
||||
10
wallet_api/signals.py
Normal file
10
wallet_api/signals.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from django.db.models.signals import post_migrate
|
||||
from django.dispatch import receiver
|
||||
from dotenv import dotenv_values
|
||||
from .utils import authenticate
|
||||
|
||||
@receiver(post_migrate)
|
||||
def init_master_passwored(sender, **kwargs):
|
||||
if sender.name == 'wallet_api':
|
||||
config = dotenv_values(".env")
|
||||
authenticate(config['MASTER_PASSWORD'])
|
||||
@@ -3,7 +3,6 @@ from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.home_view, name="home"),
|
||||
path('add/', views.add_password_api, name='add_user'),
|
||||
path('get/', views.get_password_api, name='get_password'),
|
||||
path('list/', views.list_sites_api, name='list_sites'),
|
||||
path('publish', views.publish_message, name='publish'),
|
||||
|
||||
@@ -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
|
||||
|
||||
import json
|
||||
import paho.mqtt.client as mqtt
|
||||
@@ -16,10 +16,11 @@ from .mqtt_service import MosquittoDynamicSecurity
|
||||
|
||||
|
||||
config = dotenv_values(".env")
|
||||
authenticate(config['MASTER_PASSWORD'])
|
||||
# authenticate(config['MASTER_PASSWORD'])
|
||||
|
||||
def home_view(request):
|
||||
return render(request, 'home.html')
|
||||
return redirect('list_users') # Reindirizza alla lista degli utenti
|
||||
#return render(request, 'home.html')
|
||||
|
||||
@csrf_exempt
|
||||
def publish_message(request):
|
||||
@@ -33,26 +34,82 @@ def publish_message(request):
|
||||
protocol=mqtt.MQTTv5)
|
||||
return JsonResponse({'request_data': request_data})
|
||||
|
||||
@login_required
|
||||
def list_users(request):
|
||||
users = PasswordEntry.objects.all()
|
||||
return render(request, 'wallet_api/list_users.html', {'users': users})
|
||||
return render(request, 'wallet_api/list_users.html', {'users': users, 'ase_adm_group': request.user.groups.filter(name='ase_admin').exists()})
|
||||
|
||||
@login_required
|
||||
def create_user(request):
|
||||
if request.method == 'POST':
|
||||
site = request.POST.get('site')
|
||||
username = request.POST.get('username')
|
||||
client_id = request.POST.get('clientId')
|
||||
topic = request.POST.get('topic')
|
||||
password = request.POST.get('password')
|
||||
if request.user.groups.filter(name='ase_admin').exists():
|
||||
if request.method == 'POST':
|
||||
site = request.POST.get('site')
|
||||
username = request.POST.get('username')
|
||||
client_id = request.POST.get('clientId')
|
||||
topic = request.POST.get('topic')
|
||||
password = request.POST.get('password')
|
||||
|
||||
# Comando per creare un utente
|
||||
command = {
|
||||
"commands":
|
||||
[
|
||||
{
|
||||
"command": "createClient",
|
||||
"username": username,
|
||||
"password": password
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# Invia il comando a Mosquitto
|
||||
mqtt_service = MosquittoDynamicSecurity()
|
||||
response = mqtt_service.send_command(command)
|
||||
if "error" not in response["responses"][0]:
|
||||
|
||||
key = derive_key(config['MASTER_PASSWORD'])
|
||||
encrypted_password = encrypt_password(password, key)
|
||||
|
||||
PasswordEntry.objects.create(
|
||||
site=site,
|
||||
username=username,
|
||||
password=encrypted_password,
|
||||
client_id=client_id,
|
||||
topic=topic,
|
||||
status='enabled'
|
||||
)
|
||||
|
||||
messages.success(request, 'Utente creato con successo!') # Messaggio di successo
|
||||
return redirect('list_users') # Reindirizza alla lista degli utenti
|
||||
else:
|
||||
messages.warning(request, f'Errore durante la creazione dell\'utente: {response["responses"][0]["error"]}') # Messaggio di errore
|
||||
return render(request, 'wallet_api/create_user.html', {'response': response}) # Rimani sulla stessa vista
|
||||
|
||||
# Se la richiesta non è POST, mostra il form di creazione utente
|
||||
return render(request, 'wallet_api/create_user.html')
|
||||
else:
|
||||
messages.success(request, 'Non hai i permessi per creare utenti MQTT!') # Messaggio di successo
|
||||
return redirect('list_users') # Reindirizza alla lista degli utenti
|
||||
|
||||
@login_required
|
||||
def edit_user(request, slug):
|
||||
if request.user.groups.filter(name='ase_admin').exists():
|
||||
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
|
||||
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():
|
||||
user = PasswordEntry.objects.filter(slug=slug).values('id','username')
|
||||
# Comando per creare un utente
|
||||
command = {
|
||||
"commands":
|
||||
[
|
||||
{
|
||||
"command": "createClient",
|
||||
"username": username,
|
||||
"password": password
|
||||
"command": "disableClient",
|
||||
"username": user.first()["username"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -62,90 +119,49 @@ def create_user(request):
|
||||
response = mqtt_service.send_command(command)
|
||||
if "error" not in response["responses"][0]:
|
||||
|
||||
key = derive_key(config['MASTER_PASSWORD'])
|
||||
encrypted_password = encrypt_password(password, key)
|
||||
PasswordEntry.objects.filter(id=int(user.first()["id"])).update(status='disabled')
|
||||
|
||||
PasswordEntry.objects.create(
|
||||
site=site,
|
||||
username=username,
|
||||
password=encrypted_password,
|
||||
client_id=client_id,
|
||||
topic=topic,
|
||||
status='enabled'
|
||||
)
|
||||
|
||||
messages.success(request, 'Utente creato con successo!') # Messaggio di successo
|
||||
messages.success(request, 'Utente disabilitato con successo!') # Messaggio di successo
|
||||
if request.htmx:
|
||||
return render(request, 'partials/enable_user.html')
|
||||
return redirect('list_users') # Reindirizza alla lista degli utenti
|
||||
else:
|
||||
messages.warning(request, f'Errore durante la creazione dell\'utente: {response["responses"][0]["error"]}') # Messaggio di errore
|
||||
return render(request, 'wallet_api/create_user.html', {'response': response}) # Rimani sulla stessa vista
|
||||
|
||||
# Se la richiesta non è POST, mostra il form di creazione utente
|
||||
return render(request, 'wallet_api/create_user.html')
|
||||
|
||||
def edit_user(request, slug):
|
||||
user = PasswordEntry.objects.filter(slug=slug).first()
|
||||
return render(request, 'wallet_api/edit_user.html', {'user': user})
|
||||
|
||||
def disable_user(request, slug):
|
||||
user = PasswordEntry.objects.filter(slug=slug).values('id','username')
|
||||
print(user.first())
|
||||
# Comando per creare un utente
|
||||
command = {
|
||||
"commands":
|
||||
[
|
||||
{
|
||||
"command": "disableClient",
|
||||
"username": user.first()["username"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# Invia il comando a Mosquitto
|
||||
mqtt_service = MosquittoDynamicSecurity()
|
||||
response = mqtt_service.send_command(command)
|
||||
if "error" not in response["responses"][0]:
|
||||
|
||||
PasswordEntry.objects.update(
|
||||
status='disabled'
|
||||
)
|
||||
|
||||
messages.success(request, 'Utente disabilitato con successo!') # Messaggio di successo
|
||||
if request.htmx:
|
||||
return render(request, 'partials/enable_user.html')
|
||||
return redirect('list_users') # Reindirizza alla lista degli utenti
|
||||
messages.warning(request, f'Errore durante la disabilitazione dell\'utente: {response["responses"][0]["error"]}') # Messaggio di errore
|
||||
return redirect('list_users') # Reindirizza alla lista degli utenti
|
||||
else:
|
||||
messages.warning(request, f'Errore durante la disabilitazione dell\'utente: {response["responses"][0]["error"]}') # Messaggio di errore
|
||||
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 enable_user(request, slug):
|
||||
user = PasswordEntry.objects.filter(slug=slug).values('id','username')
|
||||
print(user.first())
|
||||
# Comando per creare un utente
|
||||
command = {
|
||||
"commands":
|
||||
[
|
||||
{
|
||||
"command": "enableClient",
|
||||
"username": user.first()["username"]
|
||||
}
|
||||
]
|
||||
}
|
||||
if request.user.groups.filter(name='ase_admin').exists():
|
||||
user = PasswordEntry.objects.filter(slug=slug).values('id','username')
|
||||
# Comando per creare un utente
|
||||
command = {
|
||||
"commands":
|
||||
[
|
||||
{
|
||||
"command": "enableClient",
|
||||
"username": user.first()["username"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# Invia il comando a Mosquitto
|
||||
mqtt_service = MosquittoDynamicSecurity()
|
||||
response = mqtt_service.send_command(command)
|
||||
if "error" not in response["responses"][0]:
|
||||
# Invia il comando a Mosquitto
|
||||
mqtt_service = MosquittoDynamicSecurity()
|
||||
response = mqtt_service.send_command(command)
|
||||
if "error" not in response["responses"][0]:
|
||||
|
||||
PasswordEntry.objects.update(
|
||||
status='enabled'
|
||||
)
|
||||
PasswordEntry.objects.filter(id=int(user.first()["id"])).update(status='enabled')
|
||||
|
||||
messages.success(request, 'Utente abilitato con successo!') # Messaggio di successo
|
||||
messages.success(request, 'Utente abilitato con successo!') # Messaggio di successo
|
||||
|
||||
return redirect('list_users') # Reindirizza alla lista degli utenti
|
||||
return redirect('list_users') # Reindirizza alla lista degli utenti
|
||||
else:
|
||||
messages.warning(request, f'Errore durante la abilitazione dell\'utente: {response["responses"][0]["error"]}') # Messaggio di errore
|
||||
return redirect('list_users') # Reindirizza alla lista degli utenti
|
||||
else:
|
||||
messages.warning(request, f'Errore durante la abilitazione dell\'utente: {response["responses"][0]["error"]}') # Messaggio di errore
|
||||
messages.success(request, 'Non hai i permessi per disabilitare utenti MQTT!') # Messaggio di successo
|
||||
return redirect('list_users') # Reindirizza alla lista degli utenti
|
||||
|
||||
def view_role(request, role):
|
||||
@@ -174,6 +190,7 @@ def get_password_api(request):
|
||||
})
|
||||
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):
|
||||
@@ -186,29 +203,4 @@ def list_sites_api(request):
|
||||
|
||||
sites = PasswordEntry.objects.values_list('site', flat=True)
|
||||
return JsonResponse({"sites": list(sites)})
|
||||
|
||||
@csrf_exempt
|
||||
def add_password_api(request):
|
||||
if request.method == 'POST':
|
||||
data = json.loads(request.body)
|
||||
master_password = data.get('master_password')
|
||||
site = data.get('site')
|
||||
username = data.get('username')
|
||||
password = data.get('password')
|
||||
client_id = data.get('client_id')
|
||||
topic = data.get('topic')
|
||||
|
||||
if not authenticate(master_password):
|
||||
return JsonResponse({"error": "Master password errata"}, status=403)
|
||||
|
||||
key = derive_key(master_password)
|
||||
encrypted_password = encrypt_password(password, key)
|
||||
|
||||
PasswordEntry.objects.create(
|
||||
site=site,
|
||||
username=username,
|
||||
password=encrypted_password,
|
||||
client_id=client_id,
|
||||
topic=topic
|
||||
)
|
||||
return JsonResponse({"message": "Password aggiunta con successo"})
|
||||
return JsonResponse({"error": "Richiesta non valida"}, status=400)
|
||||
|
||||
Reference in New Issue
Block a user