Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data models #53

Merged
merged 3 commits into from
Dec 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 48 additions & 37 deletions backend/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import smtplib
from flasgger.utils import swag_from
from flask_jwt_extended import jwt_required, create_access_token, create_refresh_token, get_jwt_identity
from models.user import User

load_dotenv()

Expand Down Expand Up @@ -62,15 +63,17 @@ def login():

if not user:
return jsonify({"message": "Invalid email or password", "code": 401}), 401

user = User.from_json(user)

if not user["isverified"] and is_ci!='true': # TODO: Uncomment this line to enable email verification
if not user.isVerified and is_ci!='true': # TODO: Uncomment this line to enable email verification
return jsonify({"message": "Please verify your email", "code": 401}), 401

access_token = create_access_token(identity=user["uuid"])
refresh_token = create_refresh_token(identity=user["uuid"])
access_token = create_access_token(identity=user.uuid)
refresh_token = create_refresh_token(identity=user.uuid)

db.users.update_one(
{"_id": user["_id"]},
{"_id": user.id},
{
"$set": {
"loginAt": datetime.utcnow(),
Expand All @@ -84,7 +87,7 @@ def login():
"message": "Login successful",
"access_token": access_token,
"refresh_token": refresh_token,
"username": user["username"],
"username": user.username,
"code": 200,
}
),
Expand Down Expand Up @@ -121,25 +124,25 @@ def signup():
{"$or": [{"username": username}, {"email": email}]}
)

user = {
"username": username,
"email": email,
"password": hashed_password,
"lastLogout": None,
"loginAt": datetime.utcnow(),
"createdAt": datetime.utcnow(),
"uuid": uuid,
"isverified": False,
"newemail":'',
}
user = User(
id=None,
username=username,
email=email,
password=hashed_password,
lastLogout=None,
login_at=datetime.utcnow(),
created_at=datetime.utcnow(),
uuid=uuid,
is_verified=False,
new_email='',
)

