khaledalturkestani/uber-assignment
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
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 0
No packages published