| @@ -0,0 +1,73 @@ |
| | 1 | -- Repair OpenAPI secret bindings that point at scopes without the referenced |
| | 2 | -- Secret row. |
| | 3 | -- |
| | 4 | -- Most affected rows are user-org bindings for shared org sources where the |
| | 5 | -- backing Secret lives at the source/org scope. A smaller case is the inverse: |
| | 6 | -- an org binding whose matching Secret is user-owned under the same org. Copy |
| | 7 | -- each invalid binding to the matching in-org Secret scope, then remove any |
| | 8 | -- invalid OpenAPI secret binding that still has no Secret at its own scope. |
| | 9 | -- This deliberately does not copy secrets across org boundaries. |
| | 10 | |
| | 11 | INSERT INTO "credential_binding" ( |
| | 12 | "id", |
| | 13 | "scope_id", |
| | 14 | "plugin_id", |
| | 15 | "source_id", |
| | 16 | "source_scope_id", |
| | 17 | "slot_key", |
| | 18 | "kind", |
| | 19 | "text_value", |
| | 20 | "secret_id", |
| | 21 | "connection_id", |
| | 22 | "created_at", |
| | 23 | "updated_at" |
| | 24 | ) |
| | 25 | SELECT DISTINCT ON (s."scope_id", b."id") |
| | 26 | b."id", |
| | 27 | s."scope_id", |
| | 28 | b."plugin_id", |
| | 29 | b."source_id", |
| | 30 | b."source_scope_id", |
| | 31 | b."slot_key", |
| | 32 | b."kind", |
| | 33 | b."text_value", |
| | 34 | b."secret_id", |
| | 35 | b."connection_id", |
| | 36 | b."created_at", |
| | 37 | now() |
| | 38 | FROM "credential_binding" b |
| | 39 | JOIN "secret" s |
| | 40 | ON s."id" = b."secret_id" |
| | 41 | AND ( |
| | 42 | s."scope_id" = b."source_scope_id" |
| | 43 | OR s."scope_id" LIKE 'user-org:%:' || b."source_scope_id" |
| | 44 | ) |
| | 45 | WHERE b."plugin_id" = 'openapi' |
| | 46 | AND b."kind" = 'secret' |
| | 47 | AND NOT EXISTS ( |
| | 48 | SELECT 1 |
| | 49 | FROM "secret" exact |
| | 50 | WHERE exact."id" = b."secret_id" |
| | 51 | AND exact."scope_id" = b."scope_id" |
| | 52 | ) |
| | 53 | ORDER BY s."scope_id", b."id", b."updated_at" DESC |
| | 54 | ON CONFLICT ("scope_id", "id") DO UPDATE SET |
| | 55 | "plugin_id" = excluded."plugin_id", |
| | 56 | "source_id" = excluded."source_id", |
| | 57 | "source_scope_id" = excluded."source_scope_id", |
| | 58 | "slot_key" = excluded."slot_key", |
| | 59 | "kind" = excluded."kind", |
| | 60 | "text_value" = excluded."text_value", |
| | 61 | "secret_id" = excluded."secret_id", |
| | 62 | "connection_id" = excluded."connection_id", |
| | 63 | "updated_at" = excluded."updated_at";--> statement-breakpoint |
| | 64 | |
| | 65 | DELETE FROM "credential_binding" b |
| | 66 | WHERE b."plugin_id" = 'openapi' |
| | 67 | AND b."kind" = 'secret' |
| | 68 | AND NOT EXISTS ( |
| | 69 | SELECT 1 |
| | 70 | FROM "secret" s |
| | 71 | WHERE s."id" = b."secret_id" |
| | 72 | AND s."scope_id" = b."scope_id" |
| | 73 | );--> statement-breakpoint |