refactor: remove legacy build probe and database URL normalization scripts; update Dockerfile and docker-compose for cleaner setup

This commit is contained in:
gabdevele
2026-06-18 18:05:41 +02:00 Unverified
parent b6c315d005
commit f90afcbf52
10 changed files with 1 additions and 266 deletions
-6
View File
@@ -4,9 +4,6 @@ ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1 ENV PYTHONUNBUFFERED=1
ENV PYTHONPATH=/app ENV PYTHONPATH=/app
ARG BUILD_ID=dev
ARG BUILD_TIME_UTC=unknown
RUN apt-get update \ RUN apt-get update \
&& apt-get install -y --no-install-recommends build-essential git \ && apt-get install -y --no-install-recommends build-essential git \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
@@ -26,9 +23,6 @@ COPY federation_authority /app/federation_authority
COPY provider /app/provider COPY provider /app/provider
COPY relying_party /app/relying_party COPY relying_party /app/relying_party
RUN sh -lc 'find /app/federation_authority /app/provider /app/relying_party /app/scripts -type f | sort | xargs sha256sum | sha256sum | awk "{print \$1}" > /app/__buildfingerprint__'
RUN printf '{\"build_id\":\"%s\",\"built_at_utc\":\"%s\",\"image_marker\":\"cie-auth-image\"}\n' \"$BUILD_ID\" \"$BUILD_TIME_UTC\" > /app/__buildinfo__.json
COPY entrypoint.sh /entrypoint.sh COPY entrypoint.sh /entrypoint.sh
COPY scripts /app/scripts COPY scripts /app/scripts
RUN chmod +x /entrypoint.sh RUN chmod +x /entrypoint.sh
+1 -1
View File
@@ -12,6 +12,7 @@ Tutti i commit presenti sono bug dovuti a svariate problematiche che abbiamo avu
## Note ## Note
Setuppare questo progetto in locale è molto complesso, consiglio di testarlo direttamente in produzione con i vari domini impostati. Setuppare questo progetto in locale è molto complesso, consiglio di testarlo direttamente in produzione con i vari domini impostati.
Lo script `scripts/legacy/normalize_db_urls.py` esiste solo per migrare manualmente vecchi volumi SQLite bootstrapati con URL legacy; non viene piu eseguito automaticamente a runtime.
## Dettagli ## Dettagli
Stack: Stack:
@@ -22,4 +23,3 @@ Stack:
Il RP Visione usa `/visione/start` per iniziare il flow e `/visione/complete` per chiuderlo verso backend Visione. Il RP Visione usa `/visione/start` per iniziare il flow e `/visione/complete` per chiuderlo verso backend Visione.
Il replying party sarebbe dovuto essere unicamente il nostro backend ma certe feature sono molto complesse da implementare in C++,infatti non esiste una repo già pronta per questo linguaggio, per questo è stato scelto di fare un ponte tra il backend Visione e il RP Django, che si occupa di fare la parte più complessa del flow CIE. Il replying party sarebbe dovuto essere unicamente il nostro backend ma certe feature sono molto complesse da implementare in C++,infatti non esiste una repo già pronta per questo linguaggio, per questo è stato scelto di fare un ponte tra il backend Visione e il RP Django, che si occupa di fare la parte più complessa del flow CIE.
-9
View File
@@ -3,9 +3,6 @@ services:
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
args:
BUILD_ID: ${CIE_AUTH_BUILD_ID:-dev}
BUILD_TIME_UTC: ${CIE_AUTH_BUILD_TIME_UTC:-unknown}
working_dir: /app/federation_authority working_dir: /app/federation_authority
command: ["/app/federation_authority", "8000"] command: ["/app/federation_authority", "8000"]
environment: environment:
@@ -24,9 +21,6 @@ services:
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
args:
BUILD_ID: ${CIE_AUTH_BUILD_ID:-dev}
BUILD_TIME_UTC: ${CIE_AUTH_BUILD_TIME_UTC:-unknown}
working_dir: /app/provider working_dir: /app/provider
command: ["/app/provider", "8002"] command: ["/app/provider", "8002"]
environment: environment:
@@ -48,9 +42,6 @@ services:
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
args:
BUILD_ID: ${CIE_AUTH_BUILD_ID:-dev}
BUILD_TIME_UTC: ${CIE_AUTH_BUILD_TIME_UTC:-unknown}
working_dir: /app/relying_party working_dir: /app/relying_party
command: ["/app/relying_party", "8001"] command: ["/app/relying_party", "8001"]
environment: environment:
-10
View File
@@ -5,17 +5,11 @@ APP_DIR="$1"
PORT="$2" PORT="$2"
DB_PATH="${DJANGO_DB_PATH:-$APP_DIR/db/db.sqlite3}" DB_PATH="${DJANGO_DB_PATH:-$APP_DIR/db/db.sqlite3}"
DUMP_SRC="$APP_DIR/dumps/example.json" DUMP_SRC="$APP_DIR/dumps/example.json"
LEGACY_DB_PATH="$APP_DIR/db.sqlite3"
cd "$APP_DIR" cd "$APP_DIR"
mkdir -p logs static "$(dirname "$DB_PATH")" mkdir -p logs static "$(dirname "$DB_PATH")"
if [ ! -f "$DB_PATH" ] && [ -f "$LEGACY_DB_PATH" ]; then
mkdir -p "$(dirname "$DB_PATH")"
cp "$LEGACY_DB_PATH" "$DB_PATH"
fi
python manage.py migrate python manage.py migrate
should_load_fixture=0 should_load_fixture=0
@@ -47,10 +41,6 @@ if [ "$should_load_fixture" = "1" ]; then
rm -f "$TMP_DUMP" rm -f "$TMP_DUMP"
fi fi
python /app/scripts/normalize_db_urls.py "$DB_PATH"
# With DEBUG disabled Django no longer serves app static assets implicitly.
# Collect them into STATIC_ROOT so the explicit /static/ URL can serve them.
python manage.py collectstatic --noinput python manage.py collectstatic --noinput
if grep -aEq '127\.0\.0\.1|provider:8002' "$DB_PATH" \ if grep -aEq '127\.0\.0\.1|provider:8002' "$DB_PATH" \
@@ -18,7 +18,6 @@ from django.contrib import admin
from django.urls import include, path, re_path from django.urls import include, path, re_path
from django.views.static import serve from django.views.static import serve
from scripts.build_probe import build_probe_view
from spid_cie_oidc.entity.urls import urlpatterns as entity_urlpatterns from spid_cie_oidc.entity.urls import urlpatterns as entity_urlpatterns
from spid_cie_oidc.authority.urls import urlpatterns as ta_urlpatterns from spid_cie_oidc.authority.urls import urlpatterns as ta_urlpatterns
from spid_cie_oidc.onboarding.urls import urlpatterns as onb_urlpatterns from spid_cie_oidc.onboarding.urls import urlpatterns as onb_urlpatterns
@@ -40,7 +39,6 @@ urlpatterns.extend(onb_urlpatterns)
urlpatterns.extend( urlpatterns.extend(
( (
path(f"{ADMIN_PATH}", admin.site.urls), path(f"{ADMIN_PATH}", admin.site.urls),
path("__build", lambda request: build_probe_view("federation-authority"), name="build_probe"),
re_path('^static/(?P<path>.*)$', re_path('^static/(?P<path>.*)$',
serve, { serve, {
'document_root': settings.STATIC_ROOT, 'document_root': settings.STATIC_ROOT,
-3
View File
@@ -19,7 +19,6 @@ from django.contrib import admin
from django.views.static import serve from django.views.static import serve
from django.urls import include, path, re_path from django.urls import include, path, re_path
from scripts.build_probe import build_probe_view, diag_view
from spid_cie_oidc.entity.urls import urlpatterns as entity_urlpatterns from spid_cie_oidc.entity.urls import urlpatterns as entity_urlpatterns
admin.site.site_header = "OIDC Federation Provider Administration" admin.site.site_header = "OIDC Federation Provider Administration"
@@ -30,8 +29,6 @@ ADMIN_PATH = getattr(settings, 'ADMIN_PATH', 'admin/')
urlpatterns = [ urlpatterns = [
path(f"{ADMIN_PATH}", admin.site.urls), path(f"{ADMIN_PATH}", admin.site.urls),
path("__build", lambda request: build_probe_view("provider"), name="build_probe"),
path("__diag", lambda request: diag_view("provider"), name="diag_probe"),
re_path('^static/(?P<path>.*)$', re_path('^static/(?P<path>.*)$',
serve, { serve, {
'document_root': settings.STATIC_ROOT, 'document_root': settings.STATIC_ROOT,
-3
View File
@@ -18,7 +18,6 @@ from django.contrib import admin
from django.urls import include, path, re_path from django.urls import include, path, re_path
from django.views.static import serve from django.views.static import serve
from scripts.build_probe import build_probe_view, diag_view
from spid_cie_oidc.entity.urls import urlpatterns as ta_urlpatterns from spid_cie_oidc.entity.urls import urlpatterns as ta_urlpatterns
from .visione_views import VisioneCompleteView, VisioneStartView from .visione_views import VisioneCompleteView, VisioneStartView
from .rp_overrides import VisioneRpBeginView, VisioneRpCallbackView from .rp_overrides import VisioneRpBeginView, VisioneRpCallbackView
@@ -31,8 +30,6 @@ ADMIN_PATH = getattr(settings, 'ADMIN_PATH', 'admin/')
urlpatterns = [ urlpatterns = [
path(f"{ADMIN_PATH}", admin.site.urls), path(f"{ADMIN_PATH}", admin.site.urls),
path("__build", lambda request: build_probe_view("relying-party"), name="build_probe"),
path("__diag", lambda request: diag_view("relying-party"), name="diag_probe"),
path("visione/start", VisioneStartView.as_view(), name="visione_start"), path("visione/start", VisioneStartView.as_view(), name="visione_start"),
path("visione/complete", VisioneCompleteView.as_view(), name="visione_complete"), path("visione/complete", VisioneCompleteView.as_view(), name="visione_complete"),
re_path('^static/(?P<path>.*)$', re_path('^static/(?P<path>.*)$',
-57
View File
@@ -1,57 +0,0 @@
import json
import os
from pathlib import Path
from django.http import JsonResponse
from spid_cie_oidc.entity.models import FederationEntityConfiguration, TrustChain, FetchedEntityStatement
def build_probe_view(service: str):
info_path = Path("/app/__buildinfo__.json")
fingerprint_path = Path("/app/__buildfingerprint__")
info = {}
if info_path.exists():
try:
info = json.loads(info_path.read_text())
except Exception:
info = {}
fingerprint = ""
if fingerprint_path.exists():
try:
fingerprint = fingerprint_path.read_text().strip()
except Exception:
fingerprint = ""
return JsonResponse(
{
"ok": True,
"service": service,
"build_id": info.get("build_id", ""),
"built_at_utc": info.get("built_at_utc", ""),
"image_marker": info.get("image_marker", ""),
"fingerprint": fingerprint,
"hostname": os.getenv("HOSTNAME", ""),
}
)
def diag_view(service: str):
configs = FederationEntityConfiguration.objects.all()
active = FederationEntityConfiguration.objects.filter(is_active=True)
first = configs.order_by("id").first()
first_active = active.order_by("id").first()
return JsonResponse(
{
"ok": True,
"service": service,
"config_count": configs.count(),
"active_config_count": active.count(),
"first_sub": getattr(first, "sub", None),
"first_entity_type": getattr(first, "entity_type", None),
"first_active_sub": getattr(first_active, "sub", None),
"first_active_entity_type": getattr(first_active, "entity_type", None),
"trust_chain_count": TrustChain.objects.count(),
"fetched_statement_count": FetchedEntityStatement.objects.count(),
}
)
-175
View File
@@ -1,175 +0,0 @@
#!/usr/bin/env python3
import json
import os
import sqlite3
import sys
from typing import Iterable
def env(name: str, default: str = "") -> str:
return os.getenv(name, default).strip().rstrip("/")
def infer_base_url(kind: str) -> str:
hosts = env("DJANGO_ALLOWED_HOSTS") or env("CIE_AUTH_ALLOWED_HOSTS")
items = [host.strip() for host in hosts.split(",") if host.strip() and host.strip() != "*"]
for host in items:
if kind in host:
return f"https://{host}"
defaults = {
"fa": "http://federation-authority:8000",
"provider": "http://provider:8002",
"rp": "http://relying-party:8001",
}
return defaults[kind]
TA = env("DJANGO_TRUST_ANCHOR") or infer_base_url("fa")
PROVIDER_ISSUER = env("DJANGO_PROVIDER_ISSUER") or f"{infer_base_url('provider')}/oidc/op"
RP_BASE = env("DJANGO_RP_BASE_URL") or infer_base_url("rp")
RP_ISSUER = f"{RP_BASE}/oidc/rp"
PROVIDER_BASE = PROVIDER_ISSUER.removesuffix("/oidc/op")
def rewrite_string(value: str) -> str:
return (
value.replace("http://127.0.0.1:8000/oidc/op", TA + "/oidc/op")
.replace("http://127.0.0.1:8001/oidc/rp", RP_ISSUER)
.replace("http://127.0.0.1:8002/oidc/op", PROVIDER_ISSUER)
.replace("http://127.0.0.1:8000", TA)
.replace("http://127.0.0.1:8001", RP_BASE)
.replace("http://127.0.0.1:8002", PROVIDER_BASE)
.replace("http://provider:8002/oidc/op", PROVIDER_ISSUER)
.replace("http://provider:8002", PROVIDER_BASE)
.replace("http://relying-party:8001/oidc/rp", RP_ISSUER)
.replace("http://relying-party:8001", RP_BASE)
.replace("http://federation-authority:8000/oidc/op", TA + "/oidc/op")
.replace("http://federation-authority:8000", TA)
)
REPLACEMENTS = [
("http://127.0.0.1:8000/oidc/op", TA + "/oidc/op"),
("http://127.0.0.1:8001/oidc/rp", RP_ISSUER),
("http://127.0.0.1:8002/oidc/op", PROVIDER_ISSUER),
("http://127.0.0.1:8000", TA),
("http://127.0.0.1:8001", RP_BASE),
("http://127.0.0.1:8002", PROVIDER_BASE),
("http://provider:8002/oidc/op", PROVIDER_ISSUER),
("http://provider:8002", PROVIDER_BASE),
("http://relying-party:8001/oidc/rp", RP_ISSUER),
("http://relying-party:8001", RP_BASE),
("http://federation-authority:8000/oidc/op", TA + "/oidc/op"),
("http://federation-authority:8000", TA),
]
def deep_replace(value):
if isinstance(value, dict):
return {k: deep_replace(v) for k, v in value.items()}
if isinstance(value, list):
return [deep_replace(v) for v in value]
if isinstance(value, str):
return rewrite_string(value)
return value
def replace_in_all_text_columns(cur, table: str):
cols = cur.execute(f"PRAGMA table_info({table})").fetchall()
text_cols = [c[1] for c in cols if c[2] and c[2].upper() in {"TEXT", "VARCHAR(255)", "VARCHAR(2048)", "VARCHAR(64)", "VARCHAR(33)", "JSON"}]
for column in text_cols:
for old, new in REPLACEMENTS:
cur.execute(
f"UPDATE {table} SET {column} = REPLACE({column}, ?, ?) WHERE {column} LIKE ?",
(old, new, f"%{old}%"),
)
def update_json_column(cur, table, pk, column):
rows = cur.execute(f"SELECT id, {column} FROM {table}").fetchall()
for row_id, raw in rows:
if not raw:
continue
try:
data = json.loads(raw)
except Exception:
continue
updated = deep_replace(data)
if updated != data:
cur.execute(
f"UPDATE {table} SET {column} = ? WHERE {pk} = ?",
(json.dumps(updated, ensure_ascii=False), row_id),
)
def update_text_url_column(cur, table, pk, column):
rows = cur.execute(f"SELECT {pk}, {column} FROM {table}").fetchall()
for row_id, raw in rows:
if not raw:
continue
updated = rewrite_string(raw)
if updated != raw:
cur.execute(
f"UPDATE {table} SET {column} = ? WHERE {pk} = ?",
(updated, row_id),
)
def main():
if len(sys.argv) != 2:
raise SystemExit("usage: normalize_db_urls.py <sqlite_db_path>")
db_path = sys.argv[1]
if not os.path.exists(db_path):
raise SystemExit(0)
conn = sqlite3.connect(db_path)
try:
cur = conn.cursor()
tables = [
row[0]
for row in cur.execute(
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'"
).fetchall()
]
for table in tables:
replace_in_all_text_columns(cur, table)
for table in (
"spid_cie_oidc_entity_federationentityconfiguration",
"spid_cie_oidc_entity_fetchedentitystatement",
"spid_cie_oidc_entity_trustchain",
):
if table not in tables:
continue
if table == "spid_cie_oidc_entity_federationentityconfiguration":
update_text_url_column(cur, table, "id", "sub")
update_json_column(cur, table, "id", "metadata")
update_json_column(cur, table, "id", "authority_hints")
update_json_column(cur, table, "id", "trust_marks")
update_json_column(cur, table, "id", "trust_mark_issuers")
update_json_column(cur, table, "id", "jwks_fed")
update_json_column(cur, table, "id", "jwks_core")
elif table == "spid_cie_oidc_entity_fetchedentitystatement":
update_text_url_column(cur, table, "id", "sub")
update_text_url_column(cur, table, "id", "iss")
update_json_column(cur, table, "id", "statement")
update_text_url_column(cur, table, "id", "jwt")
elif table == "spid_cie_oidc_entity_trustchain":
update_text_url_column(cur, table, "id", "sub")
update_json_column(cur, table, "id", "chain")
update_json_column(cur, table, "id", "metadata")
update_json_column(cur, table, "id", "jwks")
update_json_column(cur, table, "id", "parties_involved")
update_json_column(cur, table, "id", "trust_marks")
conn.commit()
finally:
conn.close()
if __name__ == "__main__":
main()