Compare commits

..

3 Commits

  1. 8
      backend/app.py
  2. 101
      backend/blueprints/profile/__init__.py
  3. 6
      backend/config.py
  4. 2
      backend/db/model.py
  5. BIN
      backend/uploads/1.jpg
  6. 6
      backend/utils/utils.py

@ -15,7 +15,11 @@ from utils.utils import random_string_generator, hash_string
from blueprints.profile import profile as profileBlueprint
app = Flask(__name__)
# Set configuration directly on the app instance
app.config['ALLOWED_EXTENSIONS'] = {'png', 'jpg', 'jpeg', 'gif'}
app.config["SQLALCHEMY_DATABASE_URI"] = DB_URI
db.init_app(app)
app.register_blueprint(profileBlueprint, url_prefix='/api')
@ -30,8 +34,8 @@ def seed_data():
try:
# Drop and recreate schema (only for testing, not recommended in production)
sql = text('DROP SCHEMA public CASCADE; CREATE SCHEMA public;')
with db.engine.connect() as connection:
connection.execute(sql)
db.session.execute(sql)
db.session.commit()
db.create_all() # Recreate tables
# Define roles and constants (ensure UserRole.USER is an integer or map it)

@ -1,7 +1,100 @@
from flask import Blueprint
from email.policy import default
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
import uuid
import os
from config import *
from utils.utils import password_check_sanity,is_valid_email,InsecurePasswordException
from sqlalchemy.exc import IntegrityError
profile = Blueprint('profile', __name__)
@profile.route('/profile')
def get_profile():
return "Profile Page"
# Function to check allowed file extensions
def allowed_file(filename):
"""Check if the uploaded file has an allowed extension."""
return '.' in filename and filename.rsplit('.', 1)[1].lower() in current_app.config['ALLOWED_EXTENSIONS']
@profile.route('/register', methods=['POST'])
def register():
"""Handle user registration."""
data = request.form
# Extract form data
email = data.get('email')
first_name = data.get('firstName')
last_name = data.get('lastName')
username = data.get('username')
password = data.get('password')
bio = data.get('bio', '')
dob = data.get('dob') # Optional field for date of birth
role = int(data.get('role', UserRole.USER.value)) # Default to 'USER' role if not provided
is_activated = True # New user will be activated initially
profile_picture = request.files.get('profile_picture')
# Validate email
if not is_valid_email(email):
return jsonify({"error": "Invalid email address"}), 400
# Validate password
try:
password_check_sanity(password)
except InsecurePasswordException as e:
return jsonify({"error": str(e)}), 400
# Validate required fields
if not all([email, first_name, last_name, username, password]):
return jsonify({"error": "Missing required fields"}), 400
# Check if the file is allowed and save it
if profile_picture and allowed_file(profile_picture.filename):
filename = secure_filename(profile_picture.filename)
# file_path = os.path.join(USER_UPLOADS_DIR, filename)
profile_picture.save(
os.path.join(USER_UPLOADS_DIR, filename)
)
else:
filename = DEFAULT_PROFILE_FILE # Use a default image if no file is uploaded
# Hash the password
hashed_password = generate_password_hash(password)
# Generate activation key (a UUID for example)
activation_key = str(uuid.uuid4())
# Create a new user
new_user = User(
email=email,
firstName=first_name,
lastName=last_name,
username=username,
hash_password=hashed_password,
bio=bio,
dob=datetime.fromisoformat(dob) if dob else datetime(2002, 1, 1),
pfpFilename=filename,
role=role,
isActivated=is_activated,
activationKey=activation_key,
sessions=[],
user_badges=[],
enrollments=[],
quizzes=[],
quiz_attempts=[],
chats=[],
notifications=[]
)
# Save the user to the database
try:
db.session.add(new_user)
db.session.commit()
return jsonify({"message": "User registered successfully."}), 201
except IntegrityError as e:
db.session.rollback()
return jsonify({"error": "User with this email or username already exists."}), 400
except Exception as e:
db.session.rollback()
return jsonify({"error": "Registration failed, please try again later."}), 500

@ -15,10 +15,12 @@ DB_NAME: str = "educonnect"
DEFAULT_PROFILE_FILE: str = "defaultUserBanner.png"
DEFAULT_COURSE_COVER: str = "defaultCourseCover.png"
DEFAULT_BADGE_ICON: str = "defaultBadgeIcon.png"
DISABLE_PASSWORD_SANITY_CHECKS: bool = True
DISABLE_PASSWORD_SANITY_CHECKS: bool = False
PROJECT_ROOT: os.path = os.path.dirname(os.path.abspath(__file__))
USER_UPLOADS_DIR: str = os.path.join(PROJECT_ROOT, "uploads")
DB_URI: str = f"{DB_ENGINE}://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}"
ACTIVATE_ACCOUNTS_ON_SIGNUP: bool = True
ACTIVATE_ACCOUNTS_ON_SIGNUP: bool = True
os.makedirs(USER_UPLOADS_DIR, exist_ok=True)

@ -19,7 +19,7 @@ class User(db.Model):
email: Mapped[str] = mapped_column(String(64), nullable=False, unique=True)
firstName: Mapped[str] = mapped_column(String(32), nullable=False)
lastName: Mapped[str] = mapped_column(String(32), nullable=False)
username: Mapped[str] = mapped_column(String(32), nullable=False)
username: Mapped[str] = mapped_column(String(32), nullable=False, unique=True)
hash_password: Mapped[str] = mapped_column(String(256), nullable=False)
activationKey: Mapped[str] = mapped_column(String(128), nullable=False)
sessions: Mapped[List["Session"]] = relationship(back_populates="user", cascade="all, delete-orphan")

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

@ -32,15 +32,15 @@ def is_valid_email(email):
return True
else:
return False
def password_check(passwd: str) -> bool:
def password_check_sanity(passwd: str) -> bool:
if DISABLE_PASSWORD_SANITY_CHECKS:
return True
special_symbol_pattern = r'[$@#%]'
upper_case_pattern = r'[A-Z]'
lower_case_pattern = r'[a-z]'
digit_pattern = r'[0-9]'
if len(passwd) < 6:
raise InsecurePasswordException('Password length should be at least 6 characters.')
elif len(passwd) > 20:

Loading…
Cancel
Save