Register a before_request event for all blueprints, that defines the authentication requirement.

There are three authentication methods:
 - requires_no_auth - public endpoint that does not require an Authorisation header
 - requires_auth - public endpoints that need an API key in the Authorisation header
 - requires_admin_auth - private endpoint that requires an Authorisation header which contains the API key for the defined as the client admin user
This commit is contained in:
Rebecca Law
2017-03-16 18:15:49 +00:00
parent f880604c85
commit 78242812ef
19 changed files with 634 additions and 544 deletions

View File

@@ -2,7 +2,7 @@ import os
import uuid
from flask import Flask, _request_ctx_stack
from flask import request, url_for, g, jsonify
from flask import request, g, jsonify
from flask.ext.sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from monotonic import monotonic
@@ -20,7 +20,6 @@ from app.clients.sms.mmg import MMGClient
from app.clients.performance_platform.performance_platform_client import PerformancePlatformClient
from app.encryption import Encryption
DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ"
DATE_FORMAT = "%Y-%m-%d"
@@ -77,10 +76,10 @@ def create_app(app_name=None):
def register_blueprint(application):
from app.service.rest import service_blueprint
from app.user.rest import user as user_blueprint
from app.template.rest import template as template_blueprint
from app.user.rest import user_blueprint
from app.template.rest import template_blueprint
from app.status.healthcheck import status as status_blueprint
from app.job.rest import job as job_blueprint
from app.job.rest import job_blueprint
from app.notifications.rest import notifications as notifications_blueprint
from app.invite.rest import invite as invite_blueprint
from app.accept_invite.rest import accept_invite
@@ -90,49 +89,100 @@ def register_blueprint(application):
from app.spec.rest import spec as spec_blueprint
from app.organisation.rest import organisation_blueprint
from app.delivery.rest import delivery_blueprint
from app.notifications.receive_notifications import receive_notifications_blueprint
from app.notifications.notifications_ses_callback import ses_callback_blueprint
from app.notifications.notifications_sms_callback import sms_callback_blueprint
from app.status.healthcheck import status
from app.authentication.auth import requires_admin_auth, requires_auth, requires_no_auth
service_blueprint.before_request(requires_admin_auth)
application.register_blueprint(service_blueprint, url_prefix='/service')
user_blueprint.before_request(requires_admin_auth)
application.register_blueprint(user_blueprint, url_prefix='/user')
template_blueprint.before_request(requires_admin_auth)
application.register_blueprint(template_blueprint)
status_blueprint.before_request(requires_no_auth)
application.register_blueprint(status_blueprint)
notifications_blueprint.before_request(requires_auth)
receive_notifications_blueprint.before_request(requires_no_auth)
ses_callback_blueprint.before_request(requires_no_auth)
application.register_blueprint(ses_callback_blueprint)
sms_callback_blueprint.before_request(requires_no_auth)
application.register_blueprint(sms_callback_blueprint)
receive_notifications_blueprint.before_request(requires_no_auth)
application.register_blueprint(receive_notifications_blueprint)
notifications_blueprint.before_request(requires_auth)
application.register_blueprint(notifications_blueprint)
job_blueprint.before_request(requires_admin_auth)
application.register_blueprint(job_blueprint)
invite_blueprint.before_request(requires_admin_auth)
application.register_blueprint(invite_blueprint)
delivery_blueprint.before_request(requires_admin_auth)
application.register_blueprint(delivery_blueprint)
accept_invite.before_request(requires_admin_auth)
application.register_blueprint(accept_invite, url_prefix='/invite')
template_statistics_blueprint.before_request(requires_admin_auth)
application.register_blueprint(template_statistics_blueprint)
events_blueprint.before_request(requires_admin_auth)
application.register_blueprint(events_blueprint)
provider_details_blueprint.before_request(requires_admin_auth)
application.register_blueprint(provider_details_blueprint, url_prefix='/provider-details')
spec_blueprint.before_request(requires_no_auth)
application.register_blueprint(spec_blueprint, url_prefix='/spec')
organisation_blueprint.before_request(requires_admin_auth)
application.register_blueprint(organisation_blueprint, url_prefix='/organisation')
status.before_request(requires_no_auth)
application.register_blueprint(status)
def register_v2_blueprints(application):
from app.v2.notifications.post_notifications import notification_blueprint as post_notifications
from app.v2.notifications.get_notifications import notification_blueprint as get_notifications
from app.v2.notifications.post_notifications import v2_notification_blueprint as post_notifications
from app.v2.notifications.get_notifications import v2_notification_blueprint as get_notifications
from app.authentication.auth import requires_auth
post_notifications.before_request(requires_auth)
application.register_blueprint(post_notifications)
get_notifications.before_request(requires_auth)
application.register_blueprint(get_notifications)
def init_app(app):
@app.before_request
def required_authentication():
no_auth_req = [
url_for('status.show_status'),
url_for('notifications.process_ses_response'),
url_for('notifications.process_firetext_response'),
url_for('notifications.process_mmg_response'),
url_for('notifications.receive_mmg_sms'),
url_for('status.show_delivery_status'),
url_for('spec.get_spec')
]
if request.path not in no_auth_req:
from app.authentication import auth
error = auth.requires_auth()
if error:
return error
# @app.before_request
# def required_authentication():
# no_auth_req = [
# url_for('status.show_status'),
# url_for('notifications.process_ses_response'),
# url_for('notifications.process_firetext_response'),
# url_for('notifications.process_mmg_response'),
# url_for('notifications.receive_mmg_sms'),
# url_for('status.show_delivery_status'),
# url_for('spec.get_spec')
# ]
#
# if request.path not in no_auth_req:
# from app.authentication import auth
# error = auth.requires_auth()
# if error:
# return error
@app.before_request
def record_user_agent():

