admin priv

This commit is contained in:
gg 2025-05-06 09:12:53 +02:00
parent 3300f55fec
commit 126836abf9
15 changed files with 580 additions and 18 deletions

View File

@ -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):

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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(

View File

@ -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)

View File

@ -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

View File

@ -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))

View File

@ -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/>

View File

@ -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!")

View File

@ -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)

View File

@ -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

View File

@ -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:

View File

@ -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)