mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-21 07:51:13 -05:00
remove the global_invite (accept_invite) endpoint
move the endpoints into service_invite/rest.py and organisation/invite_rest.py respectively. Remove the prefix from all the blueprints to allow this.
This commit is contained in:
@@ -146,7 +146,6 @@ def register_blueprint(application):
|
|||||||
from app.complaint.complaint_rest import complaint_blueprint
|
from app.complaint.complaint_rest import complaint_blueprint
|
||||||
from app.email_branding.rest import email_branding_blueprint
|
from app.email_branding.rest import email_branding_blueprint
|
||||||
from app.events.rest import events as events_blueprint
|
from app.events.rest import events as events_blueprint
|
||||||
from app.global_invite.rest import global_invite_blueprint
|
|
||||||
from app.inbound_number.rest import inbound_number_blueprint
|
from app.inbound_number.rest import inbound_number_blueprint
|
||||||
from app.inbound_sms.rest import inbound_sms as inbound_sms_blueprint
|
from app.inbound_sms.rest import inbound_sms as inbound_sms_blueprint
|
||||||
from app.job.rest import job_blueprint
|
from app.job.rest import job_blueprint
|
||||||
@@ -215,15 +214,15 @@ def register_blueprint(application):
|
|||||||
service_invite_blueprint.before_request(requires_admin_auth)
|
service_invite_blueprint.before_request(requires_admin_auth)
|
||||||
application.register_blueprint(service_invite_blueprint)
|
application.register_blueprint(service_invite_blueprint)
|
||||||
|
|
||||||
|
organisation_invite_blueprint.before_request(requires_admin_auth)
|
||||||
|
application.register_blueprint(organisation_invite_blueprint)
|
||||||
|
|
||||||
inbound_number_blueprint.before_request(requires_admin_auth)
|
inbound_number_blueprint.before_request(requires_admin_auth)
|
||||||
application.register_blueprint(inbound_number_blueprint)
|
application.register_blueprint(inbound_number_blueprint)
|
||||||
|
|
||||||
inbound_sms_blueprint.before_request(requires_admin_auth)
|
inbound_sms_blueprint.before_request(requires_admin_auth)
|
||||||
application.register_blueprint(inbound_sms_blueprint)
|
application.register_blueprint(inbound_sms_blueprint)
|
||||||
|
|
||||||
global_invite_blueprint.before_request(requires_admin_auth)
|
|
||||||
application.register_blueprint(global_invite_blueprint, url_prefix='/invite')
|
|
||||||
|
|
||||||
template_statistics_blueprint.before_request(requires_admin_auth)
|
template_statistics_blueprint.before_request(requires_admin_auth)
|
||||||
application.register_blueprint(template_statistics_blueprint)
|
application.register_blueprint(template_statistics_blueprint)
|
||||||
|
|
||||||
@@ -251,9 +250,6 @@ def register_blueprint(application):
|
|||||||
organisation_blueprint.before_request(requires_admin_auth)
|
organisation_blueprint.before_request(requires_admin_auth)
|
||||||
application.register_blueprint(organisation_blueprint, url_prefix='/organisations')
|
application.register_blueprint(organisation_blueprint, url_prefix='/organisations')
|
||||||
|
|
||||||
organisation_invite_blueprint.before_request(requires_admin_auth)
|
|
||||||
application.register_blueprint(organisation_invite_blueprint)
|
|
||||||
|
|
||||||
complaint_blueprint.before_request(requires_admin_auth)
|
complaint_blueprint.before_request(requires_admin_auth)
|
||||||
application.register_blueprint(complaint_blueprint)
|
application.register_blueprint(complaint_blueprint)
|
||||||
|
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
from flask import Blueprint, current_app, jsonify
|
|
||||||
from itsdangerous import BadData, SignatureExpired
|
|
||||||
from notifications_utils.url_safe_token import check_token
|
|
||||||
|
|
||||||
from app.dao.invited_user_dao import get_invited_user_by_id
|
|
||||||
from app.dao.organisation_dao import dao_get_invited_organisation_user
|
|
||||||
from app.errors import InvalidRequest, register_errors
|
|
||||||
from app.schemas import invited_user_schema
|
|
||||||
|
|
||||||
global_invite_blueprint = Blueprint('global_invite', __name__)
|
|
||||||
register_errors(global_invite_blueprint)
|
|
||||||
|
|
||||||
|
|
||||||
@global_invite_blueprint.route('/<invitation_type>/<token>', methods=['GET'])
|
|
||||||
def validate_invitation_token(invitation_type, token):
|
|
||||||
|
|
||||||
max_age_seconds = 60 * 60 * 24 * current_app.config['INVITATION_EXPIRATION_DAYS']
|
|
||||||
|
|
||||||
try:
|
|
||||||
invited_user_id = check_token(token,
|
|
||||||
current_app.config['SECRET_KEY'],
|
|
||||||
current_app.config['DANGEROUS_SALT'],
|
|
||||||
max_age_seconds)
|
|
||||||
except SignatureExpired:
|
|
||||||
errors = {'invitation':
|
|
||||||
'Your invitation to GOV.UK Notify has expired. '
|
|
||||||
'Please ask the person that invited you to send you another one'}
|
|
||||||
raise InvalidRequest(errors, status_code=400)
|
|
||||||
except BadData:
|
|
||||||
errors = {'invitation': 'Something’s wrong with this link. Make sure you’ve copied the whole thing.'}
|
|
||||||
raise InvalidRequest(errors, status_code=400)
|
|
||||||
|
|
||||||
if invitation_type == 'service':
|
|
||||||
invited_user = get_invited_user_by_id(invited_user_id)
|
|
||||||
return jsonify(data=invited_user_schema.dump(invited_user).data), 200
|
|
||||||
elif invitation_type == 'organisation':
|
|
||||||
invited_user = dao_get_invited_organisation_user(invited_user_id)
|
|
||||||
return jsonify(data=invited_user.serialize()), 200
|
|
||||||
else:
|
|
||||||
raise InvalidRequest("Unrecognised invitation type: {}".format(invitation_type))
|
|
||||||
|
|
||||||
|
|
||||||
@global_invite_blueprint.route('/service/<uuid:invited_user_id>', methods=['GET'])
|
|
||||||
def get_invited_user(invited_user_id):
|
|
||||||
invited_user = get_invited_user_by_id(invited_user_id)
|
|
||||||
return jsonify(data=invited_user_schema.dump(invited_user).data), 200
|
|
||||||
|
|
||||||
|
|
||||||
@global_invite_blueprint.route('/organisation/<uuid:invited_org_user_id>', methods=['GET'])
|
|
||||||
def get_invited_org_user(invited_org_user_id):
|
|
||||||
invited_user = dao_get_invited_organisation_user(invited_org_user_id)
|
|
||||||
return jsonify(data=invited_user.serialize()), 200
|
|
||||||
@@ -1,14 +1,18 @@
|
|||||||
from flask import Blueprint, current_app, jsonify, request
|
from flask import Blueprint, current_app, jsonify, request
|
||||||
from notifications_utils.url_safe_token import generate_token
|
from itsdangerous import BadData, SignatureExpired
|
||||||
|
from notifications_utils.url_safe_token import check_token, generate_token
|
||||||
|
|
||||||
from app.config import QueueNames
|
from app.config import QueueNames
|
||||||
from app.dao.invited_org_user_dao import (
|
from app.dao.invited_org_user_dao import (
|
||||||
get_invited_org_user,
|
get_invited_org_user as dao_get_invited_org_user,
|
||||||
|
)
|
||||||
|
from app.dao.invited_org_user_dao import (
|
||||||
get_invited_org_users_for_organisation,
|
get_invited_org_users_for_organisation,
|
||||||
save_invited_org_user,
|
save_invited_org_user,
|
||||||
)
|
)
|
||||||
|
from app.dao.organisation_dao import dao_get_invited_organisation_user
|
||||||
from app.dao.templates_dao import dao_get_template_by_id
|
from app.dao.templates_dao import dao_get_template_by_id
|
||||||
from app.errors import register_errors
|
from app.errors import InvalidRequest, register_errors
|
||||||
from app.models import EMAIL_TYPE, KEY_TYPE_NORMAL, InvitedOrganisationUser
|
from app.models import EMAIL_TYPE, KEY_TYPE_NORMAL, InvitedOrganisationUser
|
||||||
from app.notifications.process_notifications import (
|
from app.notifications.process_notifications import (
|
||||||
persist_notification,
|
persist_notification,
|
||||||
@@ -20,14 +24,12 @@ from app.organisation.organisation_schema import (
|
|||||||
)
|
)
|
||||||
from app.schema_validation import validate
|
from app.schema_validation import validate
|
||||||
|
|
||||||
organisation_invite_blueprint = Blueprint(
|
organisation_invite_blueprint = Blueprint('organisation_invite', __name__)
|
||||||
'organisation_invite', __name__,
|
|
||||||
url_prefix='/organisation/<uuid:organisation_id>/invite')
|
|
||||||
|
|
||||||
register_errors(organisation_invite_blueprint)
|
register_errors(organisation_invite_blueprint)
|
||||||
|
|
||||||
|
|
||||||
@organisation_invite_blueprint.route('', methods=['POST'])
|
@organisation_invite_blueprint.route('/organisation/<uuid:organisation_id>/invite', methods=['POST'])
|
||||||
def invite_user_to_org(organisation_id):
|
def invite_user_to_org(organisation_id):
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
validate(data, post_create_invited_org_user_status_schema)
|
validate(data, post_create_invited_org_user_status_schema)
|
||||||
@@ -69,21 +71,27 @@ def invite_user_to_org(organisation_id):
|
|||||||
return jsonify(data=invited_org_user.serialize()), 201
|
return jsonify(data=invited_org_user.serialize()), 201
|
||||||
|
|
||||||
|
|
||||||
@organisation_invite_blueprint.route('', methods=['GET'])
|
@organisation_invite_blueprint.route('/organisation/<uuid:organisation_id>/invite', methods=['GET'])
|
||||||
def get_invited_org_users_by_organisation(organisation_id):
|
def get_invited_org_users_by_organisation(organisation_id):
|
||||||
invited_org_users = get_invited_org_users_for_organisation(organisation_id)
|
invited_org_users = get_invited_org_users_for_organisation(organisation_id)
|
||||||
return jsonify(data=[x.serialize() for x in invited_org_users]), 200
|
return jsonify(data=[x.serialize() for x in invited_org_users]), 200
|
||||||
|
|
||||||
|
|
||||||
@organisation_invite_blueprint.route('/<invited_org_user_id>', methods=['GET'])
|
@organisation_invite_blueprint.route(
|
||||||
|
'/organisation/<uuid:organisation_id>/invite/<invited_org_user_id>',
|
||||||
|
methods=['GET']
|
||||||
|
)
|
||||||
def get_invited_org_user_by_organisation(organisation_id, invited_org_user_id):
|
def get_invited_org_user_by_organisation(organisation_id, invited_org_user_id):
|
||||||
invited_org_user = get_invited_org_user(organisation_id, invited_org_user_id)
|
invited_org_user = dao_get_invited_org_user(organisation_id, invited_org_user_id)
|
||||||
return jsonify(data=invited_org_user.serialize()), 200
|
return jsonify(data=invited_org_user.serialize()), 200
|
||||||
|
|
||||||
|
|
||||||
@organisation_invite_blueprint.route('/<invited_org_user_id>', methods=['POST'])
|
@organisation_invite_blueprint.route(
|
||||||
|
'/organisation/<uuid:organisation_id>/invite/<invited_org_user_id>',
|
||||||
|
methods=['POST']
|
||||||
|
)
|
||||||
def update_org_invite_status(organisation_id, invited_org_user_id):
|
def update_org_invite_status(organisation_id, invited_org_user_id):
|
||||||
fetched = get_invited_org_user(organisation_id=organisation_id, invited_org_user_id=invited_org_user_id)
|
fetched = dao_get_invited_org_user(organisation_id=organisation_id, invited_org_user_id=invited_org_user_id)
|
||||||
|
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
validate(data, post_update_invited_org_user_status_schema)
|
validate(data, post_update_invited_org_user_status_schema)
|
||||||
@@ -105,3 +113,32 @@ def invited_org_user_url(invited_org_user_id, invite_link_host=None):
|
|||||||
invite_link_host = current_app.config['ADMIN_BASE_URL']
|
invite_link_host = current_app.config['ADMIN_BASE_URL']
|
||||||
|
|
||||||
return '{0}/organisation-invitation/{1}'.format(invite_link_host, token)
|
return '{0}/organisation-invitation/{1}'.format(invite_link_host, token)
|
||||||
|
|
||||||
|
|
||||||
|
@organisation_invite_blueprint.route('/invite/organisation/<uuid:invited_org_user_id>', methods=['GET'])
|
||||||
|
def get_invited_org_user(invited_org_user_id):
|
||||||
|
invited_user = dao_get_invited_organisation_user(invited_org_user_id)
|
||||||
|
return jsonify(data=invited_user.serialize()), 200
|
||||||
|
|
||||||
|
|
||||||
|
@organisation_invite_blueprint.route('/invite/organisation/<token>', methods=['GET'])
|
||||||
|
def validate_invitation_token(token):
|
||||||
|
|
||||||
|
max_age_seconds = 60 * 60 * 24 * current_app.config['INVITATION_EXPIRATION_DAYS']
|
||||||
|
|
||||||
|
try:
|
||||||
|
invited_user_id = check_token(token,
|
||||||
|
current_app.config['SECRET_KEY'],
|
||||||
|
current_app.config['DANGEROUS_SALT'],
|
||||||
|
max_age_seconds)
|
||||||
|
except SignatureExpired:
|
||||||
|
errors = {'invitation':
|
||||||
|
'Your invitation to GOV.UK Notify has expired. '
|
||||||
|
'Please ask the person that invited you to send you another one'}
|
||||||
|
raise InvalidRequest(errors, status_code=400)
|
||||||
|
except BadData:
|
||||||
|
errors = {'invitation': 'Something’s wrong with this link. Make sure you’ve copied the whole thing.'}
|
||||||
|
raise InvalidRequest(errors, status_code=400)
|
||||||
|
|
||||||
|
invited_user = dao_get_invited_organisation_user(invited_user_id)
|
||||||
|
return jsonify(data=invited_user.serialize()), 200
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
from flask import Blueprint, current_app, jsonify, request
|
from flask import Blueprint, current_app, jsonify, request
|
||||||
|
from itsdangerous import BadData, SignatureExpired
|
||||||
|
from notifications_utils.url_safe_token import check_token, generate_token
|
||||||
|
|
||||||
from app.config import QueueNames
|
from app.config import QueueNames
|
||||||
|
from app.dao.invited_user_dao import get_invited_user as dao_get_invited_user
|
||||||
from app.dao.invited_user_dao import (
|
from app.dao.invited_user_dao import (
|
||||||
get_invited_user,
|
get_invited_user_by_id,
|
||||||
get_invited_users_for_service,
|
get_invited_users_for_service,
|
||||||
save_invited_user,
|
save_invited_user,
|
||||||
)
|
)
|
||||||
from app.dao.templates_dao import dao_get_template_by_id
|
from app.dao.templates_dao import dao_get_template_by_id
|
||||||
from app.errors import register_errors
|
from app.errors import InvalidRequest, register_errors
|
||||||
from app.models import BROADCAST_TYPE, EMAIL_TYPE, KEY_TYPE_NORMAL, Service
|
from app.models import BROADCAST_TYPE, EMAIL_TYPE, KEY_TYPE_NORMAL, Service
|
||||||
from app.notifications.process_notifications import (
|
from app.notifications.process_notifications import (
|
||||||
persist_notification,
|
persist_notification,
|
||||||
@@ -15,12 +18,12 @@ from app.notifications.process_notifications import (
|
|||||||
)
|
)
|
||||||
from app.schemas import invited_user_schema
|
from app.schemas import invited_user_schema
|
||||||
|
|
||||||
service_invite = Blueprint('service_invite', __name__, url_prefix='/service/<service_id>/invite')
|
service_invite = Blueprint('service_invite', __name__)
|
||||||
|
|
||||||
register_errors(service_invite)
|
register_errors(service_invite)
|
||||||
|
|
||||||
|
|
||||||
@service_invite.route('', methods=['POST'])
|
@service_invite.route('/service/<service_id>/invite', methods=['POST'])
|
||||||
def create_invited_user(service_id):
|
def create_invited_user(service_id):
|
||||||
request_json = request.get_json()
|
request_json = request.get_json()
|
||||||
invited_user, errors = invited_user_schema.load(request_json)
|
invited_user, errors = invited_user_schema.load(request_json)
|
||||||
@@ -58,21 +61,21 @@ def create_invited_user(service_id):
|
|||||||
return jsonify(data=invited_user_schema.dump(invited_user).data), 201
|
return jsonify(data=invited_user_schema.dump(invited_user).data), 201
|
||||||
|
|
||||||
|
|
||||||
@service_invite.route('', methods=['GET'])
|
@service_invite.route('/service/<service_id>/invite', methods=['GET'])
|
||||||
def get_invited_users_by_service(service_id):
|
def get_invited_users_by_service(service_id):
|
||||||
invited_users = get_invited_users_for_service(service_id)
|
invited_users = get_invited_users_for_service(service_id)
|
||||||
return jsonify(data=invited_user_schema.dump(invited_users, many=True).data), 200
|
return jsonify(data=invited_user_schema.dump(invited_users, many=True).data), 200
|
||||||
|
|
||||||
|
|
||||||
@service_invite.route('/<invited_user_id>', methods=['GET'])
|
@service_invite.route('/service/<service_id>/invite/<invited_user_id>', methods=['GET'])
|
||||||
def get_invited_user_by_service(service_id, invited_user_id):
|
def get_invited_user_by_service(service_id, invited_user_id):
|
||||||
invited_user = get_invited_user(service_id, invited_user_id)
|
invited_user = dao_get_invited_user(service_id, invited_user_id)
|
||||||
return jsonify(data=invited_user_schema.dump(invited_user).data), 200
|
return jsonify(data=invited_user_schema.dump(invited_user).data), 200
|
||||||
|
|
||||||
|
|
||||||
@service_invite.route('/<invited_user_id>', methods=['POST'])
|
@service_invite.route('/service/<service_id>/invite/<invited_user_id>', methods=['POST'])
|
||||||
def update_invited_user(service_id, invited_user_id):
|
def update_invited_user(service_id, invited_user_id):
|
||||||
fetched = get_invited_user(service_id=service_id, invited_user_id=invited_user_id)
|
fetched = dao_get_invited_user(service_id=service_id, invited_user_id=invited_user_id)
|
||||||
|
|
||||||
current_data = dict(invited_user_schema.dump(fetched).data.items())
|
current_data = dict(invited_user_schema.dump(fetched).data.items())
|
||||||
current_data.update(request.get_json())
|
current_data.update(request.get_json())
|
||||||
@@ -82,10 +85,38 @@ def update_invited_user(service_id, invited_user_id):
|
|||||||
|
|
||||||
|
|
||||||
def invited_user_url(invited_user_id, invite_link_host=None):
|
def invited_user_url(invited_user_id, invite_link_host=None):
|
||||||
from notifications_utils.url_safe_token import generate_token
|
|
||||||
token = generate_token(str(invited_user_id), current_app.config['SECRET_KEY'], current_app.config['DANGEROUS_SALT'])
|
token = generate_token(str(invited_user_id), current_app.config['SECRET_KEY'], current_app.config['DANGEROUS_SALT'])
|
||||||
|
|
||||||
if invite_link_host is None:
|
if invite_link_host is None:
|
||||||
invite_link_host = current_app.config['ADMIN_BASE_URL']
|
invite_link_host = current_app.config['ADMIN_BASE_URL']
|
||||||
|
|
||||||
return '{0}/invitation/{1}'.format(invite_link_host, token)
|
return '{0}/invitation/{1}'.format(invite_link_host, token)
|
||||||
|
|
||||||
|
|
||||||
|
@service_invite.route('/invite/service/<uuid:invited_user_id>', methods=['GET'])
|
||||||
|
def get_invited_user(invited_user_id):
|
||||||
|
invited_user = get_invited_user_by_id(invited_user_id)
|
||||||
|
return jsonify(data=invited_user_schema.dump(invited_user).data), 200
|
||||||
|
|
||||||
|
|
||||||
|
@service_invite.route('/invite/service/<token>', methods=['GET'])
|
||||||
|
def validate_service_invitation_token(token):
|
||||||
|
|
||||||
|
max_age_seconds = 60 * 60 * 24 * current_app.config['INVITATION_EXPIRATION_DAYS']
|
||||||
|
|
||||||
|
try:
|
||||||
|
invited_user_id = check_token(token,
|
||||||
|
current_app.config['SECRET_KEY'],
|
||||||
|
current_app.config['DANGEROUS_SALT'],
|
||||||
|
max_age_seconds)
|
||||||
|
except SignatureExpired:
|
||||||
|
errors = {'invitation':
|
||||||
|
'Your invitation to GOV.UK Notify has expired. '
|
||||||
|
'Please ask the person that invited you to send you another one'}
|
||||||
|
raise InvalidRequest(errors, status_code=400)
|
||||||
|
except BadData:
|
||||||
|
errors = {'invitation': 'Something’s wrong with this link. Make sure you’ve copied the whole thing.'}
|
||||||
|
raise InvalidRequest(errors, status_code=400)
|
||||||
|
|
||||||
|
invited_user = get_invited_user_by_id(invited_user_id)
|
||||||
|
return jsonify(data=invited_user_schema.dump(invited_user).data), 200
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
import uuid
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
from flask import current_app, json
|
|
||||||
from freezegun import freeze_time
|
|
||||||
from notifications_utils.url_safe_token import generate_token
|
|
||||||
|
|
||||||
from tests import create_authorization_header
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('invitation_type', ['service', 'organisation'])
|
|
||||||
def test_validate_invitation_token_for_expired_token_returns_400(client, invitation_type):
|
|
||||||
with freeze_time('2016-01-01T12:00:00'):
|
|
||||||
token = generate_token(str(uuid.uuid4()), current_app.config['SECRET_KEY'],
|
|
||||||
current_app.config['DANGEROUS_SALT'])
|
|
||||||
url = '/invite/{}/{}'.format(invitation_type, token)
|
|
||||||
auth_header = create_authorization_header()
|
|
||||||
response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])
|
|
||||||
|
|
||||||
assert response.status_code == 400
|
|
||||||
json_resp = json.loads(response.get_data(as_text=True))
|
|
||||||
assert json_resp['result'] == 'error'
|
|
||||||
assert json_resp['message'] == {
|
|
||||||
'invitation': 'Your invitation to GOV.UK Notify has expired. '
|
|
||||||
'Please ask the person that invited you to send you another one'}
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('invitation_type', ['service', 'organisation'])
|
|
||||||
def test_validate_invitation_token_returns_200_when_token_valid(
|
|
||||||
client, invitation_type, sample_invited_user, sample_invited_org_user
|
|
||||||
):
|
|
||||||
invited_user = sample_invited_user if invitation_type == 'service' else sample_invited_org_user
|
|
||||||
|
|
||||||
token = generate_token(str(invited_user.id), current_app.config['SECRET_KEY'],
|
|
||||||
current_app.config['DANGEROUS_SALT'])
|
|
||||||
url = '/invite/{}/{}'.format(invitation_type, token)
|
|
||||||
auth_header = create_authorization_header()
|
|
||||||
response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])
|
|
||||||
|
|
||||||
assert response.status_code == 200
|
|
||||||
json_resp = json.loads(response.get_data(as_text=True))
|
|
||||||
if invitation_type == 'service':
|
|
||||||
assert json_resp['data']['id'] == str(sample_invited_user.id)
|
|
||||||
assert json_resp['data']['email_address'] == sample_invited_user.email_address
|
|
||||||
assert json_resp['data']['from_user'] == str(sample_invited_user.user_id)
|
|
||||||
assert json_resp['data']['service'] == str(sample_invited_user.service_id)
|
|
||||||
assert json_resp['data']['status'] == sample_invited_user.status
|
|
||||||
assert json_resp['data']['permissions'] == sample_invited_user.permissions
|
|
||||||
assert json_resp['data']['folder_permissions'] == sample_invited_user.folder_permissions
|
|
||||||
if invitation_type == 'organisation':
|
|
||||||
assert json_resp['data'] == sample_invited_org_user.serialize()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('invitation_type', ['service', 'organisation'])
|
|
||||||
def test_validate_invitation_token_returns_400_when_invited_user_does_not_exist(client, invitation_type):
|
|
||||||
token = generate_token(str(uuid.uuid4()), current_app.config['SECRET_KEY'],
|
|
||||||
current_app.config['DANGEROUS_SALT'])
|
|
||||||
url = '/invite/{}/{}'.format(invitation_type, token)
|
|
||||||
auth_header = create_authorization_header()
|
|
||||||
response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])
|
|
||||||
|
|
||||||
assert response.status_code == 404
|
|
||||||
json_resp = json.loads(response.get_data(as_text=True))
|
|
||||||
assert json_resp['result'] == 'error'
|
|
||||||
assert json_resp['message'] == 'No result found'
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('invitation_type', ['service', 'organisation'])
|
|
||||||
def test_validate_invitation_token_returns_400_when_token_is_malformed(client, invitation_type):
|
|
||||||
token = generate_token(
|
|
||||||
str(uuid.uuid4()),
|
|
||||||
current_app.config['SECRET_KEY'],
|
|
||||||
current_app.config['DANGEROUS_SALT']
|
|
||||||
)[:-2]
|
|
||||||
|
|
||||||
url = '/invite/{}/{}'.format(invitation_type, token)
|
|
||||||
auth_header = create_authorization_header()
|
|
||||||
response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])
|
|
||||||
|
|
||||||
assert response.status_code == 400
|
|
||||||
json_resp = json.loads(response.get_data(as_text=True))
|
|
||||||
assert json_resp['result'] == 'error'
|
|
||||||
assert json_resp['message'] == {
|
|
||||||
'invitation': 'Something’s wrong with this link. Make sure you’ve copied the whole thing.'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_invited_user(admin_request, sample_invited_user):
|
|
||||||
json_resp = admin_request.get(
|
|
||||||
'global_invite.get_invited_user',
|
|
||||||
invited_user_id=sample_invited_user.id
|
|
||||||
)
|
|
||||||
assert json_resp['data']['id'] == str(sample_invited_user.id)
|
|
||||||
assert json_resp['data']['email_address'] == sample_invited_user.email_address
|
|
||||||
assert json_resp['data']['service'] == str(sample_invited_user.service_id)
|
|
||||||
assert json_resp['data']['permissions'] == sample_invited_user.permissions
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_invited_user_404s_if_invite_doesnt_exist(admin_request, sample_invited_user, fake_uuid):
|
|
||||||
json_resp = admin_request.get(
|
|
||||||
'global_invite.get_invited_user',
|
|
||||||
invited_user_id=fake_uuid,
|
|
||||||
_expected_status=404
|
|
||||||
)
|
|
||||||
assert json_resp['result'] == 'error'
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_invited_org_user(admin_request, sample_invited_org_user):
|
|
||||||
json_resp = admin_request.get(
|
|
||||||
'global_invite.get_invited_org_user',
|
|
||||||
invited_org_user_id=sample_invited_org_user.id
|
|
||||||
)
|
|
||||||
assert json_resp['data']['id'] == str(sample_invited_org_user.id)
|
|
||||||
assert json_resp['data']['email_address'] == sample_invited_org_user.email_address
|
|
||||||
assert json_resp['data']['organisation'] == str(sample_invited_org_user.organisation_id)
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_invited_org_user_404s_if_invite_doesnt_exist(admin_request, sample_invited_org_user, fake_uuid):
|
|
||||||
json_resp = admin_request.get(
|
|
||||||
'global_invite.get_invited_org_user',
|
|
||||||
invited_org_user_id=fake_uuid,
|
|
||||||
_expected_status=404
|
|
||||||
)
|
|
||||||
assert json_resp['result'] == 'error'
|
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
|
import uuid
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from flask import current_app, json
|
||||||
|
from freezegun import freeze_time
|
||||||
|
from notifications_utils.url_safe_token import generate_token
|
||||||
|
|
||||||
from app.models import INVITE_PENDING, Notification
|
from app.models import INVITE_PENDING, Notification
|
||||||
|
from tests import create_authorization_header
|
||||||
from tests.app.db import create_invited_org_user
|
from tests.app.db import create_invited_org_user
|
||||||
|
|
||||||
|
|
||||||
@@ -175,3 +181,82 @@ def test_update_org_invited_user_for_invalid_data_returns_400(admin_request, sam
|
|||||||
)
|
)
|
||||||
assert len(json_resp['errors']) == 1
|
assert len(json_resp['errors']) == 1
|
||||||
assert json_resp['errors'][0]['message'] == 'status garbage is not one of [pending, accepted, cancelled]'
|
assert json_resp['errors'][0]['message'] == 'status garbage is not one of [pending, accepted, cancelled]'
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_invitation_token_returns_200_when_token_valid(client, sample_invited_org_user):
|
||||||
|
token = generate_token(str(sample_invited_org_user.id), current_app.config['SECRET_KEY'],
|
||||||
|
current_app.config['DANGEROUS_SALT'])
|
||||||
|
url = '/invite/organisation/{}'.format(token)
|
||||||
|
auth_header = create_authorization_header()
|
||||||
|
response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
json_resp = json.loads(response.get_data(as_text=True))
|
||||||
|
assert json_resp['data'] == sample_invited_org_user.serialize()
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_invitation_token_for_expired_token_returns_400(client):
|
||||||
|
with freeze_time('2016-01-01T12:00:00'):
|
||||||
|
token = generate_token(str(uuid.uuid4()), current_app.config['SECRET_KEY'],
|
||||||
|
current_app.config['DANGEROUS_SALT'])
|
||||||
|
url = '/invite/organisation/{}'.format(token)
|
||||||
|
auth_header = create_authorization_header()
|
||||||
|
response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
||||||
|
json_resp = json.loads(response.get_data(as_text=True))
|
||||||
|
assert json_resp['result'] == 'error'
|
||||||
|
assert json_resp['message'] == {
|
||||||
|
'invitation': 'Your invitation to GOV.UK Notify has expired. '
|
||||||
|
'Please ask the person that invited you to send you another one'}
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_invitation_token_returns_400_when_invited_user_does_not_exist(client):
|
||||||
|
token = generate_token(str(uuid.uuid4()), current_app.config['SECRET_KEY'],
|
||||||
|
current_app.config['DANGEROUS_SALT'])
|
||||||
|
url = '/invite/organisation/{}'.format(token)
|
||||||
|
auth_header = create_authorization_header()
|
||||||
|
response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])
|
||||||
|
|
||||||
|
assert response.status_code == 404
|
||||||
|
json_resp = json.loads(response.get_data(as_text=True))
|
||||||
|
assert json_resp['result'] == 'error'
|
||||||
|
assert json_resp['message'] == 'No result found'
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_invitation_token_returns_400_when_token_is_malformed(client):
|
||||||
|
token = generate_token(
|
||||||
|
str(uuid.uuid4()),
|
||||||
|
current_app.config['SECRET_KEY'],
|
||||||
|
current_app.config['DANGEROUS_SALT']
|
||||||
|
)[:-2]
|
||||||
|
|
||||||
|
url = '/invite/organisation/{}'.format(token)
|
||||||
|
auth_header = create_authorization_header()
|
||||||
|
response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
||||||
|
json_resp = json.loads(response.get_data(as_text=True))
|
||||||
|
assert json_resp['result'] == 'error'
|
||||||
|
assert json_resp['message'] == {
|
||||||
|
'invitation': 'Something’s wrong with this link. Make sure you’ve copied the whole thing.'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_invited_org_user(admin_request, sample_invited_org_user):
|
||||||
|
json_resp = admin_request.get(
|
||||||
|
'organisation_invite.get_invited_org_user',
|
||||||
|
invited_org_user_id=sample_invited_org_user.id
|
||||||
|
)
|
||||||
|
assert json_resp['data']['id'] == str(sample_invited_org_user.id)
|
||||||
|
assert json_resp['data']['email_address'] == sample_invited_org_user.email_address
|
||||||
|
assert json_resp['data']['organisation'] == str(sample_invited_org_user.organisation_id)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_invited_org_user_404s_if_invite_doesnt_exist(admin_request, sample_invited_org_user, fake_uuid):
|
||||||
|
json_resp = admin_request.get(
|
||||||
|
'organisation_invite.get_invited_org_user',
|
||||||
|
invited_org_user_id=fake_uuid,
|
||||||
|
_expected_status=404
|
||||||
|
)
|
||||||
|
assert json_resp['result'] == 'error'
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import json
|
import json
|
||||||
|
import uuid
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
from freezegun import freeze_time
|
||||||
|
from notifications_utils.url_safe_token import generate_token
|
||||||
|
|
||||||
from app.models import EMAIL_AUTH_TYPE, SMS_AUTH_TYPE, Notification
|
from app.models import EMAIL_AUTH_TYPE, SMS_AUTH_TYPE, Notification
|
||||||
from tests import create_authorization_header
|
from tests import create_authorization_header
|
||||||
@@ -270,3 +273,89 @@ def test_update_invited_user_for_invalid_data_returns_400(client, sample_invited
|
|||||||
response = client.post(url, data=json.dumps(data),
|
response = client.post(url, data=json.dumps(data),
|
||||||
headers=[('Content-Type', 'application/json'), auth_header])
|
headers=[('Content-Type', 'application/json'), auth_header])
|
||||||
assert response.status_code == 400
|
assert response.status_code == 400
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_invitation_token_returns_200_when_token_valid(client, sample_invited_user):
|
||||||
|
token = generate_token(str(sample_invited_user.id), current_app.config['SECRET_KEY'],
|
||||||
|
current_app.config['DANGEROUS_SALT'])
|
||||||
|
url = '/invite/service/{}'.format(token)
|
||||||
|
auth_header = create_authorization_header()
|
||||||
|
response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
json_resp = json.loads(response.get_data(as_text=True))
|
||||||
|
assert json_resp['data']['id'] == str(sample_invited_user.id)
|
||||||
|
assert json_resp['data']['email_address'] == sample_invited_user.email_address
|
||||||
|
assert json_resp['data']['from_user'] == str(sample_invited_user.user_id)
|
||||||
|
assert json_resp['data']['service'] == str(sample_invited_user.service_id)
|
||||||
|
assert json_resp['data']['status'] == sample_invited_user.status
|
||||||
|
assert json_resp['data']['permissions'] == sample_invited_user.permissions
|
||||||
|
assert json_resp['data']['folder_permissions'] == sample_invited_user.folder_permissions
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_invitation_token_for_expired_token_returns_400(client):
|
||||||
|
with freeze_time('2016-01-01T12:00:00'):
|
||||||
|
token = generate_token(str(uuid.uuid4()), current_app.config['SECRET_KEY'],
|
||||||
|
current_app.config['DANGEROUS_SALT'])
|
||||||
|
url = '/invite/service/{}'.format(token)
|
||||||
|
auth_header = create_authorization_header()
|
||||||
|
response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
||||||
|
json_resp = json.loads(response.get_data(as_text=True))
|
||||||
|
assert json_resp['result'] == 'error'
|
||||||
|
assert json_resp['message'] == {
|
||||||
|
'invitation': 'Your invitation to GOV.UK Notify has expired. '
|
||||||
|
'Please ask the person that invited you to send you another one'}
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_invitation_token_returns_400_when_invited_user_does_not_exist(client):
|
||||||
|
token = generate_token(str(uuid.uuid4()), current_app.config['SECRET_KEY'],
|
||||||
|
current_app.config['DANGEROUS_SALT'])
|
||||||
|
url = '/invite/service/{}'.format(token)
|
||||||
|
auth_header = create_authorization_header()
|
||||||
|
response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])
|
||||||
|
|
||||||
|
assert response.status_code == 404
|
||||||
|
json_resp = json.loads(response.get_data(as_text=True))
|
||||||
|
assert json_resp['result'] == 'error'
|
||||||
|
assert json_resp['message'] == 'No result found'
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_invitation_token_returns_400_when_token_is_malformed(client):
|
||||||
|
token = generate_token(
|
||||||
|
str(uuid.uuid4()),
|
||||||
|
current_app.config['SECRET_KEY'],
|
||||||
|
current_app.config['DANGEROUS_SALT']
|
||||||
|
)[:-2]
|
||||||
|
|
||||||
|
url = '/invite/service/{}'.format(token)
|
||||||
|
auth_header = create_authorization_header()
|
||||||
|
response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
||||||
|
json_resp = json.loads(response.get_data(as_text=True))
|
||||||
|
assert json_resp['result'] == 'error'
|
||||||
|
assert json_resp['message'] == {
|
||||||
|
'invitation': 'Something’s wrong with this link. Make sure you’ve copied the whole thing.'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_invited_user(admin_request, sample_invited_user):
|
||||||
|
json_resp = admin_request.get(
|
||||||
|
'service_invite.get_invited_user',
|
||||||
|
invited_user_id=sample_invited_user.id
|
||||||
|
)
|
||||||
|
assert json_resp['data']['id'] == str(sample_invited_user.id)
|
||||||
|
assert json_resp['data']['email_address'] == sample_invited_user.email_address
|
||||||
|
assert json_resp['data']['service'] == str(sample_invited_user.service_id)
|
||||||
|
assert json_resp['data']['permissions'] == sample_invited_user.permissions
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_invited_user_404s_if_invite_doesnt_exist(admin_request, sample_invited_user, fake_uuid):
|
||||||
|
json_resp = admin_request.get(
|
||||||
|
'service_invite.get_invited_user',
|
||||||
|
invited_user_id=fake_uuid,
|
||||||
|
_expected_status=404
|
||||||
|
)
|
||||||
|
assert json_resp['result'] == 'error'
|
||||||
|
|||||||
Reference in New Issue
Block a user