Catalog is a web app that supports the categorisation of items for perusal (or modification if authenticated), and includes a rate-limited JSON API.
The application is a project from Udacity's Full Stack Web Developer course.
- 35.177.46.95:2200 (Amazon Lightsail Server)
- Upgraded Linux packages and distribution
- UFW firewall (see bootstrap.sh) for SSH (port 2200), HTTP (port 80), and NTP (port 123) and SSL (port 443)
- Created a grader and catalog unix accounts
- Created rsa public key for grader .ssh/authorized_keys
- Configured /etc/ssh/sshd_config to use authorized_keys
- Added grader to /etc/sudoers.d/90-cloud-init-users
- Installed and configured Apache (to use WSGI and SSL)
- Installed and configured Postgres
- Setup a catalog database user as application schema
- Converted Python code from SQLite to Postgres Database
- Amazon Lightsail Server
- Amazon Login authentication
- Apache SSL
- Domain name from namecheap.com
- Let's Encrypt Certbot
- CSRF protection
- API rate limiting
- Responsive design
- Heroku demo site
The required software can be installed by running the bootstrap.sh, which will additionally create a configure the Postgres database.
- Procfile - Heroku application startup method
- README.md
- Vagrantfile - Vagrant build file
- application.py - Main application entry
- config.py - Configuration parameters
- database_populate.py - Generate initial test data (called from database_setup.py)
- database_setup.py - Creates base schema. Called at application startup-up or directly when first installing
- requirements.txt - Python requirements in Vagrant VM
- runtime.txt - Heroku runtime engine requirement
- static/ - Images, stylesheets
- templates/ - Flask view templates
- test/ - Contains example CSRF test
- bootstrap.sh - Installs Python Libraries and other software when executed
Deploys to 3 different target environments, detailed below in order of suggested preference.
Local VM is most recommended since it will isolate the installation and configurations.
Heroku is least recommended due to sqlite data layer; Sqlite is not reliable in such an environment and Postgres should be used instead (as a Heroku Addon). The database in this project is setup in-memory, but this does result in more that one instance in the application which can make changes appear to come and go.
- Clone the repository locally
- Run
bootstrap.sh
- Run
python database_setup.py
- Add following section to /etc/apache2/sites-enabled/000-default.conf
<VirtualHost *:443>
ServerName www.itemcatalog.club
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/www.itemcatalog.club/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.itemcatalog.club/privkey.pem
WSGIScriptAlias / /var/www/html/myapp.wsgi
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
- Restart Apache
sudo apache2ctl restart
Note: Change the URLs above as required
- Install VirtualBox and Vagrant
- Run the following:
git clone https://github.com/stevenhankin/catalog
cd catalog
vagrant up
vagrant ssh
cd /vagrant
gunicorn application:app -b 0.0.0.0:8000
- Open app in browser
- Run the following:
git clone https://github.com/stevenhankin/catalog
cd catalog
pip install -r requirements.txt
gunicorn application:app
- Open app in browser
- Create an account on Heroku website
- Create a new app
- Run the following:
git clone https://github.com/stevenhankin/catalog
cd catalog
heroku git:remote -a <your_new_app_name>
git push heroku master
- Access the application from the Heroku console using the "Open app" button
If you want users to login (which is required for modifications), then you'll need an Amazon Login account.
- Create an account on Amazon Login
- Under the Security Profile / Web Settings:
- Set Allowed Origins to be your machine's application web address (e.g. https://hankste-catalog.herokuapp.com)
- Set Allowed Return URLs to be the /login route (e.g. https://hankste-catalog.herokuapp.com/login)
- Set YOUR_CLIENT_ID in config.py to match your Amazon Client ID (also under the Web Settings)
To access the JSON data structure for an entity, make a request with the mime type set to 'application/json'
- List of items within a specified category id
/api/categories/<int:category_id>/items
Example using curl command:
curl -H "Accept: application/json" https://www.itemcatalog.club/api/categories/1/items
- Details for a specified item id
/api/items/<int:item_id>
Example using curl command:
curl -H "Accept: application/json" https://www.itemcatalog.club/api/items/1
A simple loop can quickly expose the "HTTP-429 Too Many Requests" reply:
while [[ 1==1 ]]
do
curl -H "Accept: application/json" https://www.itemcatalog.club/api/categories/1/items
sleep 0.2
done
We're sorry!
An error occurred when we tried to process your request.
Rest assured, we're already working on the problem and expect to resolve it shortly.
This is caused by incorrect account setup on Amazon Login. Please check you have the correct IDs and URL end-points configured.