techne-sdk 0.1.0

TechneSDK's logic written once: version ranking (eventState) and offline record verification over the published check, shipped to TypeScript as WebAssembly; with opt-in atproto plumbing (service auth, DID resolution, signed labels, proven record fetches, PDS password sessions) behind the `crypto` and `net` features.
Documentation
//! In-network endpoints for a stack's OWN identities (`DID_ENDPOINT_OVERRIDES`).
//!
//! Ported from regenOS `regenos_indexer::endpoint_overrides` (P20.7 G4); behaviour unchanged.
//!
//! A DID document names where its repo lives (`#atproto_pds`) and, for `did:web`, the document is
//! itself fetched from the DID's host. Inside a deployment those public names point back at the very
//! stack that is resolving them. Following the public name sends every fetch out through the edge and
//! back.
//!
//! Two kinds of rewrite, with different trust:
//!   * a PDS origin `from=to`: when a DID document's `#atproto_pds` endpoint is `from`, repo reads go
//!     to `to` instead. The DID document is resolved exactly as before, so the key it names is
//!     unchanged. Where the reader verifies what it fetched against that key (`sync::fetch_proven`),
//!     a rewrite can make a fetch fail but never make a wrong record pass.
//!   * a `did:web:<host>=<base>`: that DID's document is fetched from `<base>/.well-known/did.json`
//!     (no redirects) and must carry `id` equal to the DID. This REPLACES the trust root: name only
//!     services the operator runs inside the same deployment network.
//!
//! Format: whitespace-separated `from=to` pairs; scheme and host are compared without case (stored
//! lowercased, so naming one origin twice in two cases is refused as a duplicate). Unset or empty
//! means no rewrite. A malformed value is never ignored, since a silently ignored override is a silent
//! hairpin: each reader parses it (through [`overrides_or_fail`]) before it starts any work.

/// The parsed `DID_ENDPOINT_OVERRIDES`.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct EndpointOverrides {
    /// `(public PDS origin, in-network origin)`, both without a trailing `/`, scheme and host lowercased.
    pds: Vec<(String, String)>,
    /// `(did:web host, in-network base URL)`, host lowercased, base without a trailing `/`.
    web: Vec<(String, String)>,
}

/// The variable this module reads.
pub const VAR: &str = "DID_ENDPOINT_OVERRIDES";

/// Why `DID_ENDPOINT_OVERRIDES` was refused.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OverrideError(String);

impl std::fmt::Display for OverrideError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "DID_ENDPOINT_OVERRIDES: {}", self.0)
    }
}

impl std::error::Error for OverrideError {}

/// A bare `http(s)://host[:port]` (no path, query, fragment, userinfo or second `=`), with its scheme
/// and host lowercased, so the duplicate check compares what matching (case-insensitive) compares.
fn origin(s: &str) -> Option<String> {
    let lower = s.to_ascii_lowercase();
    let rest = lower.strip_prefix("https://").or_else(|| lower.strip_prefix("http://"))?;
    (!rest.is_empty() && !rest.contains(['/', '?', '#', '@', '='])).then_some(lower)
}

/// `DID_ENDPOINT_OVERRIDES` for a binary's boot: every reader's `main` calls this before it connects
/// to anything or spawns any task, so a bad value stops it before it does any work. With `net`, logs
/// what is rewritten (names only; nothing here is secret).
pub fn overrides_or_fail() -> Result<EndpointOverrides, OverrideError> {
    let overrides = EndpointOverrides::from_env()?;
    #[cfg(feature = "net")]
    if !overrides.is_empty() {
        tracing::info!(overrides = %overrides.describe(), "reading these endpoints in-network ({VAR})");
    }
    Ok(overrides)
}

impl EndpointOverrides {
    /// No rewrites.
    pub fn none() -> Self {
        Self::default()
    }

