PANDACUSHION 6 months ago
commit bc4cdf905f
  1. 88
      backend/blueprints/profile/__init__.py
  2. 0
      backend/blueprints/session/__init__.py
  3. 4
      backend/db/model.py
  4. 29
      backend/utils/auth.py

@ -3,8 +3,8 @@ from flask import Blueprint, request, jsonify, current_app
from werkzeug.utils import secure_filename
from datetime import datetime
from db.model import db
from db.model import User, UserRole # Adjust based on your model's location
from werkzeug.security import generate_password_hash
from db.model import User, UserRole, Session # Adjust based on your model's location
from werkzeug.security import generate_password_hash,check_password_hash
import uuid
import os
from config import *
@ -99,19 +99,73 @@ def register():
db.session.rollback()
return jsonify({"error": "Registration failed, please try again later."}), 500
# TODO: Implement laters
@profile.route('/update', methhods=['UPDATE', 'DELETE'])
def update():
if request.method == 'DELETE':
pass
if request.method == 'UPDATE':
pass
@profile.route('/me')
def my_profile():
pass
@profile.route('/info/<str:uuid>')
def profile_info(user_uuid):
return user_uuid
@profile.route('/login', methods=['POST'])
def login():
"""
Handle user login.
"""
data = request.form # Expecting JSON body
# Extract credentials from request
# username = data.get('username')
email = data.get('email')
password = data.get('password')
user_agent = request.headers.get('User-Agent', 'Unknown')
# Validate required fields
if not email or not password:
return jsonify({"error": "email and password are required"}), 400
# Find the user by username
# user = User.query.filter_by(username=username).first()
user = User.query.filter_by(email=email).first()
if not user:
return jsonify({"error": "Invalid email or password"}), 401
# Verify the password
if not check_password_hash(user.hash_password, password):
return jsonify({"error": "Invalid email or password"}), 401
# Create a new session
session_key = str(uuid.uuid4()) # Generate a unique session key
new_session = Session(
userID=user.id,
user=user, # Pass the user object here
key=session_key,
ua=user_agent,
creationDate=datetime.utcnow(),
lastUsed=datetime.utcnow(),
isValid=True
)
try:
db.session.add(new_session)
db.session.commit()
return jsonify({
"message": "Login successful",
"session_key": session_key,
"user_id": str(user.id)
}), 200
except Exception as e:
db.session.rollback()
return jsonify({"error": "Login failed, please try again later."}), 500
#Implement laters
# @profile.route('/update', methhods=['UPDATE', 'DELETE'])
# def update():
# if request.method == 'DELETE':
# pass
# if request.method == 'UPDATE':
# pass
# @profile.route('/me')
# def my_profile():
# pass
# @profile.route('/info/<str:uuid>')
# def profile_info(user_uuid):
# return user_uuid

@ -70,14 +70,14 @@ class Course(db.Model):
enrollments: Mapped[List["Enrollment"]] = relationship(back_populates="course", cascade="all, delete-orphan")
quizzes: Mapped[List['Quiz']] = relationship(back_populates="course", cascade="all, delete-orphan")
chats: Mapped[List["Chat"]] = relationship(back_populates="course", cascade="all, delete-orphan")
authorID: Mapped[uuid.UUID] = mapped_column(ForeignKey("user.id"))
author: Mapped["User"] = relationship(back_populates="publications")
description: Mapped[str] = mapped_column(String(1024), nullable=False, default='')
isActive: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
publishedStatus: Mapped[int] = mapped_column(SmallInteger, nullable=False, default=PublishedStatus.DRAFT)
creationDate: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now())
coverImage: Mapped[str] = mapped_column(String(256), nullable=False, default=DEFAULT_COURSE_COVER)
serverFilename: Mapped[str] = mapped_column(String(256), nullable=False, default='')
authorID: Mapped[uuid.UUID] = mapped_column(ForeignKey("user.id"))
author: Mapped["User"] = relationship(back_populates="publications")
class Enrollment(db.Model):

@ -1,13 +1,10 @@
from functools import wraps
from flask import request, jsonify
from flask import request, jsonify, g
from sqlalchemy import select, and_
from ..db.model import User, Session, db
from ..constants import UserRole
def requires_role(roles=None):
if roles is None:
roles = [UserRole.USER, UserRole.ADMIN]
roles = [int(r) for r in roles]
def auth_required():
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
@ -23,14 +20,26 @@ def requires_role(roles=None):
).scalar()
if not session:
return jsonify({'error': 'Invalid or expired session'}), 401
user = session.user
user: User = session.user
if not user:
return jsonify({'error': 'User not found for the Access token'}), 401
# If no roles specified, allow access
if not roles:
g.current_session = session
g.current_user = user
g.is_authed = True
return f(*args, **kwargs)
if user.role in roles:
return decorated_function
return decorator
def requires_role(roles=None):
if roles is None:
roles = [UserRole.USER, UserRole.ADMIN]
roles = [int(r) for r in roles]
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if g.get('is_authed', False) is False:
return jsonify({'error': 'Unauthorized'})
if g.current_user.role in roles:
return f(*args, **kwargs)
return jsonify({'error': 'Not authorized'}), 403
return decorated_function
return decorator
Loading…
Cancel
Save