pub fn redact_userinfo(raw: &str) -> StringExpand description
Replaces any embedded user:pass@/user@ userinfo component in raw with a fixed
***@ marker, for a caller to log or retain instead of the raw credential-bearing value.
A userinfo-bearing index URL is always rejected (IndexUrlError::UserInfoPresent), but
the raw value naming what was rejected must never itself carry the credential through to
a tracing::warn! line or an InvalidEntry-shaped struct’s raw field a user might see
surfaced as DependencySource::CustomRegistry’s url in hover/diagnostics text. A fixed
marker (rather than stripping the component outright) keeps the redacted value visibly
distinct from a URL that never carried userinfo at all, so a user can still tell that a
credential was present and removed, without ever seeing what it was. Shared by
deps-npm’s and deps-pypi’s resolve_entry (M1 fix).
raw failing url::Url::parse is not proof it carries no userinfo (S1 finding) — an
otherwise-valid user:pass@host can still fail to parse for a reason unrelated to the
userinfo component itself (an invalid port, a malformed IPv6 literal, a non-ASCII host, or
simply a missing scheme — #536 C2), so this falls back to a parse-independent redaction
rather than returning raw untouched; the fallback scans from the :// scheme separator
when one is present, or from the very start of raw otherwise. Returns raw unchanged only
when that scan finds no @ at all — nothing looks like a userinfo component to redact.
§Examples
use deps_core::net_policy::redact_userinfo;
assert_eq!(
redact_userinfo("https://user:hunter2@registry.example/simple"),
"https://***@registry.example/simple"
);
assert_eq!(
redact_userinfo("https://registry.example/simple"),
"https://registry.example/simple"
);
assert_eq!(
redact_userinfo("user:hunter2@registry.example/simple"),
"***@registry.example/simple"
);