From 4169e265ab810c26e0578a4a26e3c336b5777c85 Mon Sep 17 00:00:00 2001 From: Casu Al Snek Date: Mon, 13 Jan 2025 00:09:48 +0545 Subject: [PATCH] Ft: Allow admin mods from profile API --- backend/blueprints/course/__init__.py | 80 +++++++++++++++++++++++++- backend/blueprints/profile/__init__.py | 25 +++++++- backend/db/model.py | 2 +- 3 files changed, 104 insertions(+), 3 deletions(-) diff --git a/backend/blueprints/course/__init__.py b/backend/blueprints/course/__init__.py index 8c5da3c..b88f1e8 100644 --- a/backend/blueprints/course/__init__.py +++ b/backend/blueprints/course/__init__.py @@ -129,7 +129,7 @@ def create_course(): if course_uploaded_pdf is not None: pdf_file_name: str = random_string_generator(32) +"."+ course_uploaded_pdf.filename.split('.')[-1] course_uploaded_pdf.save(os.path.join(USER_UPLOADS_DIR, pdf_file_name)) - published_status: PublishedStatus = PublishedStatus.DRAFT + published_status: PublishedStatus = PublishedStatus.PENDING try: course_name: str = form_data['course_name'] except KeyError: @@ -358,3 +358,81 @@ def update_category(): selected_category.isActive = bool(int(form_data.get('isActive'))) db.session.commit() return jsonify({'message': 'Category updated'}), 200 + +@course.route('/enrolled') +@auth_required() +def enrolled_courses(): + enrollments: Course = db.session.execute( + select(Enrollment).where( + and_(Enrollment.userID == g.current_user.id, Course.publishedStatus == int(PublishedStatus.APPROVED)) + ) + ).scalars() + enrolled_list: list[dict] = [] + for enroll_row in enrollments: + item = enroll_row.course + enrolled_list.append( + { + 'id': enroll_row.id, + 'course_id': enroll_row.courseID, + 'lastActivity': enroll_row.lastActivity, + 'currentPage': enroll_row.currentPage, + 'maxPage': enroll_row.maxPage, + 'joinedDate': enroll_row.joinedDate, + 'userID': enroll_row.userID, + 'name': item.name, + 'description': item.description, + 'isActive': item.isActive, + 'creationDate': item.creationDate, + 'coverImage': url_for('send_file', filename=item.coverImage), + 'totalEnrolled': item.totalEnrolled, + 'author': { + 'id': item.author.id, + 'firstName': item.author.firstName, + 'lastName': item.author.lastName, + 'username': item.author.username, + 'bio': item.author.bio, + 'lastOnline': item.author.lastOnline, + 'pfpFilename': url_for('send_file', filename=item.author.pfpFilename) + }, + 'category': { + 'id': item.categoryID, + 'name': item.category.name, + 'description': item.category.description + } + }) + + return jsonify(enrolled_list), 200 + +@course.route('/myCourses') +@auth_required() +def enrolled_courses(): + courses: Course = db.session.execute(select(Course).where(Course.authorID == g.current_user.id) + ).scalars() + course_list: list[dict] = [] + for item in courses: + course_list.append( + { + 'id': item.id, + 'name': item.name, + 'description': item.description, + 'isActive': item.isActive, + 'publishedStatus': item.publishedStatus, + 'creationDate': item.creationDate, + 'coverImage': url_for('send_file', filename=item.coverImage), + 'totalEnrolled': item.totalEnrolled, + 'author': { + 'id': item.author.id, + 'firstName': item.author.firstName, + 'lastName': item.author.lastName, + 'username': item.author.username, + 'bio': item.author.bio, + 'lastOnline': item.author.lastOnline, + 'pfpFilename': url_for('send_file', filename=item.author.pfpFilename) + }, + 'category': { + 'id': item.categoryID, + 'name': item.category.name, + 'description': item.category.description + } + }) + return jsonify(course_list), 200 \ No newline at end of file diff --git a/backend/blueprints/profile/__init__.py b/backend/blueprints/profile/__init__.py index bb2eb83..08502ef 100644 --- a/backend/blueprints/profile/__init__.py +++ b/backend/blueprints/profile/__init__.py @@ -1,5 +1,6 @@ from email.policy import default from flask import Blueprint, request, jsonify, current_app, g,url_for +from sqlalchemy import select from werkzeug.utils import secure_filename from datetime import datetime from utils.auth import auth_required, requires_role @@ -109,6 +110,14 @@ def manage_profile(): Handle GET and PUT requests for the logged-in user's profile. """ current_user: User = g.current_user + if g.current_user.role == int(UserRole.ADMIN) and request.form.get('user_id'): + target_user: User = db.session.execute( + select(User).where(User.id == uuid.uuid(request.form.get('user_id'))) + ).scalar() + if not target_user: + return jsonify({'message': 'User not found'}), 404 + else: + current_user = target_user if request.method == 'GET': profile_picture = url_for('send_file', filename=current_user.pfpFilename, _external=True) try: @@ -138,6 +147,7 @@ def manage_profile(): username = request.form.get('username') dob = request.form.get('dob') bio = request.form.get('bio') + is_activated = request.form.get('isActivated') if first_name: current_user.firstName = first_name if last_name: @@ -148,6 +158,8 @@ def manage_profile(): current_user.dob = dob # Ensure the date format is validated if bio: current_user.bio = bio + if is_activated: + current_user.isActivated = bool(int(is_activated)) db.session.commit() return jsonify({"message": "Profile updated successfully."}), 200 except IntegrityError: @@ -211,6 +223,17 @@ def change_password(): """ user = g.current_user data = request.form + + if g.current_user.role == int(UserRole.ADMIN) and request.form.get('user_id'): + new_password = data.get('new_password') + target_user: User = db.session.execute( + select(User).where(User.id == uuid.uuid(request.form.get('user_id'))) + ).scalar() + if not target_user: + return jsonify({'message': 'User not found'}), 404 + target_user.hash_password = generate_password_hash(new_password) + db.session.commit() + return jsonify({'message': 'Password changed successfully'}), 200 # Validate input data current_password = data.get('current_password') new_password = data.get('new_password') @@ -232,4 +255,4 @@ def change_password(): # Update the user's password user.hash_password = generate_password_hash(new_password) db.session.commit() - return jsonify({"message": "Password updated successfully"}), 200 \ No newline at end of file + return jsonify({"message": "Password updated successfully"}), 200 diff --git a/backend/db/model.py b/backend/db/model.py index a33b7dc..b08bb5e 100644 --- a/backend/db/model.py +++ b/backend/db/model.py @@ -77,7 +77,7 @@ class Course(db.Model): totalPages: Mapped[int] = mapped_column(Integer, nullable=False, default=1) totalEnrolled: Mapped[int] = mapped_column(Integer, nullable=False, default=0) isActive: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True) - publishedStatus: Mapped[int] = mapped_column(SmallInteger, nullable=False, default=PublishedStatus.DRAFT) + publishedStatus: Mapped[int] = mapped_column(SmallInteger, nullable=False, default=int(PublishedStatus.PENDING)) 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='')