Files
secure-online-shop/README.md
T

3.5 KiB

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

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:
pip install -r requirements.txt
  1. Optional: create a local environment file from the example and adjust secrets:
cp .env.example .env

Initialize the SQLite Database

The application creates tables automatically on startup. You can also initialize the database explicitly:

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:

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

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

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