    /// Parse the env var's value (see the module docs).
    pub fn parse(raw: &str) -> Result<Self, OverrideError> {
        let mut out = Self::default();
        for pair in raw.split_whitespace() {
            let (from, to) = pair
                .split_once('=')
                .ok_or_else(|| OverrideError(format!("`{pair}` is not `from=to`")))?;
            let to = to.trim_end_matches('/');
            let to = origin(to).ok_or_else(|| OverrideError(format!("`{to}` must be a bare http(s) origin")))?;
            if let Some(host) = from.strip_prefix("did:web:") {
                if host.is_empty() || host.contains(':') || host.contains('/') {
                    return Err(OverrideError(format!("`{from}`: only a host-only did:web is supported")));
                }
                let host = host.to_ascii_lowercase();
                if out.web.iter().any(|(h, _)| *h == host) {
                    return Err(OverrideError(format!("`{from}` is named twice")));
                }
                out.web.push((host, to));
            } else {
                let trimmed = from.trim_end_matches('/');
                let from = origin(trimmed)
                    .ok_or_else(|| OverrideError(format!("`{trimmed}` must be a bare http(s) origin or a did:web")))?;
                if out.pds.iter().any(|(f, _)| *f == from) {
                    return Err(OverrideError(format!("`{from}` is named twice")));
                }
                out.pds.push((from, to));
            }
        }
        Ok(out)
    }

    /// From `DID_ENDPOINT_OVERRIDES` (unset or empty: none; not UTF-8: refused).
    pub fn from_env() -> Result<Self, OverrideError> {
        Self::from_var(std::env::var(VAR))
    }

    /// [`Self::from_env`] over one `std::env::var` result.
    fn from_var(var: Result<String, std::env::VarError>) -> Result<Self, OverrideError> {
        match var {
            Ok(v) => Self::parse(&v),
            Err(std::env::VarError::NotPresent) => Ok(Self::none()),
            Err(std::env::VarError::NotUnicode(_)) => Err(OverrideError("the value is not UTF-8".into())),
        }
    }

    /// True when nothing is rewritten.
    pub fn is_empty(&self) -> bool {
        self.pds.is_empty() && self.web.is_empty()
    }

    /// The endpoint to read a repo from, given the `#atproto_pds` endpoint a document names. An
    /// origin that is not overridden is returned as is (minus a trailing `/`).
    pub fn pds(&self, endpoint: &str) -> String {
        let endpoint = endpoint.trim_end_matches('/');
        self.pds
            .iter()
            .find(|(from, _)| from.eq_ignore_ascii_case(endpoint))
            .map(|(_, to)| to.clone())
            .unwrap_or_else(|| endpoint.to_string())
    }

    /// Where to fetch `did`'s document instead of `https://<host>/.well-known/did.json`, when `did`
    /// is an overridden `did:web`.
    pub fn did_web_doc_url(&self, did: &str) -> Option<String> {
        let host = did.strip_prefix("did:web:")?;
        self.web
            .iter()
            .find(|(h, _)| h.eq_ignore_ascii_case(host))
            .map(|(_, base)| format!("{base}/.well-known/did.json"))
    }

