generated from Code-Institute-Org/gitpod-full-template
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathclasses.py
229 lines (171 loc) · 6.13 KB
/
classes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
"""
Classes - Users Sub-module
=============
Contains the User class for Session Management and User Management,
such as password validation and database reading and writing.
Classes: User
"""
import re
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import login_user, UserMixin
from wyspa.factory.initialisation import mongo
# Create the required User class for Flask-Login
class User(UserMixin):
"""
A class to represent a User. This class utilises the Flask-Login
UserMixin for the required pre-defined methods for interaction
with Flask-Login. Additional methods have been added for User Management,
such as password validation and database reading and writing, and get_id
has been over-ridden to work with MongoDB.
Attributes
-----------
username : str
The user's username, which is stored in the session.
Methods
-------
get_id()
Returns the logged in user's username.
delete_user(username)
Deletes user and all user's Wyspas from database.
verify_password_format(user_password)
Verifies the password matches the required regex format.
verify_password_match(user password, password_confirmation)
Compares the passwords provided.
obtain_user(username)
Queries the database for a given username.
register_user(username, user_password)
Saves a users to the database.
verify_login(username, user_password)
Checks a users password against the hash and logs them in.
"""
def __init__(self, username):
"""
Constructs all the necessary attributes for the Wyspa object.
Attributes
-----------
username : str
The user's username, which is stored in the session.
"""
self.username = username
# Over-ride UserMixin "get_id" method
def get_id(self):
"""Returns the logged in user's username.
This method over-rides the UserMixin method,
which is incompatable with MongoDB.
https://stackoverflow.com/questions/54992412/flask-login-usermixin-class-with-a-mongodb
Returns
-----------
username : str
The user's username, which is stored in the session.
"""
return self.username
@staticmethod
def delete_user(username):
"""Deletes user and all user's Wyspas from database.
Removes the user's entry from the User database, along
with all Wyspa's from the Messages database where the user
is the author.
Parameters
----------
username : str
The user's username, which is stored in the session.
Returns
-------
None
"""
mongo.db.users.delete_one({"username": username})
mongo.db.messages.delete_many({"author": username})
@staticmethod
def verify_password_format(user_password):
"""Verifies the password matches the required regex format.
Parameters
----------
user_password : str
The user's registration password.
Returns
-------
re.Match object (if successful)
None (if unsuccessful)
"""
return re.search("^(?=.*[^a-zA-Z]).{6,20}$", user_password)
@staticmethod
def verify_password_match(user_password, password_confirmation):
"""Compares the passwords provided.
Parameters
----------
user_password : str
The user's registration password.
password_confirmation : str
The user's password confirmation.
Returns
-------
True : bool (if successful)
False : bool (if unsuccessful)
"""
return user_password == password_confirmation
@staticmethod
def obtain_user(username):
"""Queries the database for a given username.
Parameters
----------
username : str
The username a user has provided to log in.
Returns
-------
Dict (if successful)
Dict format: {"username" : "password"}
Empty list (if unsuccessful)
"""
return mongo.db.users.find_one(
{"username": username})
@staticmethod
def register_user(username, user_password):
"""Saves a users to the database.
Constructs a registration dictionary that is compatible
with the MongoDB document format for the User collection,
using the username and a hashed password, and writes this
to the User database. The user is then logged in via Flask-Login.
Parameters
----------
username : str
The username a user has provided to register.
user_password : str
The user's password to be hashed.
Returns
-------
None
"""
# Create a registration dictionary
registration = {
"username": username,
"password": generate_password_hash(user_password)
}
# Update DB with registration dictionary
mongo.db.users.insert_one(registration)
# Log in new user
login_user(User(username))
@staticmethod
def verify_login(username, user_password):
"""Checks a users password against the hash and logs them in.
This method calls the User.obtain_user() method to query
the User database, and checks the user's password against
the hashed password in the database. If successful, the
user is logged in via Flask-Login.
Parameters
----------
username : str
The username a user has provided to log-in.
user_password : str
The user's password to be verified against the hash.
Returns
-------
True : bool (if successful)
False : bool (if unsuccessful)
"""
login_check = User.obtain_user(username)
# Check username exists and password matches
if login_check and check_password_hash(
login_check["password"], user_password):
login_user(User(username))
return True
return False