Change endpoint responses where there are marshalling, unmarshalling

or param errors to raise invalid data exception. That will cause
those responses to be handled in by errors.py, which will log
the errors.

Set most of schemas to strict mode so that marshmallow will raise
exception rather than checking for errors in return tuple from load.

Added handler to errors.py for marshmallow validation errors.
This commit is contained in:
Adam Shimali
2016-06-14 15:07:23 +01:00
parent 5a66884f0e
commit b33312b855
16 changed files with 240 additions and 267 deletions

View File

@@ -1,7 +1,7 @@
import json
import uuid
from datetime import datetime
from flask import (jsonify, request, abort, Blueprint, current_app)
from flask import (jsonify, request, Blueprint, current_app)
from app import encryption, DATETIME_FORMAT
from app.dao.users_dao import (
get_model_users,
@@ -28,9 +28,13 @@ from app.schemas import (
from app.celery.tasks import (
send_sms,
email_reset_password,
send_email)
send_email
)
from app.errors import register_errors
from app.errors import (
register_errors,
InvalidRequest
)
user = Blueprint('user', __name__)
register_errors(user)
@@ -43,9 +47,7 @@ def create_user():
# TODO password policy, what is valid password
if not req_json.get('password', None):
errors.update({'password': ['Missing data for required field.']})
return jsonify(result="error", message=errors), 400
if errors:
return jsonify(result="error", message=errors), 400
raise InvalidRequest(errors, status_code=400)
save_model_user(user_to_create, pwd=req_json.get('password'))
return jsonify(data=user_schema.dump(user_to_create).data), 201
@@ -60,11 +62,9 @@ def update_user(user_id):
# but would be good to have the same validation here.
if pwd is not None and not pwd:
errors.update({'password': ['Invalid data for field']})
if errors:
return jsonify(result="error", message=errors), 400
status_code = 200
raise InvalidRequest(errors, status_code=400)
save_model_user(user_to_update, update_dict=update_dct, pwd=pwd)
return jsonify(data=user_schema.dump(user_to_update).data), status_code
return jsonify(data=user_schema.dump(user_to_update).data), 200
@user.route('/<uuid:user_id>/verify/password', methods=['POST'])
@@ -75,9 +75,10 @@ def verify_user_password(user_id):
try:
txt_pwd = request.get_json()['password']
except KeyError:
return jsonify(
result="error",
message={'password': ['Required field missing data']}), 400
message = 'Required field missing data'
errors = {'password': [message]}
raise InvalidRequest(errors, status_code=400)
if user_to_verify.check_password(txt_pwd):
user_to_verify.logged_in_at = datetime.utcnow()
save_model_user(user_to_verify)
@@ -85,7 +86,9 @@ def verify_user_password(user_id):
return jsonify({}), 204
else:
increment_failed_login_count(user_to_verify)
return jsonify(result='error', message={'password': ['Incorrect password']}), 400
message = 'Incorrect password'
errors = {'password': [message]}
raise InvalidRequest(errors, status_code=400)
@user.route('/<uuid:user_id>/verify/code', methods=['POST'])
@@ -105,12 +108,13 @@ def verify_user_code(user_id):
except KeyError:
errors.update({'code_type': ['Required field missing data']})
if errors:
return jsonify(result="error", message=errors), 400
raise InvalidRequest(errors, status_code=400)
code = get_user_code(user_to_verify, txt_code, txt_type)
if not code:
return jsonify(result="error", message="Code not found"), 404
raise InvalidRequest("Code not found", status_code=404)
if datetime.utcnow() > code.expiry_datetime or code.code_used:
return jsonify(result="error", message="Code has expired"), 400
raise InvalidRequest("Code has expired", status_code=400)
use_user_code(code.id)
return jsonify({}), 204
@@ -119,8 +123,6 @@ def verify_user_code(user_id):
def send_user_sms_code(user_id):
user_to_send_to = get_model_users(user_id=user_id)
verify_code, errors = request_verify_code_schema.load(request.get_json())
if errors:
return jsonify(result="error", message=errors), 400
secret_code = create_secret_code()
create_user_code(user_to_send_to, secret_code, 'sms')
@@ -150,8 +152,6 @@ def send_user_sms_code(user_id):
def send_user_email_verification(user_id):
user_to_send_to = get_model_users(user_id=user_id)
verify_code, errors = request_verify_code_schema.load(request.get_json())
if errors:
return jsonify(result="error", message=errors), 400
secret_code = create_secret_code()
create_user_code(user_to_send_to, secret_code, 'email')
@@ -191,8 +191,7 @@ def set_permissions(user_id, service_id):
user = get_model_users(user_id=user_id)
service = dao_fetch_service_by_id(service_id=service_id)
permissions, errors = permission_schema.load(request.get_json(), many=True)
if errors:
abort(400, errors)
for p in permissions:
p.user = user
p.service = service
@@ -204,7 +203,8 @@ def set_permissions(user_id, service_id):
def get_by_email():
email = request.args.get('email')
if not email:
return jsonify(result="error", message="invalid request"), 400
error = 'Invalid request. Email query string param required'
raise InvalidRequest(error, status_code=400)
fetched_user = get_user_by_email(email)
result = user_schema.dump(fetched_user)
@@ -214,8 +214,6 @@ def get_by_email():
@user.route('/reset-password', methods=['POST'])
def send_user_reset_password():
email, errors = email_data_request_schema.load(request.get_json())
if errors:
return jsonify(result="error", message=errors), 400
user_to_send_to = get_user_by_email(email['email'])