View File

@@ -39,14 +39,13 @@ def get_auth_token(req):
return auth_header[7:]
def requires_no_auth():
pass
def requires_admin_auth():
auth_token = get_auth_token(request)
try:
client = get_token_issuer(auth_token)
except TokenDecodeError as e:
raise AuthError(e.message, 403)
except TokenIssuerError:
raise AuthError("Invalid token: iss not provided", 403)
client = __get_token_issuer(auth_token)
if client == current_app.config.get('ADMIN_CLIENT_USER_NAME'):
g.service_id = current_app.config.get('ADMIN_CLIENT_USER_NAME')
@@ -57,16 +56,7 @@ def requires_admin_auth():
def requires_auth():
auth_token = get_auth_token(request)
try:
client = get_token_issuer(auth_token)
except TokenDecodeError as e:
raise AuthError(e.message, 403)
except TokenIssuerError:
raise AuthError("Invalid token: iss not provided", 403)
if client == current_app.config.get('ADMIN_CLIENT_USER_NAME'):
g.service_id = current_app.config.get('ADMIN_CLIENT_USER_NAME')
return handle_admin_key(auth_token, current_app.config.get('ADMIN_CLIENT_SECRET'))
client = __get_token_issuer(auth_token)
try:
service = dao_fetch_service_by_id(client)
@@ -98,12 +88,22 @@ def requires_auth():
raise AuthError("Invalid token: signature, api token is not valid", 403)
def __get_token_issuer(auth_token):
try:
client = get_token_issuer(auth_token)
except TokenIssuerError:
raise AuthError("Invalid token: iss field not provided", 403)
except TokenDecodeError as e:
raise AuthError("Invalid token: signature, api token is not valid", 403)
return client
def handle_admin_key(auth_token, secret):
try:
get_decode_errors(auth_token, secret)
return
except TokenDecodeError as e:
raise AuthError(e.message, 403)
raise AuthError("Invalid token: signature, api token is not valid", 403)
def get_decode_errors(auth_token, unsigned_secret):

View File

