lexa_framework/http/
context.rs1use std::ops;
12use std::sync::Arc;
13
14use super::{HttpRequest, HttpResponse};
15
16#[async_trait::async_trait]
21pub trait HttpContextInterface: Send + Sync {
22 type State;
23
24 async fn new(
25 extensions: &super::Extensions,
26 state: Self::State,
27 ) -> Option<Self>
28 where
29 Self: Sized;
30
31 fn shared(self) -> Arc<Self>
32 where
33 Self: Sized,
34 {
35 Arc::new(self)
36 }
37}
38
39pub struct HttpContext<T> {
44 pub(crate) context: Arc<T>,
45 pub request: HttpRequest<T>,
46 pub response: HttpResponse<T>,
47 #[cfg(feature = "cookies")]
48 pub cookies: super::cookies::Cookies,
49 #[cfg(feature = "cookies")]
50 pub session: super::session::Session,
51}
52
53impl<T> HttpContext<T> {
58 pub fn redirect_back(&self) -> axum::response::Redirect {
61 assert!(self.request.referer.is_some());
62 let referer = self.request.referer.as_ref().expect("Referer");
63
64 fn referer_url(referer: &axum::headers::Referer) -> String {
65 let referer_s = format!("{referer:?}");
66
67 let trimmed_referer = referer_s
68 .trim_start_matches("Referer(\"")
69 .trim_end_matches("\")");
70
71 trimmed_referer.to_owned()
72 }
73
74 let uri = referer_url(referer);
75
76 self.response.redirect_to(uri)
77 }
78}
79
80#[cfg(feature = "auth")]
81impl<T> HttpContext<T> {
82 pub async fn logout_user(&mut self) {
85 let mut session = self.session.write().await;
86 session.remove(crate::auth::AUTH_USER_ID_SESSION);
87 session.remove(crate::auth::AUTH_ADMIN_ID_SESSION);
88 session.regenerate();
89
90 if let Some(mut user_cookie) = self
91 .cookies
92 .private()
93 .get(crate::auth::AUTH_USER_ID_SESSION)
94 {
95 let expires_in = time::OffsetDateTime::now_utc()
96 .checked_sub(time::Duration::days(100));
97 user_cookie.set_path("/");
98 user_cookie.set_expires(expires_in);
99 self.cookies.private().add(user_cookie);
100 }
101
102 if let Some(mut adm_cookie) = self
103 .cookies
104 .private()
105 .get(crate::auth::AUTH_ADMIN_ID_SESSION)
106 {
107 let expires_in = time::OffsetDateTime::now_utc()
108 .checked_sub(time::Duration::days(100));
109 adm_cookie.set_path("/");
110 adm_cookie.set_expires(expires_in);
111 self.cookies.private().add(adm_cookie);
112 }
113 }
114}
115
116impl<T> ops::Deref for HttpContext<T> {
121 type Target = Arc<T>;
122
123 fn deref(&self) -> &Self::Target {
124 &self.context
125 }
126}