fix: bound Subject database retention to synchronous plugin checks
This commit is contained in:
@@ -955,7 +955,9 @@ impl WorkspaceApi {
|
|||||||
"foreign Plugin Worker".into(),
|
"foreign Plugin Worker".into(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
plugin_execution_identity(&api, &worker).map_err(|error| error.error)
|
super::plugin_host::with_authority_database(&api, || {
|
||||||
|
plugin_execution_identity(&api, &worker).map_err(|error| error.error)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,6 +134,20 @@ fn operation_name(op: &PluginHostOperation) -> &'static str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retain the physical Subject database only for this synchronous check. Each
|
||||||
|
/// policy/lineage query still reads its owner; no authorization result or lock
|
||||||
|
/// survives the closure, and FeatureStorage continues to enforce lifecycle fences.
|
||||||
|
pub(super) fn with_authority_database<T>(
|
||||||
|
api: &WorkspaceApi,
|
||||||
|
check: impl FnOnce() -> crate::Result<T>,
|
||||||
|
) -> crate::Result<T> {
|
||||||
|
let _database = api
|
||||||
|
.feature_storage
|
||||||
|
.open(&api.subjektiv_registration)
|
||||||
|
.map_err(|error| Error::Store(error.to_string()))?;
|
||||||
|
check()
|
||||||
|
}
|
||||||
|
|
||||||
async fn check(
|
async fn check(
|
||||||
api: Arc<WorkspaceApi>,
|
api: Arc<WorkspaceApi>,
|
||||||
context: ServerRequestContext,
|
context: ServerRequestContext,
|
||||||
@@ -220,28 +234,31 @@ async fn check_tools(
|
|||||||
let executor = api.config_store.db_executor();
|
let executor = api.config_store.db_executor();
|
||||||
executor
|
executor
|
||||||
.run(move || {
|
.run(move || {
|
||||||
subject_authorization::authorize_scope(
|
with_authority_database(&api, || {
|
||||||
&api,
|
subject_authorization::authorize_scope(
|
||||||
&worker,
|
&api,
|
||||||
&server_api::authorization::OperationAuthorizationRequest {
|
&worker,
|
||||||
operation: operation_name(&operation).into(),
|
&server_api::authorization::OperationAuthorizationRequest {
|
||||||
resource: server_api::authorization::PermissionResource::PluginInstallation {
|
operation: operation_name(&operation).into(),
|
||||||
workspace_id: workspace.clone(),
|
resource:
|
||||||
installation_id: installation.clone(),
|
server_api::authorization::PermissionResource::PluginInstallation {
|
||||||
|
workspace_id: workspace.clone(),
|
||||||
|
installation_id: installation.clone(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
)
|
|
||||||
.map_err(|e| e.error)?;
|
|
||||||
api.config_store.with_immediate_transaction(|tx| {
|
|
||||||
policy::authorize(
|
|
||||||
tx,
|
|
||||||
&workspace,
|
|
||||||
&execution,
|
|
||||||
&plan_id,
|
|
||||||
&installation,
|
|
||||||
&tools,
|
|
||||||
&operation,
|
|
||||||
)
|
)
|
||||||
|
.map_err(|e| e.error)?;
|
||||||
|
api.config_store.with_immediate_transaction(|tx| {
|
||||||
|
policy::authorize(
|
||||||
|
tx,
|
||||||
|
&workspace,
|
||||||
|
&execution,
|
||||||
|
&plan_id,
|
||||||
|
&installation,
|
||||||
|
&tools,
|
||||||
|
&operation,
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -31,30 +31,32 @@ async fn check_service(
|
|||||||
let executor = api.config_store.db_executor();
|
let executor = api.config_store.db_executor();
|
||||||
executor
|
executor
|
||||||
.run(move || {
|
.run(move || {
|
||||||
for op in ["plugin.service.consume", operation_name(&operation)] {
|
with_authority_database(&api, || {
|
||||||
subject_authorization::authorize_scope(
|
for op in ["plugin.service.consume", operation_name(&operation)] {
|
||||||
&api,
|
subject_authorization::authorize_scope(
|
||||||
&worker,
|
&api,
|
||||||
&OperationAuthorizationRequest {
|
&worker,
|
||||||
operation: op.into(),
|
&OperationAuthorizationRequest {
|
||||||
resource: PermissionResource::PluginInstallation {
|
operation: op.into(),
|
||||||
workspace_id: workspace.clone(),
|
resource: PermissionResource::PluginInstallation {
|
||||||
installation_id: installation.clone(),
|
workspace_id: workspace.clone(),
|
||||||
|
installation_id: installation.clone(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
)
|
||||||
)
|
.map_err(|e| e.error)?;
|
||||||
.map_err(|e| e.error)?;
|
}
|
||||||
}
|
api.config_store.with_immediate_transaction(|tx| {
|
||||||
api.config_store.with_immediate_transaction(|tx| {
|
policy::authorize_service(
|
||||||
policy::authorize_service(
|
tx,
|
||||||
tx,
|
&workspace,
|
||||||
&workspace,
|
&execution,
|
||||||
&execution,
|
&plan_id,
|
||||||
&plan_id,
|
&installation,
|
||||||
&installation,
|
&name,
|
||||||
&name,
|
&operation,
|
||||||
&operation,
|
)
|
||||||
)
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
|
|||||||
Reference in New Issue
Block a user