class FlaskUser
A Flask-Login compatible user wrapper class that adapts CDocs DocUser objects for authentication and authorization in Flask applications.
/tf/active/vicechatdev/CDocs/main_flask.py
106 - 144
moderate
Purpose
FlaskUser serves as an adapter between the CDocs DocUser model and Flask-Login's authentication system. It wraps DocUser instances to provide Flask-Login compatibility through UserMixin, manages user permissions based on roles, and provides convenient methods for checking user authorization. The class handles permission resolution by directly querying the settings module to avoid circular dependencies and provides role-based access control (RBAC) functionality.
Source Code
class FlaskUser(UserMixin):
"""Flask-Login user class that wraps CDocs DocUser."""
def __init__(self, doc_user: DocUser):
self.doc_user = doc_user
self.id = doc_user.uid
self.username = doc_user.username
self.email = doc_user.Mail if hasattr(doc_user, 'Mail') else getattr(doc_user, 'email', '')
self.roles = doc_user.roles or []
# Get permissions directly from settings instead of doc_user to avoid ROLE_PERMISSIONS issue
self.permissions = self._get_user_permissions()
def get_id(self):
return str(self.id)
def _get_user_permissions(self) -> set:
"""Get user permissions from settings.ROLE_PERMISSIONS directly."""
try:
# Use absolute import to avoid relative import issues
import CDocs.config.settings as settings_module
role_permissions = getattr(settings_module, 'ROLE_PERMISSIONS', {})
perm_set = set()
for role in self.roles:
role_perms = role_permissions.get(role.upper(), [])
perm_set.update(role_perms)
return perm_set
except Exception as e:
logger.error(f"Error getting permissions: {e}")
return set()
def has_permission(self, permission: str) -> bool:
"""Check if user has a specific permission."""
return permission in self.permissions
def has_role(self, role: str) -> bool:
"""Check if user has a specific role."""
return role.lower() in [r.lower() for r in self.roles]
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
bases |
UserMixin | - |
Parameter Details
doc_user: A DocUser instance from the CDocs system containing user information including uid, username, email/Mail, and roles. This is the core user object that gets wrapped for Flask-Login compatibility. Must have at minimum a 'uid', 'username', and 'roles' attribute.
Return Value
Instantiation returns a FlaskUser object that implements Flask-Login's UserMixin interface. The object provides user identity (id), authentication state, and authorization capabilities. Methods return: get_id() returns string representation of user ID, _get_user_permissions() returns a set of permission strings, has_permission() returns boolean indicating if user has specific permission, has_role() returns boolean indicating if user has specific role.
Class Interface
Methods
__init__(self, doc_user: DocUser)
Purpose: Initialize FlaskUser by wrapping a DocUser instance and extracting relevant attributes for Flask-Login compatibility
Parameters:
doc_user: DocUser instance containing user data including uid, username, email/Mail, and roles
Returns: None (constructor)
get_id(self) -> str
Purpose: Return string representation of user ID as required by Flask-Login for session management
Returns: String representation of the user's unique identifier (uid)
_get_user_permissions(self) -> set
Purpose: Resolve and aggregate all permissions for the user based on their roles by querying settings.ROLE_PERMISSIONS directly
Returns: Set of permission strings aggregated from all user roles, or empty set if error occurs
has_permission(self, permission: str) -> bool
Purpose: Check if the user has a specific permission string in their aggregated permissions set
Parameters:
permission: Permission string to check (e.g., 'document.edit', 'user.delete')
Returns: True if user has the specified permission, False otherwise
has_role(self, role: str) -> bool
Purpose: Check if the user has a specific role assigned, using case-insensitive comparison
Parameters:
role: Role name to check (case-insensitive, e.g., 'editor', 'ADMIN')
Returns: True if user has the specified role, False otherwise
Attributes
| Name | Type | Description | Scope |
|---|---|---|---|
doc_user |
DocUser | Reference to the original CDocs DocUser instance that this FlaskUser wraps | instance |
id |
str or int | User's unique identifier copied from doc_user.uid, used by Flask-Login for session management | instance |
username |
str | User's username copied from doc_user.username | instance |
email |
str | User's email address, extracted from doc_user.Mail or doc_user.email with fallback to empty string | instance |
roles |
List[str] | List of role names assigned to the user, copied from doc_user.roles or empty list if None | instance |
permissions |
set | Set of permission strings aggregated from all user roles via settings.ROLE_PERMISSIONS | instance |
Dependencies
flask_loginCDocs.config.settingsCDocs.models.user_extensions
Required Imports
from flask_login import UserMixin
from models.user_extensions import DocUser
import logging
Conditional/Optional Imports
These imports are only needed under specific conditions:
import CDocs.config.settings as settings_module
Condition: imported inside _get_user_permissions method to avoid circular import issues
Required (conditional)Usage Example
from models.user_extensions import DocUser
from flask_login import login_user
# Assume doc_user is retrieved from database
doc_user = DocUser(uid='user123', username='john_doe', Mail='john@example.com', roles=['editor', 'reviewer'])
# Create FlaskUser wrapper
flask_user = FlaskUser(doc_user)
# Use with Flask-Login
login_user(flask_user)
# Check permissions
if flask_user.has_permission('document.edit'):
print('User can edit documents')
# Check roles
if flask_user.has_role('editor'):
print('User is an editor')
# Get user ID for Flask-Login
user_id = flask_user.get_id() # Returns string representation of uid
# Access user attributes
print(f'Username: {flask_user.username}')
print(f'Email: {flask_user.email}')
print(f'Roles: {flask_user.roles}')
print(f'Permissions: {flask_user.permissions}')
Best Practices
- Always instantiate FlaskUser with a valid DocUser object that has uid, username, and roles attributes
- The class automatically resolves permissions from settings.ROLE_PERMISSIONS, ensure this configuration is properly set up before use
- Use has_permission() for fine-grained access control and has_role() for coarser role-based checks
- The get_id() method returns a string as required by Flask-Login, do not rely on integer comparison
- Email attribute handles both 'Mail' and 'email' attributes from DocUser for backward compatibility
- Permission resolution is case-insensitive for roles (converted to uppercase) but case-sensitive for permission strings
- The _get_user_permissions() method uses lazy import to avoid circular dependencies, do not move this import to module level
- Error handling in _get_user_permissions() returns empty set on failure, check logs for permission resolution errors
- FlaskUser instances are typically created during login process and stored in Flask-Login session
- Do not modify the doc_user, roles, or permissions attributes directly after instantiation as this may cause inconsistent state
- The class inherits from UserMixin which provides default implementations for is_authenticated, is_active, and is_anonymous properties
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
class DocUser 57.8% similar
-
function user_guide_v1 56.4% similar
-
function login_required 55.5% similar
-
class User 55.4% similar
-
function require_auth_v1 54.9% similar