function check_document_permission
Validates whether a user has specific permission(s) to access or modify a document based on their roles, ownership status, and configured role permissions.
/tf/active/vicechatdev/CDocs/config/permissions.py
103 - 174
moderate
Purpose
This function implements a role-based access control (RBAC) system for document permissions. It checks if a user has the required permission(s) for a document by evaluating: (1) user roles including ADMIN privileges, (2) document ownership status, (3) role-based permissions from settings, and (4) fallback to default USER permissions. It supports checking single or multiple permissions simultaneously and handles edge cases like missing user/document data.
Source Code
def check_document_permission(user: Any, document: Dict[str, Any],
permission_type: Union[str, List[str]]) -> bool:
"""
Check if a user has a specific permission for a document.
Parameters
----------
user : Any
The user to check permissions for
document : Dict[str, Any]
The document to check against
permission_type : Union[str, List[str]]
The type of permission to check or a list of permissions
Returns
-------
bool
True if user has the permission for the document, False otherwise
"""
if not user or not document:
return False
# Get all user roles
user_roles = user.roles if hasattr(user, 'roles') else []
# If no roles, fall back to USER role
if not user_roles:
if isinstance(permission_type, str):
return permission_type in settings.ROLE_PERMISSIONS.get('USER', [])
else:
return any(perm in settings.ROLE_PERMISSIONS.get('USER', []) for perm in permission_type)
# Admin users have all permissions
if 'ADMIN' in user_roles:
logger.debug(f"User has ADMIN role, granting document permission")
return True
# Convert permission_type to list if it's a single string
if isinstance(permission_type, str):
permissions_to_check = [permission_type]
else:
permissions_to_check = permission_type
# Check if user is the document owner
owner_id = document.get('owner_id', document.get('owner_uid'))
if owner_id and getattr(user, 'uid', '') == owner_id:
# Document owners have additional permissions on their own documents
owner_permissions = [
'VIEW_DOCUMENT', 'EDIT_DOCUMENT', 'DELETE_DOCUMENT',
'CREATE_REVIEW', 'CREATE_APPROVAL'
]
for perm in permissions_to_check:
if perm in owner_permissions:
logger.debug(f"Permission {perm} granted as document owner")
return True
# Check roles for permissions
for role in user_roles:
if role in settings.ROLE_PERMISSIONS:
role_permissions = settings.ROLE_PERMISSIONS[role]
for perm in permissions_to_check:
if perm in role_permissions:
logger.debug(f"Document permission {perm} granted via role {role}")
return True
# Fall back to USER permissions
for perm in permissions_to_check:
if perm in settings.ROLE_PERMISSIONS['USER']:
return True
return False
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
user |
Any | - | positional_or_keyword |
document |
Dict[str, Any] | - | positional_or_keyword |
permission_type |
Union[str, List[str]] | - | positional_or_keyword |
Parameter Details
user: The user object to check permissions for. Expected to have optional 'roles' attribute (list of role strings) and 'uid' attribute (user identifier string). Can be None or any object type, though None will return False immediately.
document: A dictionary representing the document to check permissions against. Should contain 'owner_id' or 'owner_uid' key with the document owner's user identifier. Can be None or empty dict, which will return False immediately.
permission_type: Either a single permission string (e.g., 'VIEW_DOCUMENT') or a list of permission strings to check. When a list is provided, the function returns True if ANY of the permissions are granted. Common permission types include 'VIEW_DOCUMENT', 'EDIT_DOCUMENT', 'DELETE_DOCUMENT', 'CREATE_REVIEW', 'CREATE_APPROVAL'.
Return Value
Type: bool
Returns a boolean value: True if the user has at least one of the specified permissions for the document (through any of the checked mechanisms: admin role, ownership, role permissions, or default USER permissions), False otherwise. Also returns False if user or document parameters are None/empty.
Dependencies
loggingtypingCDocs.config
Required Imports
import logging
from typing import Dict, List, Any, Union
from CDocs.config import settings
Usage Example
from typing import Any, Dict, List
from CDocs.config import settings
import logging
# Setup logger
logger = logging.getLogger(__name__)
# Configure settings
settings.ROLE_PERMISSIONS = {
'USER': ['VIEW_DOCUMENT'],
'EDITOR': ['VIEW_DOCUMENT', 'EDIT_DOCUMENT'],
'ADMIN': ['VIEW_DOCUMENT', 'EDIT_DOCUMENT', 'DELETE_DOCUMENT', 'CREATE_REVIEW', 'CREATE_APPROVAL']
}
# Create mock user and document
class User:
def __init__(self, uid, roles):
self.uid = uid
self.roles = roles
user = User(uid='user123', roles=['EDITOR'])
document = {'owner_id': 'user456', 'title': 'My Document'}
# Check single permission
can_view = check_document_permission(user, document, 'VIEW_DOCUMENT')
print(f"Can view: {can_view}") # True
# Check multiple permissions (returns True if ANY match)
can_edit_or_delete = check_document_permission(user, document, ['EDIT_DOCUMENT', 'DELETE_DOCUMENT'])
print(f"Can edit or delete: {can_edit_or_delete}") # True (has EDIT_DOCUMENT)
# Document owner gets special permissions
owner = User(uid='user456', roles=['USER'])
can_owner_delete = check_document_permission(owner, document, 'DELETE_DOCUMENT')
print(f"Owner can delete: {can_owner_delete}") # True (owner privilege)
Best Practices
- Ensure settings.ROLE_PERMISSIONS is properly configured before calling this function, including at minimum 'USER' and 'ADMIN' roles
- Always include 'owner_id' or 'owner_uid' in document dictionaries to enable ownership-based permissions
- Use list of permissions when checking if user has ANY of multiple permissions; use separate calls for AND logic
- ADMIN role bypasses all other checks and grants all permissions - use this role carefully
- Document owners automatically receive VIEW_DOCUMENT, EDIT_DOCUMENT, DELETE_DOCUMENT, CREATE_REVIEW, and CREATE_APPROVAL permissions regardless of their roles
- The function gracefully handles None/missing user or document by returning False, but consider validating inputs before calling for better error messages
- Configure a logger in the module scope to enable debug logging for permission grant tracking
- When user has no roles attribute or empty roles list, the function falls back to checking USER role permissions
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function user_has_permission_for_resource 78.1% similar
-
function user_has_permission 75.9% similar
-
function get_document_access 66.5% similar
-
function get_document_permissions 65.9% similar
-
function set_document_permissions_in_filecloud 64.4% similar