Skip to main content

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}