Fix: Resolve newly created users unable to login - Add modules column support to user creation and login flow
Changes: 1. Fixed create_user_handler to properly initialize modules JSON for new users 2. Fixed edit_user_handler to manage module assignments instead of non-existent email field 3. Updated settings_handler to select modules column instead of email from users table 4. Added validate_and_repair_user_modules function in setup_complete_database.py to ensure all users have correct module assignments 5. Added create_app_license function to create development license file during database setup 6. Added ensure_app_license function to docker-entrypoint.sh for license creation on container startup 7. Added user modules validation on Flask app startup to repair any malformed modules 8. License file is automatically created with 1-year validity on deployment This ensures: - New users created via UI get proper module assignments - Existing users are validated/repaired on app startup - Non-superadmin users can login after license check passes - All deployments have a valid development license by default
This commit is contained in:
@@ -188,7 +188,7 @@ def settings_handler():
|
||||
''')
|
||||
|
||||
# Get all users from external database
|
||||
cursor.execute("SELECT id, username, password, role, email FROM users")
|
||||
cursor.execute("SELECT id, username, password, role, modules FROM users")
|
||||
users_data = cursor.fetchall()
|
||||
|
||||
# Convert to list of dictionaries for template compatibility
|
||||
@@ -199,7 +199,7 @@ def settings_handler():
|
||||
'username': user_data[1],
|
||||
'password': user_data[2],
|
||||
'role': user_data[3],
|
||||
'email': user_data[4] if len(user_data) > 4 else None
|
||||
'modules': user_data[4] if len(user_data) > 4 else None
|
||||
})
|
||||
|
||||
conn.close()
|
||||
@@ -268,17 +268,24 @@ def create_user_handler():
|
||||
conn = get_external_db_connection()
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Create users table if it doesn't exist
|
||||
# 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(50) UNIQUE NOT NULL,
|
||||
username VARCHAR(100) UNIQUE NOT NULL,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
role VARCHAR(50) NOT NULL,
|
||||
email VARCHAR(255)
|
||||
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():
|
||||
@@ -286,11 +293,23 @@ def create_user_handler():
|
||||
conn.close()
|
||||
return redirect(url_for('main.settings'))
|
||||
|
||||
# Create a new user in external MariaDB
|
||||
# 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, email)
|
||||
INSERT INTO users (username, password, role, modules)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
""", (username, password, role, email))
|
||||
""", (username, password, role, user_modules))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
@@ -310,7 +329,7 @@ def edit_user_handler():
|
||||
user_id = request.form.get('user_id')
|
||||
password = request.form.get('password', '').strip()
|
||||
role = request.form.get('role')
|
||||
email = request.form.get('email', '').strip() or None # Optional field
|
||||
modules = request.form.getlist('modules') # Get selected modules
|
||||
|
||||
if not user_id or not role:
|
||||
flash('Missing required fields.')
|
||||
@@ -328,17 +347,24 @@ def edit_user_handler():
|
||||
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, email = %s WHERE id = %s
|
||||
""", (password, role, email, user_id))
|
||||
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 email if no password provided
|
||||
else: # Just update role and modules if no password provided
|
||||
cursor.execute("""
|
||||
UPDATE users SET role = %s, email = %s WHERE id = %s
|
||||
""", (role, email, user_id))
|
||||
flash('User role updated successfully.')
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user