0
# Role-Based Access Control
1
2
Authorization decorators, role management, and permission-based access control for implementing fine-grained security policies in Flask applications.
3
4
## Capabilities
5
6
### Role-Based Authorization Decorators
7
8
Decorators for controlling access based on user roles with flexible matching strategies.
9
10
```python { .api }
11
def roles_required(*roles):
12
"""
13
Decorator requiring user to have ALL specified roles.
14
15
Parameters:
16
- roles: Variable number of role names (strings) that user must have
17
18
Returns:
19
Decorator function that enforces role requirements
20
21
Raises:
22
Unauthorized exception if user lacks required roles
23
"""
24
25
def roles_accepted(*roles):
26
"""
27
Decorator requiring user to have ANY of the specified roles.
28
29
Parameters:
30
- roles: Variable number of role names (strings), user needs at least one
31
32
Returns:
33
Decorator function that accepts any matching role
34
35
Raises:
36
Unauthorized exception if user has none of the accepted roles
37
"""
38
```
39
40
### Permission-Based Authorization Decorators
41
42
Decorators for fine-grained access control using permission-based authorization.
43
44
```python { .api }
45
def permissions_required(*permissions):
46
"""
47
Decorator requiring user to have ALL specified permissions.
48
49
Parameters:
50
- permissions: Variable number of permission names that user must have
51
52
Returns:
53
Decorator function that enforces permission requirements
54
55
Raises:
56
Unauthorized exception if user lacks required permissions
57
"""
58
59
def permissions_accepted(*permissions):
60
"""
61
Decorator requiring user to have ANY of the specified permissions.
62
63
Parameters:
64
- permissions: Variable number of permission names, user needs at least one
65
66
Returns:
67
Decorator function that accepts any matching permission
68
69
Raises:
70
Unauthorized exception if user has none of the accepted permissions
71
"""
72
```
73
74
### Role Management Functions
75
76
Functions for programmatically managing user roles and role assignments.
77
78
```python { .api }
79
def create_role(name, description=None, **kwargs):
80
"""
81
Create a new role in the datastore.
82
83
Parameters:
84
- name: Role name (must be unique)
85
- description: Optional role description
86
- kwargs: Additional role attributes
87
88
Returns:
89
Created role object
90
"""
91
92
def find_role(role):
93
"""
94
Find role by name or role object.
95
96
Parameters:
97
- role: Role name (string) or role object
98
99
Returns:
100
Role object if found, None otherwise
101
"""
102
103
def add_role_to_user(user, role):
104
"""
105
Add role to user.
106
107
Parameters:
108
- user: User object
109
- role: Role name (string) or role object
110
111
Returns:
112
True if role added successfully, False if user already had role
113
"""
114
115
def remove_role_from_user(user, role):
116
"""
117
Remove role from user.
118
119
Parameters:
120
- user: User object
121
- role: Role name (string) or role object
122
123
Returns:
124
True if role removed successfully, False if user didn't have role
125
"""
126
```
127
128
### Permission Management Functions
129
130
Functions for managing permissions within roles and checking user permissions.
131
132
```python { .api }
133
def create_permission(name, description=None, **kwargs):
134
"""
135
Create a new permission.
136
137
Parameters:
138
- name: Permission name (must be unique)
139
- description: Optional permission description
140
- kwargs: Additional permission attributes
141
142
Returns:
143
Created permission object
144
"""
145
146
def add_permission_to_role(role, permission):
147
"""
148
Add permission to role.
149
150
Parameters:
151
- role: Role object or role name
152
- permission: Permission object or permission name
153
154
Returns:
155
True if permission added successfully
156
"""
157
158
def remove_permission_from_role(role, permission):
159
"""
160
Remove permission from role.
161
162
Parameters:
163
- role: Role object or role name
164
- permission: Permission object or permission name
165
166
Returns:
167
True if permission removed successfully
168
"""
169
```
170
171
### User Role and Permission Checking
172
173
Methods available on user objects for checking roles and permissions.
174
175
```python { .api }
176
# UserMixin methods for role/permission checking
177
class UserMixin:
178
def has_role(self, role) -> bool:
179
"""
180
Check if user has specified role.
181
182
Parameters:
183
- role: Role name (string) or role object
184
185
Returns:
186
True if user has the role, False otherwise
187
"""
188
189
def has_permission(self, permission) -> bool:
190
"""
191
Check if user has specified permission.
192
193
Parameters:
194
- permission: Permission name (string) or permission object
195
196
Returns:
197
True if user has the permission, False otherwise
198
"""
199
```
200
201
## Usage Examples
202
203
### Basic Role Protection
204
205
```python
206
from flask_security import roles_required, roles_accepted
207
208
@app.route('/admin')
209
@roles_required('admin')
210
def admin_panel():
211
return "Admin Panel - Only admins can access"
212
213
@app.route('/moderator')
214
@roles_accepted('admin', 'moderator')
215
def moderator_panel():
216
return "Moderator Panel - Admins or moderators can access"
217
218
@app.route('/super-admin')
219
@roles_required('admin', 'super-user')
220
def super_admin():
221
return "Super Admin - Must have BOTH admin AND super-user roles"
222
```
223
224
### Permission-Based Access Control
225
226
```python
227
from flask_security import permissions_required, permissions_accepted
228
229
@app.route('/create-post')
230
@permissions_required('create-content')
231
def create_post():
232
return "Create Post - Requires create-content permission"
233
234
@app.route('/moderate')
235
@permissions_accepted('moderate-content', 'admin-content')
236
def moderate_content():
237
return "Moderate - Requires moderate-content OR admin-content permission"
238
239
@app.route('/publish')
240
@permissions_required('create-content', 'publish-content')
241
def publish_content():
242
return "Publish - Requires BOTH create-content AND publish-content"
243
```
244
245
### Programmatic Role Management
246
247
```python
248
from flask_security import current_user, add_role_to_user, remove_role_from_user
249
250
@app.route('/promote-user/<int:user_id>')
251
@roles_required('admin')
252
def promote_user(user_id):
253
user = User.query.get(user_id)
254
if user:
255
add_role_to_user(user, 'moderator')
256
db.session.commit()
257
return f"User {user.email} promoted to moderator"
258
return "User not found", 404
259
260
@app.route('/demote-user/<int:user_id>')
261
@roles_required('admin')
262
def demote_user(user_id):
263
user = User.query.get(user_id)
264
if user:
265
remove_role_from_user(user, 'moderator')
266
db.session.commit()
267
return f"User {user.email} demoted from moderator"
268
return "User not found", 404
269
```
270
271
### Checking Roles and Permissions in Templates
272
273
```python
274
# In your view functions
275
@app.route('/dashboard')
276
@login_required
277
def dashboard():
278
return render_template('dashboard.html')
279
```
280
281
```html
282
<!-- In templates (dashboard.html) -->
283
{% if current_user.has_role('admin') %}
284
<a href="/admin">Admin Panel</a>
285
{% endif %}
286
287
{% if current_user.has_permission('create-content') %}
288
<a href="/create-post">Create Post</a>
289
{% endif %}
290
291
{% if current_user.has_role('admin') or current_user.has_role('moderator') %}
292
<a href="/moderate">Moderate Content</a>
293
{% endif %}
294
```
295
296
### Complex Authorization Logic
297
298
```python
299
from flask_security import current_user
300
301
@app.route('/edit-post/<int:post_id>')
302
@login_required
303
def edit_post(post_id):
304
post = Post.query.get_or_404(post_id)
305
306
# Allow post owner, admins, or users with edit-any-post permission
307
if (post.author_id == current_user.id or
308
current_user.has_role('admin') or
309
current_user.has_permission('edit-any-post')):
310
return render_template('edit_post.html', post=post)
311
else:
312
abort(403) # Forbidden
313
314
@app.route('/view-sensitive-data')
315
@login_required
316
def view_sensitive_data():
317
# Multiple role/permission checks
318
if not (current_user.has_role('data-analyst') and
319
current_user.has_permission('view-sensitive-data')):
320
abort(403)
321
322
return render_template('sensitive_data.html')
323
```
324
325
### Role and Permission Initialization
326
327
```python
328
from flask_security import create_role, create_user
329
330
# Initialize roles and permissions
331
def create_initial_data():
332
# Create roles
333
admin_role = create_role(name='admin', description='Administrator')
334
moderator_role = create_role(name='moderator', description='Content Moderator')
335
user_role = create_role(name='user', description='Regular User')
336
337
# Create permissions
338
create_content_perm = create_permission(name='create-content')
339
moderate_content_perm = create_permission(name='moderate-content')
340
admin_content_perm = create_permission(name='admin-content')
341
342
# Assign permissions to roles
343
add_permission_to_role(admin_role, admin_content_perm)
344
add_permission_to_role(admin_role, moderate_content_perm)
345
add_permission_to_role(admin_role, create_content_perm)
346
347
add_permission_to_role(moderator_role, moderate_content_perm)
348
add_permission_to_role(moderator_role, create_content_perm)
349
350
add_permission_to_role(user_role, create_content_perm)
351
352
# Create admin user
353
admin_user = create_user(
354
email='admin@example.com',
355
password='secure-password',
356
active=True,
357
roles=[admin_role]
358
)
359
360
db.session.commit()
361
```
362
363
## Role Hierarchy and Inheritance
364
365
Flask-Security supports complex role relationships through the permission system:
366
367
```python
368
# Example role hierarchy setup
369
def setup_role_hierarchy():
370
# Create hierarchical roles
371
super_admin = create_role('super-admin', 'Super Administrator')
372
admin = create_role('admin', 'Administrator')
373
manager = create_role('manager', 'Manager')
374
employee = create_role('employee', 'Employee')
375
376
# Create granular permissions
377
perms = [
378
create_permission('read-users'),
379
create_permission('write-users'),
380
create_permission('delete-users'),
381
create_permission('read-content'),
382
create_permission('write-content'),
383
create_permission('delete-content'),
384
]
385
386
# Assign permissions hierarchically
387
# Super admin gets all permissions
388
for perm in perms:
389
add_permission_to_role(super_admin, perm)
390
391
# Admin gets user and content management
392
for perm in perms[:5]: # All except delete-content
393
add_permission_to_role(admin, perm)
394
395
# Manager gets content management
396
add_permission_to_role(manager, perms[3]) # read-content
397
add_permission_to_role(manager, perms[4]) # write-content
398
399
# Employee gets basic read access
400
add_permission_to_role(employee, perms[3]) # read-content
401
```