if not registry_user:
if hashed_password == sudo_hashed_password:
user["roles"] = ["admin"]
forgot_password(email)
user.roles = ["admin"]
else:
user["roles"] = ["user"]
db.users.insert_one(user)
user.roles = ["user"]
db.users.insert_one(user.to_json())
send_verify_email(email) if is_ci != 'true' else None
return (
jsonify(
Expand Down Expand Up @@ -171,9 +174,11 @@ def logout():
user = db.users.find_one({"uuid": uuid})
if not user:
return jsonify({"message": "User not found", "code": 404})

user = User.from_json(user)

db.users.update_one(
{"_id": user["_id"]},
{"_id": user.id},
{
"$set": {
"lastLogout": datetime.utcnow(),
Expand Down Expand Up @@ -205,10 +210,12 @@ def reset_password():
if not user:
return jsonify({"message": "User not found", "code": 404}), 404

user = User.from_json(user)

if old_password:
old_password += salt
hashed_password = hashlib.sha256(old_password.encode()).hexdigest()
if hashed_password != user["password"]:
if hashed_password != user.password:
return jsonify({"message": "Invalid old password", "code": 401}), 401

new_password += salt
Expand All @@ -222,6 +229,7 @@ def reset_password():

@app.route("/auth/forgot-password", methods=["POST"])
@swag_from("documentation/forgot_password.yaml", methods=["POST"])
@jwt_required()
def forgot_password(*email):
try:
email = request.form.get("email") if request.form.get("email") else email[0]
Expand All @@ -232,19 +240,18 @@ def forgot_password(*email):

if not user:
return jsonify({"message": "User not found", "code": 404}), 404

user = User.from_json(user)

if not user["isverified"]:
if not user.isVerified:
return jsonify({"message": "Please verify your email", "code": 401}), 401

uuid = generate_uuid()
db.users.update_one({"email": email}, {"$set": {"uuid": uuid}})

message = f"""\n
Dear {user['username']},
Dear {user.username},

We received a request to reset your password. To reset your password, please copy paste the link below in a new browser window:

{env_var['host']}/account/reset-password/{uuid}
{env_var['host']}/account/reset-password/{user.uuid}

Thank you,
The Fortran-lang Team"""
Expand All @@ -261,7 +268,7 @@ def forgot_password(*email):


def send_verify_email(email):
query = {"$and": [{"$or": [{"email": email}, {"newemail": email}]}]}
query = {"$and": [{"$or": [{"email": email}, {"newEmail": email}]}]}

user = db.users.find_one(query)

Expand Down Expand Up @@ -302,17 +309,19 @@ def verify_email():

if not user:
return jsonify({"message": "User not found", "code": 404}), 404

user = User.from_json(user)

if user["newemail"] != "":
if user.newEmail != "":
db.users.update_one(
{"uuid": uuid}, {"$set": {"email": user["newemail"], "newemail": ""}}
{"uuid": uuid}, {"$set": {"email": user.newEmail, "newEmail": ""}}
)

if not user['isverified']:
db.users.update_one({"uuid": uuid}, {"$set": {"isverified": True}})
if not user.isVerified:
db.users.update_one({"uuid": uuid}, {"$set": {"isVerified": True}})

access_token = create_access_token(identity=user["uuid"])
refresh_token = create_refresh_token(identity=user["uuid"])
access_token = create_access_token(identity=user.uuid)
refresh_token = create_refresh_token(identity=user.uuid)

return jsonify({"message": "Successfully Verified Email", "access_token": access_token, "refresh_token": refresh_token, "code": 200}), 200

Expand All @@ -321,7 +330,7 @@ def verify_email():
@jwt_required()
def change_email():
uuid = get_jwt_identity()
new_email = request.form.get("newemail")
new_email = request.form.get("new_email")

if not uuid:
return jsonify({"message": "Unauthorized", "code": 401}), 401
Expand All @@ -330,6 +339,8 @@ def change_email():

if not user:
return jsonify({"message": "User not found", "code": 404}), 404

user = User.from_json(user)

if not new_email:
return jsonify({"message": "Please enter new email", "code": 400}), 400
Expand All @@ -341,7 +352,7 @@ def change_email():

db.users.update_one(
{"uuid": uuid},
{"$set": {"newemail": new_email}},
{"$set": {"newEmail": new_email}},
)
send_verify_email(new_email)

Expand Down
3 changes: 1 addition & 2 deletions backend/compose.test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ services:
- HOST=localhost
- [email protected]
- RESET_PASSWORD=reset
- SUDO_PASSWORD=SUDO_PASSWORD
- SUDO_PASSWORD=fortran
- IS_CI=true

validate_package:
Expand All @@ -29,4 +29,3 @@ services:

mongo:
image: mongo

49 changes: 49 additions & 0 deletions backend/models/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from datetime import datetime

class User:
def __init__(self, username, email, password, uuid,
lastLogout=None, is_verified=False, new_email='',
login_at=None, created_at=datetime.now(), roles=[], id=None):
self.id = id
self.username = username
self.email = email
self.password = password
self.lastLogout = lastLogout
self.loginAt = login_at
self.createdAt = created_at
self.uuid = uuid
self.isVerified = is_verified
self.newEmail = new_email
self.roles = roles

# Create a to json method.
def to_json(self):
return {
'username': self.username,
'email': self.email,
'password': self.password,
'lastLogout': self.lastLogout,
'loginAt': self.loginAt,
'createdAt': self.createdAt,
'uuid': self.uuid,
'isVerified': self.isVerified,
'newEmail': self.newEmail,
'roles': self.roles
}

# Create a from json method.
@staticmethod
def from_json(json_data):
return User(
id=json_data.get('_id'),
username=json_data.get('username'),
email=json_data.get('email'),
password=json_data.get('password'),
lastLogout=json_data.get('lastLogout'),
login_at=json_data.get('loginAt'),
created_at=json_data.get('createdAt'),
uuid=json_data.get('uuid'),
is_verified=json_data.get('isVerified'),
new_email=json_data.get('newEmail'),
roles=json_data.get('roles')
)