scufflecloud_core/http_ext.rs
1use std::sync::Arc;
2
3use axum::http;
4use tonic::Code;
5use tonic_types::ErrorDetails;
6
7use crate::middleware::ExpiredSession;
8use crate::models::UserSession;
9use crate::std_ext::OptionExt;
10
11pub(crate) trait RequestExt {
12 fn extensions(&self) -> &http::Extensions;
13
14 fn global<G: Send + Sync + 'static>(&self) -> Result<Arc<G>, tonic::Status> {
15 self.extensions()
16 .get::<Arc<G>>()
17 .map(Arc::clone)
18 .into_tonic_internal_err("missing global extension")
19 }
20
21 fn session(&self) -> Option<&UserSession> {
22 self.extensions().get::<UserSession>()
23 }
24
25 fn session_or_err(&self) -> Result<&UserSession, tonic::Status> {
26 self.session()
27 .into_tonic_err(Code::Unauthenticated, "you must be logged in", ErrorDetails::new())
28 }
29
30 fn expired_session_or_err(&self) -> Result<&UserSession, tonic::Status> {
31 self.extensions().get::<ExpiredSession>().map(|s| &s.0).into_tonic_err(
32 Code::Unauthenticated,
33 "you must be logged in",
34 ErrorDetails::new(),
35 )
36 }
37
38 fn ip_address_info(&self) -> Result<crate::middleware::IpAddressInfo, tonic::Status> {
39 self.extensions()
40 .get::<crate::middleware::IpAddressInfo>()
41 .copied()
42 .into_tonic_internal_err("missing IpAddressInfo extension")
43 }
44}
45
46impl<T> RequestExt for tonic::Request<T> {
47 fn extensions(&self) -> &http::Extensions {
48 self.extensions()
49 }
50}
51
52impl RequestExt for tonic::Extensions {
53 fn extensions(&self) -> &http::Extensions {
54 self
55 }
56}
57
58impl<T> RequestExt for axum::http::Request<T> {
59 fn extensions(&self) -> &http::Extensions {
60 self.extensions()
61 }
62}