Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a18e2d-f513-7742-b8e7-12af0b744ff3
134 lines
4.9 KiB
Python
134 lines
4.9 KiB
Python
"""Read-only data/schema and view probe; runs inside the existing app container."""
|
|
|
|
import hashlib
|
|
import json
|
|
import sys
|
|
import uuid
|
|
from pathlib import Path
|
|
|
|
import django
|
|
|
|
django.setup()
|
|
from coulomb_social.apps.members.models import Member, User
|
|
from coulomb_social.apps.spaces.models import Space
|
|
from django.conf import settings
|
|
from django.db import connection
|
|
from django.db.models import Count
|
|
|
|
assert connection.vendor == "postgresql"
|
|
assert connection.settings_dict["NAME"] in {
|
|
"coulomb_social_db",
|
|
"coulomb_social_restore",
|
|
}
|
|
tables = {}
|
|
with connection.cursor() as cursor:
|
|
cursor.execute(
|
|
"SELECT tablename FROM pg_tables WHERE schemaname='public' "
|
|
"AND tablename!='django_migrations' ORDER BY tablename"
|
|
)
|
|
names = [row[0] for row in cursor.fetchall()]
|
|
for table in names:
|
|
cursor.execute("SELECT * FROM " + connection.ops.quote_name(table))
|
|
rows = sorted(
|
|
json.dumps(row, default=str, separators=(",", ":"))
|
|
for row in cursor.fetchall()
|
|
)
|
|
tables[table] = {
|
|
"rows": len(rows),
|
|
"sha256": hashlib.sha256("\n".join(rows).encode()).hexdigest(),
|
|
}
|
|
cursor.execute(
|
|
"SELECT conname FROM pg_constraint WHERE conrelid='spaces_space'::regclass"
|
|
)
|
|
constraints = {row[0] for row in cursor.fetchall()}
|
|
cursor.execute(
|
|
"SELECT COUNT(*) FROM django_migrations WHERE app='spaces' AND name='0003_space_slug_global_uniq'"
|
|
)
|
|
applied = cursor.fetchone()[0] == 1
|
|
cursor.execute("SELECT * FROM django_migrations")
|
|
migration_rows = sorted(json.dumps(row, default=str, separators=(",", ":"))
|
|
for row in cursor.fetchall())
|
|
root = Path(settings.CONTENT_ROOT)
|
|
files = {
|
|
str(p.relative_to(root)): hashlib.sha256(p.read_bytes()).hexdigest()
|
|
for p in root.rglob("*")
|
|
if p.is_file()
|
|
}
|
|
result = {
|
|
"business_tables": len(tables),
|
|
"migration_rows_sha256": hashlib.sha256("\n".join(migration_rows).encode()).hexdigest(),
|
|
"business_rows": sum(t["rows"] for t in tables.values()),
|
|
"business_rows_sha256": hashlib.sha256(
|
|
json.dumps(tables, sort_keys=True, separators=(",", ":")).encode()
|
|
).hexdigest(),
|
|
"content_files": len(files),
|
|
"content_files_sha256": hashlib.sha256(
|
|
json.dumps(files, sort_keys=True, separators=(",", ":")).encode()
|
|
).hexdigest(),
|
|
"global_slug_constraint": "spaces_space_slug_global_uniq" in constraints,
|
|
"tenant_slug_constraint": "spaces_space_tenant_slug_uniq" in constraints,
|
|
"migration_0003_applied": applied,
|
|
"duplicate_slug_groups": Space.objects.values("slug")
|
|
.annotate(n=Count("pk"))
|
|
.filter(n__gt=1)
|
|
.count(),
|
|
}
|
|
if len(sys.argv) > 1 and sys.argv[1] == "views":
|
|
from coulomb_social.apps.spaces import views
|
|
from coulomb_social.apps.spaces.content import load_space_page
|
|
from django.test import RequestFactory
|
|
from django.urls import reverse
|
|
|
|
assert not settings.FLEX_AUTH_BASE_URL
|
|
factory = RequestFactory()
|
|
rendered_count, denied_count = 0, 0
|
|
for space in Space.objects.filter(is_active=True):
|
|
paths = sorted((root / "spaces" / space.slug / "pages").glob("*.md"))
|
|
if not paths:
|
|
continue
|
|
owner = space.created_by
|
|
if owner is None:
|
|
owner = (
|
|
space.memberships.filter(role="owner")
|
|
.select_related("member__user")
|
|
.first()
|
|
.member
|
|
)
|
|
token = "unsaved-release-check-" + uuid.uuid4().hex
|
|
outsider = Member(
|
|
user=User(username=token),
|
|
tenant_id=space.tenant_id,
|
|
subject=token,
|
|
issuer="https://release-check.invalid",
|
|
user_engine_user_id=token,
|
|
)
|
|
for path in paths:
|
|
page = path.stem
|
|
loaded = load_space_page(space, page)
|
|
assert loaded.error is None
|
|
|
|
def request(user, slug=space.slug, page_slug=page):
|
|
req = factory.get(
|
|
reverse("spaces:detail", kwargs={"slug": slug}),
|
|
{"page": page_slug},
|
|
)
|
|
req.user, req.session = user, {}
|
|
return req
|
|
|
|
response = views.space_detail(request(owner.user), slug=space.slug)
|
|
assert (
|
|
response.status_code == 200 and loaded.html.encode() in response.content
|
|
)
|
|
rendered_count += 1
|
|
denied = views.space_detail(request(outsider.user), slug=space.slug)
|
|
assert denied.status_code == 404
|
|
if loaded.html:
|
|
assert loaded.html.encode() not in denied.content
|
|
denied_count += 1
|
|
assert rendered_count > 0 and denied_count == rendered_count
|
|
result.update(
|
|
actual_owner_pages_rendered=rendered_count,
|
|
unsaved_outsider_page_denials=denied_count,
|
|
production_identity_or_grant_created=False,
|
|
)
|
|
print(json.dumps(result))
|