1
1
from werkzeug .security import generate_password_hash , check_password_hash
2
2
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
3
3
from flask import current_app
4
- from flask_login import UserMixin
4
+ from flask_login import UserMixin , AnonymousUserMixin
5
5
from . import db , login_manager
6
6
7
7
8
+ class Permission :
9
+ FOLLOW = 1
10
+ COMMENT = 2
11
+ WRITE = 4
12
+ MODERATE = 8
13
+ ADMIN = 16
14
+
15
+
8
16
class Role (db .Model ):
9
17
__tablename__ = 'roles'
10
18
id = db .Column (db .Integer , primary_key = True )
11
19
name = db .Column (db .String (64 ), unique = True )
20
+ default = db .Column (db .Boolean , default = False , index = True )
21
+ permissions = db .Column (db .Integer )
12
22
users = db .relationship ('User' , backref = 'role' , lazy = 'dynamic' )
13
23
24
+ def __init__ (self , ** kwargs ):
25
+ super (Role , self ).__init__ (** kwargs )
26
+ if self .permissions is None :
27
+ self .permissions = 0
28
+
29
+ @staticmethod
30
+ def insert_roles ():
31
+ roles = {
32
+ 'User' : [Permission .FOLLOW , Permission .COMMENT , Permission .WRITE ],
33
+ 'Moderator' : [Permission .FOLLOW , Permission .COMMENT ,
34
+ Permission .WRITE , Permission .MODERATE ],
35
+ 'Administrator' : [Permission .FOLLOW , Permission .COMMENT ,
36
+ Permission .WRITE , Permission .MODERATE ,
37
+ Permission .ADMIN ],
38
+ }
39
+ default_role = 'User'
40
+ for r in roles :
41
+ role = Role .query .filter_by (name = r ).first ()
42
+ if role is None :
43
+ role = Role (name = r )
44
+ role .reset_permissions ()
45
+ for perm in roles [r ]:
46
+ role .add_permission (perm )
47
+ role .default = (role .name == default_role )
48
+ db .session .add (role )
49
+ db .session .commit ()
50
+
51
+ def add_permission (self , perm ):
52
+ if not self .has_permission (perm ):
53
+ self .permissions += perm
54
+
55
+ def remove_permission (self , perm ):
56
+ if self .has_permission (perm ):
57
+ self .permissions -= perm
58
+
59
+ def reset_permissions (self ):
60
+ self .permissions = 0
61
+
62
+ def has_permission (self , perm ):
63
+ return self .permissions & perm == perm
64
+
14
65
def __repr__ (self ):
15
66
return '<Role %r>' % self .name
16
67
@@ -24,6 +75,14 @@ class User(UserMixin, db.Model):
24
75
password_hash = db .Column (db .String (128 ))
25
76
confirmed = db .Column (db .Boolean , default = False )
26
77
78
+ def __init__ (self , ** kwargs ):
79
+ super (User , self ).__init__ (** kwargs )
80
+ if self .role is None :
81
+ if self .email == current_app .config ['FLASKY_ADMIN' ]:
82
+ self .role = Role .query .filter_by (name = 'Administrator' ).first ()
83
+ if self .role is None :
84
+ self .role = Role .query .filter_by (default = True ).first ()
85
+
27
86
@property
28
87
def password (self ):
29
88
raise AttributeError ('password is not a readable attribute' )
@@ -91,10 +150,26 @@ def change_email(self, token):
91
150
db .session .add (self )
92
151
return True
93
152
153
+ def can (self , perm ):
154
+ return self .role is not None and self .role .has_permission (perm )
155
+
156
+ def is_administrator (self ):
157
+ return self .can (Permission .ADMIN )
158
+
94
159
def __repr__ (self ):
95
160
return '<User %r>' % self .username
96
161
97
162
163
+ class AnonymousUser (AnonymousUserMixin ):
164
+ def can (self , permissions ):
165
+ return False
166
+
167
+ def is_administrator (self ):
168
+ return False
169
+
170
+ login_manager .anonymous_user = AnonymousUser
171
+
172
+
98
173
@login_manager .user_loader
99
174
def load_user (user_id ):
100
175
return User .query .get (int (user_id ))
0 commit comments