Skip to content
Open
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
22 changes: 19 additions & 3 deletions App/controllers/auth.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
from flask_jwt_extended import create_access_token, jwt_required, JWTManager, get_jwt_identity, verify_jwt_in_request
from functools import wraps
from flask import jsonify
from flask_jwt_extended import create_access_token, current_user, jwt_required, JWTManager, get_jwt_identity, verify_jwt_in_request

from App.models import User
from App.database import db

def login(username, password):
def login(username, password, user_type):
result = db.session.execute(db.select(User).filter_by(username=username))
user = result.scalar_one_or_none()
if user and user.check_password(password):
if user and user.check_password(password) and user.user_type == user_type:
# Store ONLY the user id as a string in JWT 'sub'
return create_access_token(identity=str(user.userID))
return None

def login_required(required_class):
def decorator(f):
@wraps(f)
@jwt_required()
def decorated_function(*args, **kwargs):
#Check if current_user is an instance of the required class
if not isinstance(current_user, required_class):
return jsonify({
'error': 'Unauthorized access',
'message': f'User must be an instance of {required_class.__name__} to access this resource.'
}), 401
return f(*args, **kwargs)
return decorated_function
return decorator

def setup_jwt(app):
jwt = JWTManager(app)
Expand Down
33 changes: 30 additions & 3 deletions App/controllers/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,36 @@

def create_user(username, password):
newuser = User(username=username, password=password)
db.session.add(newuser)
db.session.commit()
return newuser
try:
db.session.add(newuser)
db.session.commit()
return newuser
except Exception as e:
db.session.rollback()
print(f"Error creating user: {e}")
return None

def create_staff(username, password):
newstaff = User(username=username, password=password)
try:
db.session.add(newstaff)
db.session.commit()
return newstaff
except Exception as e:
db.session.rollback()
print(f"Error creating staff user: {e}")
return None

def create_student(username, password):
newstudent = User(username=username, password=password)
try:
db.session.add(newstudent)
db.session.commit()
return newstudent
except Exception as e:
db.session.rollback()
print(f"Error creating student user: {e}")
return None

def get_user_by_username(username):
result = db.session.execute(db.select(User).filter_by(username=username))
Expand Down
60 changes: 60 additions & 0 deletions App/views/api_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from flask import Blueprint, jsonify, request
from App.controllers import (staff_log_hours,
request_confirmation,
view_leaderboard,
view_accolades,
staff_confirm_hours,
staff_reject_hours,
update_leaderboard)

listings_views = Blueprint('api_admin_views', __name__, template_folder='../templates')

@listings_views.route('/api/log_hours', methods=['POST'])
def api_staff_log_hours():
data = request.json
log = staff_log_hours(data['staff_username'], data['student_username'], data['hours'], data['activity'])
if not log:
return jsonify({'error': 'Failed to log hours'}), 400
return jsonify({'message': f"Logged {log.hoursLogged} hours for student ID {log.studentID} with log ID {log.logID}"}), 201

@listings_views.route('/api/request_confirmation', methods=['PUT'])
def api_request_confirmation():
data = request.json
log = request_confirmation(data['student_username'], data['activity_log_id'])
if not log:
return jsonify({'error': 'Failed to request confirmation'}), 400
return jsonify({'message': f"Requested confirmation for log ID {log.logID}"}), 200

@listings_views.route('/api/leaderboard', methods=['GET'])
def api_view_leaderboard():
leaderboard = view_leaderboard()
return jsonify(leaderboard), 200

@listings_views.route('/api/accolades/<student_username>', methods=['GET'])
def api_view_accolades(student_username):
accolades_data = view_accolades(student_username)
if not accolades_data:
return jsonify({'error': 'Student not found'}), 404
return jsonify(accolades_data), 200

@listings_views.route('/api/staff/confirm_hours', methods=['PUT'])
def api_staff_confirm_hours():
data = request.json
log = staff_confirm_hours(data['staff_username'], data['activity_log_id'])
if not log:
return jsonify({'error': 'Failed to confirm hours'}), 400
return jsonify({'message': f"Confirmed hours for log ID {log.logID}"}), 200

@listings_views.route('/api/staff/reject_hours', methods=['PUT'])
def api_staff_reject_hours():
data = request.json
log = staff_reject_hours(data['staff_username'], data['activity_log_id'])
if not log:
return jsonify({'error': 'Failed to reject hours'}), 400
return jsonify({'message': f"Rejected hours for log ID {log.logID}"}), 200

@listings_views.route('/api/update_leaderboard', methods=['PUT'])
def api_update_leaderboard():
update_leaderboard()
return jsonify({'message': 'Leaderboard updated successfully'}), 200

2 changes: 1 addition & 1 deletion App/views/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def identify_page():
@auth_views.route('/login', methods=['POST'])
def login_action():
data = request.form
token = login(data['username'], data['password'])
token = login(data['username'], data['password'], data.get('user_type'))
response = redirect(request.referrer)
if not token:
flash('Bad username or password given'), 401
Expand Down
22 changes: 20 additions & 2 deletions App/views/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
create_user,
get_all_users,
get_all_users_json,
jwt_required
jwt_required,
create_staff,
create_student
)

user_views = Blueprint('user_views', __name__, template_folder='../templates')
Expand Down Expand Up @@ -37,4 +39,20 @@ def create_user_endpoint():

@user_views.route('/static/users', methods=['GET'])
def static_user_page():
return send_from_directory('static', 'static-user.html')
return send_from_directory('static', 'static-user.html')

@user_views.route('/api/students', methods=['POST'])
def create_student_endpoint():
data = request.json
student = create_student(data['username'], data['password'])
if student:
return jsonify({'message': f"Student {student.username} successfully created with id {student.id}"})
return jsonify({'error': 'Failed to create student user'}), 400

@user_views.route('/api/staff', methods=['POST'])
def create_staff_endpoint():
data = request.json
staff = create_staff(data['username'], data['password'])
if staff:
return jsonify({'message': f"Staff {staff.username} successfully created with id {staff.id}"}), 201
return jsonify({'error': 'Failed to create staff user'}), 400
Loading