diff --git a/crates/bindings/src/http.rs b/crates/bindings/src/http.rs index ec476bba46e..0fb8a63d53b 100644 --- a/crates/bindings/src/http.rs +++ b/crates/bindings/src/http.rs @@ -127,18 +127,24 @@ impl HandlerContext { } /// Read the current module's [`Identity`]. + #[deprecated(note = "Use `HandlerContext::database_identity` instead.")] pub fn identity(&self) -> Identity { + self.database_identity() + } + + /// Read the current module's [`Identity`]. + pub fn database_identity(&self) -> Identity { Identity::from_byte_array(spacetimedb_bindings_sys::identity()) } /// Acquire a mutable transaction and execute `body` with read-write access. pub fn with_tx(&mut self, body: impl Fn(&TxContext) -> T) -> T { - with_tx(body) + with_tx(body, Identity::ZERO, None) } /// Acquire a mutable transaction and execute `body` with read-write access. pub fn try_with_tx(&mut self, body: impl Fn(&TxContext) -> Result) -> Result { - try_with_tx(body) + try_with_tx(body, Identity::ZERO, None) } /// Create a new random [`Uuid`] `v4` using the built-in RNG. diff --git a/crates/bindings/src/lib.rs b/crates/bindings/src/lib.rs index 62b78e14be4..0d375719829 100644 --- a/crates/bindings/src/lib.rs +++ b/crates/bindings/src/lib.rs @@ -1180,7 +1180,14 @@ impl Deref for TxContext { } } -fn try_with_tx(body: impl Fn(&TxContext) -> Result) -> Result { +/// We need to passthrough identity and connection_id because procedures can be invoked by users. +/// For [HttpContext] this is always anonymous ([Identity::ZERO]). +/// Construct the inner [ReducerContext] with the appropriate caller information. +fn try_with_tx( + body: impl Fn(&TxContext) -> Result, + identity: Identity, + connection_id: Option, +) -> Result { let abort = || { crate::sys::procedure::procedure_abort_mut_tx() .expect("should have a pending mutable anon tx as `procedure_start_mut_tx` preceded") @@ -1191,8 +1198,7 @@ fn try_with_tx(body: impl Fn(&TxContext) -> Result) -> Result .expect("holding `&mut HandlerContext`, so should not be in a tx already; called manually elsewhere?"); let timestamp = Timestamp::from_micros_since_unix_epoch(timestamp); - // Use the internal auth context (no external caller identity). - let tx = ReducerContext::new(crate::Local {}, Identity::ZERO, None, timestamp); + let tx = ReducerContext::new(crate::Local {}, identity, connection_id, timestamp); let tx = TxContext(tx); struct DoOnDrop(F); @@ -1225,9 +1231,9 @@ fn try_with_tx(body: impl Fn(&TxContext) -> Result) -> Result res } -fn with_tx(body: impl Fn(&TxContext) -> T) -> T { +fn with_tx(body: impl Fn(&TxContext) -> T, identity: Identity, connection_id: Option) -> T { use core::convert::Infallible; - match try_with_tx::(|tx| Ok(body(tx))) { + match try_with_tx::(|tx| Ok(body(tx)), identity, connection_id) { Ok(v) => v, Err(e) => match e {}, } @@ -1293,7 +1299,13 @@ impl ProcedureContext { } /// Read the current module's [`Identity`]. + #[deprecated(note = "Use `ProcedureContext::database_identity` instead.")] pub fn identity(&self) -> Identity { + self.database_identity() + } + + /// Read the current module's [`Identity`]. + pub fn database_identity(&self) -> Identity { // Hypothetically, we *could* read the module identity out of the system tables. // However, this would be: // - Onerous, because we have no tooling to inspect the system tables from module code. @@ -1359,7 +1371,7 @@ impl ProcedureContext { /// callers should avoid writing to any captured mutable state within `body`, /// This includes interior mutability through types like [`std::cell::Cell`]. pub fn with_tx(&mut self, body: impl Fn(&TxContext) -> T) -> T { - with_tx(body) + with_tx(body, self.sender(), self.connection_id()) } /// Acquire a mutable transaction @@ -1392,7 +1404,7 @@ impl ProcedureContext { /// callers should avoid writing to any captured mutable state within `body`, /// This includes interior mutability through types like [`std::cell::Cell`]. pub fn try_with_tx(&mut self, body: impl Fn(&TxContext) -> Result) -> Result { - try_with_tx(body) + try_with_tx(body, self.sender(), self.connection_id()) } /// Create a new random [`Uuid`] `v4` using the built-in RNG. diff --git a/modules/module-test/src/lib.rs b/modules/module-test/src/lib.rs index 56e6b288e2d..3cf7b75d099 100644 --- a/modules/module-test/src/lib.rs +++ b/modules/module-test/src/lib.rs @@ -543,7 +543,7 @@ fn with_tx(ctx: &mut ProcedureContext) { /// This is a silly thing to do, but an effective test of the procedure HTTP API. #[spacetimedb::procedure] fn get_my_schema_via_http(ctx: &mut ProcedureContext) -> String { - let module_identity = ctx.identity(); + let module_identity = ctx.database_identity(); match ctx.http.get(format!( "http://localhost:3000/v1/database/{module_identity}/schema?version=9" )) { diff --git a/modules/sdk-test-procedure/src/lib.rs b/modules/sdk-test-procedure/src/lib.rs index 2c51e7ee26f..a8befa92e3b 100644 --- a/modules/sdk-test-procedure/src/lib.rs +++ b/modules/sdk-test-procedure/src/lib.rs @@ -42,7 +42,7 @@ fn will_panic(_ctx: &mut ProcedureContext) { #[procedure] fn read_my_schema(ctx: &mut ProcedureContext, server_url: String) -> String { - let module_identity = ctx.identity(); + let module_identity = ctx.database_identity(); let server_url = server_url.trim_end_matches('/'); match ctx .http