mirror of
https://github.com/GSA/notifications-api.git
synced 2026-09-05 19:38:24 -04:00
Added a new endpoint that can be used for organisation or service invitations.
The other two invitation endpoints will be removed once the admin app is updated.
This commit is contained in:
@@ -9,6 +9,7 @@ from itsdangerous import SignatureExpired
|
|||||||
from notifications_utils.url_safe_token import check_token
|
from notifications_utils.url_safe_token import check_token
|
||||||
|
|
||||||
from app.dao.invited_user_dao import get_invited_user_by_id
|
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 (
|
from app.errors import (
|
||||||
register_errors,
|
register_errors,
|
||||||
@@ -24,7 +25,10 @@ register_errors(accept_invite)
|
|||||||
|
|
||||||
@accept_invite.route('/<token>', methods=['GET'])
|
@accept_invite.route('/<token>', methods=['GET'])
|
||||||
def get_invited_user_by_token(token):
|
def get_invited_user_by_token(token):
|
||||||
|
"""
|
||||||
|
This method is now deprecated,
|
||||||
|
in favor of a single accept_invite endpoint for both service and organisation invitations
|
||||||
|
"""
|
||||||
max_age_seconds = 60 * 60 * 24 * current_app.config['INVITATION_EXPIRATION_DAYS']
|
max_age_seconds = 60 * 60 * 24 * current_app.config['INVITATION_EXPIRATION_DAYS']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -41,3 +45,29 @@ def get_invited_user_by_token(token):
|
|||||||
invited_user = get_invited_user_by_id(invited_user_id)
|
invited_user = get_invited_user_by_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
|
||||||
|
|
||||||
|
|
||||||
|
@accept_invite.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)
|
||||||
|
|
||||||
|
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))
|
||||||
|
|||||||
@@ -246,11 +246,6 @@ class Organisation(db.Model):
|
|||||||
'Service',
|
'Service',
|
||||||
secondary='organisation_to_service',
|
secondary='organisation_to_service',
|
||||||
uselist=True)
|
uselist=True)
|
||||||
#
|
|
||||||
# users = db.relationship(
|
|
||||||
# 'User',
|
|
||||||
# secondary=user_to_organisation,
|
|
||||||
# backref=db.backref('user_to_organisation', lazy='dynamic'))
|
|
||||||
|
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
serialized = {
|
serialized = {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from flask import json
|
import pytest
|
||||||
|
from flask import json, current_app
|
||||||
from freezegun import freeze_time
|
from freezegun import freeze_time
|
||||||
from notifications_utils.url_safe_token import generate_token
|
from notifications_utils.url_safe_token import generate_token
|
||||||
from tests import create_authorization_header
|
from tests import create_authorization_header
|
||||||
@@ -56,3 +57,59 @@ def test_accept_invite_returns_400_when_invited_user_does_not_exist(notify_api):
|
|||||||
json_resp = json.loads(response.get_data(as_text=True))
|
json_resp = json.loads(response.get_data(as_text=True))
|
||||||
assert json_resp['result'] == 'error'
|
assert json_resp['result'] == 'error'
|
||||||
assert json_resp['message'] == 'No result found'
|
assert json_resp['message'] == 'No result found'
|
||||||
|
|
||||||
|
|
||||||
|
@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
|
||||||
|
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'
|
||||||
|
|||||||
Reference in New Issue
Block a user