passaggio su postgres del wallet

This commit is contained in:
2024-12-23 19:34:44 +01:00
parent 313fc81dc7
commit 42b4f85699
7 changed files with 86 additions and 19 deletions

8
data/.env Normal file
View File

@@ -0,0 +1,8 @@
WALLET_MASTER_PASSWORD=Ase#2024@wallet!
DB_NAME=postgres
DB_SCHEMA=mqtt_sec
DB_TABLE=passwords
DB_USER=postgres
DB_PASSWORD=BatManu#171017@mqtt!
DB_HOST=localhost
DB_PORT=5432

View File

@@ -1,6 +1,6 @@
from flask import Flask, request, jsonify from flask import Flask, request, jsonify
import os import os
import sqlite3 import psycopg2
import bcrypt import bcrypt
import base64 import base64
import hashlib import hashlib
@@ -9,20 +9,40 @@ from cryptography.fernet import Fernet
from waitress import serve from waitress import serve
# Configurazione # Configurazione
db_file = "data/passwords.db"
hash_file = "data/master_hash.txt" hash_file = "data/master_hash.txt"
# Configurazione connessione PostgreSQL
DB_CONFIG = {
"dbname": os.getenv("DB_NAME"),
"dbschema": os.getenv("DB_SCHEMA"),
"dbtable": os.getenv("DB_TABLE"),
"user": os.getenv("DB_USER"),
"password": os.getenv("DB_PASSWORD"),
"host": os.getenv("DB_HOST"),
"port": os.getenv("DB_PORT")
}
app = Flask(__name__) app = Flask(__name__)
# Configura il logging # Configura il logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - PID: %(process)d %(levelname)s - %(message)s') logging.basicConfig(level=logging.INFO, format='%(asctime)s - PID: %(process)d %(levelname)s - %(message)s')
def get_db_connection():
return psycopg2.connect(
dbname=DB_CONFIG["dbname"],
user=DB_CONFIG["user"],
password=DB_CONFIG["password"],
host=DB_CONFIG["host"],
port=DB_CONFIG["port"]
)
# Inizializza il database # Inizializza il database
def init_db(): def init_db():
conn = sqlite3.connect(db_file) conn = get_db_connection()
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute(""" cursor.execute(f"""
CREATE TABLE IF NOT EXISTS passwords ( CREATE TABLE IF NOT EXISTS {DB_CONFIG['dbschema']}.{DB_CONFIG['dbtable']} (
id INTEGER PRIMARY KEY AUTOINCREMENT, id SERIAL PRIMARY KEY,
site TEXT NOT NULL, site TEXT NOT NULL,
username TEXT NOT NULL, username TEXT NOT NULL,
password TEXT NOT NULL password TEXT NOT NULL
@@ -69,25 +89,26 @@ def authenticate(master_password):
# Aggiungi una password al database # Aggiungi una password al database
def add_password(site, username, password, cipher): def add_password(site, username, password, cipher):
conn = sqlite3.connect(db_file) conn = get_db_connection()
cursor = conn.cursor() cursor = conn.cursor()
encrypted_password = cipher.encrypt(password.encode()).decode() encrypted_password = cipher.encrypt(password.encode()).decode()
try: try:
cursor.execute("INSERT INTO passwords (site, username, password) VALUES (?, ?, ?)", cursor.execute(
(site, username, encrypted_password)) f"INSERT INTO {DB_CONFIG['dbschema']}.{DB_CONFIG['dbtable']} (site, username, password) VALUES (%s, %s, %s)",
(site, username, encrypted_password))
conn.commit() conn.commit()
logging.info(f"Password aggiunta per il sito: {site}.") logging.info(f"Password aggiunta per il sito: {site}.")
except sqlite3.Error as e: except psycopg2.Error as e:
logging.error(f"Errore durante l'aggiunta della password: {e}") logging.error(f"Errore durante l'aggiunta della password: {e}")
finally: finally:
conn.close() conn.close()
# Recupera una password dal database # Recupera una password dal database
def get_password(site, cipher): def get_password(site, cipher):
conn = sqlite3.connect(db_file) conn = get_db_connection()
cursor = conn.cursor() cursor = conn.cursor()
try: try:
cursor.execute("SELECT username, password FROM passwords WHERE site = ?", (site,)) cursor.execute(f"SELECT username, password FROM {DB_CONFIG['dbschema']}.{DB_CONFIG['dbtable']} WHERE site = %s", (site,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
username, encrypted_password = row username, encrypted_password = row
@@ -96,7 +117,7 @@ def get_password(site, cipher):
return username, decrypted_password return username, decrypted_password
logging.warning(f"Sito non trovato: {site}.") logging.warning(f"Sito non trovato: {site}.")
return None, None return None, None
except sqlite3.Error as e: except psycopg2.Error as e:
logging.error(f"Errore durante il recupero della password: {e}") logging.error(f"Errore durante il recupero della password: {e}")
return None, None return None, None
finally: finally:
@@ -104,30 +125,30 @@ def get_password(site, cipher):
# Cancella una password dal database # Cancella una password dal database
def delete_password(site): def delete_password(site):
conn = sqlite3.connect(db_file) conn = get_db_connection()
cursor = conn.cursor() cursor = conn.cursor()
try: try:
cursor.execute("DELETE FROM passwords WHERE site = ?", (site,)) cursor.execute(f"DELETE FROM {DB_CONFIG['dbschema']}.{DB_CONFIG['dbtable']} WHERE site = %s", (site,))
if cursor.rowcount > 0: if cursor.rowcount > 0:
logging.info(f"Password cancellata per il sito: {site}.") logging.info(f"Password cancellata per il sito: {site}.")
else: else:
logging.warning(f"Nessuna password trovata per il sito: {site}.") logging.warning(f"Nessuna password trovata per il sito: {site}.")
conn.commit() conn.commit()
except sqlite3.Error as e: except psycopg2.Error as e:
logging.error(f"Errore durante la cancellazione della password: {e}") logging.error(f"Errore durante la cancellazione della password: {e}")
finally: finally:
conn.close() conn.close()
# Ottieni la lista di tutti i siti # Ottieni la lista di tutti i siti
def list_sites(): def list_sites():
conn = sqlite3.connect(db_file) conn = get_db_connection()
cursor = conn.cursor() cursor = conn.cursor()
try: try:
cursor.execute("SELECT site FROM passwords") cursor.execute(f"SELECT site FROM {DB_CONFIG['dbschema']}.{DB_CONFIG['dbtable']}")
sites = [row[0] for row in cursor.fetchall()] sites = [row[0] for row in cursor.fetchall()]
logging.info("Elenco dei siti recuperato.") logging.info("Elenco dei siti recuperato.")
return sites return sites
except sqlite3.Error as e: except psycopg2.Error as e:
logging.error(f"Errore durante il recupero dell'elenco dei siti: {e}") logging.error(f"Errore durante il recupero dell'elenco dei siti: {e}")
return [] return []
finally: finally:

View File

@@ -9,6 +9,7 @@ dependencies = [
"cryptography>=44.0.0", "cryptography>=44.0.0",
"flask>=3.1.0", "flask>=3.1.0",
"paho-mqtt>=2.1.0", "paho-mqtt>=2.1.0",
"psycopg2-binary>=2.9.10",
"requests>=2.32.3", "requests>=2.32.3",
"waitress>=3.0.2", "waitress>=3.0.2",
] ]

View File

@@ -0,0 +1,2 @@
if $programname == 'control_mqtt' then /var/log/mqtt_ase/subscriber_manager.log
& stop

View File

@@ -0,0 +1,2 @@
if $programname == 'password_wallet' then /var/log/mqtt_ase/password_wallet.log
& stop

View File

@@ -6,6 +6,7 @@ After=network.target
User=mosquitto User=mosquitto
WorkingDirectory=/var/lib/mosquitto WorkingDirectory=/var/lib/mosquitto
ExecStart=/var/lib/mosquitto/.venv/bin/python3 /var/lib/mosquitto/password_wallet_api.py ExecStart=/var/lib/mosquitto/.venv/bin/python3 /var/lib/mosquitto/password_wallet_api.py
EnvironmentFile=/var/lib/mosquitto/data/.env
Restart=always Restart=always
SyslogIdentifier=password_wallet SyslogIdentifier=password_wallet

32
uv.lock generated
View File

@@ -10,6 +10,7 @@ dependencies = [
{ name = "cryptography" }, { name = "cryptography" },
{ name = "flask" }, { name = "flask" },
{ name = "paho-mqtt" }, { name = "paho-mqtt" },
{ name = "psycopg2-binary" },
{ name = "requests" }, { name = "requests" },
{ name = "waitress" }, { name = "waitress" },
] ]
@@ -20,6 +21,7 @@ requires-dist = [
{ name = "cryptography", specifier = ">=44.0.0" }, { name = "cryptography", specifier = ">=44.0.0" },
{ name = "flask", specifier = ">=3.1.0" }, { name = "flask", specifier = ">=3.1.0" },
{ name = "paho-mqtt", specifier = ">=2.1.0" }, { name = "paho-mqtt", specifier = ">=2.1.0" },
{ name = "psycopg2-binary", specifier = ">=2.9.10" },
{ name = "requests", specifier = ">=2.32.3" }, { name = "requests", specifier = ">=2.32.3" },
{ name = "waitress", specifier = ">=3.0.2" }, { name = "waitress", specifier = ">=3.0.2" },
] ]
@@ -289,6 +291,36 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/c4/cb/00451c3cf31790287768bb12c6bec834f5d292eaf3022afc88e14b8afc94/paho_mqtt-2.1.0-py3-none-any.whl", hash = "sha256:6db9ba9b34ed5bc6b6e3812718c7e06e2fd7444540df2455d2c51bd58808feee", size = 67219 }, { url = "https://files.pythonhosted.org/packages/c4/cb/00451c3cf31790287768bb12c6bec834f5d292eaf3022afc88e14b8afc94/paho_mqtt-2.1.0-py3-none-any.whl", hash = "sha256:6db9ba9b34ed5bc6b6e3812718c7e06e2fd7444540df2455d2c51bd58808feee", size = 67219 },
] ]
[[package]]
name = "psycopg2-binary"
version = "2.9.10"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/cb/0e/bdc8274dc0585090b4e3432267d7be4dfbfd8971c0fa59167c711105a6bf/psycopg2-binary-2.9.10.tar.gz", hash = "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2", size = 385764 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/49/7d/465cc9795cf76f6d329efdafca74693714556ea3891813701ac1fee87545/psycopg2_binary-2.9.10-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0", size = 3044771 },
{ url = "https://files.pythonhosted.org/packages/8b/31/6d225b7b641a1a2148e3ed65e1aa74fc86ba3fee850545e27be9e1de893d/psycopg2_binary-2.9.10-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a", size = 3275336 },
{ url = "https://files.pythonhosted.org/packages/30/b7/a68c2b4bff1cbb1728e3ec864b2d92327c77ad52edcd27922535a8366f68/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539", size = 2851637 },
{ url = "https://files.pythonhosted.org/packages/0b/b1/cfedc0e0e6f9ad61f8657fd173b2f831ce261c02a08c0b09c652b127d813/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526", size = 3082097 },
{ url = "https://files.pythonhosted.org/packages/18/ed/0a8e4153c9b769f59c02fb5e7914f20f0b2483a19dae7bf2db54b743d0d0/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1", size = 3264776 },
{ url = "https://files.pythonhosted.org/packages/10/db/d09da68c6a0cdab41566b74e0a6068a425f077169bed0946559b7348ebe9/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e", size = 3020968 },
{ url = "https://files.pythonhosted.org/packages/94/28/4d6f8c255f0dfffb410db2b3f9ac5218d959a66c715c34cac31081e19b95/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f", size = 2872334 },
{ url = "https://files.pythonhosted.org/packages/05/f7/20d7bf796593c4fea95e12119d6cc384ff1f6141a24fbb7df5a668d29d29/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00", size = 2822722 },
{ url = "https://files.pythonhosted.org/packages/4d/e4/0c407ae919ef626dbdb32835a03b6737013c3cc7240169843965cada2bdf/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5", size = 2920132 },
{ url = "https://files.pythonhosted.org/packages/2d/70/aa69c9f69cf09a01da224909ff6ce8b68faeef476f00f7ec377e8f03be70/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47", size = 2959312 },
{ url = "https://files.pythonhosted.org/packages/d3/bd/213e59854fafe87ba47814bf413ace0dcee33a89c8c8c814faca6bc7cf3c/psycopg2_binary-2.9.10-cp312-cp312-win32.whl", hash = "sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64", size = 1025191 },
{ url = "https://files.pythonhosted.org/packages/92/29/06261ea000e2dc1e22907dbbc483a1093665509ea586b29b8986a0e56733/psycopg2_binary-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0", size = 1164031 },
{ url = "https://files.pythonhosted.org/packages/3e/30/d41d3ba765609c0763505d565c4d12d8f3c79793f0d0f044ff5a28bf395b/psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d", size = 3044699 },
{ url = "https://files.pythonhosted.org/packages/35/44/257ddadec7ef04536ba71af6bc6a75ec05c5343004a7ec93006bee66c0bc/psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb", size = 3275245 },
{ url = "https://files.pythonhosted.org/packages/1b/11/48ea1cd11de67f9efd7262085588790a95d9dfcd9b8a687d46caf7305c1a/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7", size = 2851631 },
{ url = "https://files.pythonhosted.org/packages/62/e0/62ce5ee650e6c86719d621a761fe4bc846ab9eff8c1f12b1ed5741bf1c9b/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d", size = 3082140 },
{ url = "https://files.pythonhosted.org/packages/27/ce/63f946c098611f7be234c0dd7cb1ad68b0b5744d34f68062bb3c5aa510c8/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73", size = 3264762 },
{ url = "https://files.pythonhosted.org/packages/43/25/c603cd81402e69edf7daa59b1602bd41eb9859e2824b8c0855d748366ac9/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673", size = 3020967 },
{ url = "https://files.pythonhosted.org/packages/5f/d6/8708d8c6fca531057fa170cdde8df870e8b6a9b136e82b361c65e42b841e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f", size = 2872326 },
{ url = "https://files.pythonhosted.org/packages/ce/ac/5b1ea50fc08a9df82de7e1771537557f07c2632231bbab652c7e22597908/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909", size = 2822712 },
{ url = "https://files.pythonhosted.org/packages/c4/fc/504d4503b2abc4570fac3ca56eb8fed5e437bf9c9ef13f36b6621db8ef00/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1", size = 2920155 },
{ url = "https://files.pythonhosted.org/packages/b2/d1/323581e9273ad2c0dbd1902f3fb50c441da86e894b6e25a73c3fda32c57e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567", size = 2959356 },
]
[[package]] [[package]]
name = "pycparser" name = "pycparser"
version = "2.22" version = "2.22"