modo/auth/session/
data.rs1use chrono::{DateTime, Utc};
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct Session {
26 pub id: String,
27 pub user_id: String,
28 pub ip_address: String,
29 pub user_agent: String,
30 pub device_name: String,
31 pub device_type: String,
32 pub fingerprint: String,
33 pub data: serde_json::Value,
34 pub created_at: DateTime<Utc>,
35 pub last_active_at: DateTime<Utc>,
36 pub expires_at: DateTime<Utc>,
37}
38
39use super::store::SessionData;
40
41impl From<SessionData> for Session {
42 fn from(raw: SessionData) -> Self {
43 Self {
44 id: raw.id,
45 user_id: raw.user_id,
46 ip_address: raw.ip_address,
47 user_agent: raw.user_agent,
48 device_name: raw.device_name,
49 device_type: raw.device_type,
50 fingerprint: raw.fingerprint,
51 data: raw.data,
52 created_at: raw.created_at,
53 last_active_at: raw.last_active_at,
54 expires_at: raw.expires_at,
55 }
56 }
57}
58
59use axum::extract::{FromRequestParts, OptionalFromRequestParts};
60use http::request::Parts;
61
62use crate::Error;
63
64impl<S: Send + Sync> FromRequestParts<S> for Session {
65 type Rejection = Error;
66
67 async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
68 parts
69 .extensions
70 .get::<Session>()
71 .cloned()
72 .ok_or_else(|| Error::unauthorized("unauthorized").with_code("auth:session_not_found"))
73 }
74}
75
76impl<S: Send + Sync> OptionalFromRequestParts<S> for Session {
77 type Rejection = Error;
78
79 async fn from_request_parts(
80 parts: &mut Parts,
81 _state: &S,
82 ) -> Result<Option<Self>, Self::Rejection> {
83 Ok(parts.extensions.get::<Session>().cloned())
84 }
85}