def post(self): reset_password_data = request.get_json() # attempt validation validate_request(instance=reset_password_data, schema=reset_password_json_schema) new_password = reset_password_data.get("new_password", None) password_reset_token = reset_password_data.get("password_reset_token", None) if new_password and len(new_password) < 8: response = { "error": { "message": "Password must be at least 8 characters long.", "status": "Fail", } } return response, 422 decoded_token_response = User.decode_single_use_jws( token=password_reset_token, required_token_type="reset_password") is_valid_token = decoded_token_response["status"] == "Success" if not is_valid_token: response = { "error": { "message": decoded_token_response["message"], "status": "Fail", } } return make_response(jsonify(response), 401) user: User = decoded_token_response.get("user", None) is_used_token = user.check_is_used_password_reset_token( password_reset_token=password_reset_token) if is_used_token: response = { "error": { "message": "This token has already been used.", "status": "Fail", } } return make_response(jsonify(response), 401) user.hash_password(new_password) user.remove_all_password_reset_tokens() db.session.commit() response = { "message": "Password successfully changed. Please log in.", "status": "Success", } return make_response(jsonify(response), 200)
def post(self): activate_user_data = request.get_json() activation_token = activate_user_data.get("activation_token", None) if not activation_token: response = { "error": { "message": "Activation token is required.", "status": "Fail" } } return make_response(jsonify(response), 401) decoded_token_response = User.decode_single_use_jws( token=activation_token, required_token_type="user_activation") is_valid_token = decoded_token_response.get("status") == "Success" if not is_valid_token: response = { "error": { "message": decoded_token_response.get("message"), "status": "Fail", } } return make_response(jsonify(response), 401) user: User = decoded_token_response.get("user", None) is_already_activated = user.is_activated if is_already_activated: response = { "error": { "message": "User is already activated. Please login.", "status": "Fail", } } return make_response(jsonify(response), 403) user.is_activated = True authentication_token = user.encode_auth_token() db.session.commit() response = { "authentication_token": authentication_token.decode(), "data": { "user": user_schema.dump(user).data }, "message": "User successfully activated.", "status": "Success", } return make_response(jsonify(response), 200)
def get_user_role_from_auth_token(token: str): decoded_user_data = User.decode_auth_token(token) if not isinstance(decoded_user_data, str): user = ( User.query.filter_by(id=decoded_user_data.get("id")) .execution_options(show_all=True) .first() ) if not user: raise Exception("No user found.") else: return user.role.name else: raise Exception(decoded_user_data)
def create_client_user(test_client, initialize_database, seed_system_data, create_master_organization): organization = create_master_organization user = User( given_names="Jon Snow", surname="Stark", phone="+254712345678", signup_method=SignupMethod.MOBILE_SIGNUP, role_id=2, ) user.set_identification_details(id_type="NATIONAL_ID", id_value="12345678") user.hash_password("password-123") db.session.add(user) user.bind_user_to_organization(organization) db.session.commit() return user
def create_admin_user(test_client, initialize_database, seed_system_data, create_master_organization): organization = create_master_organization user = User( given_names="John Doe", surname="Jane", email="*****@*****.**", signup_method=SignupMethod.WEB_SIGNUP, role_id=1, ) user.hash_password("password-123") user.bind_user_to_organization(organization) db.session.add(user) db.session.commit() return user
def create_user( given_names=None, surname=None, email=None, phone=None, address=None, date_of_birth=None, id_type=None, id_value=None, password=None, role=None, signup_method=None, organization: Organization = None, ): """ :param role: The user's role :param organization: The organization the user belongs to :param signup_method: The channel through which teh user was signed up :param given_names: The collective first names the user identifies with :param surname: The user's surname :param email: The user's email address :param phone: The user's phone number :param address: The user's physical postal address :param date_of_birth: The user's date of birth :param id_type: The form of identification used by the user :param id_value: The value tied to that ID type :param password: Value of user's password :return: """ # create user user = User( given_names=given_names, surname=surname, email=email, phone=phone, date_of_birth=date_of_birth, address=address, signup_method=signup_method, ) user.is_activated = False # set identification information if id_value: user.set_identification_details(id_type=id_type, id_value=id_value) # hash password if password: user.hash_password(password=password) # unless special organization defined, default to master organization if not organization: organization = Organization.master_organisation() # bind user to organization user.bind_user_to_organization(organization) # set user role if role: user.set_role(role) # default to client role else: user.set_role("CLIENT") db.session.add(user) return user
def wrapper(*args, **kwargs): """ :param args: :param kwargs: :return: """ auth_header = request.headers.get("Authorization") if auth_header: auth_token = auth_header.split(" ")[1] else: auth_token = "" if auth_token: # decode authentication token decoded_user_data = User.decode_auth_token(auth_token) if not isinstance(decoded_user_data, str): user = ( User.query.filter_by(id=decoded_user_data.get("id")) .execution_options(show_all=True) .first() ) if not user: response = { "error": {"message": "User not found.", "status": "Fail"} } return make_response(jsonify(response), 401) if not user.is_activated: response = { "error": {"message": "User not activated.", "status": "Fail"} } return make_response(jsonify(response), 401) # get user role user_role = decoded_user_data.get("role", None) if len(authenticated_roles) > 0: # check if user's role matches any of the required roles if user_role not in authenticated_roles: response = { "error": { "message": "User's is not authorized to access this role.", "status": "Fail", } } return make_response(jsonify(response), 401) return function(*args, **kwargs) # if returned decoded data is a message. response = {"error": {"message": decoded_user_data, "status": "Fail"}} return make_response(jsonify(response), 401) # if no valid authentication is provided. response = { "error": { "message": "Provide a valid authentication token.", "status": "Fail", } } return make_response(jsonify(response), 401)
def send_one_time_pin(user: User): otp = user.set_otp_secret() message = f"Hello {user.given_names}, your activation code is: {otp}" send_sms(message=message, phone_number=user.phone)
def post(self): logout_instruction = request.get_json() action = logout_instruction.get("action", None) if not action or action != "logout": response = { "error": { "message": "Invalid action provided for logout.", "status": "Fail", } } return make_response(jsonify(response), 400) # get auth token auth_header = request.headers.get("Authorization") # get auth token if auth_header: auth_token = auth_header.split(" ")[1] else: auth_token = "" if auth_token: decoded_auth_token = User.decode_auth_token(auth_token) if not isinstance(decoded_auth_token, str): # mark the token as blacklisted blacklist_token = BlacklistedToken(token=auth_token) try: # insert the token db.session.add(blacklist_token) db.session.commit() response = { "message": "Successfully logged out.", "status": "Success", } return make_response(jsonify(response)), 200 except Exception as exception: response = { "error": { "message": f"System error: {exception}.", "status": "Fail", } } return make_response(jsonify(response)), 500 else: response = { "error": { "message": decoded_auth_token, "status": "Fail" } } return make_response(jsonify(response)), 401 else: response = { "error": { "message": "Provide a valid auth token.", "status": "Fail" } } return make_response(jsonify(response)), 403