From ad4f9fb4fba57e136a8a26d46e5220ab18271886 Mon Sep 17 00:00:00 2001 From: Cathy Hu Date: Sun, 6 Sep 2020 23:06:52 +0200 Subject: [PATCH] [email] Fix email unsubscribe error handling --- kibicara/platforms/email/bot.py | 4 ++-- kibicara/platforms/email/webapi.py | 28 +++++++++++++++++----------- tests/test_api_email_happy_path.py | 10 ++++++++-- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/kibicara/platforms/email/bot.py b/kibicara/platforms/email/bot.py index 1910afa..b4074cc 100644 --- a/kibicara/platforms/email/bot.py +++ b/kibicara/platforms/email/bot.py @@ -44,8 +44,8 @@ class EmailBot(Censor): body = ( '%s\n\n--\n' 'If you want to stop receiving these mails,' - 'follow this link: %s/api/hoods/%d/email/unsubscribe/%s' - ) % (message.text, config['root_url'], self.hood.id, token) + 'follow this link: %s/hoods/%d/email-unsubscribe?token=%s' + ) % (message.text, config['frontend_url'], self.hood.id, token) try: logger.debug('Trying to send: \n%s' % body) email.send_email( diff --git a/kibicara/platforms/email/webapi.py b/kibicara/platforms/email/webapi.py index 69c7ecf..9a4efc4 100644 --- a/kibicara/platforms/email/webapi.py +++ b/kibicara/platforms/email/webapi.py @@ -13,6 +13,7 @@ from kibicara.config import config from kibicara.webapi.admin import from_token, to_token from kibicara.webapi.hoods import get_hood, get_hood_unauthorized from logging import getLogger +from nacl import exceptions from ormantic.exceptions import NoMatch from os import urandom from pydantic import BaseModel, validator @@ -188,8 +189,8 @@ async def email_subscribe( :return: Returns status code 200 after sending confirmation email. """ token = to_token(hood=hood.id, email=subscriber.email) - confirm_link = '%s/api/hoods/%d/email/subscribe/confirm/%s' % ( - config['root_url'], + confirm_link = '%s/hoods/%d/email-confirm?token=%s' % ( + config['frontend_url'], hood.id, token, ) @@ -246,15 +247,20 @@ async def email_unsubscribe(token, hood=Depends(get_hood_unauthorized)): :param token: encrypted JSON token, holds subscriber email + hood.id. :param hood: Hood the Email bot belongs to. """ - logger.warning("token is: " + token) - payload = from_token(token) - # If token.hood and url.hood are different, raise an error: - if hood.id is not payload['hood']: - raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST) - subscriber = await EmailSubscribers.objects.filter( - hood=payload['hood'], email=payload['email'] - ).get() - await subscriber.delete() + try: + logger.warning("token is: " + token) + payload = from_token(token) + # If token.hood and url.hood are different, raise an error: + if hood.id is not payload['hood']: + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST) + subscriber = await EmailSubscribers.objects.filter( + hood=payload['hood'], email=payload['email'] + ).get() + await subscriber.delete() + except NoMatch: + return HTTPException(status_code=status.HTTP_404_NOT_FOUND) + except exceptions.CryptoError: + return HTTPException(status_code=status.HTTP_400_BAD_REQUEST) @router.get( diff --git a/tests/test_api_email_happy_path.py b/tests/test_api_email_happy_path.py index 44fac66..24456b5 100644 --- a/tests/test_api_email_happy_path.py +++ b/tests/test_api_email_happy_path.py @@ -22,9 +22,15 @@ def test_email_subscribe_unsubscribe(client, hood_id, receive_email): r'(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', body, )[0] - response = client.post(urlparse(confirm_url).path) + response = client.post( + '/api/hoods/%d/email/subscribe/confirm/%s' + % (hood_id, urlparse(confirm_url).query[len('token=') :]) + ) assert response.status_code == status.HTTP_201_CREATED - response = client.post(urlparse(confirm_url).path) + response = client.post( + '/api/hoods/%d/email/subscribe/confirm/%s' + % (hood_id, urlparse(confirm_url).query[len('token=') :]) + ) assert response.status_code == status.HTTP_409_CONFLICT token = to_token(email=mail['to'], hood=hood_id) response = client.delete('/api/hoods/%d/email/unsubscribe/%s' % (hood_id, token))