use crate::AuthContext;
use crate::types::RequestExtensions;
use crate::utils::json::JsValue;
use crate::{AuthRequest, AuthSchema, HttpMethod, SessionView, UserView};
use std::collections::HashMap;
pub trait SessionRequest: Send + Sync {
fn endpoint_call(&self) -> Option<&crate::endpoint::EndpointCall> {
None
}
fn physical_request(&self) -> Option<&AuthRequest> {
None
}
fn session_headers(&self) -> &HashMap<String, String>;
fn session_method(&self) -> &HttpMethod;
fn session_query_truthy(&self, name: &str) -> bool;
fn extensions(&self) -> &RequestExtensions;
fn virtual_session<S: AuthSchema>(&self, context: &AuthContext<S>) -> Option<SessionView>;
fn authenticated_user<S: AuthSchema>(&self, _context: &AuthContext<S>) -> Option<S::User> {
None
}
fn take_response_headers(&self) -> crate::Headers;
fn queue_response_header(&self, name: impl Into<String>, value: impl Into<String>);
fn set_session_hook_snapshot(&self, user: UserView, session: SessionView);
}
impl SessionRequest for AuthRequest {
fn physical_request(&self) -> Option<&AuthRequest> {
Some(self)
}
fn session_headers(&self) -> &HashMap<String, String> {
&self.headers
}
fn session_method(&self) -> &HttpMethod {
self.method()
}
fn session_query_truthy(&self, name: &str) -> bool {
self.query.get(name).is_some_and(|value| !value.is_empty())
}
fn extensions(&self) -> &RequestExtensions {
self.extensions()
}
fn virtual_session<S: AuthSchema>(&self, _context: &AuthContext<S>) -> Option<SessionView> {
self.virtual_session().cloned()
}
fn take_response_headers(&self) -> crate::Headers {
self.take_response_headers()
}
fn queue_response_header(&self, name: impl Into<String>, value: impl Into<String>) {
self.queue_response_header(name, value);
}
fn set_session_hook_snapshot(&self, user: UserView, session: SessionView) {
self.set_session_hook_snapshot(user, session);
}
}
impl SessionRequest for crate::endpoint::EndpointCall {
fn physical_request(&self) -> Option<&AuthRequest> {
self.request()
}
fn endpoint_call(&self) -> Option<&crate::endpoint::EndpointCall> {
Some(self)
}
fn session_headers(&self) -> &HashMap<String, String> {
static EMPTY: std::sync::LazyLock<HashMap<String, String>> =
std::sync::LazyLock::new(HashMap::new);
self.headers().unwrap_or(&EMPTY)
}
fn session_method(&self) -> &HttpMethod {
self.method().unwrap_or_else(|| self.default_method())
}
fn session_query_truthy(&self, name: &str) -> bool {
self.query()
.and_then(|query| query.get(name))
.is_some_and(|value| match value {
JsValue::Null => false,
JsValue::Bool(value) => *value,
JsValue::Number(value) => *value != 0.0 && !value.is_nan(),
JsValue::String(value) => !value.is_empty(),
JsValue::Date(_) | JsValue::Array(_) | JsValue::Object(_) => true,
})
}
fn extensions(&self) -> &RequestExtensions {
self.extensions()
}
fn virtual_session<S: AuthSchema>(&self, context: &AuthContext<S>) -> Option<SessionView> {
self.authenticated_user(context)
.and_then(|_| self.virtual_session())
}
fn authenticated_user<S: AuthSchema>(&self, context: &AuthContext<S>) -> Option<S::User> {
self.authenticated_user::<S>(context)
}
fn take_response_headers(&self) -> crate::Headers {
self.take_response_headers()
}
fn queue_response_header(&self, name: impl Into<String>, value: impl Into<String>) {
self.queue_response_header(name, value);
}
fn set_session_hook_snapshot(&self, user: UserView, session: SessionView) {
self.set_session_hook_snapshot(user, session);
}
}