Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1""" 

2.. module:: AdminModels 

3 :synopsis: Contains model of a user Record 

4 

5""" 

6import datetime 

7 

8from flask import current_app 

9from flask_login import AnonymousUserMixin 

10from flask_login import UserMixin 

11from init import db 

12from init import login_manager 

13from itsdangerous import URLSafeTimedSerializer 

14from sqlalchemy.ext.hybrid import hybrid_property 

15from werkzeug.security import check_password_hash 

16from werkzeug.security import generate_password_hash 

17 

18from shopyo.api.models import PkModel 

19 

20role_user_bridge = db.Table( 

21 "role_user_bridge", 

22 db.Column( 

23 "user_id", 

24 db.Integer(), 

25 db.ForeignKey("users.id", ondelete="CASCADE"), 

26 primary_key=True, 

27 ), 

28 db.Column( 

29 "role_id", 

30 db.Integer(), 

31 db.ForeignKey("roles.id", ondelete="CASCADE"), 

32 primary_key=True, 

33 ), 

34) 

35 

36 

37class AnonymousUser(AnonymousUserMixin): 

38 """Anonymous user class""" 

39 

40 def __init__(self): 

41 self.username = "guest" 

42 self.email = "<anonymous-user-no-email>" 

43 

44 @property 

45 def is_email_confirmed(self): 

46 is_disabled = False 

47 

48 if "EMAIL_CONFIRMATION_DISABLED" in current_app.config: 

49 is_disabled = current_app.config["EMAIL_CONFIRMATION_DISABLED"] 

50 

51 if is_disabled is not True: 

52 is_disabled = False 

53 

54 return is_disabled 

55 

56 @property 

57 def is_admin(self): 

58 return False 

59 

60 def __repr__(self): 

61 return f"<AnonymousUser {self.username}>" 

62 

63 

64login_manager.anonymous_user = AnonymousUser 

65 

66 

67class User(UserMixin, PkModel): 

68 """The user of the app""" 

69 

70 __tablename__ = "users" 

71 

72 username = db.Column(db.String(100), unique=True) 

73 _password = db.Column(db.String(128), nullable=False) 

74 first_name = db.Column(db.String(128)) 

75 last_name = db.Column(db.String(128)) 

76 is_admin = db.Column(db.Boolean, default=False) 

77 email = db.Column(db.String(120), unique=True, nullable=False) 

78 date_registered = db.Column( 

79 db.DateTime, nullable=False, default=datetime.datetime.now() 

80 ) 

81 is_email_confirmed = db.Column(db.Boolean(), nullable=False, default=False) 

82 email_confirm_date = db.Column(db.DateTime) 

83 

84 # A user can have many roles and a role can have many users 

85 roles = db.relationship( 

86 "Role", 

87 secondary=role_user_bridge, 

88 backref="users", 

89 ) 

90 

91 def __repr__(self): 

92 return f"<User-id: {self.id}, User-email: {self.email}>" 

93 

94 @hybrid_property 

95 def password(self): 

96 return self._password 

97 

98 @password.setter 

99 def password(self, plaintext): 

100 # the default hashing method is pbkdf2:sha256 

101 self._password = generate_password_hash(plaintext) 

102 

103 def check_password(self, password): 

104 return check_password_hash(self._password, password) 

105 

106 def generate_confirmation_token(self): 

107 serializer = URLSafeTimedSerializer(current_app.config["SECRET_KEY"]) 

108 return serializer.dumps(self.email, salt=current_app.config["PASSWORD_SALT"]) 

109 

110 def confirm_token(self, token, expiration=3600): 

111 serializer = URLSafeTimedSerializer(current_app.config["SECRET_KEY"]) 

112 email = False 

113 try: 

114 email = serializer.loads( 

115 token, 

116 salt=current_app.config["PASSWORD_SALT"], 

117 max_age=expiration, 

118 ) 

119 except Exception as e: 

120 print(f"\nShopyo-LOG, Error at confirm_token: {e}") 

121 return False 

122 

123 if email != self.email: 

124 return False 

125 

126 self.is_email_confirmed = True 

127 self.email_confirm_date = datetime.datetime.now() 

128 self.update() 

129 return True 

130 

131 

132@login_manager.user_loader 

133def load_user(user_id): 

134 return User.query.get(user_id) 

135 

136 

137login_manager.login_view = "auth.login" 

138 

139 

140class Role(PkModel): 

141 """A role for a user.""" 

142 

143 __tablename__ = "roles" 

144 name = db.Column(db.String(100), nullable=False) 

145 

146 def __repr__(self): 

147 return f"<Role-id: {self.id}, Role-name: {self.name}>"