# Coverage for modules/box__default/auth/models.py : 57%

## 78 statements

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"""

6 import datetime

7

8 from flask import current_app

9 from flask_login import AnonymousUserMixin

10 from flask_login import UserMixin

11 from init import db

12 from init import login_manager

13 from itsdangerous import URLSafeTimedSerializer

14 from sqlalchemy.ext.hybrid import hybrid_property

15 from werkzeug.security import check_password_hash

16 from werkzeug.security import generate_password_hash

17

18 from shopyo.api.models import PkModel

19

20 role_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

37 class 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

64 login_manager.anonymous_user = AnonymousUser

65

66

67 class 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

133 def load_user(user_id):

134 return User.query.get(user_id)

135

136

137 login_manager.login_view = "auth.login"

138

139

140 class 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}>"