    /// One line for the boot log (names only; nothing here is secret).
    pub fn describe(&self) -> String {
        let mut parts: Vec<String> = self.pds.iter().map(|(f, t)| format!("{f} -> {t}")).collect();
        parts.extend(self.web.iter().map(|(h, t)| format!("did:web:{h} -> {t}")));
        parts.join(", ")
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    const IN_NETWORK: &str = "https://pds.app.example=http://pds:3000 \
                              did:web:app.example=http://appview:8080/";

    #[test]
    fn unset_and_empty_rewrite_nothing() {
        let o = EndpointOverrides::parse("  ").unwrap();
        assert!(o.is_empty());
        assert_eq!(o.pds("https://pds.example/"), "https://pds.example");
        assert_eq!(o.did_web_doc_url("did:web:example.com"), None);
    }

    #[test]
    fn a_named_pds_origin_goes_in_network_and_others_are_untouched() {
        let o = EndpointOverrides::parse(IN_NETWORK).unwrap();
        assert_eq!(o.pds("https://pds.app.example"), "http://pds:3000");
        assert_eq!(o.pds("https://pds.app.example/"), "http://pds:3000");
        assert_eq!(o.pds("https://PDS.app.example"), "http://pds:3000");
        // A user's own PDS, and prod's, are never rewritten.
        assert_eq!(o.pds("https://bsky.social"), "https://bsky.social");
        assert_eq!(o.pds("https://pds.scenius.social"), "https://pds.scenius.social");
    }

    #[test]
    fn a_named_did_web_is_fetched_in_network_and_only_that_one() {
        let o = EndpointOverrides::parse(IN_NETWORK).unwrap();
        assert_eq!(
            o.did_web_doc_url("did:web:app.example").as_deref(),
            Some("http://appview:8080/.well-known/did.json")
        );
        assert_eq!(o.did_web_doc_url("did:web:rules.app.example"), None);
        assert_eq!(o.did_web_doc_url("did:plc:abc"), None);
        assert!(o.describe().contains("did:web:app.example -> http://appview:8080"));
    }

    #[test]
    fn malformed_values_are_refused_not_ignored() {
        for bad in [
            "https://pds.x",                         // no `=`
            "https://pds.x=pds:3000",                // target without a scheme
            "https://pds.x/xrpc=http://pds:3000",    // a path, not an origin
            "pds.x=http://pds:3000",                 // source without a scheme
            "did:web:a.example:8080=http://x:1",     // did:web with a port
            "did:web:=http://x:1",
            "https://a=http://b https://a=http://c", // named twice
            "https://pds.x=http://pds:3000=x",       // a second `=` in the target
            "https://pds.x=http://user@pds:3000",    // userinfo in the target
        ] {
            assert!(EndpointOverrides::parse(bad).is_err(), "{bad} must be refused");
        }
    }

    #[test]
    fn names_differing_only_in_case_are_one_name() {
        // Matching ignores case, so the duplicate check must too: otherwise the first silently wins.
        for twice in [
            "https://PDS.x=http://a:1 https://pds.x=http://b:2",
            "HTTPS://pds.x=http://a:1 https://pds.x/=http://b:2",
            "did:web:Example.com=http://a:1 did:web:example.com=http://b:2",
        ] {
            let err = EndpointOverrides::parse(twice).unwrap_err();
            assert!(err.to_string().contains("named twice"), "{twice}: {err}");
        }
        // Parsed names are stored lowercased (scheme and host), and still match any case.
        let o = EndpointOverrides::parse("HTTPS://PDS.X=HTTP://Pds:3000 did:web:Example.COM=http://AppView:8080").unwrap();
        assert_eq!(o.describe(), "https://pds.x -> http://pds:3000, did:web:example.com -> http://appview:8080");
        assert_eq!(o.pds("https://pds.x"), "http://pds:3000");
        assert_eq!(o.pds("https://Pds.X/"), "http://pds:3000");
        assert_eq!(o.did_web_doc_url("did:web:EXAMPLE.com").as_deref(), Some("http://appview:8080/.well-known/did.json"));
    }

    #[test]
    fn only_an_absent_variable_means_none() {
        assert_eq!(EndpointOverrides::from_var(Err(std::env::VarError::NotPresent)), Ok(EndpointOverrides::none()));
        #[cfg(unix)]
        {
            use std::os::unix::ffi::OsStringExt;
            let bad = std::ffi::OsString::from_vec(vec![0x66, 0xff]);
            assert!(EndpointOverrides::from_var(Err(std::env::VarError::NotUnicode(bad))).is_err(), "not UTF-8 is refused");
        }
        assert!(EndpointOverrides::from_var(Ok("nonsense".into())).is_err());
    }
}