Docs and requirements: signing key replaced and shared Redis cache are live; pin dependency versions

- CLAUDE.md: status block for 2026-10-07 (what changed on the server, how it was checked, what was not).
- docs/security-before-production.md: signing key, shared cache and unit DEBUG items moved to the guard table.
- requirements.txt: ranges replaced by the versions running on the server (pip freeze, 2026-10-07).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-07 14:02:51 +03:30
parent 4c601087dc
commit 7929f6bd85
3 changed files with 34 additions and 54 deletions

View File

@@ -70,10 +70,10 @@ paid on the server on 2026-10-03); orders without the `question_credits`/`hearts
## Before any real user: read `docs/security-before-production.md`
The server is deliberately left in demo mode for the internship presentation: the token
signing key is the one committed in this repo, seven fixed-code demo logins exist, demo
users sit in the production DB, and `/api/health`, the API schema, the leaderboard and
`/admin/` are all public. Each is listed there with its risk, why it was left, and the
The server is deliberately left in demo mode for the internship presentation: seven
fixed-code demo logins exist, demo users sit in the production DB, and `/api/health`, the API
schema, the leaderboard and `/admin/` are all public. (The token signing key is no longer the
committed one: replaced 2026-10-07, see the status block below.) Each is listed there with its risk, why it was left, and the
fix. **Do not treat this deployment as production-ready until every item there is closed**,
and when one is closed, move it to that file's «حفاظ‌هایی که هست» table with the test that holds it (the date lives in the commit message; the owner wants docs to describe the current state only).
@@ -88,7 +88,7 @@ python manage.py test accounts # single app
python manage.py test accounts.tests.SomeTestCase.test_something # single test
```
Local dev requires `DJANGO_DEBUG=1` (enables Swagger auth via `DEV_MASTER_OTP`/`devOtp` in responses). `DEBUG` defaults to `False`. Production also requires `DJANGO_SECRET_KEY`, `DJANGO_ALLOWED_HOSTS` (comma-separated), and ideally `CACHE_URL` (Redis). Without it the app still boots on per-process `LocMemCache` and `/api/health` warns — throttles and admin-driven cache invalidation are then per worker. On the server it is still unset (left to the server admin, 2026-09-24).
Local dev requires `DJANGO_DEBUG=1` (enables Swagger auth via `DEV_MASTER_OTP`/`devOtp` in responses). `DEBUG` defaults to `False`. Production also requires `DJANGO_SECRET_KEY`, `DJANGO_ALLOWED_HOSTS` (comma-separated), and ideally `CACHE_URL` (Redis). Without it the app still boots on per-process `LocMemCache` and `/api/health` warns — throttles and admin-driven cache invalidation are then per worker. On the server it points at the shared Redis, database 1 (since 2026-10-07).
No pytest; uses Django's built-in test runner. No linter/formatter configured.
@@ -441,6 +441,25 @@ preferred setup, because there is then no key to leak. **Never let the server ru
`django-insecure-…` fallback from `config/settings.py`: that string is committed here, so
anyone who can read this repo can forge a token for any user.**
## وضعیت ۲۰۲۶-۱۰-۰۷ — روی سرور (`4c60108`، ری‌استارت ۱۳:۵۹)
بکاپ‌های همان روز در `.deploy-backups/`: `env-before-secretkey-redis-20261007-135850`،
`unit-gunicorn-mathapp-before-20261007-135850.service`، `db-before-deploy-20261007-13*.sqlite3`.
- **کلیدِ امضای توکن عوض شد** (بند ۱ سندِ امنیتی). از `.env` و از یونیتِ `gunicorn-mathapp.service`
برداشته شد (یونیت فقط `DJANGO_ALLOWED_HOSTS` و `EnvironmentFile` دارد؛ `DJANGO_DEBUG` هم از یونیت
رفت و فقط `.env` می‌ماند). برنامه خودش کلید را در `.django_secret_key` (۶۰۰) ساخت. سنجش: توکنِ جعلی
با کلیدِ داخلِ ریپو برای کاربرهای ۱۰، ۱۱، ۱۲ پیش از تغییر `200` و بعدش `401` گرفت. توکنِ refresh در
دیتابیس است، نه امضاشده، پس نشست‌ها نمی‌میرند و فرانت بی‌صدا توکنِ تازه می‌گیرد؛ این را با ورودِ واقعی
**نسنجیدم**.
- **`CACHE_URL=redis://127.0.0.1:6379/1`** (Redisِ مشترکِ ماشین، بدونِ رمز، `maxmemory 0`؛ دیتابیسِ ۰ مالِ
دیگران است و دست نخورد). سقفِ نرخ حالا مشترک است: رگبارِ ۶۰۰ درخواستی ۱۲۸ تا `200` داد (پیش از آن
۳۶۰ = ۳ worker × ۱۲۰). ⚠️ اگر این Redis بخوابد، هر مسیرِ throttleدار خطا می‌دهد؛ برگشت: خطِ `CACHE_URL` را
از `.env` خالی کنید و ری‌استارت.
- پایانِ درس/جزیره بی‌جواب و روی جزیره‌ی قفل پذیرفته نمی‌شود، ۱۵ مسیر سقفِ نرخ گرفتند، `deploy.sh`
پیش از `migrate` بکاپ می‌گیرد و سلامت را از سوکتِ gunicorn می‌سنجد.
- نسخه‌ی کتابخانه‌های `requirements.txt` قفل شد (نسخه‌های روی سرور).
## وضعیت ۲۰۲۶-۱۰-۰۵ (عصر) — ورودِ مهمان از ریشه حذف شد
**روی سرور از ۲۰۲۶-۱۰-۰۵ ۱۸:۳۹** (بک‌اند `5b7e6fb`، سرویس واقعاً ری‌استارت شد، `accounts.0008` اعمال شد؛ فرانت `0db6526`).