@@ -34,17 +34,17 @@ from app.models import JOB_STATUS_SCHEDULED, JOB_STATUS_PENDING, JOB_STATUS_CANC
from app.utils import pagination_links
job = Blueprint('job', __name__, url_prefix='/service/<uuid:service_id>/job')
job_blueprint = Blueprint('job', __name__, url_prefix='/service/<uuid:service_id>/job')
from app.errors import (
register_errors,
InvalidRequest
)
register_errors(job)
register_errors(job_blueprint)
@job.route('/<job_id>', methods=['GET'])
@job_blueprint.route('/<job_id>', methods=['GET'])
def get_job_by_service_and_job_id(service_id, job_id):
job = dao_get_job_by_service_id_and_job_id(service_id, job_id)
statistics = dao_get_notification_outcomes_for_job(service_id, job_id)
@@ -55,7 +55,7 @@ def get_job_by_service_and_job_id(service_id, job_id):
return jsonify(data=data)
@job.route('/<job_id>/cancel', methods=['POST'])
@job_blueprint.route('/<job_id>/cancel', methods=['POST'])
def cancel_job(service_id, job_id):
job = dao_get_future_scheduled_job_by_id_and_service_id(job_id, service_id)
job.job_status = JOB_STATUS_CANCELLED
@@ -64,7 +64,7 @@ def cancel_job(service_id, job_id):
return get_job_by_service_and_job_id(service_id, job_id)
@job.route('/<job_id>/notifications', methods=['GET'])
@job_blueprint.route('/<job_id>/notifications', methods=['GET'])
def get_all_notifications_for_service_job(service_id, job_id):
data = notifications_filter_schema.load(request.args).data
page = data['page'] if 'page' in data else 1
@@ -100,7 +100,7 @@ def get_all_notifications_for_service_job(service_id, job_id):
), 200
@job.route('', methods=['GET'])
@job_blueprint.route('', methods=['GET'])
def get_jobs_by_service(service_id):
if request.args.get('limit_days'):
try:
@@ -117,7 +117,7 @@ def get_jobs_by_service(service_id):
return jsonify(**get_paginated_jobs(service_id, limit_days, statuses, page))
@job.route('', methods=['POST'])
@job_blueprint.route('', methods=['POST'])
def create_job(service_id):
service = dao_fetch_service_by_id(service_id)
if not service.active:

View File

@@ -0,0 +1,101 @@
from datetime import datetime
from flask import (
Blueprint,
jsonify,
request,
current_app,
json
)
from app import statsd_client
from app.clients.email.aws_ses import get_aws_responses
from app.dao import (
notifications_dao
)
from app.notifications.process_client_response import validate_callback_data
ses_callback_blueprint = Blueprint('notifications_ses_callback_', __name__)
from app.errors import (
register_errors,
InvalidRequest
)
register_errors(ses_callback_blueprint)
@ses_callback_blueprint.route('/notifications/email/ses', methods=['POST'])
def process_ses_response():
client_name = 'SES'
try:
ses_request = json.loads(request.data)
if 'Type' in ses_request and ses_request['Type'] == 'SubscriptionConfirmation':
current_app.logger.info("SNS subscription confirmation url: {}".format(ses_request['SubscribeURL']))
errors = validate_callback_data(data=ses_request, fields=['Message'], client_name=client_name)
if errors:
raise InvalidRequest(errors, status_code=400)
ses_message = json.loads(ses_request['Message'])
errors = validate_callback_data(data=ses_message, fields=['notificationType'], client_name=client_name)
if errors:
raise InvalidRequest(errors, status_code=400)
notification_type = ses_message['notificationType']
if notification_type == 'Bounce':
if ses_message['bounce']['bounceType'] == 'Permanent':
notification_type = ses_message['bounce']['bounceType'] # permanent or not
else:
notification_type = 'Temporary'
try:
aws_response_dict = get_aws_responses(notification_type)
except KeyError:
error = "{} callback failed: status {} not found".format(client_name, notification_type)
raise InvalidRequest(error, status_code=400)
notification_status = aws_response_dict['notification_status']
try:
reference = ses_message['mail']['messageId']
notification = notifications_dao.update_notification_status_by_reference(
reference,
notification_status
)
if not notification:
error = "SES callback failed: notification either not found or already updated " \
"from sending. Status {} for notification reference {}".format(notification_status, reference)
raise InvalidRequest(error, status_code=404)
if not aws_response_dict['success']:
current_app.logger.info(
"SES delivery failed: notification id {} and reference {} has error found. Status {}".format(
notification.id,
reference,
aws_response_dict['message']
)
)
else:
current_app.logger.info('{} callback return status of {} for notification: {}'.format(
client_name,
notification_status,
notification.id))
statsd_client.incr('callback.ses.{}'.format(notification_status))
if notification.sent_at:
statsd_client.timing_with_dates(
'callback.ses.elapsed-time'.format(client_name.lower()),
datetime.utcnow(),
notification.sent_at
)
return jsonify(
result="success", message="SES callback succeeded"
), 200
except KeyError:
message = "SES callback failed: messageId missing"
raise InvalidRequest(message, status_code=400)
except ValueError as ex:
error = "{} callback failed: invalid json".format(client_name)
raise InvalidRequest(error, status_code=400)

