diff --git a/Makefile b/Makefile index 03e8b22a..4b950ff5 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,8 @@ build-client: lint-client check-all: lint-all type-check test-python test-client +check-python: lint-python type-check test-python + clean: rm -rf .mypy_cache rm -rf .pytest_cache diff --git a/fittrackee/application/app_config.py b/fittrackee/application/app_config.py index e3e97f70..c97c9278 100644 --- a/fittrackee/application/app_config.py +++ b/fittrackee/application/app_config.py @@ -10,6 +10,7 @@ from fittrackee.responses import ( handle_error_and_return_response, ) from fittrackee.users.decorators import authenticate_as_admin +from fittrackee.users.models import User from .models import AppConfig from .utils import update_app_config_from_database, verify_app_config @@ -64,7 +65,7 @@ def get_application_config() -> Union[Dict, HttpResponse]: @config_blueprint.route('/config', methods=['PATCH']) @authenticate_as_admin -def update_application_config(auth_user_id: int) -> Union[Dict, HttpResponse]: +def update_application_config(auth_user: User) -> Union[Dict, HttpResponse]: """ Update Application config @@ -95,8 +96,6 @@ def update_application_config(auth_user_id: int) -> Union[Dict, HttpResponse]: "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) - : Union[Dict, HttpResponse]: @auth_blueprint.route('/auth/logout', methods=['GET']) @authenticate -def logout_user(auth_user_id: int) -> Union[Dict, HttpResponse]: +def logout_user(auth_user: User) -> Union[Dict, HttpResponse]: """ user logout @@ -274,7 +274,7 @@ def logout_user(auth_user_id: int) -> Union[Dict, HttpResponse]: auth_token = auth_header.split(' ')[1] resp = User.decode_auth_token(auth_token) - if isinstance(auth_user_id, str): + if isinstance(resp, str): return UnauthorizedErrorResponse(resp) return { @@ -286,7 +286,7 @@ def logout_user(auth_user_id: int) -> Union[Dict, HttpResponse]: @auth_blueprint.route('/auth/profile', methods=['GET']) @authenticate def get_authenticated_user_profile( - auth_user_id: int, + auth_user: User, ) -> Union[Dict, HttpResponse]: """ get authenticated user info @@ -381,13 +381,12 @@ def get_authenticated_user_profile( - invalid token, please log in again """ - user = User.query.filter_by(id=auth_user_id).first() - return {'status': 'success', 'data': user.serialize()} + return {'status': 'success', 'data': auth_user.serialize()} @auth_blueprint.route('/auth/profile/edit', methods=['POST']) @authenticate -def edit_user(auth_user_id: int) -> Union[Dict, HttpResponse]: +def edit_user(auth_user: User) -> Union[Dict, HttpResponse]: """ edit authenticated user @@ -523,24 +522,23 @@ def edit_user(auth_user_id: int) -> Union[Dict, HttpResponse]: ).decode() try: - user = User.query.filter_by(id=auth_user_id).first() - user.first_name = first_name - user.last_name = last_name - user.bio = bio - user.location = location - user.birth_date = ( + auth_user.first_name = first_name + auth_user.last_name = last_name + auth_user.bio = bio + auth_user.location = location + auth_user.birth_date = ( datetime.datetime.strptime(birth_date, '%Y-%m-%d') if birth_date else None ) if password is not None and password != '': - user.password = password + auth_user.password = password db.session.commit() return { 'status': 'success', 'message': 'user profile updated', - 'data': user.serialize(), + 'data': auth_user.serialize(), } # handler errors @@ -550,7 +548,7 @@ def edit_user(auth_user_id: int) -> Union[Dict, HttpResponse]: @auth_blueprint.route('/auth/profile/edit/preferences', methods=['POST']) @authenticate -def edit_user_preferences(auth_user_id: int) -> Union[Dict, HttpResponse]: +def edit_user_preferences(auth_user: User) -> Union[Dict, HttpResponse]: """ edit authenticated user preferences @@ -670,17 +668,16 @@ def edit_user_preferences(auth_user_id: int) -> Union[Dict, HttpResponse]: weekm = post_data.get('weekm') try: - user = User.query.filter_by(id=auth_user_id).first() - user.imperial_units = imperial_units - user.language = language - user.timezone = timezone - user.weekm = weekm + auth_user.imperial_units = imperial_units + auth_user.language = language + auth_user.timezone = timezone + auth_user.weekm = weekm db.session.commit() return { 'status': 'success', 'message': 'user preferences updated', - 'data': user.serialize(), + 'data': auth_user.serialize(), } # handler errors @@ -691,7 +688,7 @@ def edit_user_preferences(auth_user_id: int) -> Union[Dict, HttpResponse]: @auth_blueprint.route('/auth/profile/edit/sports', methods=['POST']) @authenticate def edit_user_sport_preferences( - auth_user_id: int, + auth_user: User, ) -> Union[Dict, HttpResponse]: """ edit authenticated user sport preferences @@ -758,12 +755,12 @@ def edit_user_sport_preferences( try: user_sport = UserSportPreference.query.filter_by( - user_id=auth_user_id, + user_id=auth_user.id, sport_id=sport_id, ).first() if not user_sport: user_sport = UserSportPreference( - user_id=auth_user_id, + user_id=auth_user.id, sport_id=sport_id, stopped_speed_threshold=sport.stopped_speed_threshold, ) @@ -792,7 +789,7 @@ def edit_user_sport_preferences( @auth_blueprint.route('/auth/picture', methods=['POST']) @authenticate -def edit_picture(auth_user_id: int) -> Union[Dict, HttpResponse]: +def edit_picture(auth_user: User) -> Union[Dict, HttpResponse]: """ update authenticated user picture @@ -848,23 +845,22 @@ def edit_picture(auth_user_id: int) -> Union[Dict, HttpResponse]: file = request.files['file'] filename = secure_filename(file.filename) # type: ignore dirpath = os.path.join( - current_app.config['UPLOAD_FOLDER'], 'pictures', str(auth_user_id) + current_app.config['UPLOAD_FOLDER'], 'pictures', str(auth_user.id) ) if not os.path.exists(dirpath): os.makedirs(dirpath) absolute_picture_path = os.path.join(dirpath, filename) relative_picture_path = os.path.join( - 'pictures', str(auth_user_id), filename + 'pictures', str(auth_user.id), filename ) try: - user = User.query.filter_by(id=auth_user_id).first() - if user.picture is not None: - old_picture_path = get_absolute_file_path(user.picture) + if auth_user.picture is not None: + old_picture_path = get_absolute_file_path(auth_user.picture) if os.path.isfile(get_absolute_file_path(old_picture_path)): os.remove(old_picture_path) file.save(absolute_picture_path) - user.picture = relative_picture_path + auth_user.picture = relative_picture_path db.session.commit() return { 'status': 'success', @@ -879,7 +875,7 @@ def edit_picture(auth_user_id: int) -> Union[Dict, HttpResponse]: @auth_blueprint.route('/auth/picture', methods=['DELETE']) @authenticate -def del_picture(auth_user_id: int) -> Union[Tuple[Dict, int], HttpResponse]: +def del_picture(auth_user: User) -> Union[Tuple[Dict, int], HttpResponse]: """ delete authenticated user picture @@ -908,11 +904,10 @@ def del_picture(auth_user_id: int) -> Union[Tuple[Dict, int], HttpResponse]: """ try: - user = User.query.filter_by(id=auth_user_id).first() - picture_path = get_absolute_file_path(user.picture) + picture_path = get_absolute_file_path(auth_user.picture) if os.path.isfile(picture_path): os.remove(picture_path) - user.picture = None + auth_user.picture = None db.session.commit() return {'status': 'no content'}, 204 except (exc.IntegrityError, ValueError) as e: diff --git a/fittrackee/users/decorators.py b/fittrackee/users/decorators.py index 8f260e4f..b3a841a5 100644 --- a/fittrackee/users/decorators.py +++ b/fittrackee/users/decorators.py @@ -13,11 +13,10 @@ def authenticate(f: Callable) -> Callable: def decorated_function( *args: Any, **kwargs: Any ) -> Union[Callable, HttpResponse]: - verify_admin = False - response_object, resp = verify_user(request, verify_admin) + response_object, user = verify_user(request, verify_admin=False) if response_object: return response_object - return f(resp, *args, **kwargs) + return f(user, *args, **kwargs) return decorated_function @@ -27,10 +26,9 @@ def authenticate_as_admin(f: Callable) -> Callable: def decorated_function( *args: Any, **kwargs: Any ) -> Union[Callable, HttpResponse]: - verify_admin = True - response_object, resp = verify_user(request, verify_admin) + response_object, user = verify_user(request, verify_admin=True) if response_object: return response_object - return f(resp, *args, **kwargs) + return f(user, *args, **kwargs) return decorated_function diff --git a/fittrackee/users/users.py b/fittrackee/users/users.py index 44faf458..8d0089be 100644 --- a/fittrackee/users/users.py +++ b/fittrackee/users/users.py @@ -27,7 +27,7 @@ USER_PER_PAGE = 10 @users_blueprint.route('/users', methods=['GET']) @authenticate -def get_users(auth_user_id: int) -> Dict: +def get_users(auth_user: User) -> Dict: """ Get all users @@ -144,8 +144,6 @@ def get_users(auth_user_id: int) -> Dict: "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) - :query integer page: page if using pagination (default: 1) :query integer per_page: number of users per page (default: 10, max: 50) :query string q: query on user name @@ -219,7 +217,7 @@ def get_users(auth_user_id: int) -> Dict: @users_blueprint.route('/users/', methods=['GET']) @authenticate def get_single_user( - auth_user_id: int, user_name: str + auth_user: User, user_name: str ) -> Union[Dict, HttpResponse]: """ Get single user details @@ -306,7 +304,6 @@ def get_single_user( "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) :param integer user_name: user name :reqheader Authorization: OAuth 2.0 Bearer Token @@ -371,9 +368,7 @@ def get_picture(user_name: str) -> Any: @users_blueprint.route('/users/', methods=['PATCH']) @authenticate_as_admin -def update_user( - auth_user_id: int, user_name: str -) -> Union[Dict, HttpResponse]: +def update_user(auth_user: User, user_name: str) -> Union[Dict, HttpResponse]: """ Update user to add admin rights @@ -461,7 +456,6 @@ def update_user( "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) :param string user_name: user name :', methods=['DELETE']) @authenticate def delete_user( - auth_user_id: int, user_name: str + auth_user: User, user_name: str ) -> Union[Tuple[Dict, int], HttpResponse]: """ Delete a user account @@ -524,7 +518,6 @@ def delete_user( HTTP/1.1 204 NO CONTENT Content-Type: application/json - :param integer auth_user_id: authenticate user id (from JSON Web Token) :param string user_name: user name :reqheader Authorization: OAuth 2.0 Bearer Token @@ -543,12 +536,11 @@ def delete_user( """ try: - auth_user = User.query.filter_by(id=auth_user_id).first() user = User.query.filter_by(username=user_name).first() if not user: return UserNotFoundErrorResponse() - if user.id != auth_user_id and not auth_user.admin: + if user.id != auth_user.id and not auth_user.admin: return ForbiddenErrorResponse() if ( user.admin is True diff --git a/fittrackee/users/utils.py b/fittrackee/users/utils.py index c938a522..6f6a1984 100644 --- a/fittrackee/users/utils.py +++ b/fittrackee/users/utils.py @@ -62,7 +62,7 @@ def register_controls( def verify_user( current_request: Request, verify_admin: bool -) -> Tuple[Optional[HttpResponse], Optional[int]]: +) -> Tuple[Optional[HttpResponse], Optional[User]]: """ Return user id, if the provided token is valid and if user has admin rights if 'verify_admin' is True @@ -78,9 +78,9 @@ def verify_user( user = User.query.filter_by(id=resp).first() if not user: return UnauthorizedErrorResponse(default_message), None - if verify_admin and not is_admin(resp): + if verify_admin and not user.admin: return ForbiddenErrorResponse(), None - return None, resp + return None, user def can_view_workout( diff --git a/fittrackee/workouts/records.py b/fittrackee/workouts/records.py index f0905415..5714fa8e 100644 --- a/fittrackee/workouts/records.py +++ b/fittrackee/workouts/records.py @@ -3,6 +3,7 @@ from typing import Dict from flask import Blueprint from fittrackee.users.decorators import authenticate +from fittrackee.users.models import User from .models import Record @@ -11,7 +12,7 @@ records_blueprint = Blueprint('records', __name__) @records_blueprint.route('/records', methods=['GET']) @authenticate -def get_records(auth_user_id: int) -> Dict: +def get_records(auth_user: User) -> Dict: """ Get all records for authenticated user. @@ -95,8 +96,6 @@ def get_records(auth_user_id: int) -> Dict: "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) - :reqheader Authorization: OAuth 2.0 Bearer Token :statuscode 200: success @@ -107,7 +106,7 @@ def get_records(auth_user_id: int) -> Dict: """ records = ( - Record.query.filter_by(user_id=auth_user_id) + Record.query.filter_by(user_id=auth_user.id) .order_by(Record.sport_id.asc(), Record.record_type.asc()) .all() ) diff --git a/fittrackee/workouts/sports.py b/fittrackee/workouts/sports.py index e91cf973..9236068c 100644 --- a/fittrackee/workouts/sports.py +++ b/fittrackee/workouts/sports.py @@ -20,7 +20,7 @@ sports_blueprint = Blueprint('sports', __name__) @sports_blueprint.route('/sports', methods=['GET']) @authenticate -def get_sports(auth_user_id: int) -> Dict: +def get_sports(auth_user: User) -> Dict: """ Get all sports @@ -165,8 +165,6 @@ def get_sports(auth_user_id: int) -> Dict: "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) - :reqheader Authorization: OAuth 2.0 Bearer Token :statuscode 200: success @@ -176,16 +174,15 @@ def get_sports(auth_user_id: int) -> Dict: - invalid token, please log in again """ - user = User.query.filter_by(id=int(auth_user_id)).first() sports = Sport.query.order_by(Sport.id).all() sports_data = [] for sport in sports: sport_preferences = UserSportPreference.query.filter_by( - user_id=user.id, sport_id=sport.id + user_id=auth_user.id, sport_id=sport.id ).first() sports_data.append( sport.serialize( - is_admin=user.admin, + is_admin=auth_user.admin, sport_preferences=sport_preferences.serialize() if sport_preferences else None, @@ -199,7 +196,7 @@ def get_sports(auth_user_id: int) -> Dict: @sports_blueprint.route('/sports/', methods=['GET']) @authenticate -def get_sport(auth_user_id: int, sport_id: int) -> Union[Dict, HttpResponse]: +def get_sport(auth_user: User, sport_id: int) -> Union[Dict, HttpResponse]: """ Get a sport @@ -273,7 +270,6 @@ def get_sport(auth_user_id: int, sport_id: int) -> Union[Dict, HttpResponse]: "status": "not found" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) :param integer sport_id: sport id :reqheader Authorization: OAuth 2.0 Bearer Token @@ -286,18 +282,17 @@ def get_sport(auth_user_id: int, sport_id: int) -> Union[Dict, HttpResponse]: :statuscode 404: sport not found """ - user = User.query.filter_by(id=int(auth_user_id)).first() sport = Sport.query.filter_by(id=sport_id).first() if sport: sport_preferences = UserSportPreference.query.filter_by( - user_id=user.id, sport_id=sport.id + user_id=auth_user.id, sport_id=sport.id ).first() return { 'status': 'success', 'data': { 'sports': [ sport.serialize( - is_admin=user.admin, + is_admin=auth_user.admin, sport_preferences=sport_preferences.serialize() if sport_preferences else None, @@ -310,9 +305,7 @@ def get_sport(auth_user_id: int, sport_id: int) -> Union[Dict, HttpResponse]: @sports_blueprint.route('/sports/', methods=['PATCH']) @authenticate_as_admin -def update_sport( - auth_user_id: int, sport_id: int -) -> Union[Dict, HttpResponse]: +def update_sport(auth_user: User, sport_id: int) -> Union[Dict, HttpResponse]: """ Update a sport Authenticated user must be an admin @@ -364,7 +357,6 @@ def update_sport( "status": "not found" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) :param integer sport_id: sport id :/by_time', methods=['GET']) @authenticate def get_workouts_by_time( - auth_user_id: int, user_name: str + auth_user: User, user_name: str ) -> Union[Dict, HttpResponse]: """ Get workouts statistics for a user by time @@ -258,7 +258,6 @@ def get_workouts_by_time( "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) :param integer user_name: user name :query string from: start date (format: ``%Y-%m-%d``) @@ -287,7 +286,7 @@ def get_workouts_by_time( @stats_blueprint.route('/stats//by_sport', methods=['GET']) @authenticate def get_workouts_by_sport( - auth_user_id: int, user_name: str + auth_user: User, user_name: str ) -> Union[Dict, HttpResponse]: """ Get workouts statistics for a user by sport @@ -361,7 +360,6 @@ def get_workouts_by_sport( "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) :param integer user_name: user name :query integer sport_id: sport id @@ -383,7 +381,7 @@ def get_workouts_by_sport( @stats_blueprint.route('/stats/all', methods=['GET']) @authenticate_as_admin -def get_application_stats(auth_user_id: int) -> Dict: +def get_application_stats(auth_user: User) -> Dict: """ Get all application statistics @@ -411,8 +409,6 @@ def get_application_stats(auth_user_id: int) -> Dict: "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) - :reqheader Authorization: OAuth 2.0 Bearer Token :statuscode 200: success diff --git a/fittrackee/workouts/workouts.py b/fittrackee/workouts/workouts.py index 607a65cc..192e7217 100644 --- a/fittrackee/workouts/workouts.py +++ b/fittrackee/workouts/workouts.py @@ -56,7 +56,7 @@ MAX_WORKOUTS_PER_PAGE = 100 @workouts_blueprint.route('/workouts', methods=['GET']) @authenticate -def get_workouts(auth_user_id: int) -> Union[Dict, HttpResponse]: +def get_workouts(auth_user: User) -> Union[Dict, HttpResponse]: """ Get workouts for the authenticated user. @@ -171,8 +171,6 @@ def get_workouts(auth_user_id: int) -> Union[Dict, HttpResponse]: "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) - :query integer page: page if using pagination (default: 1) :query integer per_page: number of workouts per page (default: 5, max: 100) @@ -200,10 +198,9 @@ def get_workouts(auth_user_id: int) -> Union[Dict, HttpResponse]: """ try: - user = User.query.filter_by(id=auth_user_id).first() params = request.args.copy() page = int(params.get('page', 1)) - date_from, date_to = get_datetime_from_request_args(params, user) + date_from, date_to = get_datetime_from_request_args(params, auth_user) distance_from = params.get('distance_from') distance_to = params.get('distance_to') duration_from = params.get('duration_from') @@ -220,7 +217,7 @@ def get_workouts(auth_user_id: int) -> Union[Dict, HttpResponse]: per_page = MAX_WORKOUTS_PER_PAGE workouts_pagination = ( Workout.query.filter( - Workout.user_id == auth_user_id, + Workout.user_id == auth_user.id, Workout.sport_id == sport_id if sport_id else True, Workout.workout_date >= date_from if date_from else True, Workout.workout_date < date_to + timedelta(seconds=1) @@ -302,7 +299,7 @@ def get_workouts(auth_user_id: int) -> Union[Dict, HttpResponse]: ) @authenticate def get_workout( - auth_user_id: int, workout_short_id: str + auth_user: User, workout_short_id: str ) -> Union[Dict, HttpResponse]: """ Get an workout @@ -372,8 +369,6 @@ def get_workout( }, "status": "not found" } - - :param integer auth_user_id: authenticate user id (from JSON Web Token) :param string workout_short_id: workout short id :reqheader Authorization: OAuth 2.0 Bearer Token @@ -392,7 +387,7 @@ def get_workout( if not workout: return DataNotFoundErrorResponse('workouts') - error_response = can_view_workout(auth_user_id, workout.user_id) + error_response = can_view_workout(auth_user.id, workout.user_id) if error_response: return error_response @@ -403,7 +398,7 @@ def get_workout( def get_workout_data( - auth_user_id: int, + auth_user: User, workout_short_id: str, data_type: str, segment_id: Optional[int] = None, @@ -417,7 +412,7 @@ def get_workout_data( message=f'workout not found (id: {workout_short_id})', ) - error_response = can_view_workout(auth_user_id, workout.user_id) + error_response = can_view_workout(auth_user.id, workout.user_id) if error_response: return error_response if not workout.gpx or workout.gpx == '': @@ -467,7 +462,7 @@ def get_workout_data( ) @authenticate def get_workout_gpx( - auth_user_id: int, workout_short_id: str + auth_user: User, workout_short_id: str ) -> Union[Dict, HttpResponse]: """ Get gpx file for an workout displayed on map with Leaflet @@ -494,7 +489,6 @@ def get_workout_gpx( "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) :param string workout_short_id: workout short id :reqheader Authorization: OAuth 2.0 Bearer Token @@ -510,7 +504,7 @@ def get_workout_gpx( :statuscode 500: """ - return get_workout_data(auth_user_id, workout_short_id, 'gpx') + return get_workout_data(auth_user, workout_short_id, 'gpx') @workouts_blueprint.route( @@ -518,7 +512,7 @@ def get_workout_gpx( ) @authenticate def get_workout_chart_data( - auth_user_id: int, workout_short_id: str + auth_user: User, workout_short_id: str ) -> Union[Dict, HttpResponse]: """ Get chart data from an workout gpx file, to display it with Recharts @@ -564,7 +558,6 @@ def get_workout_chart_data( "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) :param string workout_short_id: workout short id :reqheader Authorization: OAuth 2.0 Bearer Token @@ -580,7 +573,7 @@ def get_workout_chart_data( :statuscode 500: """ - return get_workout_data(auth_user_id, workout_short_id, 'chart_data') + return get_workout_data(auth_user, workout_short_id, 'chart_data') @workouts_blueprint.route( @@ -589,7 +582,7 @@ def get_workout_chart_data( ) @authenticate def get_segment_gpx( - auth_user_id: int, workout_short_id: str, segment_id: int + auth_user: User, workout_short_id: str, segment_id: int ) -> Union[Dict, HttpResponse]: """ Get gpx file for an workout segment displayed on map with Leaflet @@ -616,7 +609,6 @@ def get_segment_gpx( "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) :param string workout_short_id: workout short id :param integer segment_id: segment id @@ -632,7 +624,7 @@ def get_segment_gpx( :statuscode 500: """ - return get_workout_data(auth_user_id, workout_short_id, 'gpx', segment_id) + return get_workout_data(auth_user, workout_short_id, 'gpx', segment_id) @workouts_blueprint.route( @@ -642,7 +634,7 @@ def get_segment_gpx( ) @authenticate def get_segment_chart_data( - auth_user_id: int, workout_short_id: str, segment_id: int + auth_user: User, workout_short_id: str, segment_id: int ) -> Union[Dict, HttpResponse]: """ Get chart data from an workout gpx file, to display it with Recharts @@ -688,7 +680,6 @@ def get_segment_chart_data( "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) :param string workout_short_id: workout short id :param integer segment_id: segment id @@ -705,7 +696,7 @@ def get_segment_chart_data( """ return get_workout_data( - auth_user_id, workout_short_id, 'chart_data', segment_id + auth_user, workout_short_id, 'chart_data', segment_id ) @@ -714,7 +705,7 @@ def get_segment_chart_data( ) @authenticate def download_workout_gpx( - auth_user_id: int, workout_short_id: str + auth_user: User, workout_short_id: str ) -> Union[HttpResponse, Response]: """ Download gpx file @@ -732,7 +723,6 @@ def download_workout_gpx( HTTP/1.1 200 OK Content-Type: application/gpx+xml - :param integer auth_user_id: authenticate user id (from JSON Web Token) :param string workout_short_id: workout short id :statuscode 200: success @@ -746,7 +736,7 @@ def download_workout_gpx( """ workout_uuid = decode_short_id(workout_short_id) workout = Workout.query.filter_by( - uuid=workout_uuid, user_id=auth_user_id + uuid=workout_uuid, user_id=auth_user.id ).first() if not workout: return DataNotFoundErrorResponse( @@ -852,7 +842,7 @@ def get_map_tile(s: str, z: str, x: str, y: str) -> Tuple[Response, int]: @workouts_blueprint.route('/workouts', methods=['POST']) @authenticate -def post_workout(auth_user_id: int) -> Union[Tuple[Dict, int], HttpResponse]: +def post_workout(auth_user: User) -> Union[Tuple[Dict, int], HttpResponse]: """ Post an workout with a gpx file @@ -944,8 +934,6 @@ def post_workout(auth_user_id: int) -> Union[Tuple[Dict, int], HttpResponse]: "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) - :form file: gpx file (allowed extensions: .gpx, .zip) :form data: sport id and notes (example: ``{"sport_id": 1, "notes": ""}``) @@ -983,7 +971,7 @@ def post_workout(auth_user_id: int) -> Union[Tuple[Dict, int], HttpResponse]: workout_file = request.files['file'] upload_dir = os.path.join( - current_app.config['UPLOAD_FOLDER'], 'workouts', str(auth_user_id) + current_app.config['UPLOAD_FOLDER'], 'workouts', str(auth_user.id) ) folders = { 'extract_dir': os.path.join(upload_dir, 'extract'), @@ -992,7 +980,7 @@ def post_workout(auth_user_id: int) -> Union[Tuple[Dict, int], HttpResponse]: try: new_workouts = process_files( - auth_user_id, workout_data, workout_file, folders + auth_user.id, workout_data, workout_file, folders ) if len(new_workouts) > 0: response_object = { @@ -1021,7 +1009,7 @@ def post_workout(auth_user_id: int) -> Union[Tuple[Dict, int], HttpResponse]: @workouts_blueprint.route('/workouts/no_gpx', methods=['POST']) @authenticate def post_workout_no_gpx( - auth_user_id: int, + auth_user: User, ) -> Union[Tuple[Dict, int], HttpResponse]: """ Post an workout without gpx file @@ -1114,8 +1102,6 @@ def post_workout_no_gpx( "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) - : Union[Dict, HttpResponse]: """ Update an workout @@ -1265,7 +1250,6 @@ def update_workout( "status": "success" } - :param integer auth_user_id: authenticate user id (from JSON Web Token) :param string workout_short_id: workout short id : Union[Tuple[Dict, int], HttpResponse]: """ Delete an workout @@ -1339,7 +1323,6 @@ def delete_workout( HTTP/1.1 204 NO CONTENT Content-Type: application/json - :param integer auth_user_id: authenticate user id (from JSON Web Token) :param string workout_short_id: workout short id :reqheader Authorization: OAuth 2.0 Bearer Token @@ -1359,7 +1342,7 @@ def delete_workout( workout = Workout.query.filter_by(uuid=workout_uuid).first() if not workout: return DataNotFoundErrorResponse('workouts') - error_response = can_view_workout(auth_user_id, workout.user_id) + error_response = can_view_workout(auth_user.id, workout.user_id) if error_response: return error_response