field_ios

In-the-field app for Radroots on iOS
git clone https://radroots.dev/git/field_ios.git
Log | Files | Refs | README | LICENSE

commit 38dfa7fe45dc666f8ebc0b35a85cdbfa7b12033b
parent 069280fcf16c68d4f33e75d8de78c02e5d0ccad1
Author: triesap <tyson@radroots.org>
Date:   Sat,  8 Aug 2026 20:47:20 +0000

blossom: bind uploads to canonical endpoint authority

Separate host execution context from endpoint trust authority. Derive upload destinations in Rust, bind authorization and transfer to complete configuration fingerprints, and remove caller-owned remote URLs from prepared media inputs.

Diffstat:
Mcore/crates/tera_core/src/runtime/builder.rs | 30++++++++++++++++++++++++------
Mcore/crates/tera_core/src/runtime/product_surface/outbox.rs | 19+++++++++++--------
Mcore/crates/tera_core/src/runtime/sdk.rs | 114++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
3 files changed, 113 insertions(+), 50 deletions(-)

diff --git a/core/crates/tera_core/src/runtime/builder.rs b/core/crates/tera_core/src/runtime/builder.rs @@ -165,21 +165,39 @@ mod tests { ); assert!( runtime - .configure_simulator_blossom(vec!["http://127.0.0.1:3000".to_owned()]) + .configure_blossom( + radroots_sdk::transport::BlossomHostKind::Simulator, + radroots_sdk::transport::BlossomEndpointAuthority::LoopbackDevelopment, + "http://127.0.0.1:3000".to_owned(), + vec![], + ) .is_ok() ); assert_eq!( - runtime.sdk_blossom_profile().expect("Blossom profile"), - Some("simulator_local".to_owned()) + runtime + .sdk_blossom_configuration() + .expect("Blossom profile") + .expect("configured") + .host_kind, + "simulator" ); assert!( runtime - .configure_public_blossom(vec!["http://127.0.0.1:3000".to_owned()]) + .configure_blossom( + radroots_sdk::transport::BlossomHostKind::PhysicalDevice, + radroots_sdk::transport::BlossomEndpointAuthority::PublicWebPki, + "http://127.0.0.1:3000".to_owned(), + vec![], + ) .is_err() ); assert_eq!( - runtime.sdk_blossom_profile().expect("unchanged profile"), - Some("simulator_local".to_owned()) + runtime + .sdk_blossom_configuration() + .expect("unchanged profile") + .expect("configured") + .host_kind, + "simulator" ); runtime.shutdown().await.expect("shutdown"); } diff --git a/core/crates/tera_core/src/runtime/product_surface/outbox.rs b/core/crates/tera_core/src/runtime/product_surface/outbox.rs @@ -1291,7 +1291,15 @@ impl RadrootsRuntime { transfer_cancellation: radroots_sdk::transport::BlossomCancellation, updated_at_unix_ms: u64, ) -> Result<Phase1DraftStatus, Phase1DraftError> { - let url = request.expected_url().as_str().to_owned(); + let blossom = self + .client + .blossom() + .map_err(|_| Phase1DraftError::OperationUnavailable)? + .ok_or(Phase1DraftError::OperationUnavailable)?; + let transaction = blossom + .prepare_upload(request) + .map_err(|_| Phase1DraftError::Operation)?; + let url = transaction.expected_url().as_str().to_owned(); let uploading = self .phase1_update_draft_media( draft_id, @@ -1303,13 +1311,8 @@ impl RadrootsRuntime { ) .await?; let revision = uploading.draft().revision().get(); - let blossom = self - .client - .blossom() - .map_err(|_| Phase1DraftError::OperationUnavailable)? - .ok_or(Phase1DraftError::OperationUnavailable)?; let claim = match blossom.authored_upload_claim( - &request, + &transaction, authorization_content, authorization_created_at_unix_s, authorization_lifetime_seconds, @@ -1353,7 +1356,7 @@ impl RadrootsRuntime { } }; match blossom - .upload(request, authorization, transfer_cancellation) + .upload(transaction, authorization, transfer_cancellation) .await { Ok(receipt) => { diff --git a/core/crates/tera_core/src/runtime/sdk.rs b/core/crates/tera_core/src/runtime/sdk.rs @@ -42,6 +42,15 @@ pub struct SdkRelayStatusReportRecord { } #[derive(Clone, Debug, Eq, PartialEq)] +pub struct SdkBlossomConfigurationRecord { + pub host_kind: String, + pub endpoint_authority: String, + pub primary_origin: String, + pub fallback_origins: Vec<String>, + pub config_fingerprint: String, +} + +#[derive(Clone, Debug, Eq, PartialEq)] pub struct SdkShutdownRecord { pub state: String, pub already_closed: bool, @@ -122,33 +131,23 @@ impl RadrootsRuntime { .map_err(RadrootsAppError::from_sdk) } - /// Installs explicit public TLS Blossom origins without probing them. + /// Installs one canonical inert Blossom configuration without probing it. #[cfg(feature = "mobile-social")] - pub fn configure_public_blossom(&self, origins: Vec<String>) -> Result<(), RadrootsAppError> { - self.configure_blossom_profile( - radroots_sdk::transport::BlossomProfile::public(origins) - .map_err(|error| RadrootsAppError::runtime(error.code().to_owned()))?, - ) - } - - /// Installs exact-loopback simulator Blossom origins without probing them. - #[cfg(feature = "mobile-social")] - pub fn configure_simulator_blossom( + pub fn configure_blossom( &self, - origins: Vec<String>, + host_kind: radroots_sdk::transport::BlossomHostKind, + endpoint_authority: radroots_sdk::transport::BlossomEndpointAuthority, + primary_origin: String, + fallback_origins: Vec<String>, ) -> Result<(), RadrootsAppError> { self.configure_blossom_profile( - radroots_sdk::transport::BlossomProfile::simulator(origins) - .map_err(|error| RadrootsAppError::runtime(error.code().to_owned()))?, - ) - } - - /// Installs explicit physical-device TLS Blossom origins without probing them. - #[cfg(feature = "mobile-social")] - pub fn configure_device_blossom(&self, origins: Vec<String>) -> Result<(), RadrootsAppError> { - self.configure_blossom_profile( - radroots_sdk::transport::BlossomProfile::device(origins) - .map_err(|error| RadrootsAppError::runtime(error.code().to_owned()))?, + radroots_sdk::transport::BlossomProfile::new( + host_kind, + endpoint_authority, + primary_origin, + fallback_origins, + ) + .map_err(|error| RadrootsAppError::runtime(error.code().to_owned()))?, ) } @@ -164,23 +163,40 @@ impl RadrootsRuntime { .map_err(RadrootsAppError::from_sdk) } - /// Returns the inert Blossom environment profile, when configured. + /// Returns the configured adapter slot for Rust-owned media binding. + #[cfg(feature = "mobile-social")] + pub fn sdk_blossom_slot( + &self, + ) -> Result<Option<radroots_sdk::transport::BlossomSlot>, RadrootsAppError> { + self.client + .blossom() + .map(|slot| slot.cloned()) + .map_err(RadrootsAppError::from_sdk) + } + + /// Returns the complete inert Blossom configuration, when configured. #[cfg(feature = "mobile-social")] - pub fn sdk_blossom_profile(&self) -> Result<Option<String>, RadrootsAppError> { - let profile = self + pub fn sdk_blossom_configuration( + &self, + ) -> Result<Option<SdkBlossomConfigurationRecord>, RadrootsAppError> { + let configuration = self .client .blossom() .map_err(RadrootsAppError::from_sdk)? - .and_then(radroots_sdk::transport::BlossomSlot::profile_kind); - Ok(profile.map(|profile| { - match profile { - radroots_sdk::transport::BlossomProfileKind::Public => "public", - radroots_sdk::transport::BlossomProfileKind::Simulator => "simulator_local", - radroots_sdk::transport::BlossomProfileKind::Device => "device_development", - _ => "unknown", - } - .to_owned() - })) + .and_then(radroots_sdk::transport::BlossomSlot::configuration); + Ok( + configuration.map(|(profile, fingerprint)| SdkBlossomConfigurationRecord { + host_kind: blossom_host_kind_label(profile.host_kind()).to_owned(), + endpoint_authority: blossom_authority_label(profile.authority()).to_owned(), + primary_origin: profile.primary().origin().to_owned(), + fallback_origins: profile + .fallbacks() + .iter() + .map(|endpoint| endpoint.origin().to_owned()) + .collect(), + config_fingerprint: fingerprint.to_hex(), + }), + ) } /// Returns passive relay evidence without DNS, socket, or probe work. @@ -220,6 +236,32 @@ impl RadrootsRuntime { } #[cfg(feature = "mobile-social")] +const fn blossom_host_kind_label(value: radroots_sdk::transport::BlossomHostKind) -> &'static str { + match value { + radroots_sdk::transport::BlossomHostKind::Native => "native", + radroots_sdk::transport::BlossomHostKind::Simulator => "simulator", + radroots_sdk::transport::BlossomHostKind::PhysicalDevice => "physical_device", + _ => "unknown", + } +} + +#[cfg(feature = "mobile-social")] +const fn blossom_authority_label( + value: radroots_sdk::transport::BlossomEndpointAuthority, +) -> &'static str { + match value { + radroots_sdk::transport::BlossomEndpointAuthority::PublicWebPki => "public_webpki", + radroots_sdk::transport::BlossomEndpointAuthority::LoopbackDevelopment => { + "loopback_development" + } + radroots_sdk::transport::BlossomEndpointAuthority::PrivateNetworkDevelopment => { + "private_network_development" + } + _ => "unknown", + } +} + +#[cfg(feature = "mobile-social")] const fn relay_evidence_label(value: radroots_sdk::transport::RelayEvidenceState) -> &'static str { match value { radroots_sdk::transport::RelayEvidenceState::Unsupported => "unsupported",