mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-23 07:46:23 -04:00
Merge pull request #3355 from alphagov/invite-bug
move invite error handler to top level
This commit is contained in:
@@ -13,6 +13,7 @@ from flask import (
|
|||||||
flash,
|
flash,
|
||||||
g,
|
g,
|
||||||
make_response,
|
make_response,
|
||||||
|
redirect,
|
||||||
render_template,
|
render_template,
|
||||||
request,
|
request,
|
||||||
session,
|
session,
|
||||||
@@ -59,6 +60,7 @@ from app.navigation import (
|
|||||||
MainNavigation,
|
MainNavigation,
|
||||||
OrgNavigation,
|
OrgNavigation,
|
||||||
)
|
)
|
||||||
|
from app.notify_client import InviteTokenError
|
||||||
from app.notify_client.api_key_api_client import api_key_api_client
|
from app.notify_client.api_key_api_client import api_key_api_client
|
||||||
from app.notify_client.billing_api_client import billing_api_client
|
from app.notify_client.billing_api_client import billing_api_client
|
||||||
from app.notify_client.complaint_api_client import complaint_api_client
|
from app.notify_client.complaint_api_client import complaint_api_client
|
||||||
@@ -702,6 +704,11 @@ def register_errorhandlers(application): # noqa (C901 too complex)
|
|||||||
|
|
||||||
return _error_response(error.code)
|
return _error_response(error.code)
|
||||||
|
|
||||||
|
@application.errorhandler(InviteTokenError)
|
||||||
|
def handle_bad_invite_token(error):
|
||||||
|
flash(str(error))
|
||||||
|
return redirect(url_for('main.sign_in'))
|
||||||
|
|
||||||
@application.errorhandler(500)
|
@application.errorhandler(500)
|
||||||
@application.errorhandler(Exception)
|
@application.errorhandler(Exception)
|
||||||
def handle_bad_request(error):
|
def handle_bad_request(error):
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from itertools import chain
|
|||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
from flask import request
|
from flask import request
|
||||||
|
from flask_login import current_user
|
||||||
from flask_wtf import FlaskForm as Form
|
from flask_wtf import FlaskForm as Form
|
||||||
from flask_wtf.file import FileAllowed
|
from flask_wtf.file import FileAllowed
|
||||||
from flask_wtf.file import FileField as FileField_wtf
|
from flask_wtf.file import FileField as FileField_wtf
|
||||||
@@ -500,7 +501,7 @@ class InviteUserForm(PermissionsForm):
|
|||||||
self.invalid_email_address = invalid_email_address.lower()
|
self.invalid_email_address = invalid_email_address.lower()
|
||||||
|
|
||||||
def validate_email_address(self, field):
|
def validate_email_address(self, field):
|
||||||
if field.data.lower() == self.invalid_email_address:
|
if field.data.lower() == self.invalid_email_address and not current_user.platform_admin:
|
||||||
raise ValidationError("You cannot send an invitation to yourself")
|
raise ValidationError("You cannot send an invitation to yourself")
|
||||||
|
|
||||||
|
|
||||||
@@ -512,7 +513,7 @@ class InviteOrgUserForm(StripWhitespaceForm):
|
|||||||
self.invalid_email_address = invalid_email_address.lower()
|
self.invalid_email_address = invalid_email_address.lower()
|
||||||
|
|
||||||
def validate_email_address(self, field):
|
def validate_email_address(self, field):
|
||||||
if field.data.lower() == self.invalid_email_address:
|
if field.data.lower() == self.invalid_email_address and not current_user.platform_admin:
|
||||||
raise ValidationError("You cannot send an invitation to yourself")
|
raise ValidationError("You cannot send an invitation to yourself")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,16 +12,11 @@ from app.models.user import (
|
|||||||
User,
|
User,
|
||||||
Users,
|
Users,
|
||||||
)
|
)
|
||||||
from app.notify_client import InviteTokenError
|
|
||||||
|
|
||||||
|
|
||||||
@main.route("/invitation/<token>")
|
@main.route("/invitation/<token>")
|
||||||
def accept_invite(token):
|
def accept_invite(token):
|
||||||
try:
|
invited_user = InvitedUser.from_token(token)
|
||||||
invited_user = InvitedUser.from_token(token)
|
|
||||||
except InviteTokenError as exception:
|
|
||||||
flash(str(exception))
|
|
||||||
return redirect(url_for('main.sign_in'))
|
|
||||||
|
|
||||||
if not current_user.is_anonymous and current_user.email_address.lower() != invited_user.email_address.lower():
|
if not current_user.is_anonymous and current_user.email_address.lower() != invited_user.email_address.lower():
|
||||||
message = Markup("""
|
message = Markup("""
|
||||||
@@ -78,6 +73,7 @@ def accept_invite(token):
|
|||||||
@main.route("/organisation-invitation/<token>")
|
@main.route("/organisation-invitation/<token>")
|
||||||
def accept_org_invite(token):
|
def accept_org_invite(token):
|
||||||
invited_org_user = InvitedOrgUser.from_token(token)
|
invited_org_user = InvitedOrgUser.from_token(token)
|
||||||
|
|
||||||
if not current_user.is_anonymous and current_user.email_address.lower() != invited_org_user.email_address.lower():
|
if not current_user.is_anonymous and current_user.email_address.lower() != invited_org_user.email_address.lower():
|
||||||
message = Markup("""
|
message = Markup("""
|
||||||
You’re signed in as {}.
|
You’re signed in as {}.
|
||||||
|
|||||||
@@ -77,7 +77,3 @@ class ModelList(ABC, Sequence):
|
|||||||
|
|
||||||
def __radd__(self, other):
|
def __radd__(self, other):
|
||||||
return list(other) + list(self)
|
return list(other) + list(self)
|
||||||
|
|
||||||
|
|
||||||
class InviteTokenError(Exception):
|
|
||||||
pass
|
|
||||||
|
|||||||
@@ -308,12 +308,18 @@ def test_cancelled_invited_user_accepts_invited_redirect_to_cancelled_invitation
|
|||||||
assert page.h1.string.strip() == 'The invitation you were sent has been cancelled'
|
assert page.h1.string.strip() == 'The invitation you were sent has been cancelled'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('admin_endpoint, api_endpoint', [
|
||||||
|
('main.accept_invite', 'app.invite_api_client.check_token'),
|
||||||
|
('main.accept_org_invite', 'app.org_invite_api_client.check_token'),
|
||||||
|
])
|
||||||
def test_new_user_accept_invite_with_malformed_token(
|
def test_new_user_accept_invite_with_malformed_token(
|
||||||
|
admin_endpoint,
|
||||||
|
api_endpoint,
|
||||||
client,
|
client,
|
||||||
service_one,
|
service_one,
|
||||||
mocker,
|
mocker,
|
||||||
):
|
):
|
||||||
mocker.patch('app.invite_api_client.check_token', side_effect=HTTPError(
|
mocker.patch(api_endpoint, side_effect=HTTPError(
|
||||||
response=Mock(
|
response=Mock(
|
||||||
status_code=400,
|
status_code=400,
|
||||||
json={
|
json={
|
||||||
@@ -328,7 +334,7 @@ def test_new_user_accept_invite_with_malformed_token(
|
|||||||
message={'invitation': 'Something’s wrong with this link. Make sure you’ve copied the whole thing.'}
|
message={'invitation': 'Something’s wrong with this link. Make sure you’ve copied the whole thing.'}
|
||||||
))
|
))
|
||||||
|
|
||||||
response = client.get(url_for('main.accept_invite', token='thisisnotarealtoken'), follow_redirects=True)
|
response = client.get(url_for(admin_endpoint, token='thisisnotarealtoken'), follow_redirects=True)
|
||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||||
|
|||||||
Reference in New Issue
Block a user