API - authentication decorators return user directly instead of user id
This commit is contained in:
@ -224,7 +224,7 @@ def login_user() -> 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:
|
||||
|
@ -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
|
||||
|
@ -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/<user_name>', 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/<user_name>', 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
|
||||
|
||||
:<json boolean admin: does the user have administrator rights
|
||||
@ -500,7 +494,7 @@ def update_user(
|
||||
@users_blueprint.route('/users/<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
|
||||
|
@ -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(
|
||||
|
Reference in New Issue
Block a user