From 66a802785e8d7d2b52626aff687c18f8fa9837d9 Mon Sep 17 00:00:00 2001 From: NghiaTTran Date: Mon, 28 Dec 2015 22:58:14 -0500 Subject: [PATCH 1/2] add sms and refactor --- config/dev.json | 11 ++++- config/test.json | 10 ++++- src/models/email_model.py | 72 ++++++++++++++++++++++++++++++ src/models/sms_model.py | 24 ++++++++++ src/models/user_model.py | 11 +++-- src/utils/__init__.py | 72 ------------------------------ test/live/integration/test_user.py | 3 +- 7 files changed, 122 insertions(+), 81 deletions(-) create mode 100644 src/models/email_model.py create mode 100644 src/models/sms_model.py diff --git a/config/dev.json b/config/dev.json index fc207a5..67d5b38 100644 --- a/config/dev.json +++ b/config/dev.json @@ -23,9 +23,16 @@ "JWT_KEY": "PLACE YOUR JWT KEY HERE", - "_comment": "Change SENDGRID to 1 to use built-in and 0 to not", + "_comment": "Email automation", + "_comment": "Change SENDGRID to 1 to use built-in email automation and 0 to not", "SENDGRID": 0, "SENDGRID_API_KEY": "PLACE YOUR SENDGRID API KEY", "EMAIL_FROM_NAME": "PLACE YOUR NAME", - "EMAIL_FROM": "PLACE YOUR EMAIL" + "EMAIL_FROM": "PLACE YOUR EMAIL", + + + "_comment": "SMS automation", + "TWILLIO_ACCOUNT": "YOUR ACCOUNT SID", + "TWILLIO_AUTH_TOKEN": "YOUR AUTH TOKEN", + "TWILLIO_NUMBER": "YOUR TWILLIO NUMBER" } \ No newline at end of file diff --git a/config/test.json b/config/test.json index c3f5012..b0b62cb 100644 --- a/config/test.json +++ b/config/test.json @@ -22,10 +22,16 @@ "_comment": "JWT_KEY for checking authorization", "JWT_KEY": "qwertyuiopasdfghjklzxcvbnm123456", - + "_comment": "Email automation", "_comment": "Change SENDGRID to 1 to use built-in and 0 to not", "SENDGRID": 0, "SENDGRID_API_KEY": "PLACE YOUR SENDGRID API KEY", "EMAIL_FROM_NAME": "test user", - "EMAIL_FROM": "email@email.com" + "EMAIL_FROM": "email@email.com", + + + "_comment": "SMS automation", + "TWILLIO_ACCOUNT": "ACc74b2cc7b09b0cee62ec2365e625819a", + "TWILLIO_AUTH_TOKEN": "e3cc20902f50059d8770cbd75b43b52a", + "TWILLIO_NUMBER": "+14243391102" } \ No newline at end of file diff --git a/src/models/email_model.py b/src/models/email_model.py new file mode 100644 index 0000000..014b047 --- /dev/null +++ b/src/models/email_model.py @@ -0,0 +1,72 @@ +import sendgrid +from src.utils import get_config + +def sendgrid_init(email_to, subject, subs, email_from): + sg = sendgrid.SendGridClient(get_config(key="SENDGRID_API_KEY")) + message = sendgrid.Mail() + message.add_to(email_to) + message.set_subject(subject) + if email_from is None: + email_from = '{}<{}>'.format(get_config(key='EMAIL_FROM_NAME'), + get_config(key='EMAIL_FROM')) + message.set_from(email_from) + for key in subs: + message.add_substitution(key, subs[key]) + + return sg, message + +def send_email_template(email_to, subject, template_id, subs, email_from): + sg, message = sendgrid_init(email_to, subject, subs, email_from) + message.set_html(' ') + message.add_filter('templates', 'enable', '1') + message.add_filter('templates', 'template_id', template_id) + + return sg.send(message) + +def send_email(email_to, subject, content, subs, email_from=None): + if get_config(key="SENDGRID") == 0: + return 200, "Not send" + + sg, message = sendgrid_init(email_to,subject, subs, email_from) + message.set_html(content) + + return sg.send(message) + +def send_activation_email(email, objectId, username=None): + if username is None: + username = '{}<{}>'.format(email.split("@",1)[0], email) + + email_to = '{}<{}>'.format(username, email) + subject = 'Activation' + content = "

Hi {{name}} ,

Congrats! Your {{app}} account has been created successfully.

Click on the button below to activate your account.

Activate Your Account

Best regards,

The {{app}} team

" + subs = { + '{{name}}': username, + '{{app}}': get_config(key='APP_NAME'), + '{{link}}':'{}activate/{}>'.format(get_config(key='API_LINK'), objectId) + } + return send_email( + email_to=email_to, + email_from=None, + subject=subject, + subs=subs, + content=content) + +def send_reset_password_email(email, password, username=None): + if username is None: + username = '{}<{}>'.format(email.split("@",1)[0], email) + + email_to = '{}<{}>'.format(username, email) + subject = 'Reset for password for {}'.format(get_config(key='APP_NAME')) + content = "

Hi {{name}},

We have received a request to set a new password for your {{app}} account.

Your new password is shown in the bow below.

{{password}}

Please login to {{app}} and change your password

Best regards,

The {{app}} team

