"""The signed-in user's own profile.""" from flask import flash, redirect, render_template, request, url_for from flask_babel import gettext as _ from flask_login import current_user, login_required from marshmallow import ValidationError from app.extensions import db, hash_password from app.logging_config import log_auth_event from app.models import ( CoachAvailability, Coach, Contract, ESPORT_GAMES, GAME_PLATFORMS, Player, User, ) from app.routes.users._shared import ( flash_validation_errors, form_payload, update_user_gamertags, ) from app.routes.users.blueprint import users_bp from app.validators import EditProfileSchema @users_bp.route('/profile') @login_required def profile(): """View the current user's profile.""" contracts = None if isinstance(current_user, Player): contracts = ( Contract.query.filter_by( player_id=current_user.id, ) .order_by(Contract.uploaded_at.desc()) .all() ) existing_availability = None if isinstance(current_user, Coach): existing_availability = CoachAvailability.query.filter_by( coach_id=current_user.id, ).all() return render_template( 'pages/profile.html', user=current_user, contracts=contracts, existing_availability=existing_availability, ) @users_bp.route('/profile/edit', methods=['GET', 'POST']) @login_required def edit_profile(): """Edit the current user's profile.""" if request.method == 'POST': try: validated = EditProfileSchema().load(form_payload()) except ValidationError as err: flash_validation_errors(err) return render_template( 'pages/edit_profile.html', user=current_user, esport_games=ESPORT_GAMES, game_platforms=GAME_PLATFORMS, user_gamertags=current_user.get_gamertags(), ) username = validated['username'] full_name = validated['full_name'] email = validated['email'] phone = validated.get('phone') selected_games = validated.get('games', []) discord_username = validated.get('discord_username') discord_user_id = validated.get('discord_user_id') league_os_profile = validated.get('league_os_profile') if username != current_user.username and User.query.filter_by(username=username).first(): flash(_('Username already taken.'), 'danger') return render_template( 'pages/edit_profile.html', user=current_user, esport_games=ESPORT_GAMES, game_platforms=GAME_PLATFORMS, user_gamertags=current_user.get_gamertags(), ) if email != current_user.email and User.query.filter_by(email=email).first(): flash(_('Email already in use.'), 'danger') return render_template( 'pages/edit_profile.html', user=current_user, esport_games=ESPORT_GAMES, game_platforms=GAME_PLATFORMS, user_gamertags=current_user.get_gamertags(), ) current_user.username = username current_user.full_name = full_name current_user.email = email current_user.phone = phone current_user.games = ','.join(selected_games) if selected_games else None current_user.discord_username = discord_username or None current_user.discord_user_id = discord_user_id or None current_user.league_os_profile = league_os_profile or None update_user_gamertags(current_user, selected_games) # Blank means "keep the current password"; anything else has already # been checked against the policy by the schema. password = validated.get('password') if password: current_user.password_hash = hash_password(password) log_auth_event( 'account.password_changed', username=current_user.username, user_id=current_user.id ) db.session.commit() flash(_('Profile updated successfully!'), 'success') return redirect(url_for('users.profile')) return render_template( 'pages/edit_profile.html', user=current_user, esport_games=ESPORT_GAMES, game_platforms=GAME_PLATFORMS, user_gamertags=current_user.get_gamertags(), )