Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions nodedb/src/control/security/request_scope/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,15 +542,15 @@ mod tests {

let inside = RequestAuthScope::builder(&identity, stores)
.build_for_client("10.0.0.1:5432")
.into_scope();
.into_resolved_scope();
assert_eq!(
inside.auth().metadata.get("scope_status.pro:all"),
Some(&nodedb_types::Value::String("active".into()))
);

let outside = RequestAuthScope::builder(&identity, stores)
.build_for_client("203.0.113.9:5432")
.into_scope();
.into_resolved_scope();
assert!(
!outside.auth().metadata.contains_key("scope_status.pro:all"),
"a request from outside the permitted network must not get the scope"
Expand Down Expand Up @@ -624,7 +624,7 @@ mod tests {

let scope = RequestAuthScope::builder(&identity, stores)
.build_for_client("10.0.0.1:5432")
.into_scope();
.into_resolved_scope();

assert_eq!(scope.auth().risk_score, None);
}
Expand All @@ -639,7 +639,7 @@ mod tests {

let scope = RequestAuthScope::builder(&identity, stores)
.build_for_client("10.0.0.1:5432")
.into_scope();
.into_resolved_scope();

let score = scope
.auth()
Expand Down Expand Up @@ -668,7 +668,7 @@ mod tests {

let scope = RequestAuthScope::builder(&identity, stores)
.build_for_client("10.0.0.1:5432")
.into_scope();
.into_resolved_scope();

let refusal = scorer
.refusal_for(scope.auth())
Expand All @@ -689,7 +689,7 @@ mod tests {

let scope = RequestAuthScope::builder(&identity, stores)
.build_for_client("http")
.into_scope();
.into_resolved_scope();

assert_eq!(scope.auth().risk_score, None);
assert!(scorer.refusal_for(scope.auth()).is_some());
Expand All @@ -713,7 +713,7 @@ mod tests {

let scope = RequestAuthScope::builder(&identity, stores)
.build_for_client("10.0.0.1:5432")
.into_scope();
.into_resolved_scope();

assert_eq!(scope.auth().risk_score, None);
}
Expand Down
12 changes: 9 additions & 3 deletions nodedb/src/control/security/request_scope/client_scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,13 @@ impl<'a, 'p> ClientRequestScope<'a, 'p> {
}

/// Consume the binding once admission has run, keeping the scope.
pub fn into_scope(self) -> RequestAuthScope<'a> {
///
/// Named apart from `AuthorizedCapability::into_scope`: that one consumes a
/// granted capability, while this only unwraps the address it was resolved
/// against. The authorized-dispatch gate forbids the capability API by
/// name in external transports, so a second `into_scope` here would read as
/// every transport bypassing authorization.
pub fn into_resolved_scope(self) -> RequestAuthScope<'a> {
self.scope
}
}
Expand Down Expand Up @@ -173,7 +179,7 @@ mod tests {
}

#[test]
fn into_scope_keeps_the_resolved_scope() {
fn into_resolved_scope_keeps_the_resolved_scope() {
let identity = identity();
let grants = ScopeGrantStore::new();
let quotas = QuotaManager::new();
Expand All @@ -186,7 +192,7 @@ mod tests {
DatabaseId::new(9),
"10.0.0.1:5432",
)
.into_scope();
.into_resolved_scope();

assert_eq!(scope.database_id(), DatabaseId::new(9));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub async fn query(
&request,
"sql",
)?;
let scope = request.into_scope();
let scope = request.into_resolved_scope();
let rate_limit_headers =
super::super::super::rate_limit_headers::rate_limit_headers(&rate_limit_result);

Expand Down
2 changes: 1 addition & 1 deletion nodedb/src/control/server/http/routes/query/ndjson.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub async fn query_ndjson(
Ok(result) => result,
Err(error) => return ApiError::from(error).into_response(),
};
let scope = request.into_scope();
let scope = request.into_resolved_scope();
let rate_limit_headers =
super::super::super::rate_limit_headers::rate_limit_headers(&rate_limit_result);

Expand Down
6 changes: 4 additions & 2 deletions nodedb/src/control/server/http/routes/ws_rpc/execute_sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ pub async fn execute_sql(
// success; a denial still fails the request closed via `?`.
crate::control::server::session_auth::check_request_admission(shared, &request, "sql")?;

let (clean_sql, scope) =
crate::control::server::session_auth::apply_per_query_on_deny(sql, request.into_scope());
let (clean_sql, scope) = crate::control::server::session_auth::apply_per_query_on_deny(
sql,
request.into_resolved_scope(),
);
// Planning and lease admission run as one retried unit so a descriptor
// drain starting between them is absorbed rather than surfaced. The scope
// is retained through every orchestrated or Data-Plane execution and
Expand Down
2 changes: 1 addition & 1 deletion nodedb/src/control/server/ilp_batch/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ async fn flush_ilp_batch_inner(
// read differently on this transport than it does on a planned `INSERT`.
let scope =
ClientRequestScope::for_database(identity, state.auth_stores(), database_id, peer_addr)
.into_scope();
.into_resolved_scope();
crate::control::planner::rls_injection::inject_rls(&mut tasks, &state.rls, scope.auth())?;

// A spent hard quota refuses the batch before any of it is staged. The
Expand Down
2 changes: 1 addition & 1 deletion nodedb/src/control/server/native/session/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ impl NativeSession {
let ctx = DispatchCtx {
state: &self.state,
identity,
scope: request_scope.into_scope(),
scope: request_scope.into_resolved_scope(),
query_ctx: &self.query_ctx,
sessions: &self.sessions,
peer_addr: &self.peer_addr,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ impl NodeDbPgHandler {
// immediately.
let scope = scope_builder
.build_for_client(&peer_addr.to_string())
.into_scope();
.into_resolved_scope();

// Request-admission already ran once for this statement in
// `execute_single_sql`, before it branched to `shared::ddl::dispatch`
Expand Down
2 changes: 1 addition & 1 deletion nodedb/src/control/server/resp/gateway_dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ fn authorize_resp_task(
// call covers the whole protocol, including the IP-blacklist half via
// `session.peer_addr` (set at connection accept).
crate::control::server::session_auth::check_request_admission(state, &request, operation)?;
let scope = request.into_scope();
let scope = request.into_resolved_scope();

// Row-level security is injected here, before the capability is minted, for
// the same reason the native path injects before dispatch: the plan the
Expand Down
4 changes: 2 additions & 2 deletions nodedb/src/control/server/shared/ddl/user_dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ fn authorize_for_identity(
&request,
operation_for_plan(&plan),
)?;
request.into_scope()
request.into_resolved_scope()
}
};

Expand Down Expand Up @@ -234,7 +234,7 @@ fn resolve_dispatch_scope<'a>(
match admission {
RequestAdmission::AlreadyAdmitted => builder.build(),
RequestAdmission::NotYetAdmitted { peer_addr } => {
builder.build_for_client(peer_addr).into_scope()
builder.build_for_client(peer_addr).into_resolved_scope()
}
}
}
Expand Down
1 change: 1 addition & 0 deletions scripts/ci/check_authorized_dispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
("control/array_sync/inbound_propose.rs", "into_scope"),
("control/array_sync/snapshot_assembly.rs", "into_scope"),
("control/server/native/dispatch/sql_loop.rs", "into_physical_task"),
("control/server/native/dispatch/sql_dispatch_task.rs", "into_physical_task"),
("control/server/sync/raft_dispatch/response.rs", "propose_sync_write"),
("control/server/sync/raft_dispatch/write.rs", "propose_sync_write"),
(
Expand Down
2 changes: 1 addition & 1 deletion scripts/ci/check_reconstructed_sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"json_value_to_sql_literal",
},
"control/event_trigger.rs": {"canonical_trigger_template_sql"},
"control/scatter_gather.rs": {
"control/scatter_gather/remote_sql.rs": {
"canonical_direction_sql",
"canonical_label_sql",
},
Expand Down
Loading