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

2Copyright 2020 Hermann Krumrey <hermann@krumreyh.com> 

3 

4This file is part of jerrycan. 

5 

6jerrycan is free software: you can redistribute it and/or modify 

7it under the terms of the GNU General Public License as published by 

8the Free Software Foundation, either version 3 of the License, or 

9(at your option) any later version. 

10 

11jerrycan is distributed in the hope that it will be useful, 

12but WITHOUT ANY WARRANTY; without even the implied warranty of 

13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

14GNU General Public License for more details. 

15 

16You should have received a copy of the GNU General Public License 

17along with jerrycan. If not, see <http://www.gnu.org/licenses/>. 

18LICENSE""" 

19 

20from typing import Optional, TYPE_CHECKING, List 

21from jerrycan.Config import Config 

22from jerrycan.base import db 

23from jerrycan.db.IDModelMixin import IDModelMixin 

24from puffotter.crypto import verify_password 

25if TYPE_CHECKING: # pragma: no cover 

26 from jerrycan.db.ApiKey import ApiKey 

27 from jerrycan.db.TelegramChatId import TelegramChatId 

28 

29 

30class User(IDModelMixin, db.Model): 

31 """ 

32 Model that describes the 'users' SQL table 

33 A User stores a user's information, including their email address, username 

34 and password hash 

35 """ 

36 

37 __tablename__ = "users" 

38 """ 

39 The name of the table 

40 """ 

41 

42 username: str = db.Column( 

43 db.String(Config.MAX_USERNAME_LENGTH), 

44 nullable=False, 

45 unique=True 

46 ) 

47 """ 

48 The user's username 

49 """ 

50 

51 email: str = db.Column(db.String(150), nullable=False, unique=True) 

52 """ 

53 The user's email address 

54 """ 

55 

56 password_hash: str = db.Column(db.String(255), nullable=False) 

57 """ 

58 The user's hashed password, salted and hashed. 

59 """ 

60 

61 confirmed: bool = db.Column(db.Boolean, nullable=False, default=False) 

62 """ 

63 The account's confirmation status. Logins should be impossible as long as 

64 this value is False. 

65 """ 

66 

67 confirmation_hash: str = db.Column(db.String(255), nullable=False) 

68 """ 

69 The account's confirmation hash. This is the hash of a key emailed to 

70 the user. Only once the user follows the link in the email containing the 

71 key will their account be activated 

72 """ 

73 

74 telegram_chat_id: Optional["TelegramChatId"] = db.relationship( 

75 "TelegramChatId", 

76 uselist=False, 

77 back_populates="user", 

78 cascade="all, delete" 

79 ) 

80 """ 

81 Telegram chat ID for the user if set up 

82 """ 

83 

84 api_keys: List["ApiKey"] = db.relationship( 

85 "ApiKey", back_populates="user", cascade="all, delete" 

86 ) 

87 """ 

88 API keys for this user 

89 """ 

90 

91 @property 

92 def is_authenticated(self) -> bool: 

93 """ 

94 Property required by flask-login 

95 :return: True if the user is confirmed, False otherwise 

96 """ 

97 return True 

98 

99 @property 

100 def is_anonymous(self) -> bool: 

101 """ 

102 Property required by flask-login 

103 :return: True if the user is not confirmed, False otherwise 

104 """ 

105 return not self.is_authenticated # pragma: no cover 

106 

107 @property 

108 def is_active(self) -> bool: 

109 """ 

110 Property required by flask-login 

111 :return: True 

112 """ 

113 return self.confirmed 

114 

115 def get_id(self) -> str: 

116 """ 

117 Method required by flask-login 

118 :return: The user's ID as a unicode string 

119 """ 

120 return str(self.id) 

121 

122 def verify_password(self, password: str) -> bool: 

123 """ 

124 Verifies a password against the password hash 

125 :param password: The password to check 

126 :return: True if the password matches, False otherwise 

127 """ 

128 return verify_password(password, self.password_hash) 

129 

130 def verify_confirmation(self, confirmation_key: str) -> bool: 

131 """ 

132 Verifies a confirmation key against the confirmation hash 

133 :param confirmation_key: The key to check 

134 :return: True if the key matches, False otherwise 

135 """ 

136 return verify_password(confirmation_key, self.confirmation_hash)