plexus_core/plexus/auth.rs
1//! Authentication primitives — relocated to `plexus-auth-core`.
2//!
3//! Per AUTHZ-CORE-CRATE-1, the canonical home for the Plexus auth sealed
4//! types is now the `plexus-auth-core` crate. plexus-core re-exports them
5//! here so existing call sites keep compiling during the deprecation
6//! window. New code should import directly from `plexus_auth_core`.
7//!
8//! See `plans/AUTHZ/AUTHZ-CORE-CRATE-1.md` and AUTHZ-0 for rationale.
9
10pub use plexus_auth_core::{AuthContext, Principal, ServiceIdentity, SessionValidator, VerifiedUser};
11
12// AUTHLANG-2 — forwarding-policy primitives. Re-exported so consumers
13// of plexus-core can reference them without taking a direct
14// dependency on plexus-auth-core. New code should import directly
15// from plexus_auth_core; these re-exports exist for symmetry with the
16// existing AuthContext / Principal re-exports.
17pub use plexus_auth_core::{
18 Anonymous, CallSite, ForwardDerivation, ForwardPolicy, ForwardPolicyName,
19 IdentityOnly, MethodPath, MethodPathError, PassThrough,
20 ANONYMOUS_NAME, IDENTITY_ONLY_NAME, PASS_THROUGH_NAME,
21};
22
23// Note on `#[deprecated]`:
24//
25// We intentionally do NOT mark the `pub use` re-exports above with
26// `#[deprecated(...)]`. Doing so would emit a deprecation warning at every
27// call site across plexus-trak, plexus-transport, plexus-substrate, and
28// roughly two dozen other places — many of which carry `warnings = "deny"`
29// at the crate level (e.g. plexus-substrate/Cargo.toml). The sudden flip
30// would block builds everywhere. The deprecation hint lives here as a doc
31// comment on each module-level item; an `#[deprecated]` attribute will be
32// added in the follow-up ticket that also migrates the call sites in
33// lockstep. (See plans/AUTHZ/AUTHZ-CORE-CRATE-1-RUN-NOTES.md for the
34// detailed reasoning.)
35
36/// Re-export of `plexus_auth_core::AuthContext`.
37///
38/// **Deprecated:** import directly from `plexus_auth_core::AuthContext`.
39/// This re-export exists for backward compatibility during the migration
40/// window and will be removed in a future major release.
41#[doc(hidden)]
42pub fn _deprecation_hint_for_auth_context() {}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 /// Smoke test: the re-exported AuthContext keeps the public API
49 /// callers depend on (constructor, anonymous, role check, tenant).
50 /// This is the migration's no-functional-change canary.
51 #[test]
52 fn reexport_preserves_auth_context_api() {
53 let ctx = AuthContext::new(
54 "user-1".into(),
55 "sess-1".into(),
56 vec!["admin".into()],
57 serde_json::json!({"tenant_id": "acme"}),
58 );
59
60 assert_eq!(ctx.user_id, "user-1");
61 assert_eq!(ctx.session_id, "sess-1");
62 assert!(ctx.has_role("admin"));
63 assert!(!ctx.has_role("guest"));
64 assert_eq!(ctx.tenant(), Some("acme".into()));
65 assert!(ctx.is_authenticated());
66
67 let anon = AuthContext::anonymous();
68 assert!(!anon.is_authenticated());
69 assert_eq!(anon.user_id, "anonymous");
70 }
71
72 /// SessionValidator trait is callable through the re-export.
73 #[tokio::test]
74 async fn reexport_preserves_session_validator() {
75 struct Stub;
76 #[async_trait::async_trait]
77 impl SessionValidator for Stub {
78 async fn validate(&self, cookie: &str) -> Option<AuthContext> {
79 if cookie == "ok" {
80 Some(AuthContext::new(
81 "u".into(),
82 "s".into(),
83 vec![],
84 serde_json::Value::Null,
85 ))
86 } else {
87 None
88 }
89 }
90 }
91
92 let v = Stub;
93 assert!(v.validate("ok").await.is_some());
94 assert!(v.validate("nope").await.is_none());
95 }
96}