Skip to content

khaledalturkestani/uber-assignment

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Instructions:

- Create an ubuntu EC2 instance:
  Make sure in the security rules to add a "Custom TCP" rule for port 5000
- SSH into the instance and download the needed dependencies by typing th following in the terminal:
  $ sudo apt-get install git
  $ sudo apt-get install python-pip
  $ sudo pip install Flask
  $ sudo pip install mandrill
  $ sudo pip install sqlalchemy
  $ sudo apt-get install sqlite3
- clone the application from GitHub:
  $ git clone https://github.com/khaledalturkestani/uber-assignment.git
- Sign up for Mailgun and Mandrill and fill in the required fields at the top of send_email.py with the provided keys by the services.
- To start the server, open a terimal, cd into uber-assignment, and type:
  $ python send_email.py
- Now you can either issue a post request to instance_public_ip:5000/email with JSON parameters as specified in the assignment, or
  access a simple form in a web browser by typing the URL:
  instance_public_ip:5000
- To run automated tests, cd into uber-assignment and type:
  $ python send_email_tests.py

Language/Framework:
- I chose Python over Node.js since I am more familiar with it, it is supported by Mailgun and Mandrill, and is used by Uber.
- I chose Flask as a microframework over others since it is widely used and supported by Python community, and is supported by
  Mailgun.
- In addition, I am using SQLAlchemy for interfacing with the database since it is well integrated with Flask, has a simple ORM 
  representation, and handles basic functions like escaping input and correct query handling to prevent SQL injection.
- Used unittest, Python's unit testing framework, for testing. 

Feature summary:
- Accepts a JSON string with the parameters as specified in the assignment.
- Returns a 200 response on successfull queueing of email to one of the two services.
  - Tries Mailgun first, then Mandrill if Mailgun fails.
- Returns a 400 response on bad input.
- Returns a 502 Bad Gateway if both services fail.
- Accepts an optional "datetime" parameter for scheduled delivery.
- Saves sent emails and service responses in a SQLite database.
- Input validation in the application layer: 
  - Verifies valid email addresses format (build-in browser function).
  - Verifies presense of all email message paramters.
- Input validation in the ORM layer:
  - Only checks if email addresses are valid
  - Allows empty strings
- Input validation in the DB layer:
  - Only enforces non-null fields

Features not implemented but should be considered: 
- Need to authenticate the user issuing the POST requests. Right now the service is very insecure since anyone can post a request to it and there is no access control. Ideally, this service should be dispatched internally instead of a POST request. Another simpler solution would be to authenticate the user through a username/password or have them submit the api keys and verifying them, which require doing so over SSL to make sure the sensitive data is encrypted. 
- Error logging.
- More thorough testing on different input field combinations. Also testing of the two service providers. 
- Validating email existence and not just valid format.
- A more robust RegEx for validating email addresses. 
- Right now choosing between services always happens in the same order (i.e. Mailgun then Mandrill if Mailgun fails). It is probably better to decide which email service to choose using a slightly more intelligent function, which would probably use cost as the main metric to decide on a service at any given time. 

About

Coding assignment for Uber application. Implements a simple abstraction layer for dispatching emails to 3rd party services.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages