124 lines
3.5 KiB
Markdown
124 lines
3.5 KiB
Markdown
# Secure E-commerce API MVP
|
|
|
|
FastAPI + SQLite MVP for a retail order-payment flow with modular architecture, JWT authentication, RBAC (client/shop roles), object-level authorization, strict validation, and secure logging.
|
|
|
|
The project also includes a browser UI at `/` for the complete client flow: registration, login, catalog browsing, cart checkout, order viewing, mock payment confirmation, and shop-only product creation.
|
|
|
|
## Features
|
|
|
|
- Customer registration and login with short-lived JWT access tokens
|
|
- Product catalog browsing
|
|
- Shop-only product creation
|
|
- Order creation from cart-style line items
|
|
- Object-level authorization for viewing and paying only your own orders
|
|
- Mock payment confirmation that updates order status
|
|
- Secure audit logging that avoids passwords, JWTs, and sensitive identifiers
|
|
- Static frontend served by FastAPI with same-origin API calls
|
|
|
|
## Roles
|
|
|
|
- **`client`** — default role, assigned on registration. Can browse products, create orders, view own orders, make payments.
|
|
- **`shop`** — privileged role. Can create products. Assigned to the default shop account.
|
|
|
|
## Project Structure
|
|
|
|
```text
|
|
app/
|
|
api/
|
|
core/
|
|
db/
|
|
models/
|
|
schemas/
|
|
services/
|
|
main.py
|
|
```
|
|
|
|
## Requirements
|
|
|
|
- Python 3.12 recommended
|
|
|
|
## Setup
|
|
|
|
1. Create and activate a virtual environment.
|
|
2. Install dependencies:
|
|
|
|
```bash
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
3. Optional: create a local environment file from the example and adjust secrets:
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
## Initialize the SQLite Database
|
|
|
|
The application creates tables automatically on startup. You can also initialize the database explicitly:
|
|
|
|
```bash
|
|
python -m app.db.init_db
|
|
```
|
|
|
|
### Create a Shop Account
|
|
|
|
A shop account is **not** created by default. Run the dedicated script to create one:
|
|
|
|
```bash
|
|
python -m app.db.create_shop_account
|
|
```
|
|
|
|
For safer bootstrap, the script no longer prints generated credentials to stdout.
|
|
Use one of these approaches:
|
|
|
|
1. Interactive mode: the script securely asks for a strong password via `getpass()`.
|
|
2. Non-interactive mode: set `SHOP_ACCOUNT_PASSWORD` before running the script.
|
|
|
|
Example output:
|
|
|
|
```
|
|
============================================================
|
|
SHOP ACCOUNT CREATED SUCCESSFULLY
|
|
============================================================
|
|
Username: shop
|
|
============================================================
|
|
Password was accepted and hashed without being printed to stdout.
|
|
============================================================
|
|
```
|
|
|
|
## Run the Server
|
|
|
|
```bash
|
|
uvicorn app.main:app --reload
|
|
```
|
|
|
|
Open:
|
|
|
|
- Frontend: `http://127.0.0.1:8000/`
|
|
- API docs: `http://127.0.0.1:8000/docs`
|
|
- Health check: `http://127.0.0.1:8000/health`
|
|
|
|
## Docker
|
|
|
|
```bash
|
|
docker build -t secure-online-shop .
|
|
docker run -d --name secure-online-shop \
|
|
-p 80:8000 \
|
|
-e JWT_SECRET_KEY="replace-with-a-strong-32-plus-char-random-secret-value" \
|
|
-e SHOP_ACCOUNT_PASSWORD="StrongShopPassword1!" \
|
|
-e DEMO_SEED_PRODUCTS=true \
|
|
secure-online-shop
|
|
```
|
|
|
|
`SHOP_ACCOUNT_PASSWORD` is optional, but setting it creates the `shop` account at container startup. `DEMO_SEED_PRODUCTS=true` fills the catalog with demo rows for MVP presentation.
|
|
|
|
## Example Flow
|
|
|
|
1. Register a client with `POST /api/v1/auth/register`
|
|
2. Log in with `POST /api/v1/auth/login`
|
|
3. Log in as shop and create products with `POST /api/v1/products`
|
|
4. Browse products with `GET /api/v1/products`
|
|
5. Create an order with `POST /api/v1/orders`
|
|
6. View your orders with `GET /api/v1/orders`
|
|
7. Confirm payment with `POST /api/v1/payments/orders/{order_id}/confirm`
|