Compare commits
278
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70671adac8 | ||
|
|
6be20568a8 | ||
|
|
7ff786c6e2 | ||
|
|
f5061c9ec1 | ||
|
|
ad33251e9d | ||
|
|
df33b3889a | ||
|
|
37b8b3e0a1 | ||
|
|
5878001862 | ||
|
|
05740d5aa5 | ||
|
|
7c1370e95c | ||
|
|
96d8e48f3a | ||
|
|
bab3674d31 | ||
|
|
32d6268c95 | ||
|
|
4f79ca6ec4 | ||
|
|
9088e35157 | ||
|
|
8c9f0ef5b3 | ||
|
|
206f50b775 | ||
|
|
075094b935 | ||
|
|
325ced0cd2 | ||
|
|
c23e5aa68a | ||
|
|
130cfcf41f | ||
|
|
27a62b5611 | ||
|
|
ab4fb55aa1 | ||
|
|
a6a85492de | ||
|
|
bb661a2523 | ||
|
|
480c7f46b2 | ||
|
|
8d1893be01 | ||
|
|
c07012c007 | ||
|
|
800112a006 | ||
|
|
e69f3ee5e8 | ||
|
|
2f6208369b | ||
|
|
8c46a16fce | ||
|
|
4c8e3f8c53 | ||
|
|
ff4bf5c475 | ||
|
|
314ede846b | ||
|
|
4ea675c938 | ||
|
|
4ae180ac82 | ||
|
|
077afe42ee | ||
|
|
d01352658c | ||
|
|
53d95add63 | ||
|
|
1d42d94ef2 | ||
|
|
166e98a40e | ||
|
|
babea6871a | ||
|
|
326e529ffb | ||
|
|
bfe1f33019 | ||
|
|
31b3d5b170 | ||
|
|
d62fe1daec | ||
|
|
b5d5f7f0e1 | ||
|
|
0f1237b6fb | ||
|
|
ede2ff5355 | ||
|
|
aa9a0272d0 | ||
|
|
9e22aa5f98 | ||
|
|
89fdbd9607 | ||
|
|
ebf6005335 | ||
|
|
a8d7d35c12 | ||
|
|
67b424da4d | ||
|
|
5f58c1096c | ||
|
|
8c96bbe1e3 | ||
|
|
792053e886 | ||
|
|
3e07f2f763 | ||
|
|
730d2c1397 | ||
|
|
27ca68bad1 | ||
|
|
f5c964951d | ||
|
|
e0284ddd17 | ||
|
|
16ae0bcebf | ||
|
|
d405e57803 | ||
|
|
e177a1351d | ||
|
|
eca9e789c1 | ||
|
|
fc8982baa7 | ||
|
|
5c471179b8 | ||
|
|
38806309c3 | ||
|
|
45a1d3f704 | ||
|
|
97b2986da1 | ||
|
|
84d91fff82 | ||
|
|
cb7ecd9c04 | ||
|
|
d6fd252f48 | ||
|
|
d041079900 | ||
|
|
15c3198b33 | ||
|
|
c9350eac60 | ||
|
|
b6a203a76c | ||
|
|
ca3cb323de | ||
|
|
4ff56b83a3 | ||
|
|
a3d6a37ebc | ||
|
|
6fdbad0c09 | ||
|
|
e534c4423e | ||
|
|
a6ec5eb5cc | ||
|
|
80f48ca964 | ||
|
|
f1934f6131 | ||
|
|
6a09576762 | ||
|
|
f4fef63475 | ||
|
|
05fe5f711e | ||
|
|
0be4bbb62d | ||
|
|
598eb12970 | ||
|
|
f08f872d0f | ||
|
|
46050dda85 | ||
|
|
686a456dbb | ||
|
|
6c886af6d1 | ||
|
|
150c592e64 | ||
|
|
b136b7235e | ||
|
|
32a8fc9e40 | ||
|
|
9a9f72dd21 | ||
|
|
a6b4bccd51 | ||
|
|
fa4111424a | ||
|
|
1af2385b1c | ||
|
|
8a52c1e4ec | ||
|
|
c7b009ed3d | ||
|
|
95299d42db | ||
|
|
e26fa2348f | ||
|
|
4ea85bcdc8 | ||
|
|
41a32e98c5 | ||
|
|
f21daa2f11 | ||
|
|
83c34416ce | ||
|
|
c4451d565d | ||
|
|
6fdc9b9ae6 | ||
|
|
25e0f26b95 | ||
|
|
62bb44b0f9 | ||
|
|
3db7c41ae4 | ||
|
|
c1d4dd2b90 | ||
|
|
66eb06cfa0 | ||
|
|
0b20b0f9c6 | ||
|
|
a0a418080b | ||
|
|
0ac73d8a94 | ||
|
|
8ce575bdd6 | ||
|
|
2e0d3cf7a3 | ||
|
|
c6a4fd5045 | ||
|
|
231ca2b824 | ||
|
|
61c5043f5d | ||
|
|
d2560b3ec8 | ||
|
|
37c3cd1a8a | ||
|
|
bece36013c | ||
|
|
6fb91e1b77 | ||
|
|
e5c5c32ff0 | ||
|
|
ab1ad4b00d | ||
|
|
3ed1a8fb1b | ||
|
|
c22c1e2f9b | ||
|
|
b8c78fa10a | ||
|
|
48745ee21b | ||
|
|
e20cc1359b | ||
|
|
03e1010253 | ||
|
|
ad032efe4e | ||
|
|
ed32aa1fc7 | ||
|
|
02b892eb6d | ||
|
|
72493d622e | ||
|
|
2e96349c15 | ||
|
|
bfe74e24a6 | ||
|
|
f2700ecd90 | ||
|
|
2a692e48b7 | ||
|
|
eccf0820f2 | ||
|
|
285b3c5241 | ||
|
|
b80a274626 | ||
|
|
11f2f523d8 | ||
|
|
2b57979466 | ||
|
|
c9366e405e | ||
|
|
6fe251909b | ||
|
|
7323bd2885 | ||
|
|
fbf8b12c8b | ||
|
|
3b4cd4b9a4 | ||
|
|
beae39d628 | ||
|
|
1a1ea9d76b | ||
|
|
691c2e4bae | ||
|
|
1f8e4508c3 | ||
|
|
e25d37fecb | ||
|
|
0bb18ce75f | ||
|
|
f57229f470 | ||
|
|
452c214c15 | ||
|
|
821c0b115a | ||
|
|
c319a3307c | ||
|
|
12b5f53096 | ||
|
|
2f77e86450 | ||
|
|
05fecdf293 | ||
|
|
438d53abc5 | ||
|
|
1dac71da45 | ||
|
|
d9145b15f7 | ||
|
|
524b2d8f9f | ||
|
|
12fa8b9275 | ||
|
|
a00edb86c0 | ||
|
|
f6763b85fd | ||
|
|
896afa7b2d | ||
|
|
be78862c72 | ||
|
|
360e3c5930 | ||
|
|
1312729836 | ||
|
|
6cd30c8c0f | ||
|
|
b21a83e28b | ||
|
|
8d7796ab9f | ||
|
|
63180c6488 | ||
|
|
79afc8e1c5 | ||
|
|
ecefc1900d | ||
|
|
b6f1ee0c8b | ||
|
|
c0cdc5ca50 | ||
|
|
e8ca0768ab | ||
|
|
e735553cb3 | ||
|
|
1387ebd49e | ||
|
|
52908a548c | ||
|
|
ead24674b6 | ||
|
|
d2a100d827 | ||
|
|
79d7a6fec8 | ||
|
|
239c29b1f5 | ||
|
|
1962c46b11 | ||
|
|
7940e7c46f | ||
|
|
a45684c0e4 | ||
|
|
bcbb38d0d9 | ||
|
|
3630dc1c14 | ||
|
|
2d599629f4 | ||
|
|
2ce03b3e2b | ||
|
|
f222b289c0 | ||
|
|
b83b07b8d8 | ||
|
|
f83f173233 | ||
|
|
1ffd20b68f | ||
|
|
bb7b93fc8c | ||
|
|
ccc94b5bbe | ||
|
|
c4582503b9 | ||
|
|
95419c7467 | ||
|
|
5b7e5e72d8 | ||
|
|
8ac49e4db3 | ||
|
|
44985084d2 | ||
|
|
88e86c59ba | ||
|
|
e8081a9b30 | ||
|
|
dc1951745b | ||
|
|
ace56eed24 | ||
|
|
89eb4ed854 | ||
|
|
d80cd40207 | ||
|
|
ba997ddf5b | ||
|
|
89bf76759b | ||
|
|
7e3a8a5aaa | ||
|
|
ee53c7acda | ||
|
|
73845486b3 | ||
|
|
b110b880b2 | ||
|
|
6add11e846 | ||
|
|
197bbe1150 | ||
|
|
e0f898ef72 | ||
|
|
c9c991f898 | ||
|
|
5740c9ce16 | ||
|
|
bd55d19248 | ||
|
|
b05a5c70a3 | ||
|
|
0eaf842ca8 | ||
|
|
cabc57ea90 | ||
|
|
29730e9987 | ||
|
|
4c004085b1 | ||
|
|
3e013a8e8c | ||
|
|
76eaef6f05 | ||
|
|
41b54f3264 | ||
|
|
1dfd06a331 | ||
|
|
e7ca0671f3 | ||
|
|
e587a6d515 | ||
|
|
bbbdcee77a | ||
|
|
4acb3157f1 | ||
|
|
86b8390acb | ||
|
|
d439ec2dd8 | ||
|
|
46ad21e9c1 | ||
|
|
2cab80bda4 | ||
|
|
de0db1b6af | ||
|
|
2463375398 | ||
|
|
5dc64507a7 | ||
|
|
09aa30694e | ||
|
|
ffbdd91d9b | ||
|
|
10c75845a9 | ||
|
|
61d2cc3a6d | ||
|
|
1e953fe21c | ||
|
|
94541d1813 | ||
|
|
979fee8253 | ||
|
|
b24f340d91 | ||
|
|
1088dc76e4 | ||
|
|
37ea8d0191 | ||
|
|
c5ca461e3d | ||
|
|
6469274f14 | ||
|
|
a763ba212a | ||
|
|
43acda716b | ||
|
|
e5234122c9 | ||
|
|
6ff5d159cb | ||
|
|
d1d9b1bd1f | ||
|
|
81d95bb4b3 | ||
|
|
f361d25728 | ||
|
|
0ab06af8be | ||
|
|
dd085582cc | ||
|
|
95abec2b4b | ||
|
|
3bde83cf92 | ||
|
|
5b2e6dda67 | ||
|
|
39e80c64fa |
@@ -1,207 +0,0 @@
|
|||||||
from flask import flash, make_response, Response, session
|
|
||||||
from flask.helpers import url_for
|
|
||||||
from flask.json import jsonify
|
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
|
||||||
from werkzeug.utils import redirect
|
|
||||||
from flask_mail import Message
|
|
||||||
import secrets
|
|
||||||
|
|
||||||
from common.security import encrypt, decrypt
|
|
||||||
from common.security.database import decrypt_find_one, encrypted_update
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
|
|
||||||
class User:
|
|
||||||
|
|
||||||
def __init__(self, _id=None, username=None, password=None, email=None, remember=False):
|
|
||||||
self._id = _id
|
|
||||||
self.username = username
|
|
||||||
self.email = email
|
|
||||||
self.password = password
|
|
||||||
self.remember = remember
|
|
||||||
|
|
||||||
def start_session(self, resp:Response):
|
|
||||||
from main import app
|
|
||||||
resp.set_cookie(
|
|
||||||
key = '_id',
|
|
||||||
value = self._id,
|
|
||||||
max_age = timedelta(days=14) if self.remember else None,
|
|
||||||
path = '/',
|
|
||||||
expires = datetime.utcnow() + timedelta(days=14) if self.remember else None,
|
|
||||||
domain = f'.{app.config["SERVER_NAME"]}',
|
|
||||||
secure = True
|
|
||||||
)
|
|
||||||
if self.remember:
|
|
||||||
resp.set_cookie (
|
|
||||||
key = 'remember',
|
|
||||||
value = 'True',
|
|
||||||
max_age = timedelta(days=14),
|
|
||||||
path = '/',
|
|
||||||
expires = datetime.utcnow() + timedelta(days=14),
|
|
||||||
domain = f'.{app.config["SERVER_NAME"]}',
|
|
||||||
secure = True
|
|
||||||
)
|
|
||||||
|
|
||||||
def register(self):
|
|
||||||
from main import db
|
|
||||||
from ..views import get_id_from_cookie
|
|
||||||
user = {
|
|
||||||
'_id': self._id,
|
|
||||||
'email': encrypt(self.email),
|
|
||||||
'password': generate_password_hash(self.password, method='sha256'),
|
|
||||||
'username': encrypt(self.username)
|
|
||||||
}
|
|
||||||
if decrypt_find_one(db.users, { 'username': self.username }):
|
|
||||||
return jsonify({ 'error': f'Username {self.username} is not available.' }), 400
|
|
||||||
if db.users.insert_one(user):
|
|
||||||
flash(f'User {self.username} has been created successfully. You may now use it to log in and administer the tests.', 'success')
|
|
||||||
resp = make_response(jsonify(user), 200)
|
|
||||||
if not get_id_from_cookie:
|
|
||||||
self.start_session(resp)
|
|
||||||
return resp
|
|
||||||
return jsonify({ 'error': f'Registration failed. An error occurred.' }), 400
|
|
||||||
|
|
||||||
def login(self):
|
|
||||||
from main import db
|
|
||||||
user = decrypt_find_one( db.users, { 'username': self.username })
|
|
||||||
if not user:
|
|
||||||
return jsonify({ 'error': f'Username {self.username} does not exist.' }), 401
|
|
||||||
if not check_password_hash( user['password'], self.password ):
|
|
||||||
return jsonify({ 'error': f'The password you entered is incorrect.' }), 401
|
|
||||||
response = {
|
|
||||||
'success': f'Successfully logged in user {self.username}.'
|
|
||||||
}
|
|
||||||
if 'prev_page' in session:
|
|
||||||
response['redirect_to'] = session['prev_page']
|
|
||||||
session.pop('prev_page')
|
|
||||||
resp = make_response(jsonify(response), 200)
|
|
||||||
self._id = user['_id']
|
|
||||||
self.start_session(resp)
|
|
||||||
return resp
|
|
||||||
|
|
||||||
def logout(self):
|
|
||||||
resp = make_response(redirect(url_for('admin_auth.login')))
|
|
||||||
from main import app
|
|
||||||
resp.set_cookie(
|
|
||||||
key = '_id',
|
|
||||||
value = '',
|
|
||||||
max_age = timedelta(days=-1),
|
|
||||||
path = '/',
|
|
||||||
expires= datetime.utcnow() + timedelta(days=-1),
|
|
||||||
domain = f'.{app.config["SERVER_NAME"]}',
|
|
||||||
secure = True
|
|
||||||
)
|
|
||||||
resp.set_cookie (
|
|
||||||
key = 'cookie_consent',
|
|
||||||
value = 'True',
|
|
||||||
max_age = None,
|
|
||||||
path = '/',
|
|
||||||
expires = None,
|
|
||||||
domain = f'.{app.config["SERVER_NAME"]}',
|
|
||||||
secure = True
|
|
||||||
)
|
|
||||||
resp.set_cookie (
|
|
||||||
key = 'remember',
|
|
||||||
value = 'True',
|
|
||||||
max_age = timedelta(days=-1),
|
|
||||||
path = '/',
|
|
||||||
expires = datetime.utcnow() + timedelta(days=-1),
|
|
||||||
domain = f'.{app.config["SERVER_NAME"]}',
|
|
||||||
secure = True
|
|
||||||
)
|
|
||||||
flash('You have been logged out. All cookies pertaining to your account have been deleted. Have a nice day.', 'alert')
|
|
||||||
return resp
|
|
||||||
|
|
||||||
def reset_password(self):
|
|
||||||
from main import db, mail
|
|
||||||
user = decrypt_find_one(db.users, { 'username': self.username })
|
|
||||||
if not user:
|
|
||||||
return jsonify({ 'error': f'Username {self.username} does not exist.' }), 401
|
|
||||||
if not user['email'] == self.email:
|
|
||||||
return jsonify({ 'error': f'The email address {self.email} does not match the user account {self.username}.' }), 401
|
|
||||||
new_password = secrets.token_hex(12)
|
|
||||||
reset_token = secrets.token_urlsafe(16)
|
|
||||||
verification_token = secrets.token_urlsafe(16)
|
|
||||||
user['password'] = generate_password_hash(new_password, method='sha256')
|
|
||||||
if encrypted_update(db.users, { 'username': self.username }, { '$set': {'password': user['password'], 'reset_token': reset_token, 'verification_token': verification_token } } ):
|
|
||||||
flash(f'Your password has been reset. Instructions to recover your account have been sent to {self.email}. Please be sure to check your spam folder in case you have not received the email.', 'alert')
|
|
||||||
email = Message(
|
|
||||||
subject = 'RefTest | Password Reset',
|
|
||||||
recipients = [self.email],
|
|
||||||
body = f"""
|
|
||||||
Hello {user['username']}, \n\n
|
|
||||||
This email was generated because we received a request to reset the password for your administrator account for the SKA RefTest app.\n\n
|
|
||||||
If you did not make this request, please ignore this email.\n\n
|
|
||||||
If you did make this request, then you have two options to recover your account.\n\n
|
|
||||||
For the time being, your password has been reset to the following:\n\n
|
|
||||||
{new_password}\n\n
|
|
||||||
You may use this to log back in to your account, and subsequently change your password to something more suitable.\n\n
|
|
||||||
Alternatively, you may visit the following private link using your unique token to override your password. Copy and paste the following link in a web browser. Please note that this token is only valid once:\n\n
|
|
||||||
{url_for('admin_auth.reset_gateway', token1 = reset_token, token2 = verification_token, _external = True)}\n\n
|
|
||||||
Have a nice day.
|
|
||||||
""",
|
|
||||||
html = f"""
|
|
||||||
<p>Hello {user['username']},</p>
|
|
||||||
<p>This email was generated because we received a request to reset the password for your administrator account for the SKA RefTest app. </p>
|
|
||||||
<p>If you did not make this request, please ignore this email.</p>
|
|
||||||
<p>If you did make this request, then you have two options to recover your account.</p>
|
|
||||||
<p>For the time being, your password has been reset to the following:</p>
|
|
||||||
<strong>{new_password}</strong>
|
|
||||||
<p>You may use this to log back in to your account, and subsequently change your password to something more suitable.</p>
|
|
||||||
<p>Alternatively, you may visit the following private link using your unique token to override your password. Click on the following link, or copy and paste it into a browser. <strong>Please note that this token is only valid once</strong>:</p>
|
|
||||||
<p><a href='{url_for('admin_auth.reset_gateway', token1 = reset_token, token2 = verification_token, _external = True)}'>{url_for('admin_auth.reset_gateway', token1 = reset_token, token2 = verification_token, _external = True)}</a></p>
|
|
||||||
<p>Have a nice day.</p>
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
mail.send(email)
|
|
||||||
return jsonify({ 'success': 'Password reset request has been processed.'}), 200
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
from main import db
|
|
||||||
from ..views import get_id_from_cookie
|
|
||||||
retrieved_user = decrypt_find_one(db.users, { '_id': self._id })
|
|
||||||
if not retrieved_user:
|
|
||||||
return jsonify({ 'error': f'User {retrieved_user["username"]} does not exist.' }), 401
|
|
||||||
user = {}
|
|
||||||
updated = []
|
|
||||||
if not self.email == '' and self.email is not None:
|
|
||||||
user['email'] = self.email
|
|
||||||
updated.append('email')
|
|
||||||
if not self.password == '' and self.password is not None:
|
|
||||||
user['password'] = generate_password_hash(self.password, method='sha256')
|
|
||||||
updated.append('password')
|
|
||||||
output = ''
|
|
||||||
if len(updated) == 0:
|
|
||||||
flash(f'There were no changes requested for your account.', 'alert'), 200
|
|
||||||
return jsonify({'success': 'There were no changes requested for your account.'}), 200
|
|
||||||
elif len(updated) == 1:
|
|
||||||
output = updated[0]
|
|
||||||
elif len(updated) == 2:
|
|
||||||
output = ' and '.join(updated)
|
|
||||||
elif len(updated) > 2:
|
|
||||||
output = updated[0]
|
|
||||||
for index in range(1,len(updated)):
|
|
||||||
if index < len(updated) - 2:
|
|
||||||
output = ', '.join([output, updated[index]])
|
|
||||||
elif index == len(updated) - 2:
|
|
||||||
output = ', and '.join([output, updated[index]])
|
|
||||||
else:
|
|
||||||
output = ''.join([output, updated[index]])
|
|
||||||
encrypted_update(db.users, {'_id': self._id}, { '$set': user })
|
|
||||||
if self._id == get_id_from_cookie():
|
|
||||||
_output = 'Your '
|
|
||||||
elif retrieved_user['username'][-1] == 's':
|
|
||||||
_output = '’'.join([retrieved_user['username'], ''])
|
|
||||||
else:
|
|
||||||
_output = '’'.join([retrieved_user['username'], 's'])
|
|
||||||
_output = f'{_output} {output} {"has" if len(updated) == 1 else "have"} been updated.'
|
|
||||||
flash(_output)
|
|
||||||
return jsonify({'success': _output}), 200
|
|
||||||
|
|
||||||
def delete(self):
|
|
||||||
from main import db
|
|
||||||
retrieved_user = decrypt_find_one(db.users, { '_id': self._id })
|
|
||||||
if not retrieved_user:
|
|
||||||
return jsonify({ 'error': f'User does not exist.' }), 401
|
|
||||||
db.users.find_one_and_delete({'_id': self._id})
|
|
||||||
flash(f'User {retrieved_user["username"]} has been deleted.')
|
|
||||||
return jsonify({'success': f'User {retrieved_user["username"]} has been deleted.'}), 200
|
|
||||||
Reference in New Issue
Block a user