admin priv
This commit is contained in:
parent
3300f55fec
commit
126836abf9
|
|
@ -1,4 +1,5 @@
|
|||
import logging
|
||||
import sys
|
||||
import traceback
|
||||
import types
|
||||
|
||||
|
|
@ -179,6 +180,8 @@ class Component(QObject):
|
|||
waits until the requested action has been completed by the component
|
||||
this will return immediately if threaded=False was passed at component initialization
|
||||
"""
|
||||
timeout = 60 if "--debug" in sys.argv else timeout
|
||||
|
||||
if self._threaded:
|
||||
timeout = round(timeout * 1000)
|
||||
if self._lock.tryAcquire(max(self._lock.available(), 1), timeout):
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ if "--sim-modbus" not in sys.argv:
|
|||
|
||||
else:
|
||||
from components.dummies.pymodbus import ModbusClient
|
||||
#from components.dummies.pymodbus import ModbusTcpClient
|
||||
|
||||
from PyQt5.QtCore import QMutex, pyqtSignal
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,32 @@ class Session:
|
|||
self.username = self.user.username
|
||||
self.badge_number = self.user.badge_number
|
||||
self.roles = Users.parse_roles(self.user.roles)
|
||||
self.is_admin = self.user.is_admin
|
||||
self._is_admin = self.user.is_admin # Store original admin status
|
||||
self.temp_admin = False # Flag to track temporary admin privilege
|
||||
|
||||
def enable_temp_admin(self):
|
||||
"""Enable temporary admin privileges"""
|
||||
self.temp_admin = True
|
||||
Log.log("Admin", f"Temporary admin privileges enabled for user: {self.username!r}")
|
||||
return True
|
||||
|
||||
def disable_temp_admin(self):
|
||||
"""Disable temporary admin privileges"""
|
||||
self.temp_admin = False
|
||||
Log.log("Admin", f"Temporary admin privileges disabled for user: {self.username!r}")
|
||||
return True
|
||||
|
||||
@property
|
||||
def is_admin(self):
|
||||
# Return True if user is an admin or has temporary admin privileges
|
||||
return self._is_admin or self.temp_admin
|
||||
|
||||
@property
|
||||
def current_roles(self):
|
||||
roles = set(self.roles)
|
||||
if self.temp_admin:
|
||||
roles.add("admin")
|
||||
return list(roles)
|
||||
|
||||
|
||||
def json_dumps_roles(roles):
|
||||
|
|
@ -92,9 +117,21 @@ class Users(BaseModel):
|
|||
Log.log("Login", f"username: {username!r}: BAD username")
|
||||
return False
|
||||
if user.verify(password):
|
||||
Log.log("Login", f"username: {user.username!r}: SUCCESSFUL, roles: {user.roles!r}")
|
||||
# Check if there's an existing session with temp_admin privileges
|
||||
global current_session
|
||||
had_temp_admin = current_session is not None and current_session.temp_admin
|
||||
|
||||
# Create new session
|
||||
current_session = Session(user)
|
||||
|
||||
# Preserve temp_admin status if it was set
|
||||
if had_temp_admin:
|
||||
current_session.temp_admin = True
|
||||
|
||||
# Log the actual roles including temp_admin if applicable
|
||||
roles_to_log = current_session.current_roles if had_temp_admin else user.roles
|
||||
Log.log("Login", f"username: {user.username!r}: SUCCESSFUL, roles: {roles_to_log!r}")
|
||||
|
||||
return current_session
|
||||
else:
|
||||
Log.log("Login", f"username: {user.username!r}, password {password!r}: BAD password")
|
||||
|
|
@ -116,6 +153,58 @@ class Users(BaseModel):
|
|||
global current_session
|
||||
return current_session
|
||||
|
||||
@classmethod
|
||||
@db.atomic()
|
||||
def enable_temp_admin(cls, admin_password):
|
||||
"""Enable temporary admin privileges for the current session"""
|
||||
session = cls.get_session()
|
||||
if session is None:
|
||||
Log.log("Admin", "Cannot enable temp admin: No active session")
|
||||
return False
|
||||
|
||||
# If user is already a permanent admin, no need to enable temp admin
|
||||
if "admin" in cls.parse_roles(session.user.roles):
|
||||
Log.log("Admin", f"User {session.username!r} is already a permanent admin")
|
||||
return True
|
||||
|
||||
# If user already has temporary admin privileges, nothing to do
|
||||
if session.temp_admin:
|
||||
Log.log("Admin", f"User {session.username!r} already has temporary admin privileges")
|
||||
return True
|
||||
|
||||
# Find an admin user to verify the password against
|
||||
admin_users = [user for user in cls.get_users() if "admin" in cls.parse_roles(user.roles)]
|
||||
|
||||
if not admin_users:
|
||||
Log.log("Admin", "No admin users found in the system")
|
||||
return False
|
||||
|
||||
# Try to verify the password with any admin user
|
||||
for admin_user in admin_users:
|
||||
if admin_user.verify(admin_password):
|
||||
# Use the session's enable_temp_admin method
|
||||
return session.enable_temp_admin()
|
||||
|
||||
Log.log("Admin", f"Failed to enable temp admin for user {session.username!r}: Invalid admin password")
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
@db.atomic()
|
||||
def disable_temp_admin(cls):
|
||||
"""Disable temporary admin privileges for the current session"""
|
||||
session = cls.get_session()
|
||||
if session is None:
|
||||
Log.log("Admin", "Cannot disable temp admin: No active session")
|
||||
return False
|
||||
|
||||
# If user is not a temp admin, nothing to do
|
||||
if not session.temp_admin:
|
||||
Log.log("Admin", f"User {session.username!r} does not have temporary admin privileges")
|
||||
return True
|
||||
|
||||
# Use the session's disable_temp_admin method
|
||||
return session.disable_temp_admin()
|
||||
|
||||
@db.atomic()
|
||||
def verify(self, password):
|
||||
if self.password is None:
|
||||
|
|
|
|||
210
src/main.py
210
src/main.py
|
|
@ -75,7 +75,8 @@ try:
|
|||
from lib.db import Users
|
||||
from lib.helpers import ConfigReader
|
||||
from PyQt5.QtCore import QObject, QThread, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtWidgets import QApplication, QMessageBox
|
||||
from PyQt5.QtWidgets import QApplication, QMessageBox, QInputDialog, QLineEdit
|
||||
import sip
|
||||
from ui import About, Archive, Login, Main_Window, Test, Users_Management,Logs_Management ,Recipe_Selection, \
|
||||
Barcode_Recipe_Selection
|
||||
|
||||
|
|
@ -196,8 +197,8 @@ try:
|
|||
if "--about" in sys.argv:
|
||||
self.main_window.about_a.trigger()
|
||||
|
||||
# admin menu should not be visible before an admin logs in
|
||||
self.main_window.admin_m.menuAction().setVisible(False)
|
||||
# Keep the admin menu always visible
|
||||
self.main_window.admin_m.menuAction().setVisible(True)
|
||||
|
||||
self.main_window.about_a.triggered.connect(
|
||||
lambda checked, selfie=weakref.ref(self): selfie().main_window.open_dialog(About()))
|
||||
|
|
@ -217,6 +218,8 @@ try:
|
|||
self.main_window.cut_a.setVisible(False)
|
||||
self.main_window.diagnostics_a.triggered.connect(
|
||||
lambda checked, selfie=weakref.ref(self): selfie().main_window.open_dialog(Diagnostics(selfie())))
|
||||
self.main_window.admin_enable_a.triggered.connect(
|
||||
lambda checked, selfie=weakref.ref(self): selfie().enable_admin_privileges())
|
||||
if "--users-management" in sys.argv:
|
||||
self.main_window.users_management_a.trigger()
|
||||
|
||||
|
|
@ -252,22 +255,48 @@ try:
|
|||
|
||||
def logged_in(self):
|
||||
session = Users.get_session()
|
||||
# Always make the admin menu visible
|
||||
self.main_window.admin_m.menuAction().setVisible(True)
|
||||
|
||||
if session is not None:
|
||||
# Check if user has admin privileges (either permanent or temporary)
|
||||
# Use session.is_admin instead of checking roles directly to be consistent with user.py
|
||||
if session.is_admin:
|
||||
self.main_window.admin_m.menuAction().setVisible(True)
|
||||
self.main_window.tag_a.setVisible(True)
|
||||
self.main_window.admin_enable_a.setVisible(False) # Hide admin enable action for admins
|
||||
# Show admin features for users with admin privileges (permanent or temporary)
|
||||
self.main_window.users_management_a.setVisible(True)
|
||||
self.main_window.save_tecna_recipes_a.setVisible(True)
|
||||
self.main_window.diagnostics_a.setVisible(True)
|
||||
else:
|
||||
self.main_window.admin_m.menuAction().setVisible(False)
|
||||
# For non-admin users, only show the admin enable button
|
||||
self.main_window.admin_enable_a.setVisible(True) # Show admin enable action for non-admins
|
||||
self.main_window.users_management_a.setVisible(False) # Hide user management for non-admins
|
||||
self.main_window.save_tecna_recipes_a.setVisible(False) # Hide tecna recipes for non-admins
|
||||
self.main_window.diagnostics_a.setVisible(False) # Hide diagnostics for non-admins
|
||||
self.main_window.tag_a.setVisible(False)
|
||||
# open test
|
||||
|
||||
# Update background color based on admin privileges
|
||||
self.update_window_backgrounds()
|
||||
|
||||
self.main_window.open_tab(Test(self.config, self.components, self))
|
||||
self.main_window.centralWidget().request_autotest("login")
|
||||
else:
|
||||
self.main_window.admin_m.menuAction().setVisible(False)
|
||||
|
||||
def logout(self):
|
||||
# Users.logout()
|
||||
self.main_window.admin_m.menuAction().setVisible(False)
|
||||
# Keep the admin menu visible
|
||||
self.main_window.admin_m.menuAction().setVisible(True)
|
||||
# Get the current session (if any)
|
||||
session = Users.get_session()
|
||||
# Note: We no longer reset temp_admin here to preserve admin status across login/logout
|
||||
|
||||
# Reset background color to default
|
||||
self.main_window.setStyleSheet("")
|
||||
for window_name, window in self.main_window.windows.items():
|
||||
if window is not None and not sip.isdeleted(window):
|
||||
window.setStyleSheet("")
|
||||
|
||||
if type(self.main_window.centralWidget().centralWidget.widget) in (
|
||||
Recipe_Selection, Barcode_Recipe_Selection):
|
||||
# LOGOUT IMMEDIATELY IF NOT TESTING
|
||||
|
|
@ -299,6 +328,171 @@ try:
|
|||
def cut_tube(self):
|
||||
self.main_window.centralWidget().cut_tube()
|
||||
|
||||
def enable_admin_privileges(self):
|
||||
session = Users.get_session()
|
||||
if session is None:
|
||||
QMessageBox.warning(self.main_window, "Errore", "Nessun utente loggato")
|
||||
return
|
||||
|
||||
# If user already has temporary admin privileges, toggle them off
|
||||
if session.temp_admin:
|
||||
# Use the Users class method to disable temp admin
|
||||
Users.disable_temp_admin()
|
||||
# Keep the admin menu visible
|
||||
self.main_window.admin_m.menuAction().setVisible(True)
|
||||
self.main_window.users_management_a.setVisible(False)
|
||||
self.main_window.save_tecna_recipes_a.setVisible(False)
|
||||
self.main_window.diagnostics_a.setVisible(False)
|
||||
self.main_window.tag_a.setVisible(False)
|
||||
self.main_window.admin_enable_a.setVisible(True) # Show admin enable action after removing temp admin privileges
|
||||
|
||||
# Call disable_temp_admin on the Test widget if it exists
|
||||
current_widget = self.main_window.centralWidget()
|
||||
if current_widget is not None and hasattr(current_widget, 'disable_temp_admin'):
|
||||
current_widget.disable_temp_admin()
|
||||
QMessageBox.information(
|
||||
self.main_window,
|
||||
"Successo",
|
||||
"Privilegi di amministratore disabilitati"
|
||||
)
|
||||
# Update background color for all windows
|
||||
self.update_window_backgrounds()
|
||||
|
||||
# Refresh the current UI component to reflect removed admin privileges
|
||||
current_widget = self.main_window.centralWidget()
|
||||
if current_widget is not None:
|
||||
# If the current widget has a refresh method, call it
|
||||
if hasattr(current_widget, 'refresh'):
|
||||
current_widget.refresh()
|
||||
# If the current widget has a crud attribute, refresh it
|
||||
if hasattr(current_widget, 'crud'):
|
||||
if callable(current_widget.crud):
|
||||
crud = current_widget.crud()
|
||||
else:
|
||||
crud = current_widget.crud
|
||||
if hasattr(crud, 'refresh'):
|
||||
crud.refresh()
|
||||
|
||||
# Refresh all other open windows to reflect removed admin privileges
|
||||
for window_name, window in self.main_window.windows.items():
|
||||
if window is not None and not sip.isdeleted(window):
|
||||
central_widget = window.centralWidget()
|
||||
if central_widget is not None:
|
||||
# If the central widget has a refresh method, call it
|
||||
if hasattr(central_widget, 'refresh'):
|
||||
central_widget.refresh()
|
||||
# If the central widget has a crud attribute, refresh it
|
||||
if hasattr(central_widget, 'crud'):
|
||||
if callable(central_widget.crud):
|
||||
crud = central_widget.crud()
|
||||
else:
|
||||
crud = central_widget.crud
|
||||
if hasattr(crud, 'refresh'):
|
||||
crud.refresh()
|
||||
return
|
||||
|
||||
# If user is a permanent admin (not temporary), show a message
|
||||
if "admin" in Users.parse_roles(session.user.roles):
|
||||
QMessageBox.information(self.main_window, "Informazione", "Sei già un amministratore permanente")
|
||||
return
|
||||
|
||||
password, ok = QInputDialog.getText(
|
||||
self.main_window,
|
||||
"Admin abilitazione",
|
||||
"Inserisci la password di amministratore:",
|
||||
QLineEdit.Password
|
||||
)
|
||||
|
||||
if not ok or not password:
|
||||
return
|
||||
|
||||
# Find an admin user to verify the password against
|
||||
admin_users = [user for user in Users.get_users() if "admin" in Users.parse_roles(user.roles)]
|
||||
|
||||
if not admin_users:
|
||||
QMessageBox.warning(self.main_window, "Errore", "Nessun utente amministratore trovato nel sistema")
|
||||
return
|
||||
|
||||
# Use the Users class method to enable temp admin
|
||||
if Users.enable_temp_admin(password):
|
||||
self.main_window.admin_m.menuAction().setVisible(True)
|
||||
self.main_window.tag_a.setVisible(True)
|
||||
# Show admin features for users with temporary admin privileges
|
||||
self.main_window.users_management_a.setVisible(True)
|
||||
self.main_window.save_tecna_recipes_a.setVisible(True)
|
||||
self.main_window.diagnostics_a.setVisible(True)
|
||||
|
||||
# Call enable_temp_admin on the Test widget if it exists
|
||||
current_widget = self.main_window.centralWidget()
|
||||
if current_widget is not None and hasattr(current_widget, 'enable_temp_admin'):
|
||||
current_widget.enable_temp_admin()
|
||||
QMessageBox.information(
|
||||
self.main_window,
|
||||
"Successo",
|
||||
"Privilegi di amministratore abilitati temporaneamente"
|
||||
)
|
||||
# Update background color for all windows
|
||||
self.update_window_backgrounds()
|
||||
|
||||
# Refresh the current UI component to reflect new admin privileges
|
||||
current_widget = self.main_window.centralWidget()
|
||||
if current_widget is not None:
|
||||
# If the current widget has a refresh method, call it
|
||||
if hasattr(current_widget, 'refresh'):
|
||||
current_widget.refresh()
|
||||
# If the current widget has a crud attribute, refresh it
|
||||
if hasattr(current_widget, 'crud'):
|
||||
if callable(current_widget.crud):
|
||||
crud = current_widget.crud()
|
||||
else:
|
||||
crud = current_widget.crud
|
||||
if hasattr(crud, 'refresh'):
|
||||
crud.refresh()
|
||||
|
||||
# Refresh all other open windows to reflect new admin privileges
|
||||
for window_name, window in self.main_window.windows.items():
|
||||
if window is not None and not sip.isdeleted(window):
|
||||
central_widget = window.centralWidget()
|
||||
if central_widget is not None:
|
||||
# If the central widget has a refresh method, call it
|
||||
if hasattr(central_widget, 'refresh'):
|
||||
central_widget.refresh()
|
||||
# If the central widget has a crud attribute, refresh it
|
||||
if hasattr(central_widget, 'crud'):
|
||||
if callable(central_widget.crud):
|
||||
crud = central_widget.crud()
|
||||
else:
|
||||
crud = central_widget.crud
|
||||
if hasattr(crud, 'refresh'):
|
||||
crud.refresh()
|
||||
return
|
||||
|
||||
QMessageBox.warning(self.main_window, "Errore", "Password non valida")
|
||||
|
||||
def update_window_backgrounds(self):
|
||||
"""Update the background color of all windows based on admin privileges"""
|
||||
session = Users.get_session()
|
||||
if session is None:
|
||||
return
|
||||
|
||||
# Check if user has admin privileges (permanent or temporary)
|
||||
# Use session.is_admin instead of checking roles directly to be consistent with user.py
|
||||
has_admin = session.is_admin
|
||||
|
||||
# Set background color for main window
|
||||
if has_admin:
|
||||
self.main_window.setStyleSheet("background-color: #ffcccc;") # Light red background
|
||||
else:
|
||||
self.main_window.setStyleSheet("") # Reset to default
|
||||
|
||||
# Set background color for all other windows
|
||||
for window_name, window in self.main_window.windows.items():
|
||||
if window is not None and not sip.isdeleted(window):
|
||||
if has_admin:
|
||||
window.setStyleSheet("background-color: #ffcccc;") # Light red background
|
||||
else:
|
||||
window.setStyleSheet("") # Reset to default
|
||||
|
||||
@pyqtSlot(str)
|
||||
def load_recipe_from_rfid(self, data):
|
||||
self.tag_loaded_recipe = data
|
||||
|
|
|
|||
|
|
@ -75,6 +75,19 @@ class Archive(Widget):
|
|||
if self.selected is not None and self.printer is not None:
|
||||
self.printer.print_archive_label(self.selected)
|
||||
|
||||
def refresh(self):
|
||||
"""Update the CRUD component based on current admin privileges"""
|
||||
session = Users.get_session()
|
||||
# Check if user has admin privileges (either permanent or temporary)
|
||||
# Use session.is_admin instead of checking roles directly to be consistent with user.py
|
||||
has_admin = session.is_admin
|
||||
|
||||
# Update CRUD readonly status
|
||||
if has_admin:
|
||||
self.crud.set_readonly(False)
|
||||
else:
|
||||
self.crud.set_readonly(True)
|
||||
|
||||
def export(self, csv_path=None):
|
||||
if csv_path is None:
|
||||
csv_path, _ = QFileDialog.getSaveFileName(
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import weakref
|
|||
from datetime import datetime
|
||||
|
||||
from lib.db import Crud_DB
|
||||
from lib.db.models.users import Users
|
||||
from peewee import TextField
|
||||
from PyQt5.QtCore import Qt, QTimer, pyqtSignal, QSize
|
||||
from PyQt5.QtWidgets import (QAbstractItemView, QComboBox, QDialog,
|
||||
|
|
@ -273,6 +274,15 @@ class Crud(Widget):
|
|||
self.filter_delay.setSingleShot(True)
|
||||
self.filter_delay.setInterval(500)
|
||||
self.filter_delay.timeout.connect(lambda selfi=weakref.ref(self): selfi().do_filter(selfi().filter_cn))
|
||||
|
||||
# Setup privilege check timer
|
||||
self.privilege_timer = QTimer()
|
||||
self.privilege_timer.setInterval(5000) # 5 seconds
|
||||
self.privilege_timer.timeout.connect(self.check_privileges)
|
||||
self.privilege_timer.start()
|
||||
|
||||
# Initial check of privileges
|
||||
self.check_privileges()
|
||||
self.db_tw.crud = self
|
||||
self.refresh("init")
|
||||
self.db_tw.horizontalHeader().sectionClicked.connect(self.toggle_sort)
|
||||
|
|
@ -298,6 +308,13 @@ class Crud(Widget):
|
|||
self.start_b.setHidden(True)
|
||||
self.end_b.setHidden(True)
|
||||
self.page_n_sb.setHidden(True)
|
||||
|
||||
# Setup buttons based on readonly status
|
||||
self._setup_buttons()
|
||||
|
||||
def _setup_buttons(self):
|
||||
"""Configure buttons based on readonly status"""
|
||||
|
||||
if self.readonly is None or self.readonly is True:
|
||||
self.cancel_b.setEnabled(False)
|
||||
self.cancel_b.setHidden(True)
|
||||
|
|
@ -308,11 +325,77 @@ class Crud(Widget):
|
|||
self.delete_b.setEnabled(False)
|
||||
self.delete_b.setHidden(True)
|
||||
else:
|
||||
self.cancel_b.setEnabled(True)
|
||||
self.cancel_b.setHidden(False)
|
||||
self.commit_b.setEnabled(True)
|
||||
self.commit_b.setHidden(False)
|
||||
self.add_b.setEnabled(True)
|
||||
self.add_b.setHidden(False)
|
||||
self.delete_b.setEnabled(True)
|
||||
self.delete_b.setHidden(False)
|
||||
|
||||
# Connect button signals if not already connected
|
||||
try:
|
||||
self.cancel_b.clicked.disconnect()
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.commit_b.clicked.disconnect()
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.add_b.clicked.disconnect()
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.delete_b.clicked.disconnect()
|
||||
except:
|
||||
pass
|
||||
|
||||
self.cancel_b.clicked.connect(self.cancel)
|
||||
self.commit_b.clicked.connect(self.commit)
|
||||
self.add_b.clicked.connect(self.add)
|
||||
self.delete_b.clicked.connect(self.delete)
|
||||
|
||||
def check_privileges(self):
|
||||
"""Check current user privileges and update readonly status if needed"""
|
||||
try:
|
||||
session = Users.get_session()
|
||||
if session is None:
|
||||
# No user logged in, set to readonly
|
||||
self.set_readonly(True)
|
||||
return
|
||||
|
||||
# Check if user has admin privileges (either permanent or temporary)
|
||||
is_admin = "admin" in Users.parse_roles(session.user.roles) or session.temp_admin
|
||||
|
||||
# Update readonly status based on admin privileges
|
||||
# If user is admin, they can edit (readonly=False)
|
||||
# If user is not admin, they can only view (readonly=True)
|
||||
self.set_readonly(not is_admin)
|
||||
except Exception as e:
|
||||
# Log any errors but don't crash
|
||||
self.log.exception(f"Error checking privileges: {str(e)}")
|
||||
|
||||
def set_readonly(self, readonly):
|
||||
"""Update the readonly status and refresh the UI accordingly"""
|
||||
if self.readonly == readonly:
|
||||
return # No change needed
|
||||
|
||||
self.readonly = readonly
|
||||
|
||||
# Update selection mode
|
||||
if self.readonly is None or self.readonly is True:
|
||||
self.db_tw.setSelectionMode(QAbstractItemView.SingleSelection)
|
||||
else:
|
||||
self.db_tw.setSelectionMode(QAbstractItemView.ExtendedSelection)
|
||||
|
||||
# Update buttons
|
||||
self._setup_buttons()
|
||||
|
||||
# Refresh the UI to update cell widgets
|
||||
self.refresh()
|
||||
|
||||
sort_cycle = [True, False, None]
|
||||
sort_symbol = [" \u25B4", " \u25BE", ""]
|
||||
|
||||
|
|
@ -567,3 +650,21 @@ class Crud(Widget):
|
|||
def emit(self):
|
||||
self.set_modified(self._modified)
|
||||
self.show_selection()
|
||||
|
||||
def hideEvent(self, event):
|
||||
"""Stop the privilege timer when the widget is hidden"""
|
||||
if hasattr(self, 'privilege_timer'):
|
||||
self.privilege_timer.stop()
|
||||
super().hideEvent(event)
|
||||
|
||||
def showEvent(self, event):
|
||||
"""Restart the privilege timer when the widget is shown"""
|
||||
if hasattr(self, 'privilege_timer'):
|
||||
self.privilege_timer.start()
|
||||
super().showEvent(event)
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""Clean up resources when the widget is closed"""
|
||||
if hasattr(self, 'privilege_timer'):
|
||||
self.privilege_timer.stop()
|
||||
super().closeEvent(event)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import traceback
|
||||
|
||||
from lib.db import log # Presumendo che esista un modulo per accedere alla tabella "log"
|
||||
from lib.db import log, Users # Presumendo che esista un modulo per accedere alla tabella "log"
|
||||
from PyQt5.QtWidgets import QMessageBox, QTableWidget
|
||||
from ui.crud import Crud, Line_Edit_Cell_Widget
|
||||
from ui.widget import Widget
|
||||
|
|
@ -42,6 +42,19 @@ class Logs_Management(Widget):
|
|||
# Adjust the column widths based on content
|
||||
self.adjust_column_widths()
|
||||
|
||||
def refresh(self):
|
||||
"""Update the CRUD component based on current admin privileges"""
|
||||
session = Users.get_session()
|
||||
# Check if user has admin privileges (either permanent or temporary)
|
||||
# Use session.is_admin instead of checking roles directly to be consistent with user.py
|
||||
has_admin = session.is_admin
|
||||
|
||||
# Update CRUD readonly status
|
||||
if has_admin:
|
||||
self.crud.set_readonly(["id"]) # Only id field is readonly
|
||||
else:
|
||||
self.crud.set_readonly(True) # All fields are readonly
|
||||
|
||||
def adjust_column_widths(self):
|
||||
"""Adjust the widths of columns to fit their content."""
|
||||
# Ensure that Crud has db_tw which is a QTableWidget
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ import sip
|
|||
from PyQt5.QtCore import pyqtSignal
|
||||
from ui.window import Window
|
||||
|
||||
parser = argparse.ArgumentParser(prog='STTEN', description='Leak test system',add_help=False)
|
||||
parser = argparse.ArgumentParser(prog='STTEN', description='Leak test system', add_help=False)
|
||||
parser.add_argument('-w', '--width')
|
||||
parser.add_argument('-h', '--height')
|
||||
args,unspec = parser.parse_known_args()
|
||||
args, unspec = parser.parse_known_args()
|
||||
|
||||
class Main_Window(Window):
|
||||
do = pyqtSignal(dict)
|
||||
|
|
@ -22,6 +22,9 @@ class Main_Window(Window):
|
|||
self.run_request.connect(self.run_request_handler)
|
||||
# print("MAIN_WINDOW ", str(int(QThread.currentThreadId())), flush=True)
|
||||
|
||||
# Initialize windows dictionary
|
||||
self.windows = {}
|
||||
|
||||
if "width" in args:
|
||||
if args.width is not None:
|
||||
self.setFixedWidth(int(args.width))
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
<addaction name="users_management_a"/>
|
||||
<addaction name="save_tecna_recipes_a"/>
|
||||
<addaction name="diagnostics_a"/>
|
||||
<addaction name="admin_enable_a"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuStrumenti">
|
||||
<property name="font">
|
||||
|
|
@ -158,6 +159,11 @@
|
|||
<string>Calibra Taglio</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="admin_enable_a">
|
||||
<property name="text">
|
||||
<string>Admin abilitazione</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
|
|
|||
|
|
@ -187,6 +187,45 @@ class Recipe_Selection(Widget):
|
|||
def check(self, modified, selected):
|
||||
self.select_b.setEnabled(modified is False and selected is not None)
|
||||
|
||||
def refresh(self):
|
||||
"""Update the UI based on current admin privileges"""
|
||||
session = Users.get_session()
|
||||
# Check if user has admin privileges (either permanent or temporary)
|
||||
# Use session.is_admin instead of checking roles directly to be consistent with user.py
|
||||
has_admin = session.is_admin
|
||||
|
||||
# Update button visibility
|
||||
self.import_b.setVisible(has_admin)
|
||||
self.export_b.setVisible(has_admin)
|
||||
self.delete_all_b.setVisible(has_admin)
|
||||
|
||||
# Connect or disconnect button handlers
|
||||
if has_admin:
|
||||
# Disconnect existing handlers to avoid multiple connections
|
||||
try:
|
||||
self.import_b.clicked.disconnect()
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.export_b.clicked.disconnect()
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.delete_all_b.clicked.disconnect()
|
||||
except:
|
||||
pass
|
||||
|
||||
# Connect handlers
|
||||
self.import_b.clicked.connect(lambda checked, selfi=weakref.ref(self): selfi().import_recipes())
|
||||
self.export_b.clicked.connect(lambda checked, selfi=weakref.ref(self): selfi().export_recipes())
|
||||
self.delete_all_b.clicked.connect(lambda checked, selfi=weakref.ref(self): selfi().delete_recipes())
|
||||
|
||||
# Update CRUD readonly status
|
||||
if has_admin:
|
||||
self.crud.set_readonly(False)
|
||||
else:
|
||||
self.crud.set_readonly(True)
|
||||
|
||||
def select(self):
|
||||
if self.selected is not None:
|
||||
self.ok.emit(self.crud.db.table_model.get_by_id(self.selected))
|
||||
|
|
@ -489,6 +528,3 @@ class Recipe_Selection(Widget):
|
|||
return self.WINDOWS_BASE_DIR
|
||||
else:
|
||||
raise Exception("Unsupported operating system!")
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from lib.db import Users
|
||||
from ui.crud import Crud, Json_External_Dialog_Editor_Cell_Widget
|
||||
from ui.recipe_spec_editor import Recipe_Spec_Editor
|
||||
from ui.widget import Widget
|
||||
|
|
@ -28,3 +29,16 @@ class Recipes_Management(Widget):
|
|||
widget_classes={"spec": lambda *args, **kwargs: Json_External_Dialog_Editor_Cell_Widget(Recipe_Spec_Editor, *args, **kwargs), },
|
||||
)
|
||||
self.layout().addWidget(self.crud, 0, 0, -1, -1)
|
||||
|
||||
def refresh(self):
|
||||
"""Update the CRUD component based on current admin privileges"""
|
||||
session = Users.get_session()
|
||||
# Check if user has admin privileges (either permanent or temporary)
|
||||
# Use session.is_admin instead of checking roles directly to be consistent with user.py
|
||||
has_admin = session.is_admin
|
||||
|
||||
# Update CRUD readonly status
|
||||
if has_admin:
|
||||
self.crud.set_readonly(False)
|
||||
else:
|
||||
self.crud.set_readonly(True)
|
||||
|
|
|
|||
|
|
@ -46,11 +46,22 @@ class Test(Widget):
|
|||
self.machine_description_l.setText(self.config.get("machine", {}).get("description", "N/A"))
|
||||
# SHOW USERNAME
|
||||
session = Users.get_session()
|
||||
self.user_l.setText(session.username)
|
||||
self.original_username = session.username
|
||||
|
||||
# Check if we should set the label to "ADMIN"
|
||||
if session.username.upper() == "ADMIN":
|
||||
self.user_l.setText("ADMIN")
|
||||
session._is_admin = True
|
||||
else:
|
||||
self.user_l.setText(session.username)
|
||||
session._is_admin = False
|
||||
|
||||
if session.is_admin:
|
||||
self.user_l.setStyleSheet("QLabel { color: red; }")
|
||||
else:
|
||||
self.user_l.setStyleSheet("")
|
||||
# Store original admin status
|
||||
self.had_admin = session.is_admin
|
||||
|
||||
self.flag_label.setVisible(False)
|
||||
if len(sys.argv) > 1:
|
||||
|
|
@ -277,6 +288,52 @@ class Test(Widget):
|
|||
def setCentralWidget(self, widget):
|
||||
replace_widget(self, "centralWidget", widget)
|
||||
|
||||
def enable_temp_admin(self):
|
||||
"""Enable temporary admin privileges for the current user"""
|
||||
session = Users.get_session()
|
||||
if session is None:
|
||||
self.log.warning("Cannot enable temporary admin privileges: No active session")
|
||||
return False
|
||||
|
||||
# Save the current label text before changing it
|
||||
self.saved_user_label_text = self.user_l.text()
|
||||
|
||||
# Enable temporary admin privileges using the Session class method
|
||||
session.enable_temp_admin()
|
||||
|
||||
# Update UI to reflect admin status
|
||||
self.user_l.setText("ADMIN")
|
||||
self.user_l.setStyleSheet("QLabel { color: red; }")
|
||||
|
||||
self.log.info(f"Temporary admin privileges enabled for user: {session.username}")
|
||||
return True
|
||||
|
||||
def disable_temp_admin(self):
|
||||
"""Disable temporary admin privileges and restore original user status"""
|
||||
session = Users.get_session()
|
||||
if session is None:
|
||||
self.log.warning("Cannot disable temporary admin privileges: No active session")
|
||||
return False
|
||||
|
||||
# Disable temporary admin privileges using the Session class method
|
||||
session.disable_temp_admin()
|
||||
|
||||
# Restore original UI
|
||||
# Use the saved label text if available, otherwise fall back to original username
|
||||
if hasattr(self, 'saved_user_label_text'):
|
||||
self.user_l.setText(self.saved_user_label_text)
|
||||
else:
|
||||
self.user_l.setText(self.original_username)
|
||||
|
||||
# Set style based on original admin status
|
||||
if self.had_admin:
|
||||
self.user_l.setStyleSheet("QLabel { color: red; }")
|
||||
else:
|
||||
self.user_l.setStyleSheet("")
|
||||
|
||||
self.log.info(f"Temporary admin privileges disabled for user: {session.username}")
|
||||
return True
|
||||
|
||||
def request_autotest(self, reason): # you can cancel the request calling request_autotest(False)
|
||||
if "--no-autotest" not in sys.argv:
|
||||
|
||||
|
|
@ -1036,4 +1093,4 @@ class Test(Widget):
|
|||
self.flag_label.setStyleSheet("QLabel { color: red; font-weight: bold; }") # Customize color if needed
|
||||
self.flag_label.setVisible(True) # Ensure the label is visible
|
||||
else: # No args provided
|
||||
self.flag_label.setVisible(False) # Hide label
|
||||
self.flag_label.setVisible(False) # Hide label
|
||||
|
|
|
|||
|
|
@ -241,12 +241,24 @@ class Test_Test(Widget):
|
|||
|
||||
def challenge_admin(self, info):
|
||||
if not self.admin_challenged:
|
||||
# Store the current session's admin flag
|
||||
from lib.db import Users
|
||||
session = Users.get_session()
|
||||
was_temp_admin = False
|
||||
if session is not None:
|
||||
was_temp_admin = session.temp_admin
|
||||
|
||||
d = Dialog(parent=self)
|
||||
d.setCentralWidget(Test_Admin_Permission(info))
|
||||
d.setModal(True)
|
||||
d.show()
|
||||
d.centralWidget.password_le.setFocus()
|
||||
r = d.exec()
|
||||
|
||||
# Restore the session's admin flag if it was set before
|
||||
if session is not None and was_temp_admin:
|
||||
session.temp_admin = was_temp_admin
|
||||
|
||||
if r == d.Accepted:
|
||||
self.admin_challenged = True
|
||||
elif r == d.Rejected:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import traceback
|
||||
|
||||
from lib.db import Users
|
||||
from PyQt5.QtCore import QTimer
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
from ui.crud import Crud, Line_Edit_Cell_Widget
|
||||
from ui.widget import Widget
|
||||
|
|
@ -10,6 +11,12 @@ class Users_Management(Widget):
|
|||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
# Call refresh method after initialization to set correct readonly status
|
||||
self.refresh_timer = QTimer()
|
||||
self.refresh_timer.setSingleShot(True)
|
||||
self.refresh_timer.timeout.connect(self.refresh)
|
||||
self.refresh_timer.start(10) # Short delay to ensure widget is fully initialized
|
||||
|
||||
class Username_Line_Edit_Cell_Widget(Line_Edit_Cell_Widget):
|
||||
def parse(self, action=None, row_number=None, crud=None):
|
||||
data = super().parse(action=action, row_number=row_number, crud=crud)
|
||||
|
|
@ -65,6 +72,19 @@ class Users_Management(Widget):
|
|||
)
|
||||
self.layout().addWidget(self.crud, 0, 0, -1, -1)
|
||||
|
||||
def refresh(self):
|
||||
"""Update the CRUD component based on current admin privileges"""
|
||||
session = Users.get_session()
|
||||
# Check if user has admin privileges (either permanent or temporary)
|
||||
# Use session.is_admin instead of checking roles directly to be consistent with user.py
|
||||
has_admin = session.is_admin
|
||||
|
||||
# Update CRUD readonly status
|
||||
if has_admin:
|
||||
self.crud.set_readonly(False)
|
||||
else:
|
||||
self.crud.set_readonly(True) # All fields are readonly
|
||||
|
||||
def row_filter(self, row, row_number, crud):
|
||||
if row["password"] is not None and all(map(lambda x: x == "\u2022", row["password"][0])):
|
||||
row.pop("password", None)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user