Add SYSTEM_ADMINISTRATOR role.
This commit is contained in:
33
app.py
33
app.py
@@ -681,17 +681,37 @@ def login_required(f):
|
|||||||
def admin_required(f):
|
def admin_required(f):
|
||||||
@wraps(f)
|
@wraps(f)
|
||||||
def decorated_function(*args, **kwargs):
|
def decorated_function(*args, **kwargs):
|
||||||
if g.user is None or g.user.role != Role.ADMIN:
|
if g.user is None or (g.user.role != Role.ADMIN and g.user.role != Role.SYSTEM_ADMIN):
|
||||||
flash('You need administrator privileges to access this page.', 'error')
|
flash('You need administrator privileges to access this page.', 'error')
|
||||||
return redirect(url_for('home'))
|
return redirect(url_for('home'))
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
return decorated_function
|
return decorated_function
|
||||||
|
|
||||||
|
# System Admin-only decorator
|
||||||
|
def system_admin_required(f):
|
||||||
|
@wraps(f)
|
||||||
|
def decorated_function(*args, **kwargs):
|
||||||
|
if g.user is None or g.user.role != Role.SYSTEM_ADMIN:
|
||||||
|
flash('You need system administrator privileges to access this page.', 'error')
|
||||||
|
return redirect(url_for('home'))
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
return decorated_function
|
||||||
|
|
||||||
def get_system_setting(key, default='false'):
|
def get_system_setting(key, default='false'):
|
||||||
"""Helper function to get system setting value"""
|
"""Helper function to get system setting value"""
|
||||||
setting = SystemSettings.query.filter_by(key=key).first()
|
setting = SystemSettings.query.filter_by(key=key).first()
|
||||||
return setting.value if setting else default
|
return setting.value if setting else default
|
||||||
|
|
||||||
|
def is_system_admin(user=None):
|
||||||
|
"""Helper function to check if user is system admin"""
|
||||||
|
if user is None:
|
||||||
|
user = g.user
|
||||||
|
return user and user.role == Role.SYSTEM_ADMIN
|
||||||
|
|
||||||
|
def can_access_system_settings(user=None):
|
||||||
|
"""Helper function to check if user can access system-wide settings"""
|
||||||
|
return is_system_admin(user)
|
||||||
|
|
||||||
# Add this decorator function after your existing decorators
|
# Add this decorator function after your existing decorators
|
||||||
def role_required(min_role):
|
def role_required(min_role):
|
||||||
"""
|
"""
|
||||||
@@ -704,8 +724,8 @@ def role_required(min_role):
|
|||||||
if g.user is None:
|
if g.user is None:
|
||||||
return redirect(url_for('login', next=request.url))
|
return redirect(url_for('login', next=request.url))
|
||||||
|
|
||||||
# Admin always has access
|
# Admin and System Admin always have access
|
||||||
if g.user.role == Role.ADMIN:
|
if g.user.role == Role.ADMIN or g.user.role == Role.SYSTEM_ADMIN:
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
|
|
||||||
# Check role hierarchy
|
# Check role hierarchy
|
||||||
@@ -713,7 +733,8 @@ def role_required(min_role):
|
|||||||
Role.TEAM_MEMBER: 1,
|
Role.TEAM_MEMBER: 1,
|
||||||
Role.TEAM_LEADER: 2,
|
Role.TEAM_LEADER: 2,
|
||||||
Role.SUPERVISOR: 3,
|
Role.SUPERVISOR: 3,
|
||||||
Role.ADMIN: 4
|
Role.ADMIN: 4,
|
||||||
|
Role.SYSTEM_ADMIN: 5
|
||||||
}
|
}
|
||||||
|
|
||||||
if role_hierarchy.get(g.user.role, 0) < role_hierarchy.get(min_role, 0):
|
if role_hierarchy.get(g.user.role, 0) < role_hierarchy.get(min_role, 0):
|
||||||
@@ -733,6 +754,10 @@ def company_required(f):
|
|||||||
if g.user is None:
|
if g.user is None:
|
||||||
return redirect(url_for('login', next=request.url))
|
return redirect(url_for('login', next=request.url))
|
||||||
|
|
||||||
|
# System admins can access without company association
|
||||||
|
if g.user.role == Role.SYSTEM_ADMIN:
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
|
||||||
if g.user.company_id is None:
|
if g.user.company_id is None:
|
||||||
flash('You must be associated with a company to access this page.', 'error')
|
flash('You must be associated with a company to access this page.', 'error')
|
||||||
return redirect(url_for('setup_company'))
|
return redirect(url_for('setup_company'))
|
||||||
|
|||||||
@@ -294,6 +294,14 @@ def migrate_database():
|
|||||||
if updated:
|
if updated:
|
||||||
updated_count += 1
|
updated_count += 1
|
||||||
|
|
||||||
|
# Check if any system admin users exist
|
||||||
|
system_admin_count = User.query.filter_by(role=Role.SYSTEM_ADMIN).count()
|
||||||
|
if system_admin_count == 0:
|
||||||
|
print("No system administrators found. Consider promoting a user to SYSTEM_ADMIN role manually.")
|
||||||
|
print("Use: UPDATE user SET role = 'System Administrator' WHERE username = 'your_username';")
|
||||||
|
else:
|
||||||
|
print(f"Found {system_admin_count} system administrator(s)")
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
print(f"Associated {len(orphan_entries)} existing time entries with admin user")
|
print(f"Associated {len(orphan_entries)} existing time entries with admin user")
|
||||||
print(f"Associated {len(orphan_configs)} existing work configs with admin user")
|
print(f"Associated {len(orphan_configs)} existing work configs with admin user")
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ class Role(enum.Enum):
|
|||||||
TEAM_MEMBER = "Team Member"
|
TEAM_MEMBER = "Team Member"
|
||||||
TEAM_LEADER = "Team Leader"
|
TEAM_LEADER = "Team Leader"
|
||||||
SUPERVISOR = "Supervisor"
|
SUPERVISOR = "Supervisor"
|
||||||
ADMIN = "Administrator" # Keep existing admin role
|
ADMIN = "Administrator" # Company-level admin
|
||||||
|
SYSTEM_ADMIN = "System Administrator" # System-wide admin
|
||||||
|
|
||||||
# Define Account Type for freelancer support
|
# Define Account Type for freelancer support
|
||||||
class AccountType(enum.Enum):
|
class AccountType(enum.Enum):
|
||||||
|
|||||||
Reference in New Issue
Block a user