1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//! Axum integration (enabled by the `axum` feature).
//!
//! Praetor never validates JWTs or authenticates requests. The application's
//! own middleware is responsible for validating the request, building an
//! [`Ability`](crate::Ability), and inserting it into the request extensions as
//! an `Arc`:
//!
//! ```no_run
//! # use std::sync::Arc;
//! # use axum::{extract::Request, middleware::Next, response::Response};
//! # type AppAbility = praetor::Ability<(), (), ()>;
//! # fn build_ability() -> AppAbility { praetor::Ability::builder(()).build() }
//! async fn auth(mut request: Request, next: Next) -> Response {
//! let ability: AppAbility = build_ability(); // after validating the JWT
//! request.extensions_mut().insert(Arc::new(ability));
//! next.run(request).await
//! }
//! ```
//!
//! Handlers then retrieve it with the [`Praetor`] extractor:
//!
//! ```no_run
//! # use praetor::axum::Praetor;
//! # type AppAbility = praetor::Ability<(), (), ()>;
//! async fn handler(Praetor(ability): Praetor<AppAbility>) {
//! // `ability` is an `Arc<AppAbility>`; it derefs to the ability, so
//! // `ability.authorize(..)` works directly.
//! }
//! ```
use Deref;
use Arc;
use FromRequestParts;
use StatusCode;
use Parts;
use ;
/// Extractor that retrieves a shared `T` (typically an
/// [`Ability`](crate::Ability)) previously inserted into the request extensions
/// as `Arc<T>`.
///
/// The value is shared, not cloned: extraction clones the `Arc` only. Destructure
/// it to obtain the inner `Arc<T>`, which derefs to `T`:
///
/// ```no_run
/// # use praetor::axum::Praetor;
/// # type AppAbility = praetor::Ability<(), (), ()>;
/// async fn handler(Praetor(ability): Praetor<AppAbility>) {
/// // `ability.authorize(..)` and other `Ability` methods work via deref.
/// }
/// ```
;
/// Rejection returned by [`Praetor`] when no `Arc<T>` is present in the request
/// extensions.
///
/// This indicates the ability was never inserted — usually a misconfiguration
/// where the middleware that builds the ability did not run. It converts into a
/// `500 Internal Server Error`. Applications that prefer a different status can
/// insert the ability unconditionally, or wrap the extractor.
;