View File

@@ -0,0 +1,47 @@
from flask import Blueprint
from flask import json
from flask import request, jsonify
from app.errors import InvalidRequest, register_errors
from app.notifications.process_client_response import validate_callback_data, process_sms_client_response
sms_callback_blueprint = Blueprint("sms_callback_blueprint", __name__, url_prefix="/notifications/sms")
register_errors(sms_callback_blueprint)
@sms_callback_blueprint.route('/mmg', methods=['POST'])
def process_mmg_response():
client_name = 'MMG'
data = json.loads(request.data)
errors = validate_callback_data(data=data,
fields=['status', 'CID'],
client_name=client_name)
if errors:
raise InvalidRequest(errors, status_code=400)
success, errors = process_sms_client_response(status=str(data.get('status')),
reference=data.get('CID'),
client_name=client_name)
if errors:
raise InvalidRequest(errors, status_code=400)
else:
return jsonify(result='success', message=success), 200
@sms_callback_blueprint.route('/firetext', methods=['POST'])
def process_firetext_response():
client_name = 'Firetext'
errors = validate_callback_data(data=request.form,
fields=['status', 'reference'],
client_name=client_name)
if errors:
raise InvalidRequest(errors, status_code=400)
status = request.form.get('status')
success, errors = process_sms_client_response(status=status,
reference=request.form.get('reference'),
client_name=client_name)
if errors:
raise InvalidRequest(errors, status_code=400)
else:
return jsonify(result='success', message=success), 200

View File

@@ -0,0 +1,17 @@
from flask import Blueprint
from flask import current_app
from flask import request
from app.errors import register_errors
receive_notifications_blueprint = Blueprint('receive_notifications', __name__)
register_errors(receive_notifications_blueprint)
@receive_notifications_blueprint.route('/notifications/sms/receive/mmg', methods=['POST'])
def receive_mmg_sms():
post_data = request.get_json()
post_data.pop('MSISDN', None)
current_app.logger.info("Recieve notification form data: {}".format(post_data))
return "RECEIVED"

View File

