fix: persist preview admin access
This commit is contained in:
@@ -118,6 +118,25 @@ python manage.py ensure_superuser
|
||||
python manage.py runserver
|
||||
```
|
||||
|
||||
### Persistent local preview without Docker
|
||||
|
||||
The local preview uses `instance/preview.sqlite3`, which survives server restarts and is
|
||||
ignored by Git. Put the preview admin credentials in `instance/preview_admin.env`
|
||||
(also ignored by Git):
|
||||
|
||||
```text
|
||||
DJANGO_SUPERUSER_USERNAME=admin
|
||||
DJANGO_SUPERUSER_EMAIL=admin@localhost
|
||||
DJANGO_SUPERUSER_PASSWORD=your-local-password
|
||||
DJANGO_SUPERUSER_SYNC_PASSWORD=False
|
||||
```
|
||||
|
||||
Then start the preview with `./run_preview.sh`. It applies migrations and ensures the
|
||||
admin account exists before starting the server. Existing passwords are preserved;
|
||||
set `DJANGO_SUPERUSER_SYNC_PASSWORD=True` for one start only if you intentionally
|
||||
need to reset the account password. This preview database is separate from the
|
||||
PostgreSQL database used by Docker and production.
|
||||
|
||||
## Management commands
|
||||
|
||||
```bash
|
||||
|
||||
@@ -31,9 +31,10 @@ class Command(BaseCommand):
|
||||
user.email = email
|
||||
user.is_staff = True
|
||||
user.is_superuser = True
|
||||
user.is_active = True
|
||||
user.set_password(password)
|
||||
user.save(
|
||||
update_fields=["email", "is_staff", "is_superuser", "password"]
|
||||
update_fields=["email", "is_staff", "is_superuser", "is_active", "password"]
|
||||
)
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
@@ -41,9 +42,16 @@ class Command(BaseCommand):
|
||||
)
|
||||
)
|
||||
return
|
||||
fields_to_update = []
|
||||
for field in ("is_staff", "is_superuser", "is_active"):
|
||||
if not getattr(user, field):
|
||||
setattr(user, field, True)
|
||||
fields_to_update.append(field)
|
||||
if fields_to_update:
|
||||
user.save(update_fields=fields_to_update)
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f"Admin '{username}' already exists; its password was preserved."
|
||||
f"Admin '{username}' is ready; its password was preserved."
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
@@ -76,6 +76,24 @@ class EnsureSuperuserCommandTests(TestCase):
|
||||
user.refresh_from_db()
|
||||
self.assertTrue(user.check_password("changed-in-admin"))
|
||||
|
||||
def test_existing_user_regains_admin_access_without_password_reset(self):
|
||||
user = get_user_model().objects.create_user(
|
||||
username="admin", email="admin@com2care.com", password="existing-password"
|
||||
)
|
||||
user.is_active = False
|
||||
user.save(update_fields=["is_active"])
|
||||
environment = {
|
||||
"DJANGO_SUPERUSER_USERNAME": "admin",
|
||||
"DJANGO_SUPERUSER_PASSWORD": "different-password",
|
||||
"DJANGO_SUPERUSER_SYNC_PASSWORD": "False",
|
||||
}
|
||||
with patch.dict(os.environ, environment, clear=False):
|
||||
call_command("ensure_superuser", verbosity=0)
|
||||
|
||||
user.refresh_from_db()
|
||||
self.assertTrue(user.is_active and user.is_staff and user.is_superuser)
|
||||
self.assertTrue(user.check_password("existing-password"))
|
||||
|
||||
def test_server_operator_can_explicitly_rotate_password(self):
|
||||
user = get_user_model().objects.create_superuser(
|
||||
username="admin",
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
"""Persistent local preview database, separate from the production PostgreSQL database."""
|
||||
|
||||
from .development import * # noqa: F401,F403
|
||||
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.sqlite3",
|
||||
"NAME": BASE_DIR / "instance" / "preview.sqlite3",
|
||||
}
|
||||
}
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
mkdir -p instance
|
||||
|
||||
if [ -f instance/preview_admin.env ]; then
|
||||
set -a
|
||||
. ./instance/preview_admin.env
|
||||
set +a
|
||||
fi
|
||||
|
||||
export DJANGO_SETTINGS_MODULE=config.settings.preview
|
||||
PYTHON=${PYTHON:-venv/bin/python}
|
||||
|
||||
"$PYTHON" manage.py migrate --noinput
|
||||
"$PYTHON" manage.py ensure_superuser
|
||||
exec "$PYTHON" manage.py runserver 127.0.0.1:8000
|
||||
Reference in New Issue
Block a user