Files
TimeTracker/app/services/permission_service.py
T
Dries Peeters 90dde470da style: standardize code formatting and normalize line endings
- 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.
2025-11-28 20:05:37 +01:00

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]