@@ -1,5 +1,3 @@
from datetime import datetime
from flask import (
Blueprint,
jsonify,
@@ -8,8 +6,7 @@ from flask import (
json
)
from app import api_user, statsd_client
from app.clients.email.aws_ses import get_aws_responses
from app import api_user
from app.dao import (
templates_dao,
services_dao,
@@ -49,129 +46,6 @@ from app.errors import (
register_errors(notifications)
@notifications.route('/notifications/sms/receive/mmg', methods=['POST'])
def receive_mmg_sms():
post_data = request.get_json()
post_data.pop('MSISDN', None)
current_app.logger.info("Recieve notification form data: {}".format(post_data))
return "RECEIVED"
@notifications.route('/notifications/email/ses', methods=['POST'])
def process_ses_response():
client_name = 'SES'
try:
ses_request = json.loads(request.data)
if 'Type' in ses_request and ses_request['Type'] == 'SubscriptionConfirmation':
current_app.logger.info("SNS subscription confirmation url: {}".format(ses_request['SubscribeURL']))
errors = validate_callback_data(data=ses_request, fields=['Message'], client_name=client_name)
if errors:
raise InvalidRequest(errors, status_code=400)
ses_message = json.loads(ses_request['Message'])
errors = validate_callback_data(data=ses_message, fields=['notificationType'], client_name=client_name)
if errors:
raise InvalidRequest(errors, status_code=400)
notification_type = ses_message['notificationType']
if notification_type == 'Bounce':
if ses_message['bounce']['bounceType'] == 'Permanent':
notification_type = ses_message['bounce']['bounceType'] # permanent or not
else:
notification_type = 'Temporary'
try:
aws_response_dict = get_aws_responses(notification_type)
except KeyError:
error = "{} callback failed: status {} not found".format(client_name, notification_type)
raise InvalidRequest(error, status_code=400)
notification_status = aws_response_dict['notification_status']
try:
reference = ses_message['mail']['messageId']
notification = notifications_dao.update_notification_status_by_reference(
reference,
notification_status
)
if not notification:
error = "SES callback failed: notification either not found or already updated " \
"from sending. Status {} for notification reference {}".format(notification_status, reference)
raise InvalidRequest(error, status_code=404)
if not aws_response_dict['success']:
current_app.logger.info(
"SES delivery failed: notification id {} and reference {} has error found. Status {}".format(
notification.id,
reference,
aws_response_dict['message']
)
)
else:
current_app.logger.info('{} callback return status of {} for notification: {}'.format(
client_name,
notification_status,
notification.id))
statsd_client.incr('callback.ses.{}'.format(notification_status))
if notification.sent_at:
statsd_client.timing_with_dates(
'callback.ses.elapsed-time'.format(client_name.lower()),
datetime.utcnow(),
notification.sent_at
)
return jsonify(
result="success", message="SES callback succeeded"
), 200
except KeyError:
message = "SES callback failed: messageId missing"
raise InvalidRequest(message, status_code=400)
except ValueError as ex:
error = "{} callback failed: invalid json".format(client_name)
raise InvalidRequest(error, status_code=400)
@notifications.route('/notifications/sms/mmg', methods=['POST'])
def process_mmg_response():
client_name = 'MMG'
data = json.loads(request.data)
errors = validate_callback_data(data=data,
fields=['status', 'CID'],
client_name=client_name)
if errors:
raise InvalidRequest(errors, status_code=400)
success, errors = process_sms_client_response(status=str(data.get('status')),
reference=data.get('CID'),
client_name=client_name)
if errors:
raise InvalidRequest(errors, status_code=400)
else:
return jsonify(result='success', message=success), 200
@notifications.route('/notifications/sms/firetext', methods=['POST'])
def process_firetext_response():
client_name = 'Firetext'
errors = validate_callback_data(data=request.form,
fields=['status', 'reference'],
client_name=client_name)
if errors:
raise InvalidRequest(errors, status_code=400)
status = request.form.get('status')
success, errors = process_sms_client_response(status=status,
reference=request.form.get('reference'),
client_name=client_name)
if errors:
raise InvalidRequest(errors, status_code=400)
else:
return jsonify(result='success', message=success), 200
@notifications.route('/notifications/<uuid:notification_id>', methods=['GET'])
def get_notification_by_id(notification_id):
notification = notifications_dao.get_notification_with_personalisation(str(api_user.service_id),

View File

@@ -41,8 +41,7 @@ from app.dao import notifications_dao
from app.dao.provider_statistics_dao import get_fragment_count
from app.dao.users_dao import get_user_by_id
from app.errors import (
InvalidRequest,
register_errors)
InvalidRequest, register_errors)
from app.service import statistics
from app.service.utils import get_whitelist_objects
from app.schemas import (
@@ -57,11 +56,8 @@ from app.schemas import (
from app.utils import pagination_links, get_london_midnight_in_utc
from flask import Blueprint
from app.authentication.auth import requires_admin_auth
service_blueprint = Blueprint('service', __name__)
service_blueprint.before_request(requires_admin_auth)
register_errors(service_blueprint)

View File

@@ -17,7 +17,7 @@ from app.dao.services_dao import dao_fetch_service_by_id
from app.models import SMS_TYPE
from app.schemas import (template_schema, template_history_schema)
template = Blueprint('template', __name__, url_prefix='/service/<uuid:service_id>/template')
template_blueprint = Blueprint('template', __name__, url_prefix='/service/<uuid:service_id>/template')
from app.errors import (
register_errors,
@@ -25,7 +25,7 @@ from app.errors import (
)
from app.utils import get_template_instance
register_errors(template)
register_errors(template_blueprint)
def _content_count_greater_than_limit(content, template_type):
@@ -35,7 +35,7 @@ def _content_count_greater_than_limit(content, template_type):
return template.content_count > current_app.config.get('SMS_CHAR_COUNT_LIMIT')
@template.route('', methods=['POST'])
@template_blueprint.route('', methods=['POST'])
def create_template(service_id):
fetched_service = dao_fetch_service_by_id(service_id=service_id)
new_template = template_schema.load(request.get_json()).data
@@ -51,7 +51,7 @@ def create_template(service_id):
return jsonify(data=template_schema.dump(new_template).data), 201
@template.route('/<uuid:template_id>', methods=['POST'])
@template_blueprint.route('/<uuid:template_id>', methods=['POST'])
def update_template(service_id, template_id):
fetched_template = dao_get_template_by_id_and_service_id(template_id=template_id, service_id=service_id)
@@ -73,21 +73,21 @@ def update_template(service_id, template_id):
return jsonify(data=template_schema.dump(update_dict).data), 200
@template.route('', methods=['GET'])
@template_blueprint.route('', methods=['GET'])
def get_all_templates_for_service(service_id):
templates = dao_get_all_templates_for_service(service_id=service_id)
data = template_schema.dump(templates, many=True).data
return jsonify(data=data)
@template.route('/<uuid:template_id>', methods=['GET'])
@template_blueprint.route('/<uuid:template_id>', methods=['GET'])
def get_template_by_id_and_service_id(service_id, template_id):
fetched_template = dao_get_template_by_id_and_service_id(template_id=template_id, service_id=service_id)
data = template_schema.dump(fetched_template).data
return jsonify(data=data)
@template.route('/<uuid:template_id>/preview', methods=['GET'])
@template_blueprint.route('/<uuid:template_id>/preview', methods=['GET'])
def preview_template_by_id_and_service_id(service_id, template_id):
fetched_template = dao_get_template_by_id_and_service_id(template_id=template_id, service_id=service_id)
data = template_schema.dump(fetched_template).data
@@ -106,7 +106,7 @@ def preview_template_by_id_and_service_id(service_id, template_id):
return jsonify(data)
@template.route('/<uuid:template_id>/version/<int:version>')
@template_blueprint.route('/<uuid:template_id>/version/<int:version>')
def get_template_version(service_id, template_id, version):
data = template_history_schema.dump(
dao_get_template_by_id_and_service_id(
@@ -118,7 +118,7 @@ def get_template_version(service_id, template_id, version):
return jsonify(data=data)
@template.route('/<uuid:template_id>/versions')
@template_blueprint.route('/<uuid:template_id>/versions')
def get_template_versions(service_id, template_id):
data = template_history_schema.dump(
dao_get_template_versions(service_id=service_id, template_id=template_id),

View File

@@ -41,11 +41,11 @@ from app.errors import (
)
from app.utils import url_with_token
user = Blueprint('user', __name__)
register_errors(user)
user_blueprint = Blueprint('user', __name__)
register_errors(user_blueprint)
@user.route('', methods=['POST'])
@user_blueprint.route('', methods=['POST'])
def create_user():
user_to_create, errors = user_schema.load(request.get_json())
req_json = request.get_json()
@@ -56,7 +56,7 @@ def create_user():
return jsonify(data=user_schema.dump(user_to_create).data), 201
@user.route('/<uuid:user_id>', methods=['PUT'])
@user_blueprint.route('/<uuid:user_id>', methods=['PUT'])
def update_user(user_id):
user_to_update = get_user_by_id(user_id=user_id)
req_json = request.get_json()
@@ -73,7 +73,7 @@ def update_user(user_id):
return jsonify(data=user_schema.dump(user_to_update).data), 200
@user.route('/<uuid:user_id>', methods=['POST'])
@user_blueprint.route('/<uuid:user_id>', methods=['POST'])
def update_user_attribute(user_id):
user_to_update = get_user_by_id(user_id=user_id)
req_json = request.get_json()
@@ -84,14 +84,14 @@ def update_user_attribute(user_id):
return jsonify(data=user_schema.dump(user_to_update).data), 200
@user.route('/<uuid:user_id>/reset-failed-login-count', methods=['POST'])
@user_blueprint.route('/<uuid:user_id>/reset-failed-login-count', methods=['POST'])
def user_reset_failed_login_count(user_id):
user_to_update = get_user_by_id(user_id=user_id)
reset_failed_login_count(user_to_update)
return jsonify(data=user_schema.dump(user_to_update).data), 200
@user.route('/<uuid:user_id>/verify/password', methods=['POST'])
@user_blueprint.route('/<uuid:user_id>/verify/password', methods=['POST'])
def verify_user_password(user_id):
user_to_verify = get_user_by_id(user_id=user_id)
@@ -112,7 +112,7 @@ def verify_user_password(user_id):
raise InvalidRequest(errors, status_code=400)
@user.route('/<uuid:user_id>/verify/code', methods=['POST'])
@user_blueprint.route('/<uuid:user_id>/verify/code', methods=['POST'])
def verify_user_code(user_id):
user_to_verify = get_user_by_id(user_id=user_id)
@@ -151,7 +151,7 @@ def verify_user_code(user_id):
return jsonify({}), 204
@user.route('/<uuid:user_id>/sms-code', methods=['POST'])
@user_blueprint.route('/<uuid:user_id>/sms-code', methods=['POST'])
def send_user_sms_code(user_id):
user_to_send_to = get_user_by_id(user_id=user_id)
verify_code, errors = request_verify_code_schema.load(request.get_json())
@@ -187,7 +187,7 @@ def send_user_sms_code(user_id):
return jsonify({}), 204
@user.route('/<uuid:user_id>/change-email-verification', methods=['POST'])
@user_blueprint.route('/<uuid:user_id>/change-email-verification', methods=['POST'])
def send_user_confirm_new_email(user_id):
user_to_send_to = get_user_by_id(user_id=user_id)
email, errors = email_data_request_schema.load(request.get_json())
@@ -216,7 +216,7 @@ def send_user_confirm_new_email(user_id):
return jsonify({}), 204
@user.route('/<uuid:user_id>/email-verification', methods=['POST'])
@user_blueprint.route('/<uuid:user_id>/email-verification', methods=['POST'])
def send_user_email_verification(user_id):
user_to_send_to = get_user_by_id(user_id=user_id)
secret_code = create_secret_code()
@@ -244,7 +244,7 @@ def send_user_email_verification(user_id):
return jsonify({}), 204
@user.route('/<uuid:user_id>/email-already-registered', methods=['POST'])
@user_blueprint.route('/<uuid:user_id>/email-already-registered', methods=['POST'])
def send_already_registered_email(user_id):
to, errors = email_data_request_schema.load(request.get_json())
template = dao_get_template_by_id(current_app.config['ALREADY_REGISTERED_EMAIL_TEMPLATE_ID'])
@@ -270,15 +270,15 @@ def send_already_registered_email(user_id):
return jsonify({}), 204
@user.route('/<uuid:user_id>', methods=['GET'])
@user.route('', methods=['GET'])
@user_blueprint.route('/<uuid:user_id>', methods=['GET'])
@user_blueprint.route('', methods=['GET'])
def get_user(user_id=None):
users = get_user_by_id(user_id=user_id)
result = user_schema.dump(users, many=True) if isinstance(users, list) else user_schema.dump(users)
return jsonify(data=result.data)
@user.route('/<uuid:user_id>/service/<uuid:service_id>/permission', methods=['POST'])
@user_blueprint.route('/<uuid:user_id>/service/<uuid:service_id>/permission', methods=['POST'])
def set_permissions(user_id, service_id):
# TODO fix security hole, how do we verify that the user
# who is making this request has permission to make the request.
@@ -293,7 +293,7 @@ def set_permissions(user_id, service_id):
return jsonify({}), 204
@user.route('/email', methods=['GET'])
@user_blueprint.route('/email', methods=['GET'])
def get_by_email():
email = request.args.get('email')
if not email:
@@ -305,7 +305,7 @@ def get_by_email():
return jsonify(data=result.data)
@user.route('/reset-password', methods=['POST'])
@user_blueprint.route('/reset-password', methods=['POST'])
def send_user_reset_password():
email, errors = email_data_request_schema.load(request.get_json())
@@ -332,7 +332,7 @@ def send_user_reset_password():
return jsonify({}), 204
@user.route('/<uuid:user_id>/update-password', methods=['POST'])
@user_blueprint.route('/<uuid:user_id>/update-password', methods=['POST'])
def update_password(user_id):
user = get_user_by_id(user_id=user_id)
req_json = request.get_json()

View File

@@ -1,7 +1,6 @@
from flask import Blueprint
from app.v2.errors import register_errors
notification_blueprint = Blueprint("v2_notifications", __name__, url_prefix='/v2/notifications')
v2_notification_blueprint = Blueprint("v2_notifications", __name__, url_prefix='/v2/notifications')
register_errors(notification_blueprint)
register_errors(v2_notification_blueprint)

View File

@@ -6,11 +6,11 @@ from werkzeug.exceptions import abort
from app import api_user
from app.dao import notifications_dao
from app.schema_validation import validate
from app.v2.notifications import notification_blueprint
from app.v2.notifications import v2_notification_blueprint
from app.v2.notifications.notification_schemas import get_notifications_request
@notification_blueprint.route("/<id>", methods=['GET'])
@v2_notification_blueprint.route("/<id>", methods=['GET'])
def get_notification_by_id(id):
try:
casted_id = uuid.UUID(id)
@@ -23,7 +23,7 @@ def get_notification_by_id(id):
return jsonify(notification.serialize()), 200
@notification_blueprint.route("", methods=['GET'])
@v2_notification_blueprint.route("", methods=['GET'])
def get_notifications():
_data = request.args.to_dict(flat=False)

View File

@@ -15,13 +15,13 @@ from app.notifications.validators import (check_service_message_limit,
validate_and_format_recipient)
from app.schema_validation import validate
from app.v2.errors import BadRequestError
from app.v2.notifications import notification_blueprint
from app.v2.notifications import v2_notification_blueprint
from app.v2.notifications.notification_schemas import (post_sms_request,
create_post_sms_response_from_notification, post_email_request,
create_post_email_response_from_notification)
@notification_blueprint.route('/<notification_type>', methods=['POST'])
@v2_notification_blueprint.route('/<notification_type>', methods=['POST'])
def post_notification(notification_type):
if notification_type == EMAIL_TYPE:
form = validate(request.get_json(), post_email_request)