forked from baron/baron-sso
chore: consolidate local integration changes
This commit is contained in:
@@ -80,6 +80,11 @@ public.users:228
|
||||
public.tenants:266
|
||||
public.relying_parties:1
|
||||
EOF
|
||||
cat >"$tmp_dir/reports/baron-postgres-custom-claim-counts.txt" <<'EOF'
|
||||
public.rp_user_metadata:7
|
||||
public.users.global_custom_claims:3
|
||||
public.users.global_custom_claim_types:2
|
||||
EOF
|
||||
cat >"$tmp_dir/reports/ory_hydra-row-counts.txt" <<'EOF'
|
||||
public.hydra_client:5
|
||||
EOF
|
||||
@@ -90,8 +95,17 @@ grep -Fq "# Baron SSO Backup Report" "$backup_md" || fail "backup report must ha
|
||||
grep -Fq "| 사용자 | 228 |" "$backup_md" || fail "backup report must include user count."
|
||||
grep -Fq "| 테넌트 | 266 |" "$backup_md" || fail "backup report must include tenant count."
|
||||
grep -Fq "| RP | 1 |" "$backup_md" || fail "backup report must include RP count."
|
||||
grep -Fq "| RP 사용자 custom claim | 7 |" "$backup_md" || fail "backup report must include RP user custom claim count."
|
||||
grep -Fq "| 전역 custom claim 사용자 | 3 |" "$backup_md" || fail "backup report must include global custom claim user count."
|
||||
grep -Fq "| postgres | 2 |" "$backup_md" || fail "backup report must include service duration."
|
||||
|
||||
grep -Fq "baron-postgres-custom-claim-counts.txt" "$repo_root/scripts/backup/lib/postgres.sh" \
|
||||
|| fail "Baron Postgres dump must collect custom claim backup verification counts."
|
||||
grep -Fq "global_custom_claims" "$repo_root/scripts/backup/lib/postgres.sh" \
|
||||
|| fail "Baron Postgres dump must count users.metadata.global_custom_claims for backup verification."
|
||||
grep -Fq "rp_user_metadata" "$repo_root/scripts/backup/lib/postgres.sh" \
|
||||
|| fail "Baron Postgres dump must count rp_user_metadata rows for backup verification."
|
||||
|
||||
printf 'original\n' >"$tmp_dir/example.txt"
|
||||
(cd "$tmp_dir" && sha256sum example.txt > checksums.sha256)
|
||||
printf 'changed\n' >"$tmp_dir/example.txt"
|
||||
|
||||
@@ -47,14 +47,33 @@ grep -Fq -- "--dart-define=USERFRONT_URL=" "$USERFRONT_DEV_SERVER" || fail "user
|
||||
grep -Fq -- 'USERFRONT_FLUTTER_RUN_FLAGS' "$USERFRONT_DEV_SERVER" || fail "userfront dev server must accept optional Flutter run flags"
|
||||
grep -Fq -- 'USERFRONT_FLUTTER_RUN_FLAGS="${USERFRONT_FLUTTER_RUN_FLAGS:---debug}"' "$USERFRONT_DEV_SERVER" || fail "userfront dev server must keep Flutter debug mode as the default"
|
||||
grep -Fq -- 'warm_userfront_once' "$USERFRONT_DEV_SERVER" || fail "userfront dev server must run a one-shot boot warmup"
|
||||
grep -Fq -- 'rm -rf build/web' "$USERFRONT_DEV_SERVER" || fail "userfront dev server must remove stale build/web before flutter run"
|
||||
grep -Fq -- 'USERFRONT_BOOT_BUILD_MARKER' "$USERFRONT_DEV_SERVER" || fail "userfront boot warmup must track the current flutter run build start"
|
||||
grep -Fq -- 'USERFRONT_BOOT_LOG' "$USERFRONT_DEV_SERVER" || fail "userfront boot warmup must capture flutter run output"
|
||||
grep -Fq -- 'wait_for_userfront_serve_log' "$USERFRONT_DEV_SERVER" || fail "userfront boot warmup must wait for Flutter serve completion log"
|
||||
grep -Fq -- 'lib/main.dart is being served at' "$USERFRONT_DEV_SERVER" || fail "userfront boot warmup must start only after Flutter serves main.dart"
|
||||
grep -Fq -- 'tee "$USERFRONT_BOOT_LOG"' "$USERFRONT_DEV_SERVER" || fail "userfront dev server must preserve flutter output while tracking serve readiness"
|
||||
grep -Fq -- '-nt "$USERFRONT_BOOT_BUILD_MARKER"' "$USERFRONT_DEV_SERVER" || fail "userfront boot warmup must only accept build/web from the current flutter run"
|
||||
grep -Fq -- 'USERFRONT_BOOT_WARMUP_LOCALES' "$USERFRONT_DEV_SERVER" || fail "userfront boot warmup must declare the language matrix"
|
||||
grep -Fq -- 'USERFRONT_BOOT_WARMUP_VIEWPORTS' "$USERFRONT_DEV_SERVER" || fail "userfront boot warmup must declare the viewport matrix"
|
||||
grep -Fq -- 'Accept-Language:' "$USERFRONT_DEV_SERVER" || fail "userfront boot warmup must GET each route with the locale header"
|
||||
grep -Fq -- 'Viewport-Width:' "$USERFRONT_DEV_SERVER" || fail "userfront boot warmup must GET each route with viewport width metadata"
|
||||
grep -Fq -- '/signin' "$USERFRONT_DEV_SERVER" || fail "userfront boot warmup must cover signin routes"
|
||||
grep -Fq -- '/flutter_bootstrap.js' "$USERFRONT_DEV_SERVER" || fail "userfront boot warmup must load the Flutter bootstrap entrypoint"
|
||||
grep -Fq -- '/main.dart.mjs' "$USERFRONT_DEV_SERVER" || fail "userfront boot warmup must load the wasm JS module entrypoint"
|
||||
grep -Fq -- '/main.dart.wasm' "$USERFRONT_DEV_SERVER" || fail "userfront boot warmup must load the wasm module"
|
||||
grep -Fq -- 'warm_flutter_bootstrap_assets' "$USERFRONT_DEV_SERVER" || fail "userfront boot warmup must discover hashed Flutter assets from flutter_bootstrap.js"
|
||||
if grep -Fq -- '/main.dart.mjs' "$USERFRONT_DEV_SERVER" || grep -Fq -- '/main.dart.wasm' "$USERFRONT_DEV_SERVER"; then
|
||||
fail "userfront boot warmup must not use stale unversioned Flutter wasm entrypoint paths"
|
||||
fi
|
||||
if grep -Fq -- 'client.navigate' "$USERFRONT_DEV_SERVER"; then
|
||||
fail "userfront dev service worker reset must not navigate clients during Flutter bootstrap"
|
||||
fi
|
||||
grep -Fq -- 'disable_userfront_dev_service_worker' "$USERFRONT_DEV_SERVER" || fail "userfront dev boot must disable Flutter service worker navigation loops"
|
||||
warmup_timer_line="$(grep -nF 'started_at="$(date +%s)"' "$USERFRONT_DEV_SERVER" | cut -d: -f1)"
|
||||
warmup_start_log_line="$(grep -nF 'one-shot warmup starting' "$USERFRONT_DEV_SERVER" | cut -d: -f1)"
|
||||
http_readiness_skip_line="$(grep -nF 'readiness attempts' "$USERFRONT_DEV_SERVER" | tail -n 1 | cut -d: -f1)"
|
||||
if [ "$warmup_timer_line" -le "$http_readiness_skip_line" ] || [ "$warmup_timer_line" -ge "$warmup_start_log_line" ]; then
|
||||
fail "userfront warmup timer must start after current Flutter server readiness and immediately before warmup start log"
|
||||
fi
|
||||
assert_contains 'CLIENT_LOG_DEBUG=${CLIENT_LOG_DEBUG:-false}'
|
||||
assert_contains 'BACKEND_URL=${BACKEND_URL:-}'
|
||||
assert_contains 'USERFRONT_URL=${USERFRONT_URL}'
|
||||
|
||||
83
test/kratos_identity_write_path_policy_test.sh
Executable file
83
test/kratos_identity_write_path_policy_test.sh
Executable file
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
policy_doc="$repo_root/docs/identity-redis-mirror-policy-2026-06-09.md"
|
||||
|
||||
allowed_files="$(
|
||||
cat <<'EOF'
|
||||
backend/cmd/adminctl/main.go
|
||||
backend/cmd/fix_kratos_roles.go
|
||||
backend/internal/bootstrap/admin_account.go
|
||||
backend/internal/bootstrap/kratos_seed.go
|
||||
backend/internal/handler/auth_handler.go
|
||||
backend/internal/handler/user_handler.go
|
||||
backend/internal/service/kratos_admin_service.go
|
||||
backend/internal/service/ory_service.go
|
||||
backend/internal/service/user_group_service.go
|
||||
scripts/clear_orphan_tenant_memberships.sh
|
||||
EOF
|
||||
)"
|
||||
|
||||
pattern='admin/identities|KratosAdmin[.]UpdateIdentity|KratosAdmin[.]DeleteIdentity|kratos[.]UpdateIdentity|kratosAdmin[.]UpdateIdentity|identityAdmin[.]CreateUser|identityAdmin[.]UpdateIdentityPassword|idp[.]CreateUser|IdpProvider[.]CreateUser|IdpProvider[.]UpdateUserPassword|OryProvider[.]CreateUser|OryProvider[.]UpdateUserPassword|UPDATE identities'
|
||||
|
||||
findings="$(
|
||||
git -C "$repo_root" grep -nE "$pattern" -- \
|
||||
backend \
|
||||
scripts \
|
||||
':(exclude)backend/**/*_test.go' \
|
||||
':(exclude)scripts/backup' || true
|
||||
)"
|
||||
|
||||
unexpected=""
|
||||
if [ -n "$findings" ]; then
|
||||
while IFS= read -r finding; do
|
||||
file="${finding%%:*}"
|
||||
if ! grep -Fxq "$file" <<<"$allowed_files"; then
|
||||
unexpected="${unexpected}${finding}"$'\n'
|
||||
fi
|
||||
done <<<"$findings"
|
||||
fi
|
||||
|
||||
if [ -n "$unexpected" ]; then
|
||||
echo "ERROR: undocumented Kratos identity write path detected." >&2
|
||||
printf '%s' "$unexpected" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$policy_doc" ]; then
|
||||
echo "ERROR: missing identity Redis mirror policy document: $policy_doc" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if grep -Fq "admin/identities/" "$repo_root/backend/internal/handler/auth_handler.go"; then
|
||||
echo "ERROR: auth_handler must not call Kratos admin identity endpoints directly; use KratosAdminService or IdentityWriteService." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep -Fq "maintenance-window" "$repo_root/backend/cmd/fix_kratos_roles.go" || \
|
||||
! grep -Fq "dry-run" "$repo_root/backend/cmd/fix_kratos_roles.go" || \
|
||||
! grep -Fq "mark-mirror-stale" "$repo_root/backend/cmd/fix_kratos_roles.go"; then
|
||||
echo "ERROR: fix_kratos_roles must require dry-run/maintenance-window/mark-mirror-stale guards." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep -Fq "CONFIRM_KRATOS_DB_MAINTENANCE" "$repo_root/scripts/clear_orphan_tenant_memberships.sh" || \
|
||||
! grep -Fq "MARK_IDENTITY_MIRROR_STALE" "$repo_root/scripts/clear_orphan_tenant_memberships.sh"; then
|
||||
echo "ERROR: clear_orphan_tenant_memberships.sh must require explicit Kratos DB maintenance and mirror-stale guards." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep -Fq "## Kratos write 경로 감사" "$policy_doc"; then
|
||||
echo "ERROR: policy document must include the Kratos write path audit section." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
while IFS= read -r file; do
|
||||
if [ -n "$file" ] && ! grep -Fq "$file" "$policy_doc"; then
|
||||
echo "ERROR: allowed Kratos write path is not documented: $file" >&2
|
||||
exit 1
|
||||
fi
|
||||
done <<<"$allowed_files"
|
||||
|
||||
echo "kratos identity write path policy checks passed"
|
||||
@@ -52,6 +52,8 @@ done
|
||||
|
||||
assert_contains "$LOCAL_COMPOSE" "dockerfile: ./orgfront/Dockerfile"
|
||||
assert_contains "$LOCAL_COMPOSE" "./orgfront:/workspace/orgfront"
|
||||
assert_contains "$LOCAL_COMPOSE" "VITE_ORGFRONT_PUBLIC_URL: \${ORGFRONT_URL}"
|
||||
assert_contains "$LOCAL_COMPOSE" "VITE_OIDC_CLIENT_ID: orgfront"
|
||||
assert_not_contains "$LOCAL_COMPOSE" "../baron-orgchart"
|
||||
|
||||
for file in "$STAGING_COMPOSE" "$PULL_COMPOSE" "$DEPLOY_TEMPLATE"; do
|
||||
|
||||
@@ -62,8 +62,6 @@ for workflow in "$staging_pull"; do
|
||||
assert_contains "$workflow" 'ORGFRONT_URL=${{ vars.ORGFRONT_URL }}'
|
||||
assert_contains "$workflow" 'KRATOS_ALLOWED_RETURN_URLS_JSON=${{ vars.KRATOS_ALLOWED_RETURN_URLS_JSON }}'
|
||||
assert_contains "$workflow" 'KRATOS_ALLOWED_RETURN_URLS_EXTRA=${{ vars.KRATOS_ALLOWED_RETURN_URLS_EXTRA }}'
|
||||
assert_contains "$workflow" 'STAGING_PUBLIC_HEALTH_URL=${{ vars.STAGING_PUBLIC_HEALTH_URL }}'
|
||||
assert_contains "$workflow" 'STAGING_PUBLIC_HEALTH_MAX_ATTEMPTS=${{ vars.STAGING_PUBLIC_HEALTH_MAX_ATTEMPTS }}'
|
||||
done
|
||||
|
||||
assert_contains "$staging_pull" 'bash scripts/render_ory_config.sh'
|
||||
@@ -71,12 +69,15 @@ assert_contains "$staging_pull" 'chmod -R 777 config/.generated/ory'
|
||||
assert_contains "$staging_pull" 'docker compose -f staging_pull_compose.yaml build --pull'
|
||||
assert_contains "$staging_pull" 'docker compose -f staging_pull_compose.yaml up -d --remove-orphans --renew-anon-volumes'
|
||||
assert_contains "$staging_pull" 'check_container_http baron_gateway 5000'
|
||||
assert_contains "$staging_pull" 'check_public_http "${STAGING_PUBLIC_HEALTH_URL}"'
|
||||
assert_contains "$staging_pull" 'curl -fsS --max-time 10 "${url}"'
|
||||
assert_contains "$staging_pull" 'check_container_http baron_userfront 5000'
|
||||
|
||||
assert_contains "$userfront_dockerfile" "FROM ghcr.io/cirruslabs/flutter:3.38.0 AS build"
|
||||
assert_contains "$userfront_dockerfile" "RUN flutter build web --release --wasm"
|
||||
assert_contains ".dockerignore" "**/build"
|
||||
assert_contains "$userfront_dockerfile" "RUN rm -rf build/web && flutter build web --release --wasm"
|
||||
assert_contains "$userfront_dockerfile" "FROM alpine:3.23 AS production"
|
||||
assert_contains "$userfront_dockerfile" "COPY --from=optimize /work/build/web /usr/share/nginx/html"
|
||||
assert_contains ".gitea/workflows/code_check.yml" "rm -rf build/web"
|
||||
assert_contains ".gitea/workflows/userfront_e2e_full_nightly.yml" "rm -rf build/web"
|
||||
assert_contains "$pull_compose" "baron_devfront"
|
||||
assert_contains "$pull_compose" "baron_orgfront"
|
||||
for app in adminfront devfront orgfront; do
|
||||
@@ -89,6 +90,7 @@ for app in adminfront devfront orgfront; do
|
||||
done
|
||||
assert_not_contains "$pull_compose" "/app/node_modules"
|
||||
assert_contains "$pull_compose" "dockerfile: userfront/Dockerfile"
|
||||
assert_contains "$pull_compose" "target: production"
|
||||
assert_not_contains "$pull_compose" 'target: ${USERFRONT_BUILD_TARGET:-dev}'
|
||||
assert_not_contains "$pull_compose" "target: dev"
|
||||
assert_not_contains "$pull_compose" "flutter run"
|
||||
@@ -99,6 +101,8 @@ assert_contains "$pull_compose" 'APP_ENV=${APP_ENV:-stage}'
|
||||
assert_contains "$deploy_compose" "dockerfile: ./adminfront/Dockerfile"
|
||||
assert_contains "$deploy_compose" "dockerfile: ./devfront/Dockerfile"
|
||||
assert_contains "$deploy_compose" "dockerfile: ./orgfront/Dockerfile"
|
||||
assert_contains "$deploy_compose" "dockerfile: ./userfront/Dockerfile"
|
||||
assert_contains "$deploy_compose" "target: production"
|
||||
assert_not_contains "$deploy_compose" "sh ./scripts/runtime-mode.sh"
|
||||
assert_not_contains "$deploy_compose" "command: npm run dev"
|
||||
assert_not_contains "$deploy_compose" "image: node:20-alpine"
|
||||
@@ -113,6 +117,11 @@ for app in adminfront devfront orgfront; do
|
||||
assert_contains ".gitea/workflows/build_RC.yml" "file: ./$app/Dockerfile"
|
||||
assert_not_contains ".gitea/workflows/build_RC.yml" "context: ./$app"
|
||||
done
|
||||
assert_contains ".gitea/workflows/build_RC.yml" "Build and push userfront RC image"
|
||||
assert_contains ".gitea/workflows/build_RC.yml" "context: ."
|
||||
assert_contains ".gitea/workflows/build_RC.yml" "file: ./userfront/Dockerfile"
|
||||
assert_contains ".gitea/workflows/build_RC.yml" "target: production"
|
||||
assert_not_contains ".gitea/workflows/build_RC.yml" "context: ./userfront"
|
||||
|
||||
for app in adminfront devfront orgfront; do
|
||||
dockerfile="$app/Dockerfile"
|
||||
|
||||
@@ -33,6 +33,31 @@ assert_service_has_restart_policy() {
|
||||
}
|
||||
}
|
||||
|
||||
assert_service_has_no_restart_policy() {
|
||||
service="$1"
|
||||
if awk -v service="$service" '
|
||||
$0 ~ "^ " service ":" {
|
||||
in_service = 1
|
||||
found = 0
|
||||
next
|
||||
}
|
||||
in_service && /^ [A-Za-z0-9_-]+:/ {
|
||||
exit found ? 0 : 1
|
||||
}
|
||||
in_service && /^[[:space:]]+restart:/ {
|
||||
found = 1
|
||||
}
|
||||
END {
|
||||
if (in_service) {
|
||||
exit found ? 0 : 1
|
||||
}
|
||||
}
|
||||
' "$compose_file"; then
|
||||
echo "ERROR: one-shot staging service must not define restart policy: $service" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
for service in \
|
||||
postgres \
|
||||
clickhouse \
|
||||
@@ -53,4 +78,16 @@ do
|
||||
assert_service_has_restart_policy "$service"
|
||||
done
|
||||
|
||||
for service in \
|
||||
kratos-migrate \
|
||||
hydra-migrate \
|
||||
keto-migrate \
|
||||
oathkeeper_logs_init \
|
||||
ory_stack_check \
|
||||
init-rp \
|
||||
infra_check
|
||||
do
|
||||
assert_service_has_no_restart_policy "$service"
|
||||
done
|
||||
|
||||
echo "staging pull restart policy checks passed"
|
||||
|
||||
Reference in New Issue
Block a user