Quickly add security features to your Flask application.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Authorization decorators, role management, and permission-based access control for implementing fine-grained security policies in Flask applications.
Decorators for controlling access based on user roles with flexible matching strategies.
def roles_required(*roles):
"""
Decorator requiring user to have ALL specified roles.
Parameters:
- roles: Variable number of role names (strings) that user must have
Returns:
Decorator function that enforces role requirements
Raises:
Unauthorized exception if user lacks required roles
"""
def roles_accepted(*roles):
"""
Decorator requiring user to have ANY of the specified roles.
Parameters:
- roles: Variable number of role names (strings), user needs at least one
Returns:
Decorator function that accepts any matching role
Raises:
Unauthorized exception if user has none of the accepted roles
"""Decorators for fine-grained access control using permission-based authorization.
def permissions_required(*permissions):
"""
Decorator requiring user to have ALL specified permissions.
Parameters:
- permissions: Variable number of permission names that user must have
Returns:
Decorator function that enforces permission requirements
Raises:
Unauthorized exception if user lacks required permissions
"""
def permissions_accepted(*permissions):
"""
Decorator requiring user to have ANY of the specified permissions.
Parameters:
- permissions: Variable number of permission names, user needs at least one
Returns:
Decorator function that accepts any matching permission
Raises:
Unauthorized exception if user has none of the accepted permissions
"""Functions for programmatically managing user roles and role assignments.
def create_role(name, description=None, **kwargs):
"""
Create a new role in the datastore.
Parameters:
- name: Role name (must be unique)
- description: Optional role description
- kwargs: Additional role attributes
Returns:
Created role object
"""
def find_role(role):
"""
Find role by name or role object.
Parameters:
- role: Role name (string) or role object
Returns:
Role object if found, None otherwise
"""
def add_role_to_user(user, role):
"""
Add role to user.
Parameters:
- user: User object
- role: Role name (string) or role object
Returns:
True if role added successfully, False if user already had role
"""
def remove_role_from_user(user, role):
"""
Remove role from user.
Parameters:
- user: User object
- role: Role name (string) or role object
Returns:
True if role removed successfully, False if user didn't have role
"""Functions for managing permissions within roles and checking user permissions.
def create_permission(name, description=None, **kwargs):
"""
Create a new permission.
Parameters:
- name: Permission name (must be unique)
- description: Optional permission description
- kwargs: Additional permission attributes
Returns:
Created permission object
"""
def add_permission_to_role(role, permission):
"""
Add permission to role.
Parameters:
- role: Role object or role name
- permission: Permission object or permission name
Returns:
True if permission added successfully
"""
def remove_permission_from_role(role, permission):
"""
Remove permission from role.
Parameters:
- role: Role object or role name
- permission: Permission object or permission name
Returns:
True if permission removed successfully
"""Methods available on user objects for checking roles and permissions.
# UserMixin methods for role/permission checking
class UserMixin:
def has_role(self, role) -> bool:
"""
Check if user has specified role.
Parameters:
- role: Role name (string) or role object
Returns:
True if user has the role, False otherwise
"""
def has_permission(self, permission) -> bool:
"""
Check if user has specified permission.
Parameters:
- permission: Permission name (string) or permission object
Returns:
True if user has the permission, False otherwise
"""from flask_security import roles_required, roles_accepted
@app.route('/admin')
@roles_required('admin')
def admin_panel():
return "Admin Panel - Only admins can access"
@app.route('/moderator')
@roles_accepted('admin', 'moderator')
def moderator_panel():
return "Moderator Panel - Admins or moderators can access"
@app.route('/super-admin')
@roles_required('admin', 'super-user')
def super_admin():
return "Super Admin - Must have BOTH admin AND super-user roles"from flask_security import permissions_required, permissions_accepted
@app.route('/create-post')
@permissions_required('create-content')
def create_post():
return "Create Post - Requires create-content permission"
@app.route('/moderate')
@permissions_accepted('moderate-content', 'admin-content')
def moderate_content():
return "Moderate - Requires moderate-content OR admin-content permission"
@app.route('/publish')
@permissions_required('create-content', 'publish-content')
def publish_content():
return "Publish - Requires BOTH create-content AND publish-content"from flask_security import current_user, add_role_to_user, remove_role_from_user
@app.route('/promote-user/<int:user_id>')
@roles_required('admin')
def promote_user(user_id):
user = User.query.get(user_id)
if user:
add_role_to_user(user, 'moderator')
db.session.commit()
return f"User {user.email} promoted to moderator"
return "User not found", 404
@app.route('/demote-user/<int:user_id>')
@roles_required('admin')
def demote_user(user_id):
user = User.query.get(user_id)
if user:
remove_role_from_user(user, 'moderator')
db.session.commit()
return f"User {user.email} demoted from moderator"
return "User not found", 404# In your view functions
@app.route('/dashboard')
@login_required
def dashboard():
return render_template('dashboard.html')<!-- In templates (dashboard.html) -->
{% if current_user.has_role('admin') %}
<a href="/admin">Admin Panel</a>
{% endif %}
{% if current_user.has_permission('create-content') %}
<a href="/create-post">Create Post</a>
{% endif %}
{% if current_user.has_role('admin') or current_user.has_role('moderator') %}
<a href="/moderate">Moderate Content</a>
{% endif %}from flask_security import current_user
@app.route('/edit-post/<int:post_id>')
@login_required
def edit_post(post_id):
post = Post.query.get_or_404(post_id)
# Allow post owner, admins, or users with edit-any-post permission
if (post.author_id == current_user.id or
current_user.has_role('admin') or
current_user.has_permission('edit-any-post')):
return render_template('edit_post.html', post=post)
else:
abort(403) # Forbidden
@app.route('/view-sensitive-data')
@login_required
def view_sensitive_data():
# Multiple role/permission checks
if not (current_user.has_role('data-analyst') and
current_user.has_permission('view-sensitive-data')):
abort(403)
return render_template('sensitive_data.html')from flask_security import create_role, create_user
# Initialize roles and permissions
def create_initial_data():
# Create roles
admin_role = create_role(name='admin', description='Administrator')
moderator_role = create_role(name='moderator', description='Content Moderator')
user_role = create_role(name='user', description='Regular User')
# Create permissions
create_content_perm = create_permission(name='create-content')
moderate_content_perm = create_permission(name='moderate-content')
admin_content_perm = create_permission(name='admin-content')
# Assign permissions to roles
add_permission_to_role(admin_role, admin_content_perm)
add_permission_to_role(admin_role, moderate_content_perm)
add_permission_to_role(admin_role, create_content_perm)
add_permission_to_role(moderator_role, moderate_content_perm)
add_permission_to_role(moderator_role, create_content_perm)
add_permission_to_role(user_role, create_content_perm)
# Create admin user
admin_user = create_user(
email='admin@example.com',
password='secure-password',
active=True,
roles=[admin_role]
)
db.session.commit()Flask-Security supports complex role relationships through the permission system:
# Example role hierarchy setup
def setup_role_hierarchy():
# Create hierarchical roles
super_admin = create_role('super-admin', 'Super Administrator')
admin = create_role('admin', 'Administrator')
manager = create_role('manager', 'Manager')
employee = create_role('employee', 'Employee')
# Create granular permissions
perms = [
create_permission('read-users'),
create_permission('write-users'),
create_permission('delete-users'),
create_permission('read-content'),
create_permission('write-content'),
create_permission('delete-content'),
]
# Assign permissions hierarchically
# Super admin gets all permissions
for perm in perms:
add_permission_to_role(super_admin, perm)
# Admin gets user and content management
for perm in perms[:5]: # All except delete-content
add_permission_to_role(admin, perm)
# Manager gets content management
add_permission_to_role(manager, perms[3]) # read-content
add_permission_to_role(manager, perms[4]) # write-content
# Employee gets basic read access
add_permission_to_role(employee, perms[3]) # read-content