Added task for sending email verification links out on intial

registration.

Left original email code endpoint in as it is still used for things like
email change.
This commit is contained in:
Adam Shimali
2016-03-17 13:06:17 +00:00
parent 8b83e6a02a
commit 2d1d883283
5 changed files with 100 additions and 5 deletions

View File

@@ -370,3 +370,23 @@ def email_reset_password(encrypted_reset_password_message):
url=reset_password_message['reset_password_url']))
except AwsSesClientException as e:
current_app.logger.exception(e)
def registration_verification_template(name, url):
from string import Template
t = Template("Hi $name,\n\n"
"To complete your registration for GOV.UK Notify please click the link below\n\n $url")
return t.substitute(name=name, url=url)
@notify_celery.task(name='email-registration-verification')
def email_registration_verification(encrypted_verification_message):
verification_message = encryption.decrypt(encrypted_verification_message)
try:
aws_ses_client.send_email(current_app.config['VERIFY_CODE_FROM_EMAIL_ADDRESS'],
verification_message['to'],
"Confirm GOV.UK Notify registration",
registration_verification_template(name=verification_message['name'],
url=verification_message['url']))
except AwsSesClientException as e:
current_app.logger.exception(e)

View File

@@ -24,7 +24,13 @@ from app.schemas import (
permission_schema
)
from app.celery.tasks import (send_sms_code, send_email_code, email_reset_password)
from app.celery.tasks import (
send_sms_code,
send_email_code,
email_reset_password,
email_registration_verification
)
from app.errors import register_errors
user = Blueprint('user', __name__)
@@ -148,6 +154,28 @@ def send_user_email_code(user_id):
return jsonify({}), 204
@user.route('/<int:user_id>/email-verification', methods=['POST'])
def send_user_email_verification(user_id):
user_to_send_to = get_model_users(user_id=user_id)
verify_code, errors = request_verify_code_schema.load(request.get_json())
if errors:
return jsonify(result="error", message=errors), 400
from app.dao.users_dao import create_secret_code
secret_code = create_secret_code()
create_user_code(user_to_send_to, secret_code, 'email')
email = user_to_send_to.email_address
verification_message = {'to': email,
'name': user_to_send_to.name,
'url': _create_verification_url(user_to_send_to, secret_code)}
email_registration_verification.apply_async([encryption.encrypt(verification_message)],
queue='email-registration-verification')
return jsonify({}), 204
@user.route('/<int:user_id>', methods=['GET'])
@user.route('', methods=['GET'])
def get_user(user_id=None):
@@ -207,3 +235,12 @@ def _create_reset_password_url(email):
token = generate_token(data, current_app.config['SECRET_KEY'], current_app.config['DANGEROUS_SALT'])
return current_app.config['ADMIN_BASE_URL'] + '/new-password/' + token
def _create_verification_url(user, secret_code):
from utils.url_safe_token import generate_token
import json
data = json.dumps({'user_id': user.id, 'email': user.email_address, 'secret_code': secret_code})
token = generate_token(data, current_app.config['SECRET_KEY'], current_app.config['DANGEROUS_SALT'])
return current_app.config['ADMIN_BASE_URL'] + '/verify-email/' + token

View File

@@ -69,7 +69,8 @@ class Config(object):
Queue('process-job', Exchange('default'), routing_key='process-job'),
Queue('bulk-sms', Exchange('default'), routing_key='bulk-sms'),
Queue('bulk-email', Exchange('default'), routing_key='bulk-email'),
Queue('email-invited-user', Exchange('default'), routing_key='email-invited-user')
Queue('email-invited-user', Exchange('default'), routing_key='email-invited-user'),
Queue('email-registration-verification', Exchange('default'), routing_key='email-registration-verification')
]
TWILIO_ACCOUNT_SID = os.getenv('TWILIO_ACCOUNT_SID')
TWILIO_AUTH_TOKEN = os.getenv('TWILIO_AUTH_TOKEN')

View File

@@ -327,6 +327,11 @@ def mock_celery_send_email_code(mocker):
return mocker.patch('app.celery.tasks.send_email_code.apply_async')
@pytest.fixture(scope='function')
def mock_celery_email_registration_verification(mocker):
return mocker.patch('app.celery.tasks.email_registration_verification.apply_async')
@pytest.fixture(scope='function')
def mock_encryption(mocker):
return mocker.patch('app.encryption.encrypt', return_value="something_encrypted")

View File

@@ -1,13 +1,25 @@
import json
import moto
from datetime import (datetime, timedelta)
from datetime import (
datetime,
timedelta
)
from flask import url_for
from app.models import (VerifyCode, User)
import app.celery.tasks
from app.models import (
VerifyCode,
User
)
from app import db, encryption
from tests import create_authorization_header
from freezegun import freeze_time
import app.celery.tasks
def test_user_verify_code_sms(notify_api,
sample_sms_code):
@@ -341,3 +353,23 @@ def test_send_user_email_code_returns_404_for_when_user_does_not_exist(notify_ap
headers=[('Content-Type', 'application/json'), auth_header])
assert resp.status_code == 404
assert json.loads(resp.get_data(as_text=True))['message'] == 'No result found'
def test_send_user_email_verification(notify_api,
sample_email_code,
mock_celery_email_registration_verification,
mock_encryption):
with notify_api.test_request_context():
with notify_api.test_client() as client:
data = json.dumps({})
auth_header = create_authorization_header(
path=url_for('user.send_user_email_verification', user_id=sample_email_code.user.id),
method='POST',
request_body=data)
resp = client.post(
url_for('user.send_user_email_verification', user_id=sample_email_code.user.id),
data=data,
headers=[('Content-Type', 'application/json'), auth_header])
assert resp.status_code == 204
app.celery.tasks.email_registration_verification.apply_async.assert_called_once_with(['something_encrypted'], queue='email-registration-verification') # noqa