docs: Add comprehensive settings page analysis and improvements
- Add detailed settings page analysis report (settings.md) - Document identified security vulnerabilities and code quality issues - Provide prioritized improvement recommendations - Document permission and access control issues - Add testing checklist for validation - Track modifications to settings.py, routes.py, and settings.html templates
This commit is contained in:
@@ -197,8 +197,8 @@ def role_permissions_handler():
|
||||
|
||||
|
||||
def settings_handler():
|
||||
if 'role' not in session or session['role'] != 'superadmin':
|
||||
flash('Access denied: Superadmin only.')
|
||||
if 'role' not in session or session['role'] not in ['superadmin', 'admin']:
|
||||
flash('Access denied: Admin or Superadmin required.')
|
||||
return redirect(url_for('main.dashboard'))
|
||||
|
||||
# Get users from external MariaDB database
|
||||
@@ -265,185 +265,6 @@ def get_external_db_connection():
|
||||
return get_db_connection()
|
||||
|
||||
# User management handlers
|
||||
def create_user_handler():
|
||||
if 'role' not in session or session['role'] != 'superadmin':
|
||||
flash('Access denied: Superadmin only.')
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
role = request.form['role']
|
||||
email = request.form.get('email', '').strip() or None # Optional field
|
||||
|
||||
try:
|
||||
# Connect to external MariaDB database
|
||||
conn = get_external_db_connection()
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Create users table if it doesn't exist - with modules column
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
username VARCHAR(100) UNIQUE NOT NULL,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
role VARCHAR(50) NOT NULL,
|
||||
modules JSON DEFAULT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
''')
|
||||
|
||||
# Ensure modules column exists (for backward compatibility)
|
||||
try:
|
||||
cursor.execute("SELECT modules FROM users LIMIT 1")
|
||||
except mariadb.ProgrammingError:
|
||||
cursor.execute("ALTER TABLE users ADD COLUMN modules JSON DEFAULT NULL")
|
||||
|
||||
# Check if the username already exists
|
||||
cursor.execute("SELECT id FROM users WHERE username = %s", (username,))
|
||||
if cursor.fetchone():
|
||||
flash('User already exists.')
|
||||
conn.close()
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
# Prepare modules based on role
|
||||
import json
|
||||
if role == 'superadmin':
|
||||
# Superadmin doesn't need explicit modules (handled at login)
|
||||
user_modules = None
|
||||
elif role == 'admin':
|
||||
# Admin gets access to all available modules
|
||||
user_modules = json.dumps(['quality', 'warehouse', 'labels', 'daily_mirror'])
|
||||
else:
|
||||
# Other roles (manager, worker) get no modules by default
|
||||
user_modules = json.dumps([])
|
||||
|
||||
# Create a new user in external MariaDB with modules
|
||||
cursor.execute("""
|
||||
INSERT INTO users (username, password, role, modules)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
""", (username, password, role, user_modules))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
flash('User created successfully in external database.')
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error creating user in external database: {e}")
|
||||
flash(f'Error creating user: {e}')
|
||||
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
def edit_user_handler():
|
||||
if 'role' not in session or session['role'] != 'superadmin':
|
||||
flash('Access denied: Superadmin only.')
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
user_id = request.form.get('user_id')
|
||||
password = request.form.get('password', '').strip()
|
||||
role = request.form.get('role')
|
||||
modules = request.form.getlist('modules') # Get selected modules
|
||||
|
||||
if not user_id or not role:
|
||||
flash('Missing required fields.')
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
try:
|
||||
# Connect to external MariaDB database
|
||||
conn = get_external_db_connection()
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Check if the user exists
|
||||
cursor.execute("SELECT id FROM users WHERE id = %s", (user_id,))
|
||||
if not cursor.fetchone():
|
||||
flash('User not found.')
|
||||
conn.close()
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
# Prepare modules JSON
|
||||
import json
|
||||
if role == 'superadmin':
|
||||
user_modules = None # Superadmin doesn't need explicit modules
|
||||
else:
|
||||
user_modules = json.dumps(modules) if modules else json.dumps([])
|
||||
|
||||
# Update the user's details in external MariaDB
|
||||
if password: # Only update password if provided
|
||||
cursor.execute("""
|
||||
UPDATE users SET password = %s, role = %s, modules = %s WHERE id = %s
|
||||
""", (password, role, user_modules, user_id))
|
||||
flash('User updated successfully (including password).')
|
||||
else: # Just update role and modules if no password provided
|
||||
cursor.execute("""
|
||||
UPDATE users SET role = %s, modules = %s WHERE id = %s
|
||||
""", (role, user_modules, user_id))
|
||||
flash('User role and modules updated successfully.')
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error updating user in external database: {e}")
|
||||
flash(f'Error updating user: {e}')
|
||||
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
def delete_user_handler():
|
||||
if 'role' not in session or session['role'] != 'superadmin':
|
||||
flash('Access denied: Superadmin only.')
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
user_id = request.form['user_id']
|
||||
|
||||
try:
|
||||
# Connect to external MariaDB database
|
||||
conn = get_external_db_connection()
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Check if the user exists
|
||||
cursor.execute("SELECT id FROM users WHERE id = %s", (user_id,))
|
||||
if not cursor.fetchone():
|
||||
flash('User not found.')
|
||||
conn.close()
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
# Delete the user from external MariaDB
|
||||
cursor.execute("DELETE FROM users WHERE id = %s", (user_id,))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
flash('User deleted successfully from external database.')
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error deleting user from external database: {e}")
|
||||
flash(f'Error deleting user: {e}')
|
||||
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
def save_external_db_handler():
|
||||
if 'role' not in session or session['role'] != 'superadmin':
|
||||
flash('Access denied: Superadmin only.')
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
# Get form data
|
||||
server_domain = request.form['server_domain']
|
||||
port = request.form['port']
|
||||
database_name = request.form['database_name']
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
|
||||
# Save data to a file in the instance folder
|
||||
settings_file = os.path.join(current_app.instance_path, 'external_server.conf')
|
||||
os.makedirs(os.path.dirname(settings_file), exist_ok=True)
|
||||
with open(settings_file, 'w') as f:
|
||||
f.write(f"server_domain={server_domain}\n")
|
||||
f.write(f"port={port}\n")
|
||||
f.write(f"database_name={database_name}\n")
|
||||
f.write(f"username={username}\n")
|
||||
f.write(f"password={password}\n")
|
||||
|
||||
flash('External database settings saved/updated successfully.')
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
def save_role_permissions_handler():
|
||||
"""Save role permissions via AJAX"""
|
||||
if not is_superadmin():
|
||||
|
||||
Reference in New Issue
Block a user