API - allow admin to reset password for a given user
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
import os
|
||||
import random
|
||||
import shutil
|
||||
from typing import Any, Dict, Tuple, Union
|
||||
|
||||
import click
|
||||
from flask import Blueprint, request, send_file
|
||||
from flask import Blueprint, current_app, request, send_file
|
||||
from sqlalchemy import exc
|
||||
|
||||
from fittrackee import db
|
||||
from fittrackee import bcrypt, db
|
||||
from fittrackee.emails.tasks import password_change_email, reset_password_email
|
||||
from fittrackee.files import get_absolute_file_path
|
||||
from fittrackee.responses import (
|
||||
ForbiddenErrorResponse,
|
||||
@@ -16,12 +18,14 @@ from fittrackee.responses import (
|
||||
UserNotFoundErrorResponse,
|
||||
handle_error_and_return_response,
|
||||
)
|
||||
from fittrackee.utils import get_readable_duration
|
||||
from fittrackee.workouts.models import Record, Workout, WorkoutSegment
|
||||
|
||||
from .decorators import authenticate, authenticate_as_admin
|
||||
from .exceptions import UserNotFoundException
|
||||
from .models import User, UserSportPreference
|
||||
from .utils.admin import set_admin_rights
|
||||
from .utils.random import random_string
|
||||
|
||||
users_blueprint = Blueprint('users', __name__)
|
||||
|
||||
@@ -487,16 +491,62 @@ def update_user(auth_user: User, user_name: str) -> Union[Dict, HttpResponse]:
|
||||
:statuscode 500:
|
||||
"""
|
||||
user_data = request.get_json()
|
||||
if not user_data or user_data.get('admin') is None:
|
||||
if not user_data:
|
||||
return InvalidPayloadErrorResponse()
|
||||
|
||||
send_emails = False
|
||||
try:
|
||||
user = User.query.filter_by(username=user_name).first()
|
||||
if not user:
|
||||
return UserNotFoundErrorResponse()
|
||||
|
||||
user.admin = user_data['admin']
|
||||
if 'admin' in user_data:
|
||||
user.admin = user_data['admin']
|
||||
|
||||
if (
|
||||
'reset_password' in user_data
|
||||
and user_data['reset_password'] is True
|
||||
):
|
||||
new_password = random_string(length=random.randint(10, 20))
|
||||
user.password = bcrypt.generate_password_hash(
|
||||
new_password, current_app.config.get('BCRYPT_LOG_ROUNDS')
|
||||
).decode()
|
||||
send_emails = True
|
||||
|
||||
db.session.commit()
|
||||
|
||||
if send_emails:
|
||||
user_language = 'en' if user.language is None else user.language
|
||||
ui_url = current_app.config['UI_URL']
|
||||
user_data = {
|
||||
'language': user_language,
|
||||
'email': user.email,
|
||||
}
|
||||
password_change_email.send(
|
||||
user_data,
|
||||
{
|
||||
'username': user.username,
|
||||
'fittrackee_url': ui_url,
|
||||
},
|
||||
)
|
||||
password_reset_token = user.encode_password_reset_token(user.id)
|
||||
reset_password_email.send(
|
||||
user_data,
|
||||
{
|
||||
'expiration_delay': get_readable_duration(
|
||||
current_app.config[
|
||||
'PASSWORD_TOKEN_EXPIRATION_SECONDS'
|
||||
],
|
||||
user_language,
|
||||
),
|
||||
'username': user.username,
|
||||
'password_reset_url': (
|
||||
f'{ui_url}/password-reset?token={password_reset_token}'
|
||||
),
|
||||
'fittrackee_url': ui_url,
|
||||
},
|
||||
)
|
||||
|
||||
return {
|
||||
'status': 'success',
|
||||
'data': {'users': [user.serialize()]},
|
||||
|
12
fittrackee/users/utils/random.py
Normal file
12
fittrackee/users/utils/random.py
Normal file
@@ -0,0 +1,12 @@
|
||||
import random
|
||||
import string
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def random_string(length: Optional[int] = None) -> str:
|
||||
if length is None:
|
||||
length = 10
|
||||
return ''.join(
|
||||
random.choice(string.ascii_letters + string.digits)
|
||||
for _ in range(length)
|
||||
)
|
Reference in New Issue
Block a user