A lightweight, secure RESTful API for managing a phone book. Built with Flask and SQLite and designed to demonstrate:
- Basic HTTP authentication with role‑based access
- Input validation using regular expressions
- Audit logging of every action
- Parameterised SQL queries (SQL‑injection safe)
- Docker‑first deployment
- Complete unit‑test suite
- Prerequisites
- Installation & Setup
2.1 Run with Docker
2.2 Run Locally (without Docker) - Authentication
- API Quick‑Start (curl)
- Validation & Error Handling
- Unit Tests
- Features Implemented
Choose one supported runtime:
| Option | Requirement |
|---|---|
| Docker | Docker Desktop |
| Local Python | Python ≥ 3.11 and SQLite ≥ 3 |
# 1 – enter directory
cd secure-phonebook-api
# 2 – build the image
docker build -t phonebook-api .
# 3 – (optional) remove any old container
docker rm -f phonebook
# 4 – run the container (host 5001 → container 5002)
docker run -d -p 5001:5002 --name phonebook phonebook-api
# 5 – open the docs page
open http://localhost:5001python3 -m venv venv
source venv/bin/activate
pip install --break-system-packages -r requirements.txt
python app.py --port 5002
# Open your browser at http://localhost:5002This API uses Basic HTTP Authentication with two roles:
| Role | Username | Password | Permissions |
|---|---|---|---|
| Read‑only | readonly | read123 | GET /PhoneBook/list |
| Read‑write | readwrite | write123 | All endpoints |
# List entries (GET)
curl -u readonly:read123 http://localhost:5001/PhoneBook/list
# Add an entry (POST)
curl -u readwrite:write123 -H "Content-Type: application/json" -d '{"name":"Bruce Schneier","phoneNumber":"123-1234"}' http://localhost:5001/PhoneBook/add
# Delete by name (PUT)
curl -X PUT -u readwrite:write123 "http://localhost:5001/PhoneBook/deleteByName?name=Bruce%20Schneier"
# Delete by number (PUT)
curl -X PUT -u readwrite:write123 "http://localhost:5001/PhoneBook/deleteByNumber?number=123-1234"# Successful add – returns 200 OK
curl -i -u readwrite:write123 -H "Content-Type: application/json" -d '{"name":"Alice Smith","phoneNumber":"+1(703)555-9876"}' http://localhost:5001/PhoneBook/add
# Expected: HTTP/1.1 200 OK {"message":"Success"}
# Invalid phone – returns 400 Bad Request
curl -i -u readwrite:write123 -H "Content-Type: application/json" -d '{"name":"Foo","phoneNumber":"123"}' http://localhost:5001/PhoneBook/add
# Expected: HTTP/1.1 400 BAD REQUEST {"error":"Invalid input"}
# Delete missing name – returns 404 Not Found
curl -i -X PUT -u readwrite:write123 "http://localhost:5001/PhoneBook/deleteByName?name=Not%20There"
# Expected: HTTP/1.1 404 NOT FOUND {"error":"Not found"}- OpenAPI specification – the full interface is defined in
PhoneBook.json(OpenAPI 3.0). - Audit log – every request is recorded with a UTC timestamp in
audit.log(project root or/app/audit.loginside the container).
Run the complete security‑focused suite:
python -m unittest discover testsdocker exec phonebook python -m unittest discover testsThe tests cover:
- Name & phone format validation
- Duplicate‑entry rejection
- Role‑based access control
- 404 handling for deletes
- Audit‑log entries (
audit.log)
- Flask‑based REST API
- SQLite persistent storage
- Secure Basic‑Auth with two roles
- Regex input validation
- Timestamped audit logging
- Prepared‑statement SQL (no injection)
- Dockerised deployment
- Complete automated tests