Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions config/dev.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
10 changes: 8 additions & 2 deletions config/test.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
72 changes: 72 additions & 0 deletions src/models/email_model.py
Original file line number Diff line number Diff line change
@@ -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 = "<html><head><title></title><link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'><style type='text/css'></style></head><body style='background-color: #fDfDfD;'><div style='font-family: Ubuntu, sans-serif;background-color: white;width: 80%;margin: auto;padding: 20px;border: 1px solid #E5E5E5;'> <h4 style='font-size:24px'>Hi {{name}} ,</h4><p style='font-size:18px'>Congrats! Your {{app}} account has been created successfully.</p><p style='font-size:18px'>Click on the button below to activate your account.</p><div style='padding-top: 15px;padding-bottom: 15px;width: 100%;margin: auto;text-align:center'><a href='{{link}}' style='margin: auto;background: #3BCA96;background-image: -webkit-linear-gradient(top, #3BCA96, #3BCA90);background-image: -moz-linear-gradient(top, #3BCA96, #3BCA90);background-image: -ms-linear-gradient(top, #3BCA96, #3BCA90);background-image: -o-linear-gradient(top, #3BCA96, #3BCA90);background-image: linear-gradient(to bottom, #3BCA96, #3BCA90);-webkit-border-radius: 3;-moz-border-radius: 3;border-radius: 3px;text-shadow: 1px 1px 3px #666666;font-family: Arial;color: #ffffff;font-size: 23px;padding: 10px 20px 10px 20px;text-decoration: none;'>Activate Your Account</a></div><p style='font-size:18px'>Best regards,</p><p style='font-size:18px'>The {{app}} team</p></div></body></html>"
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 = "<html><head><title></title><link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'><style type='text/css'></style></head><body style='background-color: #fDfDfD;'><div style='font-family: Ubuntu, sans-serif;background-color: white;width: 80%;margin: auto;padding: 20px;border: 1px solid #E5E5E5;'> <h4 style='font-size:24px'>Hi {{name}},</h4><p style='font-size:18px'>We have received a request to set a new password for your {{app}} account. </p><p style='font-size:18px'>Your new password is shown in the bow below.</p><div style='padding-top: 15px;padding-bottom: 15px;width: 100%;margin: auto;text-align:center'><div style='margin: auto;background: #3BCA96;background-image: -webkit-linear-gradient(top, #3BCA96, #3BCA90);background-image: -moz-linear-gradient(top, #3BCA96, #3BCA90);background-image: -ms-linear-gradient(top, #3BCA96, #3BCA90);background-image: -o-linear-gradient(top, #3BCA96, #3BCA90);background-image: linear-gradient(to bottom, #3BCA96, #3BCA90);-webkit-border-radius: 3;-moz-border-radius: 3;border-radius: 3px;text-shadow: 1px 1px 3px #666666;font-family: Arial;width: 400px;color: #ffffff;font-size: 23px;padding: 10px 20px 10px 20px;text-decoration: none;'>{{password}}</div></div><p style='font-size:18px'>Please login to <a href='{{link}}'>{{app}}</a> and change your password</p><p style='font-size:18px'>Best regards,</p><p style='font-size:18px'>The {{app}} team</p></div></body></html>"
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)
24 changes: 24 additions & 0 deletions src/models/sms_model.py
Original file line number Diff line number Diff line change
@@ -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
11 changes: 7 additions & 4 deletions src/models/user_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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 = {
Expand Down
72 changes: 0 additions & 72 deletions src/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import json
import sendgrid
import os
import random
import string
Expand Down Expand Up @@ -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 = "<html><head><title></title><link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'><style type='text/css'></style></head><body style='background-color: #fDfDfD;'><div style='font-family: Ubuntu, sans-serif;background-color: white;width: 80%;margin: auto;padding: 20px;border: 1px solid #E5E5E5;'> <h4 style='font-size:24px'>Hi {{name}} ,</h4><p style='font-size:18px'>Congrats! Your {{app}} account has been created successfully.</p><p style='font-size:18px'>Click on the button below to activate your account.</p><div style='padding-top: 15px;padding-bottom: 15px;width: 100%;margin: auto;text-align:center'><a href='{{link}}' style='margin: auto;background: #3BCA96;background-image: -webkit-linear-gradient(top, #3BCA96, #3BCA90);background-image: -moz-linear-gradient(top, #3BCA96, #3BCA90);background-image: -ms-linear-gradient(top, #3BCA96, #3BCA90);background-image: -o-linear-gradient(top, #3BCA96, #3BCA90);background-image: linear-gradient(to bottom, #3BCA96, #3BCA90);-webkit-border-radius: 3;-moz-border-radius: 3;border-radius: 3px;text-shadow: 1px 1px 3px #666666;font-family: Arial;color: #ffffff;font-size: 23px;padding: 10px 20px 10px 20px;text-decoration: none;'>Activate Your Account</a></div><p style='font-size:18px'>Best regards,</p><p style='font-size:18px'>The {{app}} team</p></div></body></html>"
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 = "<html><head><title></title><link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'><style type='text/css'></style></head><body style='background-color: #fDfDfD;'><div style='font-family: Ubuntu, sans-serif;background-color: white;width: 80%;margin: auto;padding: 20px;border: 1px solid #E5E5E5;'> <h4 style='font-size:24px'>Hi {{name}},</h4><p style='font-size:18px'>We have received a request to set a new password for your {{app}} account. </p><p style='font-size:18px'>Your new password is shown in the bow below.</p><div style='padding-top: 15px;padding-bottom: 15px;width: 100%;margin: auto;text-align:center'><div style='margin: auto;background: #3BCA96;background-image: -webkit-linear-gradient(top, #3BCA96, #3BCA90);background-image: -moz-linear-gradient(top, #3BCA96, #3BCA90);background-image: -ms-linear-gradient(top, #3BCA96, #3BCA90);background-image: -o-linear-gradient(top, #3BCA96, #3BCA90);background-image: linear-gradient(to bottom, #3BCA96, #3BCA90);-webkit-border-radius: 3;-moz-border-radius: 3;border-radius: 3px;text-shadow: 1px 1px 3px #666666;font-family: Arial;width: 400px;color: #ffffff;font-size: 23px;padding: 10px 20px 10px 20px;text-decoration: none;'>{{password}}</div></div><p style='font-size:18px'>Please login to <a href='{{link}}'>{{app}}</a> and change your password</p><p style='font-size:18px'>Best regards,</p><p style='font-size:18px'>The {{app}} team</p></div></body></html>"
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))
2 changes: 1 addition & 1 deletion test/live/integration/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ def test_reset_password(self):
'password': get_config(key="TEST_PASSWORD"),
'email': "%s@email.com" % string
}
user = self.post_data(url='signup', data=payload)

user = self.post_data(url='signup', data=payload)
res = self.post_data(url='resetpassword', data=payload)

assert 'updatedAt' in res
Expand Down