@opengeni/db 1.0.1 → 3.2.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attached-browser-devices.d.ts +7 -0
- package/dist/automations.d.ts +154 -0
- package/dist/canonical-human-identities.js +3 -3
- package/dist/capability-integrations.d.ts +13 -0
- package/dist/child-lifecycle-notices.d.ts +68 -0
- package/dist/{chunk-4SR4HKKA.js → chunk-2EH4WRHL.js} +19 -11
- package/dist/chunk-2EH4WRHL.js.map +1 -0
- package/dist/{chunk-CUPM3FGB.js → chunk-2PRS4J5Q.js} +3 -3
- package/dist/chunk-6HMM2R5T.js +390 -0
- package/dist/chunk-6HMM2R5T.js.map +1 -0
- package/dist/{chunk-ZWREYEWA.js → chunk-AZHW7R5V.js} +56 -11
- package/dist/chunk-AZHW7R5V.js.map +1 -0
- package/dist/{chunk-LTG3S6ZY.js → chunk-E6CLMKEE.js} +2 -2
- package/dist/{chunk-6ZYKCRFO.js → chunk-KRLPEMLH.js} +7591 -4417
- package/dist/chunk-KRLPEMLH.js.map +1 -0
- package/dist/chunk-NAB6FKFN.js +516 -0
- package/dist/chunk-NAB6FKFN.js.map +1 -0
- package/dist/{chunk-SK7YYHBI.js → chunk-SIBYBA2D.js} +46 -1
- package/dist/chunk-SIBYBA2D.js.map +1 -0
- package/dist/chunk-UZNXG44K.js +4508 -0
- package/dist/chunk-UZNXG44K.js.map +1 -0
- package/dist/codemode-operations.d.ts +1 -6
- package/dist/company-brain-context-selection-schema.d.ts +705 -0
- package/dist/company-brain-context-selection.d.ts +94 -0
- package/dist/company-brain-governed-writes.d.ts +24 -0
- package/dist/company-brain.d.ts +55 -0
- package/dist/company-profile-agent-admin.d.ts +15 -0
- package/dist/company-profile-schema.d.ts +619 -2
- package/dist/company-profile.d.ts +9 -4
- package/dist/connection-authority.d.ts +95 -0
- package/dist/connection-scopes.d.ts +8 -0
- package/dist/connection-tenancy-backfill.d.ts +85 -0
- package/dist/connection-token-resolver.d.ts +30 -1
- package/dist/database.d.ts +23 -4
- package/dist/editable-artifact-durable-export.js +2 -2
- package/dist/editable-artifacts.d.ts +2 -2
- package/dist/editable-artifacts.js +3 -3
- package/dist/governed-learning-activation-schema.d.ts +984 -0
- package/dist/governed-learning-activation.d.ts +98 -0
- package/dist/governed-learning-evaluator-schema.d.ts +633 -0
- package/dist/governed-learning-evaluator.d.ts +28 -0
- package/dist/index.d.ts +1606 -81
- package/dist/index.js +21898 -8147
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +18 -0
- package/dist/integration-bindings.d.ts +1 -0
- package/dist/integration-facets.d.ts +30 -0
- package/dist/interaction-placement-loss.d.ts +22 -0
- package/dist/managed-human-provisioning.d.ts +25 -0
- package/dist/memory-domain.d.ts +3 -3
- package/dist/migrate.d.ts +11 -1
- package/dist/migrate.js +1 -1
- package/dist/new-session-drafts.d.ts +43 -5
- package/dist/organization-membership-backfill.d.ts +174 -0
- package/dist/organization-membership-lifecycle.d.ts +162 -0
- package/dist/pr-review.d.ts +107 -0
- package/dist/preference-registry-schema.d.ts +2 -0
- package/dist/preference-registry.d.ts +2 -0
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +29 -8
- package/dist/schema.d.ts +24914 -13703
- package/dist/schema.js +99 -1
- package/dist/scoped-knowledge-schema.d.ts +52 -1
- package/dist/session-background-commands.d.ts +125 -0
- package/dist/session-background-commands.js +34 -0
- package/dist/session-background-commands.js.map +1 -0
- package/dist/session-control.d.ts +156 -3
- package/dist/session-goal-pacing.d.ts +68 -0
- package/dist/session-queue-commands.d.ts +43 -4
- package/dist/session-realtime-ledger.d.ts +2 -0
- package/dist/session-tenancy.d.ts +71 -1
- package/dist/session-tenancy.js +25 -3
- package/dist/session-tool-call-settlement.d.ts +9 -4
- package/dist/slack-routing-personal-workspace.d.ts +23 -0
- package/dist/slack-routing.d.ts +268 -0
- package/dist/slack-task-policy-schema.d.ts +34 -0
- package/dist/slack-task-policy.d.ts +8 -0
- package/dist/slack-user-link-access.d.ts +28 -0
- package/dist/task-notes-schema.d.ts +594 -0
- package/dist/task-notes.d.ts +39 -0
- package/dist/turn-initiator.d.ts +2 -0
- package/dist/user-resource-authority.d.ts +109 -0
- package/dist/video-generation.js +3 -3
- package/dist/workspace-authority.d.ts +81 -0
- package/dist/workspace-instruction-policies-schema.d.ts +279 -0
- package/dist/workspace-instruction-policies.d.ts +62 -0
- package/dist/workspace-learning-policy.d.ts +1 -0
- package/dist/workspace-membership-permissions.d.ts +2 -0
- package/drizzle/0240_enrollment_connection_authority.sql +39 -0
- package/drizzle/0241_atomic_personal_resource_delegation.sql +1000 -0
- package/drizzle/0241_enrollment_agent_runtime.sql +70 -0
- package/drizzle/0244_slack_app_home_refresh_queue.sql +120 -0
- package/drizzle/0245_model_context_contribution_facts.sql +88 -0
- package/drizzle/0246_integration_personal_instance_authority.sql +70 -0
- package/drizzle/0247_terraform_stacks_provenance_repair.sql +428 -0
- package/drizzle/0248_terraform_stacks_component_resolution_fence.sql +83 -0
- package/drizzle/0249_personal_resource_delegation_authority_correction.sql +662 -0
- package/drizzle/0250_direct_retained_process_owner_liveness.sql +199 -0
- package/drizzle/0251_connected_machine_operation_policy.sql +45 -0
- package/drizzle/0252_scheduled_personal_resource_delegation.sql +1867 -0
- package/drizzle/0253_common_user_resource_authority_lifecycle.sql +1555 -0
- package/drizzle/0254_scoped_variable_set_authority.sql +1255 -0
- package/drizzle/0255_company_brain_governed_write_proposals.sql +524 -0
- package/drizzle/0256_connection_authority_delegation.sql +703 -0
- package/drizzle/0257_goal_revision_decisions_and_root_constraints.sql +436 -0
- package/drizzle/0258_three_scope_document_knowledge_authority.sql +1273 -0
- package/drizzle/0259_company_brain_context_selection_receipts.sql +869 -0
- package/drizzle/0260_task_note_knowledge_promotion.sql +820 -0
- package/drizzle/0261_preference_knowledge_proposal_actor_binding.sql +471 -0
- package/drizzle/0262_scoped_connected_machines_and_rigs.sql +1700 -0
- package/drizzle/0263_organization_membership_lifecycle.sql +3284 -0
- package/drizzle/0264_connection_authority_runtime_activation.sql +1084 -0
- package/drizzle/0266_company_brain_context_receipt_inspection.sql +156 -0
- package/drizzle/0268_governed_learning_decision_receipts.sql +825 -0
- package/drizzle/0269_governed_learning_activation_controller.sql +1874 -0
- package/drizzle/0270_governed_learning_history_inspection.sql +170 -0
- package/drizzle/0271_company_brain_retrieval_only_default.sql +524 -0
- package/drizzle/0272_human_confirmed_learning_activation.sql +591 -0
- package/drizzle/0273_scheduled_variable_set_materialization.sql +268 -0
- package/drizzle/0274_human_confirmed_knowledge_review.sql +310 -0
- package/drizzle/0275_scheduled_connection_authority.sql +5527 -0
- package/drizzle/0276_onboarding_proposal_initiating_human_guc.sql +198 -0
- package/drizzle/0277_workspace_writer_authority_attribution.sql +393 -0
- package/drizzle/0278_workspace_membership_removal_fencing.sql +1174 -0
- package/drizzle/0279_workspace_connection_use_lane.sql +343 -0
- package/drizzle/0280_connection_and_variable_set_audit_attribution.sql +773 -0
- package/drizzle/0281_viewer_holder_authority_claims.sql +52 -0
- package/drizzle/0282_variable_set_session_attach_attribution.sql +178 -0
- package/drizzle/0283_editable_spreadsheet_authored_state.sql +82 -0
- package/drizzle/0284_truthful_human_confirmed_review_reason.sql +930 -0
- package/drizzle/0285_organization_tenancy_inventory.sql +329 -0
- package/drizzle/0286_widen_task_note_expiry_ceiling.sql +391 -0
- package/drizzle/0287_open_suffix_pending_tool_calls.sql +18 -0
- package/drizzle/0288_attached_browser_reenrollment.sql +64 -0
- package/drizzle/0289_session_composer_policy_authority.sql +597 -0
- package/drizzle/0290_organization_membership_backfill.sql +268 -0
- package/drizzle/0291_resource_authority_classification_assertion.sql +371 -0
- package/drizzle/0292_truthful_tenancy_inventory_counters.sql +291 -0
- package/drizzle/0293_confirm_time_rule_rebaseline.sql +615 -0
- package/drizzle/0294_preference_activation_authority.sql +237 -0
- package/drizzle/0295_retire_legacy_standing_memory_mode.sql +476 -0
- package/drizzle/0296_force_rls_backfill_noop_repair.sql +215 -0
- package/drizzle/0297_session_ownership_classification_and_backfill.sql +752 -0
- package/drizzle/0298_organization_tenancy_parity.sql +609 -0
- package/drizzle/0299_organization_membership_lock_order.sql +291 -0
- package/drizzle/0300_tenancy_backfill_ledger.sql +459 -0
- package/drizzle/0301_session_snapshot_and_pin_visibility.sql +181 -0
- package/drizzle/0302_personal_workspace_session_ownership.sql +303 -0
- package/drizzle/0303_session_tenancy_product_activation.sql +919 -0
- package/drizzle/0304_personal_workspace_private_session_reads.sql +97 -0
- package/drizzle/0305_personal_resource_grant_management.sql +584 -0
- package/drizzle/0306_atomic_personal_resource_attachments.sql +1374 -0
- package/drizzle/0307_session_attention_state.sql +51 -0
- package/drizzle/0308_session_archives.sql +35 -0
- package/drizzle/0309_channel_project_pins.sql +6 -0
- package/drizzle/0310_channel_project_order.sql +27 -0
- package/drizzle/0311_company_scope_and_private_session_create.sql +656 -0
- package/drizzle/0312_quiescent_session_tree_deletion.sql +39 -0
- package/drizzle/0313_private_child_session_authority.sql +365 -0
- package/drizzle/0314_unregistered_organization_invitations.sql +606 -0
- package/drizzle/0315_personal_github_repository_selection.sql +624 -0
- package/drizzle/0316_human_confirmed_activation_resumed_generation.sql +869 -0
- package/drizzle/0317_session_goal_continuation_hold.sql +64 -0
- package/drizzle/0318_session_turn_startup_milestones.sql +115 -0
- package/drizzle/0319_event_triggered_automations.sql +254 -0
- package/drizzle/0320_pr_review_pack.sql +113 -0
- package/drizzle/0321_slack_bot_environment_display_name.sql +15 -0
- package/drizzle/0322_session_turns_unclaimed_prompt_trigger_index.sql +5 -0
- package/drizzle/0323_organization_private_session_enablement.sql +489 -0
- package/drizzle/0324_human_confirmed_company_profile_agent_admin.sql +856 -0
- package/drizzle/0325_child_lifecycle_notices.sql +44 -0
- package/drizzle/0326_interaction_operation_error_codes.sql +62 -0
- package/drizzle/0327_slack_first_task_hint.sql +29 -0
- package/drizzle/0328_session_background_commands.sql +590 -0
- package/drizzle/0329_slack_orchestration_delivery_events.sql +91 -0
- package/drizzle/0330_api_key_descriptions.sql +20 -0
- package/drizzle/0331_managed_organization_creation.sql +163 -0
- package/drizzle/0332_organization_shared_workspace_control_plane.sql +539 -0
- package/drizzle/0333_session_turn_prompt_routing.sql +45 -0
- package/drizzle/0334_connected_machine_workspace_root.sql +99 -0
- package/drizzle/0335_slack_workspace_routing.sql +460 -0
- package/drizzle/0336_atomic_session_fork_visibility.sql +667 -0
- package/drizzle/0337_slack_routed_action_handles.sql +189 -0
- package/drizzle/0338_atomic_connected_machine_attachments.sql +410 -0
- package/drizzle/0339_document_authority_reclassification.sql +1153 -0
- package/drizzle/0340_tenancy_backfill_activation_evidence.sql +1347 -0
- package/drizzle/0341_slack_routing_probe_organization_fence.sql +109 -0
- package/drizzle/0342_slack_route_prompt_single_pending.sql +32 -0
- package/drizzle/0343_personal_document_force_rls_lock_repair.sql +146 -0
- package/drizzle/0344_private_session_visibility_transition_gate.sql +85 -0
- package/drizzle/0345_tenant_scoped_session_tenancy_fence.sql +2839 -0
- package/drizzle/0346_document_migration_audit_surface.sql +454 -0
- package/drizzle/0347_connection_authority_convergence_evidence.sql +396 -0
- package/package.json +10 -6
- package/src/attached-browser-devices.ts +233 -5
- package/src/automations.ts +911 -0
- package/src/browser-sessions.ts +10 -0
- package/src/capability-integrations.ts +175 -1
- package/src/child-lifecycle-notices.ts +241 -0
- package/src/codemode-operations.ts +1 -35
- package/src/company-brain-context-selection-schema.ts +100 -0
- package/src/company-brain-context-selection.ts +359 -0
- package/src/company-brain-governed-writes.ts +1170 -0
- package/src/company-brain.ts +309 -0
- package/src/company-profile-agent-admin.ts +225 -0
- package/src/company-profile-schema.ts +121 -1
- package/src/company-profile.ts +21 -0
- package/src/computer-sessions.ts +10 -1
- package/src/connection-authority.ts +290 -0
- package/src/connection-scopes.ts +20 -0
- package/src/connection-tenancy-backfill.ts +167 -0
- package/src/connection-token-resolver.ts +263 -31
- package/src/database.ts +87 -2
- package/src/editable-artifacts-schema.ts +10 -5
- package/src/editable-artifacts.ts +21 -11
- package/src/governed-learning-activation-schema.ts +121 -0
- package/src/governed-learning-activation.ts +588 -0
- package/src/governed-learning-evaluator-schema.ts +72 -0
- package/src/governed-learning-evaluator.ts +217 -0
- package/src/index.ts +11676 -1550
- package/src/insights.ts +107 -0
- package/src/integration-bindings.ts +88 -6
- package/src/integration-facets.ts +287 -84
- package/src/interaction-placement-loss.ts +234 -0
- package/src/managed-human-provisioning.ts +116 -0
- package/src/memory-domain.ts +27 -32
- package/src/migrate.ts +77 -1
- package/src/new-session-drafts.ts +229 -35
- package/src/organization-membership-backfill.ts +735 -0
- package/src/organization-membership-lifecycle.ts +995 -0
- package/src/pr-review.ts +890 -0
- package/src/preference-registry.ts +31 -1
- package/src/provision-roles.ts +905 -6
- package/src/runtime-posture-cli.ts +2 -0
- package/src/runtime-posture.ts +1317 -72
- package/src/schema.ts +3316 -428
- package/src/scoped-knowledge-schema.ts +16 -8
- package/src/scoped-knowledge.ts +1 -1
- package/src/session-background-commands.ts +759 -0
- package/src/session-control.ts +640 -74
- package/src/session-goal-pacing.ts +126 -0
- package/src/session-queue-commands.ts +441 -85
- package/src/session-realtime-context.ts +4 -6
- package/src/session-realtime-ledger.ts +28 -14
- package/src/session-realtime-mirror.ts +1 -1
- package/src/session-tenancy.ts +410 -49
- package/src/session-tool-call-settlement.ts +38 -29
- package/src/slack-routing-personal-workspace.ts +67 -0
- package/src/slack-routing.ts +867 -0
- package/src/slack-task-policy-schema.ts +5 -0
- package/src/slack-task-policy.ts +18 -0
- package/src/slack-user-link-access.ts +138 -11
- package/src/task-notes-schema.ts +74 -0
- package/src/task-notes.ts +124 -2
- package/src/turn-initiator.ts +8 -0
- package/src/user-resource-authority.ts +377 -0
- package/src/workspace-authority.ts +160 -0
- package/src/workspace-instruction-policies-schema.ts +53 -1
- package/src/workspace-instruction-policies.ts +528 -77
- package/src/workspace-learning-policy.ts +21 -5
- package/src/workspace-membership-permissions.ts +9 -0
- package/dist/chunk-4SR4HKKA.js.map +0 -1
- package/dist/chunk-6ZYKCRFO.js.map +0 -1
- package/dist/chunk-NXAFLCQX.js +0 -2468
- package/dist/chunk-NXAFLCQX.js.map +0 -1
- package/dist/chunk-SK7YYHBI.js.map +0 -1
- package/dist/chunk-WD5ROSLL.js +0 -117
- package/dist/chunk-WD5ROSLL.js.map +0 -1
- package/dist/chunk-ZWREYEWA.js.map +0 -1
- /package/dist/{chunk-CUPM3FGB.js.map → chunk-2PRS4J5Q.js.map} +0 -0
- /package/dist/{chunk-LTG3S6ZY.js.map → chunk-E6CLMKEE.js.map} +0 -0
|
@@ -0,0 +1,1000 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
-- Admit personal Variable Set and Rig selections at the exact accepted session
|
|
3
|
+
-- attempt. This slice stores immutable authority snapshots and atomically
|
|
4
|
+
-- consumes once grants. It does not load secrets, materialize resources,
|
|
5
|
+
-- activate scheduled tasks, or expose Variable Set/Rig CRUD.
|
|
6
|
+
|
|
7
|
+
SET LOCAL lock_timeout = '5s';
|
|
8
|
+
SET LOCAL statement_timeout = '10min';
|
|
9
|
+
|
|
10
|
+
CREATE TABLE opengeni_private.personal_resource_delegation_capabilities (
|
|
11
|
+
"backend_pid" integer NOT NULL,
|
|
12
|
+
"transaction_id" xid8 NOT NULL,
|
|
13
|
+
"capability_kind" text NOT NULL,
|
|
14
|
+
"created_at" timestamptz NOT NULL DEFAULT clock_timestamp(),
|
|
15
|
+
CONSTRAINT "personal_resource_delegation_capabilities_kind_chk" CHECK (
|
|
16
|
+
"capability_kind" IN ('admit', 'resolve')
|
|
17
|
+
),
|
|
18
|
+
CONSTRAINT "personal_resource_delegation_capabilities_pk" PRIMARY KEY (
|
|
19
|
+
"backend_pid", "transaction_id", "capability_kind"
|
|
20
|
+
)
|
|
21
|
+
);
|
|
22
|
+
REVOKE ALL ON TABLE opengeni_private.personal_resource_delegation_capabilities FROM PUBLIC;
|
|
23
|
+
|
|
24
|
+
DO $personal_resource_capability_revoke$
|
|
25
|
+
BEGIN
|
|
26
|
+
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
|
|
27
|
+
REVOKE ALL ON TABLE opengeni_private.personal_resource_delegation_capabilities
|
|
28
|
+
FROM opengeni_app;
|
|
29
|
+
END IF;
|
|
30
|
+
END
|
|
31
|
+
$personal_resource_capability_revoke$;
|
|
32
|
+
|
|
33
|
+
CREATE OR REPLACE FUNCTION opengeni_private.personal_resource_delegation_capability_active(
|
|
34
|
+
p_capability_kind text DEFAULT NULL
|
|
35
|
+
)
|
|
36
|
+
RETURNS boolean
|
|
37
|
+
LANGUAGE sql
|
|
38
|
+
STABLE
|
|
39
|
+
SECURITY DEFINER
|
|
40
|
+
SET search_path = pg_catalog
|
|
41
|
+
AS $personal_resource_capability_active$
|
|
42
|
+
SELECT EXISTS (
|
|
43
|
+
SELECT 1
|
|
44
|
+
FROM opengeni_private.personal_resource_delegation_capabilities capability
|
|
45
|
+
WHERE capability.backend_pid = pg_catalog.pg_backend_pid()
|
|
46
|
+
AND capability.transaction_id = pg_catalog.pg_current_xact_id_if_assigned()
|
|
47
|
+
AND (
|
|
48
|
+
p_capability_kind IS NULL
|
|
49
|
+
OR capability.capability_kind = p_capability_kind
|
|
50
|
+
)
|
|
51
|
+
)
|
|
52
|
+
$personal_resource_capability_active$;
|
|
53
|
+
|
|
54
|
+
REVOKE ALL ON FUNCTION
|
|
55
|
+
opengeni_private.personal_resource_delegation_capability_active(text)
|
|
56
|
+
FROM PUBLIC;
|
|
57
|
+
|
|
58
|
+
DO $personal_resource_capability_grant$
|
|
59
|
+
BEGIN
|
|
60
|
+
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
|
|
61
|
+
GRANT EXECUTE ON FUNCTION
|
|
62
|
+
opengeni_private.personal_resource_delegation_capability_active(text)
|
|
63
|
+
TO opengeni_app;
|
|
64
|
+
END IF;
|
|
65
|
+
END
|
|
66
|
+
$personal_resource_capability_grant$;
|
|
67
|
+
|
|
68
|
+
CREATE TABLE "session_attempt_personal_resource_admissions" (
|
|
69
|
+
"attempt_id" uuid PRIMARY KEY REFERENCES "session_turn_attempts"("id") ON DELETE CASCADE,
|
|
70
|
+
"account_id" uuid NOT NULL,
|
|
71
|
+
"workspace_id" uuid NOT NULL,
|
|
72
|
+
"session_id" uuid NOT NULL,
|
|
73
|
+
"turn_id" uuid NOT NULL,
|
|
74
|
+
"execution_generation" integer NOT NULL,
|
|
75
|
+
"initiating_human_subject_id" text NOT NULL,
|
|
76
|
+
"owner_organization_membership_id" uuid NOT NULL,
|
|
77
|
+
"membership_authorization_revision" bigint NOT NULL,
|
|
78
|
+
"session_visibility" text NOT NULL,
|
|
79
|
+
"session_authority_epoch" integer NOT NULL,
|
|
80
|
+
"resource_count" integer NOT NULL,
|
|
81
|
+
"admitted_at" timestamptz NOT NULL DEFAULT clock_timestamp(),
|
|
82
|
+
CONSTRAINT "session_attempt_personal_resource_admissions_attempt_fk"
|
|
83
|
+
FOREIGN KEY (
|
|
84
|
+
"account_id", "workspace_id", "session_id", "turn_id", "attempt_id"
|
|
85
|
+
) REFERENCES "session_turn_attempts"(
|
|
86
|
+
"account_id", "workspace_id", "session_id", "turn_id", "id"
|
|
87
|
+
) ON DELETE CASCADE,
|
|
88
|
+
CONSTRAINT "session_attempt_personal_resource_admissions_owner_fk"
|
|
89
|
+
FOREIGN KEY ("owner_organization_membership_id", "account_id")
|
|
90
|
+
REFERENCES "organization_memberships"("id", "account_id") ON DELETE RESTRICT,
|
|
91
|
+
CONSTRAINT "session_attempt_personal_resource_admissions_generation_chk" CHECK (
|
|
92
|
+
"execution_generation" > 0
|
|
93
|
+
AND "membership_authorization_revision" > 0
|
|
94
|
+
AND "session_authority_epoch" > 0
|
|
95
|
+
AND "resource_count" > 0
|
|
96
|
+
),
|
|
97
|
+
CONSTRAINT "session_attempt_personal_resource_admissions_visibility_chk" CHECK (
|
|
98
|
+
"session_visibility" IN ('user_private', 'workspace_shared')
|
|
99
|
+
),
|
|
100
|
+
CONSTRAINT "session_attempt_personal_resource_admissions_subject_chk" CHECK (
|
|
101
|
+
length(btrim("initiating_human_subject_id")) BETWEEN 1 AND 1024
|
|
102
|
+
)
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
CREATE UNIQUE INDEX "session_attempt_personal_resource_admissions_identity_uq"
|
|
106
|
+
ON "session_attempt_personal_resource_admissions" (
|
|
107
|
+
"account_id", "workspace_id", "session_id", "turn_id", "attempt_id",
|
|
108
|
+
"execution_generation"
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
CREATE TABLE "session_attempt_personal_resource_snapshots" (
|
|
112
|
+
"attempt_id" uuid NOT NULL,
|
|
113
|
+
"account_id" uuid NOT NULL,
|
|
114
|
+
"workspace_id" uuid NOT NULL,
|
|
115
|
+
"session_id" uuid NOT NULL,
|
|
116
|
+
"turn_id" uuid NOT NULL,
|
|
117
|
+
"execution_generation" integer NOT NULL,
|
|
118
|
+
"resource_kind" text NOT NULL,
|
|
119
|
+
"resource_id" uuid NOT NULL,
|
|
120
|
+
"resource_version_id" uuid,
|
|
121
|
+
"selection_sources" text[] NOT NULL,
|
|
122
|
+
"action" text NOT NULL,
|
|
123
|
+
"origin_workspace_id" uuid NOT NULL,
|
|
124
|
+
"owner_organization_membership_id" uuid NOT NULL,
|
|
125
|
+
"membership_authorization_revision" bigint NOT NULL,
|
|
126
|
+
"authority_id" uuid NOT NULL,
|
|
127
|
+
"authority_generation" bigint NOT NULL,
|
|
128
|
+
"target_workspace_id" uuid NOT NULL,
|
|
129
|
+
"session_visibility" text NOT NULL,
|
|
130
|
+
"session_authority_epoch" integer NOT NULL,
|
|
131
|
+
"grant_id" uuid NOT NULL,
|
|
132
|
+
"grant_generation" bigint NOT NULL,
|
|
133
|
+
"grant_mode" text NOT NULL,
|
|
134
|
+
"grant_context" text NOT NULL,
|
|
135
|
+
"grant_session_id" uuid,
|
|
136
|
+
"grant_authority_epoch" integer,
|
|
137
|
+
"created_at" timestamptz NOT NULL DEFAULT clock_timestamp(),
|
|
138
|
+
CONSTRAINT "session_attempt_personal_resource_snapshots_pk" PRIMARY KEY (
|
|
139
|
+
"attempt_id", "resource_kind", "resource_id"
|
|
140
|
+
),
|
|
141
|
+
CONSTRAINT "session_attempt_personal_resource_snapshots_admission_fk"
|
|
142
|
+
FOREIGN KEY (
|
|
143
|
+
"account_id", "workspace_id", "session_id", "turn_id", "attempt_id",
|
|
144
|
+
"execution_generation"
|
|
145
|
+
) REFERENCES "session_attempt_personal_resource_admissions"(
|
|
146
|
+
"account_id", "workspace_id", "session_id", "turn_id", "attempt_id",
|
|
147
|
+
"execution_generation"
|
|
148
|
+
) ON DELETE CASCADE,
|
|
149
|
+
CONSTRAINT "session_attempt_personal_resource_snapshots_authority_fk"
|
|
150
|
+
FOREIGN KEY (
|
|
151
|
+
"authority_id", "account_id", "owner_organization_membership_id"
|
|
152
|
+
) REFERENCES "organization_user_resource_authorities"(
|
|
153
|
+
"id", "account_id", "organization_membership_id"
|
|
154
|
+
) ON DELETE RESTRICT,
|
|
155
|
+
CONSTRAINT "session_attempt_personal_resource_snapshots_grant_fk"
|
|
156
|
+
FOREIGN KEY ("grant_id", "account_id")
|
|
157
|
+
REFERENCES "organization_user_resource_grants"("id", "account_id") ON DELETE RESTRICT,
|
|
158
|
+
CONSTRAINT "session_attempt_personal_resource_snapshots_kind_chk" CHECK (
|
|
159
|
+
("resource_kind" = 'variable_set' AND "resource_version_id" IS NULL)
|
|
160
|
+
OR ("resource_kind" = 'rig' AND "resource_version_id" IS NOT NULL)
|
|
161
|
+
),
|
|
162
|
+
CONSTRAINT "session_attempt_personal_resource_snapshots_action_chk" CHECK (
|
|
163
|
+
("resource_kind" = 'variable_set' AND "action" = 'variable_set.use')
|
|
164
|
+
OR ("resource_kind" = 'rig' AND "action" = 'rig.use')
|
|
165
|
+
),
|
|
166
|
+
CONSTRAINT "session_attempt_personal_resource_snapshots_sources_chk" CHECK (
|
|
167
|
+
cardinality("selection_sources") > 0
|
|
168
|
+
),
|
|
169
|
+
CONSTRAINT "session_attempt_personal_resource_snapshots_generation_chk" CHECK (
|
|
170
|
+
"execution_generation" > 0
|
|
171
|
+
AND "membership_authorization_revision" > 0
|
|
172
|
+
AND "authority_generation" > 0
|
|
173
|
+
AND "session_authority_epoch" > 0
|
|
174
|
+
AND "grant_generation" > 0
|
|
175
|
+
),
|
|
176
|
+
CONSTRAINT "session_attempt_personal_resource_snapshots_visibility_chk" CHECK (
|
|
177
|
+
"session_visibility" IN ('user_private', 'workspace_shared')
|
|
178
|
+
AND "grant_context" = "session_visibility"
|
|
179
|
+
),
|
|
180
|
+
CONSTRAINT "session_attempt_personal_resource_snapshots_workspace_chk" CHECK (
|
|
181
|
+
"target_workspace_id" = "workspace_id"
|
|
182
|
+
),
|
|
183
|
+
CONSTRAINT "session_attempt_personal_resource_snapshots_grant_fence_chk" CHECK (
|
|
184
|
+
(
|
|
185
|
+
"grant_mode" = 'always'
|
|
186
|
+
AND "grant_session_id" IS NULL
|
|
187
|
+
AND "grant_authority_epoch" IS NULL
|
|
188
|
+
) OR (
|
|
189
|
+
"grant_mode" IN ('once', 'session')
|
|
190
|
+
AND "grant_session_id" = "session_id"
|
|
191
|
+
AND "grant_authority_epoch" = "session_authority_epoch"
|
|
192
|
+
)
|
|
193
|
+
)
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
CREATE INDEX "session_attempt_personal_resource_snapshots_authority_idx"
|
|
197
|
+
ON "session_attempt_personal_resource_snapshots" (
|
|
198
|
+
"account_id", "authority_id", "authority_generation"
|
|
199
|
+
);
|
|
200
|
+
CREATE INDEX "session_attempt_personal_resource_snapshots_grant_idx"
|
|
201
|
+
ON "session_attempt_personal_resource_snapshots" (
|
|
202
|
+
"account_id", "grant_id", "grant_generation"
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
CREATE TABLE "personal_resource_once_consumption_receipts" (
|
|
206
|
+
"grant_id" uuid PRIMARY KEY,
|
|
207
|
+
"account_id" uuid NOT NULL,
|
|
208
|
+
"attempt_id" uuid NOT NULL,
|
|
209
|
+
"workspace_id" uuid NOT NULL,
|
|
210
|
+
"session_id" uuid NOT NULL,
|
|
211
|
+
"turn_id" uuid NOT NULL,
|
|
212
|
+
"execution_generation" integer NOT NULL,
|
|
213
|
+
"authority_id" uuid NOT NULL,
|
|
214
|
+
"authority_generation" bigint NOT NULL,
|
|
215
|
+
"grant_generation" bigint NOT NULL,
|
|
216
|
+
"consumed_at" timestamptz NOT NULL DEFAULT clock_timestamp(),
|
|
217
|
+
CONSTRAINT "personal_resource_once_consumption_receipts_grant_fk"
|
|
218
|
+
FOREIGN KEY ("grant_id", "account_id")
|
|
219
|
+
REFERENCES "organization_user_resource_grants"("id", "account_id") ON DELETE RESTRICT,
|
|
220
|
+
CONSTRAINT "personal_resource_once_consumption_receipts_attempt_fk"
|
|
221
|
+
FOREIGN KEY (
|
|
222
|
+
"account_id", "workspace_id", "session_id", "turn_id", "attempt_id",
|
|
223
|
+
"execution_generation"
|
|
224
|
+
) REFERENCES "session_attempt_personal_resource_admissions"(
|
|
225
|
+
"account_id", "workspace_id", "session_id", "turn_id", "attempt_id",
|
|
226
|
+
"execution_generation"
|
|
227
|
+
) ON DELETE CASCADE,
|
|
228
|
+
CONSTRAINT "personal_resource_once_consumption_receipts_generation_chk" CHECK (
|
|
229
|
+
"execution_generation" > 0
|
|
230
|
+
AND "authority_generation" > 0
|
|
231
|
+
AND "grant_generation" > 0
|
|
232
|
+
)
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
ALTER TABLE "session_attempt_personal_resource_admissions" ENABLE ROW LEVEL SECURITY;
|
|
236
|
+
ALTER TABLE "session_attempt_personal_resource_admissions" FORCE ROW LEVEL SECURITY;
|
|
237
|
+
ALTER TABLE "session_attempt_personal_resource_snapshots" ENABLE ROW LEVEL SECURITY;
|
|
238
|
+
ALTER TABLE "session_attempt_personal_resource_snapshots" FORCE ROW LEVEL SECURITY;
|
|
239
|
+
ALTER TABLE "personal_resource_once_consumption_receipts" ENABLE ROW LEVEL SECURITY;
|
|
240
|
+
ALTER TABLE "personal_resource_once_consumption_receipts" FORCE ROW LEVEL SECURITY;
|
|
241
|
+
|
|
242
|
+
DO $personal_resource_capability_policies$
|
|
243
|
+
DECLARE
|
|
244
|
+
data_schema text := current_schema();
|
|
245
|
+
migration_owner text := current_user;
|
|
246
|
+
table_name text;
|
|
247
|
+
BEGIN
|
|
248
|
+
FOREACH table_name IN ARRAY ARRAY[
|
|
249
|
+
'session_attempt_personal_resource_admissions',
|
|
250
|
+
'session_attempt_personal_resource_snapshots',
|
|
251
|
+
'personal_resource_once_consumption_receipts'
|
|
252
|
+
] LOOP
|
|
253
|
+
EXECUTE format(
|
|
254
|
+
'CREATE POLICY personal_resource_delegation_capability_read ON %I.%I '
|
|
255
|
+
|| 'FOR SELECT USING ('
|
|
256
|
+
|| 'current_user = %L AND '
|
|
257
|
+
|| 'opengeni_private.personal_resource_delegation_capability_active()'
|
|
258
|
+
|| ')',
|
|
259
|
+
data_schema,
|
|
260
|
+
table_name,
|
|
261
|
+
migration_owner
|
|
262
|
+
);
|
|
263
|
+
EXECUTE format(
|
|
264
|
+
'CREATE POLICY personal_resource_delegation_capability_insert ON %I.%I '
|
|
265
|
+
|| 'FOR INSERT WITH CHECK ('
|
|
266
|
+
|| 'current_user = %L AND '
|
|
267
|
+
|| 'opengeni_private.personal_resource_delegation_capability_active(''admit'')'
|
|
268
|
+
|| ')',
|
|
269
|
+
data_schema,
|
|
270
|
+
table_name,
|
|
271
|
+
migration_owner
|
|
272
|
+
);
|
|
273
|
+
END LOOP;
|
|
274
|
+
|
|
275
|
+
FOREACH table_name IN ARRAY ARRAY[
|
|
276
|
+
'organization_memberships',
|
|
277
|
+
'organization_user_resource_authorities',
|
|
278
|
+
'workspace_variable_sets',
|
|
279
|
+
'rigs',
|
|
280
|
+
'rig_versions'
|
|
281
|
+
] LOOP
|
|
282
|
+
EXECUTE format(
|
|
283
|
+
'CREATE POLICY personal_resource_delegation_read ON %I.%I '
|
|
284
|
+
|| 'FOR SELECT USING ('
|
|
285
|
+
|| 'current_user = %L AND '
|
|
286
|
+
|| 'opengeni_private.personal_resource_delegation_capability_active()'
|
|
287
|
+
|| ')',
|
|
288
|
+
data_schema,
|
|
289
|
+
table_name,
|
|
290
|
+
migration_owner
|
|
291
|
+
);
|
|
292
|
+
END LOOP;
|
|
293
|
+
|
|
294
|
+
EXECUTE format(
|
|
295
|
+
'CREATE POLICY personal_resource_delegation_grant_read '
|
|
296
|
+
|| 'ON %I.organization_user_resource_grants FOR SELECT USING ('
|
|
297
|
+
|| 'current_user = %L AND '
|
|
298
|
+
|| 'opengeni_private.personal_resource_delegation_capability_active()'
|
|
299
|
+
|| ')',
|
|
300
|
+
data_schema,
|
|
301
|
+
migration_owner
|
|
302
|
+
);
|
|
303
|
+
EXECUTE format(
|
|
304
|
+
'CREATE POLICY personal_resource_delegation_grant_update '
|
|
305
|
+
|| 'ON %I.organization_user_resource_grants FOR UPDATE USING ('
|
|
306
|
+
|| 'current_user = %L AND '
|
|
307
|
+
|| 'opengeni_private.personal_resource_delegation_capability_active(''admit'')'
|
|
308
|
+
|| ') WITH CHECK ('
|
|
309
|
+
|| 'current_user = %L AND '
|
|
310
|
+
|| 'opengeni_private.personal_resource_delegation_capability_active(''admit'')'
|
|
311
|
+
|| ')',
|
|
312
|
+
data_schema,
|
|
313
|
+
migration_owner,
|
|
314
|
+
migration_owner
|
|
315
|
+
);
|
|
316
|
+
END
|
|
317
|
+
$personal_resource_capability_policies$;
|
|
318
|
+
|
|
319
|
+
DO $personal_resource_delegation_functions$
|
|
320
|
+
DECLARE
|
|
321
|
+
data_schema text := current_schema();
|
|
322
|
+
BEGIN
|
|
323
|
+
EXECUTE format($ddl$
|
|
324
|
+
CREATE OR REPLACE FUNCTION %1$I.admit_session_attempt_personal_resources()
|
|
325
|
+
RETURNS trigger
|
|
326
|
+
LANGUAGE plpgsql
|
|
327
|
+
SECURITY DEFINER
|
|
328
|
+
SET search_path = %1$I, pg_catalog
|
|
329
|
+
AS $body$
|
|
330
|
+
DECLARE
|
|
331
|
+
session_row sessions%%ROWTYPE;
|
|
332
|
+
turn_row session_turns%%ROWTYPE;
|
|
333
|
+
member_row organization_memberships%%ROWTYPE;
|
|
334
|
+
resource_row record;
|
|
335
|
+
grant_row organization_user_resource_grants%%ROWTYPE;
|
|
336
|
+
resource_total integer := 0;
|
|
337
|
+
snapshot_total integer := 0;
|
|
338
|
+
initiating_subject text;
|
|
339
|
+
affected integer;
|
|
340
|
+
BEGIN
|
|
341
|
+
INSERT INTO opengeni_private.personal_resource_delegation_capabilities (
|
|
342
|
+
backend_pid, transaction_id, capability_kind
|
|
343
|
+
) VALUES (pg_catalog.pg_backend_pid(), pg_catalog.pg_current_xact_id(), 'admit')
|
|
344
|
+
ON CONFLICT DO NOTHING;
|
|
345
|
+
|
|
346
|
+
SELECT session_value.* INTO STRICT session_row
|
|
347
|
+
FROM sessions session_value
|
|
348
|
+
WHERE session_value.id = NEW.session_id
|
|
349
|
+
AND session_value.account_id = NEW.account_id
|
|
350
|
+
AND session_value.workspace_id = NEW.workspace_id
|
|
351
|
+
FOR SHARE;
|
|
352
|
+
|
|
353
|
+
SELECT turn_value.* INTO STRICT turn_row
|
|
354
|
+
FROM session_turns turn_value
|
|
355
|
+
WHERE turn_value.id = NEW.turn_id
|
|
356
|
+
AND turn_value.account_id = NEW.account_id
|
|
357
|
+
AND turn_value.workspace_id = NEW.workspace_id
|
|
358
|
+
AND turn_value.session_id = NEW.session_id
|
|
359
|
+
FOR SHARE;
|
|
360
|
+
|
|
361
|
+
SELECT count(*)::integer INTO resource_total
|
|
362
|
+
FROM (
|
|
363
|
+
SELECT DISTINCT selected.resource_kind, selected.resource_id
|
|
364
|
+
FROM (
|
|
365
|
+
SELECT 'variable_set'::text AS resource_kind, variable_set.id AS resource_id
|
|
366
|
+
FROM workspace_variable_sets variable_set
|
|
367
|
+
WHERE variable_set.id = session_row.variable_set_id
|
|
368
|
+
AND variable_set.account_id = NEW.account_id
|
|
369
|
+
AND variable_set.authority_scope = 'user'
|
|
370
|
+
UNION ALL
|
|
371
|
+
SELECT 'rig'::text, rig.id
|
|
372
|
+
FROM rigs rig
|
|
373
|
+
WHERE rig.id = session_row.rig_id
|
|
374
|
+
AND rig.account_id = NEW.account_id
|
|
375
|
+
AND rig.authority_scope = 'user'
|
|
376
|
+
UNION ALL
|
|
377
|
+
SELECT 'variable_set'::text, default_variable_set.id
|
|
378
|
+
FROM rig_versions rig_version
|
|
379
|
+
CROSS JOIN LATERAL jsonb_array_elements_text(
|
|
380
|
+
rig_version.default_variable_set_ids
|
|
381
|
+
) default_id(value)
|
|
382
|
+
JOIN workspace_variable_sets default_variable_set
|
|
383
|
+
ON default_variable_set.id = default_id.value::uuid
|
|
384
|
+
AND default_variable_set.account_id = NEW.account_id
|
|
385
|
+
AND default_variable_set.authority_scope = 'user'
|
|
386
|
+
WHERE rig_version.id = session_row.rig_version_id
|
|
387
|
+
AND rig_version.rig_id = session_row.rig_id
|
|
388
|
+
AND rig_version.account_id = NEW.account_id
|
|
389
|
+
) selected
|
|
390
|
+
) selected_personal_resources;
|
|
391
|
+
|
|
392
|
+
IF resource_total = 0 THEN
|
|
393
|
+
DELETE FROM opengeni_private.personal_resource_delegation_capabilities
|
|
394
|
+
WHERE backend_pid = pg_catalog.pg_backend_pid()
|
|
395
|
+
AND transaction_id = pg_catalog.pg_current_xact_id_if_assigned()
|
|
396
|
+
AND capability_kind = 'admit';
|
|
397
|
+
RETURN NEW;
|
|
398
|
+
END IF;
|
|
399
|
+
|
|
400
|
+
IF NEW.execution_generation <= 0
|
|
401
|
+
OR NEW.state NOT IN ('claimed', 'running')
|
|
402
|
+
OR NEW.closed_at IS NOT NULL
|
|
403
|
+
OR NEW.quiesced_at IS NOT NULL
|
|
404
|
+
OR session_row.active_turn_id IS DISTINCT FROM NEW.turn_id
|
|
405
|
+
OR turn_row.active_attempt_id IS DISTINCT FROM NEW.id
|
|
406
|
+
OR turn_row.execution_generation IS DISTINCT FROM NEW.execution_generation
|
|
407
|
+
OR turn_row.status NOT IN ('running', 'requires_action', 'recovering', 'waiting_capacity')
|
|
408
|
+
OR EXISTS (
|
|
409
|
+
SELECT 1
|
|
410
|
+
FROM session_attempt_interruptions interruption
|
|
411
|
+
WHERE interruption.account_id = NEW.account_id
|
|
412
|
+
AND interruption.workspace_id = NEW.workspace_id
|
|
413
|
+
AND interruption.session_id = NEW.session_id
|
|
414
|
+
AND interruption.attempt_id = NEW.id
|
|
415
|
+
AND interruption.state IN ('pending', 'delivered', 'acknowledged')
|
|
416
|
+
)
|
|
417
|
+
THEN
|
|
418
|
+
RAISE EXCEPTION 'personal-resource admission requires the exact current uninterrupted attempt'
|
|
419
|
+
USING ERRCODE = '42501';
|
|
420
|
+
END IF;
|
|
421
|
+
|
|
422
|
+
IF NEW.authority_visibility IS DISTINCT FROM session_row.visibility
|
|
423
|
+
OR NEW.authority_epoch IS DISTINCT FROM session_row.authority_epoch
|
|
424
|
+
OR NEW.authority_owner_organization_membership_id
|
|
425
|
+
IS DISTINCT FROM session_row.owner_organization_membership_id
|
|
426
|
+
THEN
|
|
427
|
+
RAISE EXCEPTION 'personal-resource admission requires the exact session authority'
|
|
428
|
+
USING ERRCODE = '42501';
|
|
429
|
+
END IF;
|
|
430
|
+
|
|
431
|
+
initiating_subject := coalesce(
|
|
432
|
+
nullif(btrim(turn_row.initiating_human_subject_id), ''),
|
|
433
|
+
CASE WHEN turn_row.initiator_kind = 'subject'
|
|
434
|
+
THEN nullif(btrim(turn_row.initiator_subject_id), '') END
|
|
435
|
+
);
|
|
436
|
+
IF initiating_subject IS NULL THEN
|
|
437
|
+
RAISE EXCEPTION 'personal-resource admission requires an initiating human subject'
|
|
438
|
+
USING ERRCODE = '42501';
|
|
439
|
+
END IF;
|
|
440
|
+
|
|
441
|
+
SELECT membership.* INTO STRICT member_row
|
|
442
|
+
FROM organization_memberships membership
|
|
443
|
+
WHERE membership.account_id = NEW.account_id
|
|
444
|
+
AND membership.subject_id = initiating_subject
|
|
445
|
+
AND membership.status = 'active'
|
|
446
|
+
AND membership.revoked_at IS NULL
|
|
447
|
+
AND membership.personal_workspace_id IS NOT NULL
|
|
448
|
+
FOR SHARE;
|
|
449
|
+
|
|
450
|
+
PERFORM 1
|
|
451
|
+
FROM workspace_memberships workspace_membership
|
|
452
|
+
WHERE workspace_membership.account_id = NEW.account_id
|
|
453
|
+
AND workspace_membership.workspace_id = NEW.workspace_id
|
|
454
|
+
AND workspace_membership.subject_id = initiating_subject
|
|
455
|
+
FOR KEY SHARE;
|
|
456
|
+
IF NOT FOUND THEN
|
|
457
|
+
RAISE EXCEPTION 'initiating human lacks target-workspace membership'
|
|
458
|
+
USING ERRCODE = '42501';
|
|
459
|
+
END IF;
|
|
460
|
+
|
|
461
|
+
INSERT INTO session_attempt_personal_resource_admissions (
|
|
462
|
+
attempt_id, account_id, workspace_id, session_id, turn_id,
|
|
463
|
+
execution_generation, initiating_human_subject_id,
|
|
464
|
+
owner_organization_membership_id, membership_authorization_revision,
|
|
465
|
+
session_visibility, session_authority_epoch, resource_count
|
|
466
|
+
) VALUES (
|
|
467
|
+
NEW.id, NEW.account_id, NEW.workspace_id, NEW.session_id, NEW.turn_id,
|
|
468
|
+
NEW.execution_generation, initiating_subject, member_row.id,
|
|
469
|
+
member_row.authorization_revision, session_row.visibility,
|
|
470
|
+
session_row.authority_epoch, resource_total
|
|
471
|
+
);
|
|
472
|
+
|
|
473
|
+
FOR resource_row IN
|
|
474
|
+
WITH selected AS (
|
|
475
|
+
SELECT
|
|
476
|
+
'variable_set'::text AS resource_kind,
|
|
477
|
+
variable_set.id AS resource_id,
|
|
478
|
+
NULL::uuid AS resource_version_id,
|
|
479
|
+
'variable_set.use'::text AS action,
|
|
480
|
+
'session_variable_set'::text AS selection_source,
|
|
481
|
+
variable_set.workspace_id AS resource_workspace_id,
|
|
482
|
+
variable_set.authority_id,
|
|
483
|
+
variable_set.owner_organization_membership_id,
|
|
484
|
+
variable_set.origin_workspace_id
|
|
485
|
+
FROM workspace_variable_sets variable_set
|
|
486
|
+
WHERE variable_set.id = session_row.variable_set_id
|
|
487
|
+
AND variable_set.account_id = NEW.account_id
|
|
488
|
+
AND variable_set.authority_scope = 'user'
|
|
489
|
+
UNION ALL
|
|
490
|
+
SELECT
|
|
491
|
+
'rig'::text, rig.id, session_row.rig_version_id, 'rig.use'::text,
|
|
492
|
+
'session_rig'::text, rig.workspace_id, rig.authority_id,
|
|
493
|
+
rig.owner_organization_membership_id, rig.origin_workspace_id
|
|
494
|
+
FROM rigs rig
|
|
495
|
+
WHERE rig.id = session_row.rig_id
|
|
496
|
+
AND rig.account_id = NEW.account_id
|
|
497
|
+
AND rig.authority_scope = 'user'
|
|
498
|
+
UNION ALL
|
|
499
|
+
SELECT
|
|
500
|
+
'variable_set'::text, default_variable_set.id, NULL::uuid,
|
|
501
|
+
'variable_set.use'::text,
|
|
502
|
+
('rig_default_variable_set:' || default_id.ordinality::text)::text,
|
|
503
|
+
default_variable_set.workspace_id, default_variable_set.authority_id,
|
|
504
|
+
default_variable_set.owner_organization_membership_id,
|
|
505
|
+
default_variable_set.origin_workspace_id
|
|
506
|
+
FROM rig_versions rig_version
|
|
507
|
+
CROSS JOIN LATERAL jsonb_array_elements_text(
|
|
508
|
+
rig_version.default_variable_set_ids
|
|
509
|
+
) WITH ORDINALITY default_id(value, ordinality)
|
|
510
|
+
JOIN workspace_variable_sets default_variable_set
|
|
511
|
+
ON default_variable_set.id = default_id.value::uuid
|
|
512
|
+
AND default_variable_set.account_id = NEW.account_id
|
|
513
|
+
AND default_variable_set.authority_scope = 'user'
|
|
514
|
+
WHERE rig_version.id = session_row.rig_version_id
|
|
515
|
+
AND rig_version.rig_id = session_row.rig_id
|
|
516
|
+
AND rig_version.account_id = NEW.account_id
|
|
517
|
+
)
|
|
518
|
+
SELECT resource_kind, resource_id,
|
|
519
|
+
min(resource_version_id::text)::uuid AS resource_version_id,
|
|
520
|
+
action, array_agg(selection_source ORDER BY selection_source) AS selection_sources,
|
|
521
|
+
min(resource_workspace_id::text)::uuid AS resource_workspace_id,
|
|
522
|
+
min(authority_id::text)::uuid AS authority_id,
|
|
523
|
+
min(owner_organization_membership_id::text)::uuid
|
|
524
|
+
AS owner_organization_membership_id,
|
|
525
|
+
min(origin_workspace_id::text)::uuid AS origin_workspace_id
|
|
526
|
+
FROM selected
|
|
527
|
+
GROUP BY resource_kind, resource_id, action
|
|
528
|
+
ORDER BY resource_kind, resource_id
|
|
529
|
+
LOOP
|
|
530
|
+
IF resource_row.owner_organization_membership_id IS DISTINCT FROM member_row.id
|
|
531
|
+
OR resource_row.resource_workspace_id IS DISTINCT FROM member_row.personal_workspace_id
|
|
532
|
+
OR resource_row.origin_workspace_id IS DISTINCT FROM member_row.personal_workspace_id
|
|
533
|
+
THEN
|
|
534
|
+
RAISE EXCEPTION 'personal resource owner/origin does not match initiating membership'
|
|
535
|
+
USING ERRCODE = '42501';
|
|
536
|
+
END IF;
|
|
537
|
+
|
|
538
|
+
IF resource_row.resource_kind = 'variable_set' THEN
|
|
539
|
+
PERFORM 1 FROM workspace_variable_sets variable_set
|
|
540
|
+
WHERE variable_set.id = resource_row.resource_id
|
|
541
|
+
AND variable_set.account_id = NEW.account_id
|
|
542
|
+
AND variable_set.workspace_id = member_row.personal_workspace_id
|
|
543
|
+
AND variable_set.authority_scope = 'user'
|
|
544
|
+
AND variable_set.authority_id = resource_row.authority_id
|
|
545
|
+
AND variable_set.owner_organization_membership_id = member_row.id
|
|
546
|
+
AND variable_set.origin_workspace_id = member_row.personal_workspace_id
|
|
547
|
+
FOR SHARE;
|
|
548
|
+
ELSE
|
|
549
|
+
PERFORM 1 FROM rigs rig
|
|
550
|
+
WHERE rig.id = resource_row.resource_id
|
|
551
|
+
AND rig.account_id = NEW.account_id
|
|
552
|
+
AND rig.workspace_id = member_row.personal_workspace_id
|
|
553
|
+
AND rig.authority_scope = 'user'
|
|
554
|
+
AND rig.authority_id = resource_row.authority_id
|
|
555
|
+
AND rig.owner_organization_membership_id = member_row.id
|
|
556
|
+
AND rig.origin_workspace_id = member_row.personal_workspace_id
|
|
557
|
+
FOR SHARE;
|
|
558
|
+
IF FOUND THEN
|
|
559
|
+
PERFORM 1 FROM rig_versions rig_version
|
|
560
|
+
WHERE rig_version.id = resource_row.resource_version_id
|
|
561
|
+
AND rig_version.account_id = NEW.account_id
|
|
562
|
+
AND rig_version.rig_id = resource_row.resource_id
|
|
563
|
+
AND rig_version.workspace_id = member_row.personal_workspace_id
|
|
564
|
+
FOR SHARE;
|
|
565
|
+
END IF;
|
|
566
|
+
END IF;
|
|
567
|
+
IF NOT FOUND THEN
|
|
568
|
+
RAISE EXCEPTION 'personal resource identity changed during admission'
|
|
569
|
+
USING ERRCODE = '42501';
|
|
570
|
+
END IF;
|
|
571
|
+
|
|
572
|
+
PERFORM 1
|
|
573
|
+
FROM organization_user_resource_authorities authority
|
|
574
|
+
WHERE authority.id = resource_row.authority_id
|
|
575
|
+
AND authority.account_id = NEW.account_id
|
|
576
|
+
AND authority.organization_membership_id = member_row.id
|
|
577
|
+
AND authority.resource_kind = resource_row.resource_kind
|
|
578
|
+
AND authority.resource_id = resource_row.resource_id
|
|
579
|
+
AND authority.origin_workspace_id = member_row.personal_workspace_id
|
|
580
|
+
AND authority.status = 'active'
|
|
581
|
+
AND authority.revoked_at IS NULL
|
|
582
|
+
FOR SHARE;
|
|
583
|
+
IF NOT FOUND THEN
|
|
584
|
+
RAISE EXCEPTION 'personal resource authority is not live'
|
|
585
|
+
USING ERRCODE = '42501';
|
|
586
|
+
END IF;
|
|
587
|
+
|
|
588
|
+
SELECT grant_value.* INTO grant_row
|
|
589
|
+
FROM organization_user_resource_grants grant_value
|
|
590
|
+
WHERE grant_value.account_id = NEW.account_id
|
|
591
|
+
AND grant_value.authority_id = resource_row.authority_id
|
|
592
|
+
AND grant_value.owner_organization_membership_id = member_row.id
|
|
593
|
+
AND grant_value.workspace_id = NEW.workspace_id
|
|
594
|
+
AND grant_value.action = resource_row.action
|
|
595
|
+
AND grant_value.context = session_row.visibility
|
|
596
|
+
AND grant_value.status = 'active'
|
|
597
|
+
AND (grant_value.expires_at IS NULL OR grant_value.expires_at > clock_timestamp())
|
|
598
|
+
AND (
|
|
599
|
+
(
|
|
600
|
+
grant_value.mode IN ('once', 'session')
|
|
601
|
+
AND grant_value.session_id = NEW.session_id
|
|
602
|
+
AND grant_value.authority_epoch = session_row.authority_epoch
|
|
603
|
+
) OR (
|
|
604
|
+
grant_value.mode = 'always'
|
|
605
|
+
AND grant_value.session_id IS NULL
|
|
606
|
+
AND grant_value.authority_epoch IS NULL
|
|
607
|
+
)
|
|
608
|
+
)
|
|
609
|
+
ORDER BY
|
|
610
|
+
CASE grant_value.mode WHEN 'once' THEN 1 WHEN 'session' THEN 2 ELSE 3 END,
|
|
611
|
+
grant_value.generation DESC,
|
|
612
|
+
grant_value.id
|
|
613
|
+
LIMIT 1
|
|
614
|
+
FOR UPDATE;
|
|
615
|
+
IF NOT FOUND THEN
|
|
616
|
+
RAISE EXCEPTION 'matching personal-resource grant required'
|
|
617
|
+
USING ERRCODE = '42501';
|
|
618
|
+
END IF;
|
|
619
|
+
|
|
620
|
+
INSERT INTO session_attempt_personal_resource_snapshots (
|
|
621
|
+
attempt_id, account_id, workspace_id, session_id, turn_id,
|
|
622
|
+
execution_generation, resource_kind, resource_id, resource_version_id,
|
|
623
|
+
selection_sources, action, origin_workspace_id,
|
|
624
|
+
owner_organization_membership_id, membership_authorization_revision,
|
|
625
|
+
authority_id, authority_generation, target_workspace_id,
|
|
626
|
+
session_visibility, session_authority_epoch, grant_id, grant_generation,
|
|
627
|
+
grant_mode, grant_context, grant_session_id, grant_authority_epoch
|
|
628
|
+
)
|
|
629
|
+
SELECT
|
|
630
|
+
NEW.id, NEW.account_id, NEW.workspace_id, NEW.session_id, NEW.turn_id,
|
|
631
|
+
NEW.execution_generation, resource_row.resource_kind, resource_row.resource_id,
|
|
632
|
+
resource_row.resource_version_id, resource_row.selection_sources,
|
|
633
|
+
resource_row.action, member_row.personal_workspace_id, member_row.id,
|
|
634
|
+
member_row.authorization_revision, authority.id, authority.generation,
|
|
635
|
+
NEW.workspace_id, session_row.visibility, session_row.authority_epoch,
|
|
636
|
+
grant_row.id, grant_row.generation, grant_row.mode, grant_row.context,
|
|
637
|
+
grant_row.session_id, grant_row.authority_epoch
|
|
638
|
+
FROM organization_user_resource_authorities authority
|
|
639
|
+
WHERE authority.id = resource_row.authority_id
|
|
640
|
+
AND authority.account_id = NEW.account_id;
|
|
641
|
+
|
|
642
|
+
IF grant_row.mode = 'once' THEN
|
|
643
|
+
UPDATE organization_user_resource_grants
|
|
644
|
+
SET status = 'consumed', updated_at = clock_timestamp()
|
|
645
|
+
WHERE id = grant_row.id
|
|
646
|
+
AND account_id = NEW.account_id
|
|
647
|
+
AND generation = grant_row.generation
|
|
648
|
+
AND status = 'active';
|
|
649
|
+
GET DIAGNOSTICS affected = ROW_COUNT;
|
|
650
|
+
IF affected <> 1 THEN
|
|
651
|
+
RAISE EXCEPTION 'once grant lost its first-use race'
|
|
652
|
+
USING ERRCODE = '40001';
|
|
653
|
+
END IF;
|
|
654
|
+
INSERT INTO personal_resource_once_consumption_receipts (
|
|
655
|
+
grant_id, account_id, attempt_id, workspace_id, session_id, turn_id,
|
|
656
|
+
execution_generation, authority_id, authority_generation, grant_generation
|
|
657
|
+
) SELECT
|
|
658
|
+
grant_row.id, NEW.account_id, NEW.id, NEW.workspace_id, NEW.session_id,
|
|
659
|
+
NEW.turn_id, NEW.execution_generation, authority.id, authority.generation,
|
|
660
|
+
grant_row.generation
|
|
661
|
+
FROM organization_user_resource_authorities authority
|
|
662
|
+
WHERE authority.id = resource_row.authority_id
|
|
663
|
+
AND authority.account_id = NEW.account_id;
|
|
664
|
+
END IF;
|
|
665
|
+
snapshot_total := snapshot_total + 1;
|
|
666
|
+
END LOOP;
|
|
667
|
+
|
|
668
|
+
IF snapshot_total <> resource_total THEN
|
|
669
|
+
RAISE EXCEPTION 'personal-resource snapshot collection is not exact'
|
|
670
|
+
USING ERRCODE = '23514';
|
|
671
|
+
END IF;
|
|
672
|
+
|
|
673
|
+
DELETE FROM opengeni_private.personal_resource_delegation_capabilities
|
|
674
|
+
WHERE backend_pid = pg_catalog.pg_backend_pid()
|
|
675
|
+
AND transaction_id = pg_catalog.pg_current_xact_id_if_assigned()
|
|
676
|
+
AND capability_kind = 'admit';
|
|
677
|
+
RETURN NEW;
|
|
678
|
+
EXCEPTION WHEN OTHERS THEN
|
|
679
|
+
DELETE FROM opengeni_private.personal_resource_delegation_capabilities
|
|
680
|
+
WHERE backend_pid = pg_catalog.pg_backend_pid()
|
|
681
|
+
AND transaction_id = pg_catalog.pg_current_xact_id_if_assigned()
|
|
682
|
+
AND capability_kind = 'admit';
|
|
683
|
+
RAISE;
|
|
684
|
+
END;
|
|
685
|
+
$body$;
|
|
686
|
+
$ddl$, data_schema);
|
|
687
|
+
|
|
688
|
+
EXECUTE format($ddl$
|
|
689
|
+
CREATE OR REPLACE FUNCTION %1$I.resolve_session_attempt_personal_resources(
|
|
690
|
+
p_account_id uuid,
|
|
691
|
+
p_workspace_id uuid,
|
|
692
|
+
p_attempt_id uuid
|
|
693
|
+
) RETURNS TABLE (
|
|
694
|
+
resource_kind text,
|
|
695
|
+
resource_id uuid,
|
|
696
|
+
resource_version_id uuid,
|
|
697
|
+
selection_sources text[],
|
|
698
|
+
action text,
|
|
699
|
+
authority_id uuid,
|
|
700
|
+
authority_generation bigint,
|
|
701
|
+
grant_id uuid,
|
|
702
|
+
grant_generation bigint,
|
|
703
|
+
grant_mode text
|
|
704
|
+
)
|
|
705
|
+
LANGUAGE plpgsql
|
|
706
|
+
SECURITY DEFINER
|
|
707
|
+
SET search_path = %1$I, pg_catalog
|
|
708
|
+
AS $body$
|
|
709
|
+
DECLARE
|
|
710
|
+
admission_row session_attempt_personal_resource_admissions%%ROWTYPE;
|
|
711
|
+
invalid_count integer;
|
|
712
|
+
caller_subject text := coalesce(
|
|
713
|
+
nullif(pg_catalog.current_setting('opengeni.initiating_human_subject_id', true), ''),
|
|
714
|
+
nullif(pg_catalog.current_setting('opengeni.subject_id', true), '')
|
|
715
|
+
);
|
|
716
|
+
BEGIN
|
|
717
|
+
IF p_account_id IS DISTINCT FROM nullif(
|
|
718
|
+
pg_catalog.current_setting('opengeni.account_id', true), ''
|
|
719
|
+
)::uuid
|
|
720
|
+
OR p_workspace_id IS DISTINCT FROM nullif(
|
|
721
|
+
pg_catalog.current_setting('opengeni.workspace_id', true), ''
|
|
722
|
+
)::uuid
|
|
723
|
+
THEN
|
|
724
|
+
RAISE EXCEPTION 'personal-resource resolve scope mismatch'
|
|
725
|
+
USING ERRCODE = '42501';
|
|
726
|
+
END IF;
|
|
727
|
+
|
|
728
|
+
INSERT INTO opengeni_private.personal_resource_delegation_capabilities (
|
|
729
|
+
backend_pid, transaction_id, capability_kind
|
|
730
|
+
) VALUES (pg_catalog.pg_backend_pid(), pg_catalog.pg_current_xact_id(), 'resolve')
|
|
731
|
+
ON CONFLICT DO NOTHING;
|
|
732
|
+
|
|
733
|
+
SELECT admission.* INTO STRICT admission_row
|
|
734
|
+
FROM session_attempt_personal_resource_admissions admission
|
|
735
|
+
WHERE admission.attempt_id = p_attempt_id
|
|
736
|
+
AND admission.account_id = p_account_id
|
|
737
|
+
AND admission.workspace_id = p_workspace_id;
|
|
738
|
+
|
|
739
|
+
IF caller_subject IS DISTINCT FROM admission_row.initiating_human_subject_id THEN
|
|
740
|
+
RAISE EXCEPTION 'personal-resource resolve initiating human mismatch'
|
|
741
|
+
USING ERRCODE = '42501';
|
|
742
|
+
END IF;
|
|
743
|
+
|
|
744
|
+
PERFORM 1
|
|
745
|
+
FROM sessions session_value
|
|
746
|
+
JOIN session_turns turn_value
|
|
747
|
+
ON turn_value.account_id = session_value.account_id
|
|
748
|
+
AND turn_value.workspace_id = session_value.workspace_id
|
|
749
|
+
AND turn_value.session_id = session_value.id
|
|
750
|
+
JOIN session_turn_attempts attempt
|
|
751
|
+
ON attempt.account_id = turn_value.account_id
|
|
752
|
+
AND attempt.workspace_id = turn_value.workspace_id
|
|
753
|
+
AND attempt.session_id = turn_value.session_id
|
|
754
|
+
AND attempt.turn_id = turn_value.id
|
|
755
|
+
WHERE session_value.id = admission_row.session_id
|
|
756
|
+
AND session_value.account_id = admission_row.account_id
|
|
757
|
+
AND session_value.workspace_id = admission_row.workspace_id
|
|
758
|
+
AND session_value.active_turn_id = admission_row.turn_id
|
|
759
|
+
AND turn_value.id = admission_row.turn_id
|
|
760
|
+
AND turn_value.active_attempt_id = admission_row.attempt_id
|
|
761
|
+
AND turn_value.execution_generation = admission_row.execution_generation
|
|
762
|
+
AND turn_value.status IN ('running', 'requires_action', 'recovering', 'waiting_capacity')
|
|
763
|
+
AND attempt.id = admission_row.attempt_id
|
|
764
|
+
AND attempt.execution_generation = admission_row.execution_generation
|
|
765
|
+
AND attempt.state IN ('claimed', 'running')
|
|
766
|
+
AND attempt.closed_at IS NULL
|
|
767
|
+
AND attempt.quiesced_at IS NULL
|
|
768
|
+
FOR SHARE OF session_value, turn_value
|
|
769
|
+
FOR UPDATE OF attempt;
|
|
770
|
+
IF NOT FOUND THEN
|
|
771
|
+
RAISE EXCEPTION 'personal-resource resolve requires the exact current uninterrupted attempt'
|
|
772
|
+
USING ERRCODE = '42501';
|
|
773
|
+
END IF;
|
|
774
|
+
|
|
775
|
+
IF EXISTS (
|
|
776
|
+
SELECT 1
|
|
777
|
+
FROM session_attempt_interruptions interruption
|
|
778
|
+
WHERE interruption.account_id = admission_row.account_id
|
|
779
|
+
AND interruption.workspace_id = admission_row.workspace_id
|
|
780
|
+
AND interruption.session_id = admission_row.session_id
|
|
781
|
+
AND interruption.attempt_id = admission_row.attempt_id
|
|
782
|
+
AND interruption.state IN ('pending', 'delivered', 'acknowledged')
|
|
783
|
+
)
|
|
784
|
+
THEN
|
|
785
|
+
RAISE EXCEPTION 'personal-resource resolve requires the exact current uninterrupted attempt'
|
|
786
|
+
USING ERRCODE = '42501';
|
|
787
|
+
END IF;
|
|
788
|
+
|
|
789
|
+
SELECT count(*)::integer INTO invalid_count
|
|
790
|
+
FROM session_attempt_personal_resource_snapshots snapshot
|
|
791
|
+
WHERE snapshot.attempt_id = admission_row.attempt_id
|
|
792
|
+
AND NOT (
|
|
793
|
+
EXISTS (
|
|
794
|
+
SELECT 1
|
|
795
|
+
FROM session_turn_attempts attempt
|
|
796
|
+
JOIN sessions session_value
|
|
797
|
+
ON session_value.id = attempt.session_id
|
|
798
|
+
AND session_value.account_id = attempt.account_id
|
|
799
|
+
AND session_value.workspace_id = attempt.workspace_id
|
|
800
|
+
JOIN session_turns turn_value
|
|
801
|
+
ON turn_value.id = attempt.turn_id
|
|
802
|
+
AND turn_value.account_id = attempt.account_id
|
|
803
|
+
AND turn_value.workspace_id = attempt.workspace_id
|
|
804
|
+
AND turn_value.session_id = attempt.session_id
|
|
805
|
+
WHERE attempt.id = snapshot.attempt_id
|
|
806
|
+
AND attempt.account_id = snapshot.account_id
|
|
807
|
+
AND attempt.workspace_id = snapshot.workspace_id
|
|
808
|
+
AND attempt.session_id = snapshot.session_id
|
|
809
|
+
AND attempt.turn_id = snapshot.turn_id
|
|
810
|
+
AND attempt.execution_generation = snapshot.execution_generation
|
|
811
|
+
AND attempt.state IN ('claimed', 'running')
|
|
812
|
+
AND attempt.quiesced_at IS NULL
|
|
813
|
+
AND attempt.authority_visibility = snapshot.session_visibility
|
|
814
|
+
AND attempt.authority_epoch = snapshot.session_authority_epoch
|
|
815
|
+
AND session_value.visibility = snapshot.session_visibility
|
|
816
|
+
AND session_value.authority_epoch = snapshot.session_authority_epoch
|
|
817
|
+
AND coalesce(
|
|
818
|
+
nullif(btrim(turn_value.initiating_human_subject_id), ''),
|
|
819
|
+
CASE WHEN turn_value.initiator_kind = 'subject'
|
|
820
|
+
THEN nullif(btrim(turn_value.initiator_subject_id), '') END
|
|
821
|
+
) = admission_row.initiating_human_subject_id
|
|
822
|
+
)
|
|
823
|
+
AND EXISTS (
|
|
824
|
+
SELECT 1
|
|
825
|
+
FROM organization_memberships membership
|
|
826
|
+
JOIN workspace_memberships workspace_membership
|
|
827
|
+
ON workspace_membership.account_id = membership.account_id
|
|
828
|
+
AND workspace_membership.workspace_id = snapshot.workspace_id
|
|
829
|
+
AND workspace_membership.subject_id = membership.subject_id
|
|
830
|
+
WHERE membership.id = snapshot.owner_organization_membership_id
|
|
831
|
+
AND membership.account_id = snapshot.account_id
|
|
832
|
+
AND membership.subject_id = admission_row.initiating_human_subject_id
|
|
833
|
+
AND membership.status = 'active'
|
|
834
|
+
AND membership.revoked_at IS NULL
|
|
835
|
+
AND membership.personal_workspace_id = snapshot.origin_workspace_id
|
|
836
|
+
AND membership.authorization_revision
|
|
837
|
+
= snapshot.membership_authorization_revision
|
|
838
|
+
)
|
|
839
|
+
AND EXISTS (
|
|
840
|
+
SELECT 1
|
|
841
|
+
FROM organization_user_resource_authorities authority
|
|
842
|
+
WHERE authority.id = snapshot.authority_id
|
|
843
|
+
AND authority.account_id = snapshot.account_id
|
|
844
|
+
AND authority.organization_membership_id
|
|
845
|
+
= snapshot.owner_organization_membership_id
|
|
846
|
+
AND authority.resource_kind = snapshot.resource_kind
|
|
847
|
+
AND authority.resource_id = snapshot.resource_id
|
|
848
|
+
AND authority.origin_workspace_id = snapshot.origin_workspace_id
|
|
849
|
+
AND authority.generation = snapshot.authority_generation
|
|
850
|
+
AND authority.status = 'active'
|
|
851
|
+
AND authority.revoked_at IS NULL
|
|
852
|
+
)
|
|
853
|
+
AND (
|
|
854
|
+
(
|
|
855
|
+
snapshot.resource_kind = 'variable_set'
|
|
856
|
+
AND EXISTS (
|
|
857
|
+
SELECT 1 FROM workspace_variable_sets variable_set
|
|
858
|
+
WHERE variable_set.id = snapshot.resource_id
|
|
859
|
+
AND variable_set.account_id = snapshot.account_id
|
|
860
|
+
AND variable_set.workspace_id = snapshot.origin_workspace_id
|
|
861
|
+
AND variable_set.authority_scope = 'user'
|
|
862
|
+
AND variable_set.authority_id = snapshot.authority_id
|
|
863
|
+
AND variable_set.owner_organization_membership_id
|
|
864
|
+
= snapshot.owner_organization_membership_id
|
|
865
|
+
AND variable_set.origin_workspace_id = snapshot.origin_workspace_id
|
|
866
|
+
)
|
|
867
|
+
) OR (
|
|
868
|
+
snapshot.resource_kind = 'rig'
|
|
869
|
+
AND EXISTS (
|
|
870
|
+
SELECT 1 FROM rigs rig
|
|
871
|
+
JOIN rig_versions rig_version
|
|
872
|
+
ON rig_version.id = snapshot.resource_version_id
|
|
873
|
+
AND rig_version.rig_id = rig.id
|
|
874
|
+
AND rig_version.account_id = rig.account_id
|
|
875
|
+
AND rig_version.workspace_id = snapshot.origin_workspace_id
|
|
876
|
+
WHERE rig.id = snapshot.resource_id
|
|
877
|
+
AND rig.account_id = snapshot.account_id
|
|
878
|
+
AND rig.workspace_id = snapshot.origin_workspace_id
|
|
879
|
+
AND rig.authority_scope = 'user'
|
|
880
|
+
AND rig.authority_id = snapshot.authority_id
|
|
881
|
+
AND rig.owner_organization_membership_id
|
|
882
|
+
= snapshot.owner_organization_membership_id
|
|
883
|
+
AND rig.origin_workspace_id = snapshot.origin_workspace_id
|
|
884
|
+
)
|
|
885
|
+
)
|
|
886
|
+
)
|
|
887
|
+
AND EXISTS (
|
|
888
|
+
SELECT 1
|
|
889
|
+
FROM organization_user_resource_grants grant_value
|
|
890
|
+
WHERE grant_value.id = snapshot.grant_id
|
|
891
|
+
AND grant_value.account_id = snapshot.account_id
|
|
892
|
+
AND grant_value.authority_id = snapshot.authority_id
|
|
893
|
+
AND grant_value.owner_organization_membership_id
|
|
894
|
+
= snapshot.owner_organization_membership_id
|
|
895
|
+
AND grant_value.workspace_id = snapshot.target_workspace_id
|
|
896
|
+
AND grant_value.action = snapshot.action
|
|
897
|
+
AND grant_value.mode = snapshot.grant_mode
|
|
898
|
+
AND grant_value.context = snapshot.grant_context
|
|
899
|
+
AND grant_value.generation = snapshot.grant_generation
|
|
900
|
+
AND grant_value.session_id IS NOT DISTINCT FROM snapshot.grant_session_id
|
|
901
|
+
AND grant_value.authority_epoch
|
|
902
|
+
IS NOT DISTINCT FROM snapshot.grant_authority_epoch
|
|
903
|
+
AND (grant_value.expires_at IS NULL OR grant_value.expires_at > clock_timestamp())
|
|
904
|
+
AND (
|
|
905
|
+
(
|
|
906
|
+
snapshot.grant_mode = 'once'
|
|
907
|
+
AND grant_value.status = 'consumed'
|
|
908
|
+
AND EXISTS (
|
|
909
|
+
SELECT 1 FROM personal_resource_once_consumption_receipts receipt
|
|
910
|
+
WHERE receipt.grant_id = snapshot.grant_id
|
|
911
|
+
AND receipt.account_id = snapshot.account_id
|
|
912
|
+
AND receipt.attempt_id = snapshot.attempt_id
|
|
913
|
+
AND receipt.authority_id = snapshot.authority_id
|
|
914
|
+
AND receipt.authority_generation = snapshot.authority_generation
|
|
915
|
+
AND receipt.grant_generation = snapshot.grant_generation
|
|
916
|
+
)
|
|
917
|
+
) OR (
|
|
918
|
+
snapshot.grant_mode IN ('session', 'always')
|
|
919
|
+
AND grant_value.status = 'active'
|
|
920
|
+
)
|
|
921
|
+
)
|
|
922
|
+
)
|
|
923
|
+
);
|
|
924
|
+
|
|
925
|
+
IF invalid_count <> 0 THEN
|
|
926
|
+
RAISE EXCEPTION 'personal-resource authority snapshot is no longer live'
|
|
927
|
+
USING ERRCODE = '42501';
|
|
928
|
+
END IF;
|
|
929
|
+
|
|
930
|
+
SELECT count(*)::integer INTO invalid_count
|
|
931
|
+
FROM session_attempt_personal_resource_snapshots snapshot
|
|
932
|
+
WHERE snapshot.attempt_id = admission_row.attempt_id;
|
|
933
|
+
IF invalid_count <> admission_row.resource_count THEN
|
|
934
|
+
RAISE EXCEPTION 'personal-resource snapshot collection is incomplete'
|
|
935
|
+
USING ERRCODE = '42501';
|
|
936
|
+
END IF;
|
|
937
|
+
|
|
938
|
+
RETURN QUERY
|
|
939
|
+
SELECT snapshot.resource_kind, snapshot.resource_id,
|
|
940
|
+
snapshot.resource_version_id, snapshot.selection_sources, snapshot.action,
|
|
941
|
+
snapshot.authority_id, snapshot.authority_generation, snapshot.grant_id,
|
|
942
|
+
snapshot.grant_generation, snapshot.grant_mode
|
|
943
|
+
FROM session_attempt_personal_resource_snapshots snapshot
|
|
944
|
+
WHERE snapshot.attempt_id = admission_row.attempt_id
|
|
945
|
+
ORDER BY snapshot.resource_kind, snapshot.resource_id;
|
|
946
|
+
|
|
947
|
+
DELETE FROM opengeni_private.personal_resource_delegation_capabilities
|
|
948
|
+
WHERE backend_pid = pg_catalog.pg_backend_pid()
|
|
949
|
+
AND transaction_id = pg_catalog.pg_current_xact_id_if_assigned()
|
|
950
|
+
AND capability_kind = 'resolve';
|
|
951
|
+
RETURN;
|
|
952
|
+
EXCEPTION WHEN OTHERS THEN
|
|
953
|
+
DELETE FROM opengeni_private.personal_resource_delegation_capabilities
|
|
954
|
+
WHERE backend_pid = pg_catalog.pg_backend_pid()
|
|
955
|
+
AND transaction_id = pg_catalog.pg_current_xact_id_if_assigned()
|
|
956
|
+
AND capability_kind = 'resolve';
|
|
957
|
+
RAISE;
|
|
958
|
+
END;
|
|
959
|
+
$body$;
|
|
960
|
+
$ddl$, data_schema);
|
|
961
|
+
|
|
962
|
+
EXECUTE format(
|
|
963
|
+
'DROP TRIGGER IF EXISTS session_attempt_personal_resource_admission '
|
|
964
|
+
|| 'ON %I.session_turn_attempts',
|
|
965
|
+
data_schema
|
|
966
|
+
);
|
|
967
|
+
EXECUTE format(
|
|
968
|
+
'CREATE TRIGGER session_attempt_personal_resource_admission '
|
|
969
|
+
|| 'AFTER INSERT ON %I.session_turn_attempts FOR EACH ROW '
|
|
970
|
+
|| 'EXECUTE FUNCTION %I.admit_session_attempt_personal_resources()',
|
|
971
|
+
data_schema,
|
|
972
|
+
data_schema
|
|
973
|
+
);
|
|
974
|
+
END
|
|
975
|
+
$personal_resource_delegation_functions$;
|
|
976
|
+
|
|
977
|
+
REVOKE ALL ON FUNCTION resolve_session_attempt_personal_resources(uuid, uuid, uuid)
|
|
978
|
+
FROM PUBLIC;
|
|
979
|
+
REVOKE ALL ON FUNCTION admit_session_attempt_personal_resources() FROM PUBLIC;
|
|
980
|
+
|
|
981
|
+
DO $personal_resource_runtime_grants$
|
|
982
|
+
BEGIN
|
|
983
|
+
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
|
|
984
|
+
GRANT EXECUTE ON FUNCTION resolve_session_attempt_personal_resources(uuid, uuid, uuid)
|
|
985
|
+
TO opengeni_app;
|
|
986
|
+
REVOKE ALL ON TABLE "session_attempt_personal_resource_admissions" FROM opengeni_app;
|
|
987
|
+
REVOKE ALL ON TABLE "session_attempt_personal_resource_snapshots" FROM opengeni_app;
|
|
988
|
+
REVOKE ALL ON TABLE "personal_resource_once_consumption_receipts" FROM opengeni_app;
|
|
989
|
+
END IF;
|
|
990
|
+
END
|
|
991
|
+
$personal_resource_runtime_grants$;
|
|
992
|
+
|
|
993
|
+
COMMENT ON TABLE "session_attempt_personal_resource_admissions" IS
|
|
994
|
+
'Exact accepted-attempt personal-resource authority receipt; no secrets or runtime materialization.';
|
|
995
|
+
COMMENT ON TABLE "session_attempt_personal_resource_snapshots" IS
|
|
996
|
+
'Normalized immutable direct/transitive personal-resource delegation collection for one accepted attempt.';
|
|
997
|
+
COMMENT ON TABLE "personal_resource_once_consumption_receipts" IS
|
|
998
|
+
'Unique first-use receipt binding one consumed once grant to its exact accepted attempt.';
|
|
999
|
+
COMMENT ON FUNCTION resolve_session_attempt_personal_resources(uuid, uuid, uuid) IS
|
|
1000
|
+
'Fail-closed exact-attempt authority revalidation and identifier-only personal-resource collection read.';
|