API - authentication decorators return user directly instead of user id

This commit is contained in:
Sam
2021-12-01 19:22:47 +01:00
parent d9048032e4
commit 00b6e05805
10 changed files with 88 additions and 133 deletions

View File

@ -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()
)

View File

@ -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/<int:sport_id>', 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/<int:sport_id>', 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
:<json string is_active: sport active status
@ -387,7 +379,6 @@ def update_sport(
return InvalidPayloadErrorResponse()
try:
user = User.query.filter_by(id=int(auth_user_id)).first()
sport = Sport.query.filter_by(id=sport_id).first()
if not sport:
return DataNotFoundErrorResponse('sports')
@ -395,14 +386,14 @@ def update_sport(
sport.is_active = sport_data.get('is_active')
db.session.commit()
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,

View File

@ -179,7 +179,7 @@ def get_workouts(
@stats_blueprint.route('/stats/<user_name>/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/<user_name>/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

View File

@ -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)
:<json string workout_date: workout date (format: ``%Y-%m-%d %H:%M``)
:<json float distance: workout distance in km
:<json integer duration: workout duration in seconds
@ -1145,8 +1131,7 @@ def post_workout_no_gpx(
return InvalidPayloadErrorResponse()
try:
user = User.query.filter_by(id=auth_user_id).first()
new_workout = create_workout(user, workout_data)
new_workout = create_workout(auth_user, workout_data)
db.session.add(new_workout)
db.session.commit()
@ -1172,7 +1157,7 @@ def post_workout_no_gpx(
)
@authenticate
def update_workout(
auth_user_id: int, workout_short_id: str
auth_user: User, workout_short_id: str
) -> 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
:<json string workout_date: workout date (format: ``%Y-%m-%d %H:%M``)
@ -1300,11 +1284,11 @@ def update_workout(
if not workout:
return DataNotFoundErrorResponse('workouts')
response_object = can_view_workout(auth_user_id, workout.user_id)
response_object = can_view_workout(auth_user.id, workout.user_id)
if response_object:
return response_object
workout = edit_workout(workout, workout_data, auth_user_id)
workout = edit_workout(workout, workout_data, auth_user.id)
db.session.commit()
return {
'status': 'success',
@ -1320,7 +1304,7 @@ def update_workout(
)
@authenticate
def delete_workout(
auth_user_id: int, workout_short_id: str
auth_user: User, workout_short_id: str
) -> 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