" + subs = { + '{{name}}': username, + '{{app}}': get_config(key='APP_NAME'), + '{{link}}': get_config(key='APP_LINK'), + '{{password}}': password + } + return send_email( + email_to=email_to, + email_from=None, + subject=subject, + subs=subs, + content=content) \ No newline at end of file diff --git a/src/models/sms_model.py b/src/models/sms_model.py new file mode 100644 index 0000000..99eee83 --- /dev/null +++ b/src/models/sms_model.py @@ -0,0 +1,24 @@ +from src.utils import get_config +import twilio +import twilio.rest + +def init(): + client = twilio.rest.TwilioRestClient( + get_config(key='TWILLIO_ACCOUNT'), + get_config(key='TWILLIO_AUTH_TOKEN') + ) + return client + +def send_sms(to_number, body, media_url=None): + try: + client = init() + + message = client.messages.create( + to=to_number, + from_=get_config(key='TWILLIO_NUMBER'), + body=body, + media_url=media_url + ) + return message.error_code + except twilio.TwilioRestException as e: + return e \ No newline at end of file diff --git a/src/models/user_model.py b/src/models/user_model.py index 8214c37..6a275d9 100644 --- a/src/models/user_model.py +++ b/src/models/user_model.py @@ -2,10 +2,8 @@ from src.models.authentication_model import \ generate_auth_token from src.models import BaseModel -from src.utils import \ - send_activation_email,\ - random_string, \ - send_reset_password_email +from src.utils import random_string +from src.models.email_model import send_activation_email, send_reset_password_email class UserModel(BaseModel): _parse_class_name = '_User' @@ -66,6 +64,11 @@ def user_reset_password(self, where): if 'error' in user: return user + elif len(user['results']) != 1: + return { + 'error':404, + 'message': 'Invalid email' + } # Reset user's password payload = { diff --git a/src/utils/__init__.py b/src/utils/__init__.py index b0e400d..378b487 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -1,5 +1,4 @@ import json -import sendgrid import os import random import string @@ -27,76 +26,5 @@ def get_config( return CONFIG - -def sendgrid_init(email_to, subject, subs, email_from): - sg = sendgrid.SendGridClient(get_config(key="SENDGRID_API_KEY")) - message = sendgrid.Mail() - message.add_to(email_to) - message.set_subject(subject) - if email_from is None: - email_from = '{}<{}>'.format(get_config(key='EMAIL_FROM_NAME'), - get_config(key='EMAIL_FROM')) - message.set_from(email_from) - for key in subs: - message.add_substitution(key, subs[key]) - - return sg, message - -def send_email_template(email_to, subject, template_id, subs, email_from): - sg, message = sendgrid_init(email_to, subject, subs, email_from) - message.set_html(' ') - message.add_filter('templates', 'enable', '1') - message.add_filter('templates', 'template_id', template_id) - - return sg.send(message) - -def send_email(email_to, subject, content, subs, email_from=None): - if get_config(key="SENDGRID") == 0: - return 200, "Not send" - - sg, message = sendgrid_init(email_to,subject, subs, email_from) - message.set_html(content) - - return sg.send(message) - -def send_activation_email(email, objectId, username=None): - if username is None: - username = '{}<{}>'.format(email.split("@",1)[0], email) - - email_to = '{}<{}>'.format(username, email) - subject = 'Activation' - content = "

Hi {{name}} ,

Congrats! Your {{app}} account has been created successfully.

Click on the button below to activate your account.

Activate Your Account

Best regards,

The {{app}} team

" - subs = { - '{{name}}': username, - '{{app}}': get_config(key='APP_NAME'), - '{{link}}':'{}activate/{}>'.format(get_config(key='API_LINK'), objectId) - } - return send_email( - email_to=email_to, - email_from=None, - subject=subject, - subs=subs, - content=content) - -def send_reset_password_email(email, password, username=None): - if username is None: - username = '{}<{}>'.format(email.split("@",1)[0], email) - - email_to = '{}<{}>'.format(username, email) - subject = 'Reset for password for {}'.format(get_config(key='APP_NAME')) - content = "

Hi {{name}},

We have received a request to set a new password for your {{app}} account.

Your new password is shown in the bow below.

{{password}}

Please login to {{app}} and change your password

Best regards,

The {{app}} team

" - subs = { - '{{name}}': username, - '{{app}}': get_config(key='APP_NAME'), - '{{link}}': get_config(key='APP_LINK'), - '{{password}}': password - } - return send_email( - email_to=email_to, - email_from=None, - subject=subject, - subs=subs, - content=content) - def random_string(length = 20, chars=string.ascii_uppercase + string.digits): return ''.join(random.choice(chars) for _ in range(length)) \ No newline at end of file diff --git a/test/live/integration/test_user.py b/test/live/integration/test_user.py index 547e745..95fd8d4 100644 --- a/test/live/integration/test_user.py +++ b/test/live/integration/test_user.py @@ -134,9 +134,10 @@ def test_reset_password(self): 'password': get_config(key="TEST_PASSWORD"), 'email': "%s@email.com" % string } + print payload user = self.post_data(url='signup', data=payload) res = self.post_data(url='resetpassword', data=payload) - + print res assert 'updatedAt' in res assert res['email']['status'] is 200 From dd538acfc669cd122fad1172e91b0fc177c97eaa Mon Sep 17 00:00:00 2001 From: NghiaTTran Date: Fri, 22 Jan 2016 11:27:49 -0500 Subject: [PATCH 2/2] merged --- test/live/integration/test_user.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/live/integration/test_user.py b/test/live/integration/test_user.py index 95fd8d4..bf07048 100644 --- a/test/live/integration/test_user.py +++ b/test/live/integration/test_user.py @@ -134,10 +134,9 @@ def test_reset_password(self): 'password': get_config(key="TEST_PASSWORD"), 'email': "%s@email.com" % string } - print payload - user = self.post_data(url='signup', data=payload) + user = self.post_data(url='signup', data=payload) res = self.post_data(url='resetpassword', data=payload) - print res + assert 'updatedAt' in res assert res['email']['status'] is 200