mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-05-24 15:20:52 -05:00
90dde470da
- Normalize line endings from CRLF to LF across all files to match .editorconfig - Standardize quote style from single quotes to double quotes - Normalize whitespace and formatting throughout codebase - Apply consistent code style across 372 files including: * Application code (models, routes, services, utils) * Test files * Configuration files * CI/CD workflows This ensures consistency with the project's .editorconfig settings and improves code maintainability.
121 lines
3.7 KiB
Python
121 lines
3.7 KiB
Python
"""
|
|
Service for permission and role management.
|
|
"""
|
|
|
|
from typing import List, Dict, Any, Optional
|
|
from app import db
|
|
from app.models import Permission, Role, User
|
|
from app.repositories import UserRepository
|
|
from app.utils.db import safe_commit
|
|
|
|
|
|
class PermissionService:
|
|
"""Service for permission operations"""
|
|
|
|
def __init__(self):
|
|
self.user_repo = UserRepository()
|
|
|
|
def check_permission(self, user_id: int, permission_name: str) -> bool:
|
|
"""
|
|
Check if a user has a specific permission.
|
|
|
|
Returns:
|
|
True if user has permission, False otherwise
|
|
"""
|
|
user = self.user_repo.get_by_id(user_id)
|
|
|
|
if not user:
|
|
return False
|
|
|
|
# Admins have all permissions
|
|
if user.role == "admin":
|
|
return True
|
|
|
|
# Check role permissions
|
|
role = Role.query.filter_by(name=user.role).first()
|
|
if role:
|
|
permission = Permission.query.filter_by(name=permission_name, role_id=role.id).first()
|
|
if permission and permission.granted:
|
|
return True
|
|
|
|
return False
|
|
|
|
def grant_permission(self, role_name: str, permission_name: str) -> Dict[str, Any]:
|
|
"""
|
|
Grant a permission to a role.
|
|
|
|
Returns:
|
|
dict with 'success' and 'message' keys
|
|
"""
|
|
role = Role.query.filter_by(name=role_name).first()
|
|
if not role:
|
|
return {"success": False, "message": "Role not found", "error": "invalid_role"}
|
|
|
|
# Check if permission already exists
|
|
permission = Permission.query.filter_by(name=permission_name, role_id=role.id).first()
|
|
|
|
if permission:
|
|
permission.granted = True
|
|
else:
|
|
permission = Permission(name=permission_name, role_id=role.id, granted=True)
|
|
db.session.add(permission)
|
|
|
|
if not safe_commit("grant_permission", {"role": role_name, "permission": permission_name}):
|
|
return {
|
|
"success": False,
|
|
"message": "Could not grant permission due to a database error",
|
|
"error": "database_error",
|
|
}
|
|
|
|
return {"success": True, "message": "Permission granted successfully"}
|
|
|
|
def revoke_permission(self, role_name: str, permission_name: str) -> Dict[str, Any]:
|
|
"""
|
|
Revoke a permission from a role.
|
|
|
|
Returns:
|
|
dict with 'success' and 'message' keys
|
|
"""
|
|
role = Role.query.filter_by(name=role_name).first()
|
|
if not role:
|
|
return {"success": False, "message": "Role not found", "error": "invalid_role"}
|
|
|
|
permission = Permission.query.filter_by(name=permission_name, role_id=role.id).first()
|
|
|
|
if permission:
|
|
permission.granted = False
|
|
|
|
if not safe_commit("revoke_permission", {"role": role_name, "permission": permission_name}):
|
|
return {
|
|
"success": False,
|
|
"message": "Could not revoke permission due to a database error",
|
|
"error": "database_error",
|
|
}
|
|
|
|
return {"success": True, "message": "Permission revoked successfully"}
|
|
|
|
def get_user_permissions(self, user_id: int) -> List[str]:
|
|
"""
|
|
Get all permissions for a user.
|
|
|
|
Returns:
|
|
List of permission names
|
|
"""
|
|
user = self.user_repo.get_by_id(user_id)
|
|
|
|
if not user:
|
|
return []
|
|
|
|
# Admins have all permissions
|
|
if user.role == "admin":
|
|
return ["admin:all"]
|
|
|
|
# Get role permissions
|
|
role = Role.query.filter_by(name=user.role).first()
|
|
if not role:
|
|
return []
|
|
|
|
permissions = Permission.query.filter_by(role_id=role.id, granted=True).all()
|
|
|
|
return [p.name for p in permissions]
|