1use super::*;
2use rbp_core::ID;
3use rbp_core::Unique;
4
5#[derive(Debug, Clone)]
7pub struct Session {
8 id: ID<Self>,
9 user: ID<Member>,
10 hash: Vec<u8>,
11 expires: std::time::SystemTime,
12 #[allow(unused)]
14 revoked: bool,
15}
16
17impl Unique for Session {
18 fn id(&self) -> ID<Self> {
19 self.id
20 }
21}
22
23impl Session {
24 pub fn new(id: ID<Self>, user: ID<Member>, hash: Vec<u8>) -> Self {
25 Self {
26 id,
27 user,
28 hash,
29 expires: std::time::SystemTime::now() + Crypto::duration(),
30 revoked: false,
31 }
32 }
33 pub fn user(&self) -> ID<Member> {
34 self.user
35 }
36 pub fn hash(&self) -> &[u8] {
37 &self.hash
38 }
39 pub fn expires_at(&self) -> std::time::SystemTime {
40 self.expires
41 }
42}
43
44#[cfg(feature = "database")]
45mod schema {
46 use super::*;
47 use rbp_database::*;
48
49 impl Schema for Session {
50 fn name() -> &'static str {
51 SESSIONS
52 }
53 fn columns() -> &'static [tokio_postgres::types::Type] {
54 &[
55 tokio_postgres::types::Type::UUID,
56 tokio_postgres::types::Type::UUID,
57 tokio_postgres::types::Type::BYTEA,
58 tokio_postgres::types::Type::TIMESTAMPTZ,
59 tokio_postgres::types::Type::BOOL,
60 ]
61 }
62 fn creates() -> &'static str {
63 const_format::concatcp!(
64 "CREATE TABLE IF NOT EXISTS ",
65 SESSIONS,
66 " (
67 id UUID PRIMARY KEY,
68 user_id UUID NOT NULL REFERENCES ",
69 USERS,
70 "(id) ON DELETE CASCADE,
71 token_hash BYTEA NOT NULL,
72 expires_at TIMESTAMPTZ NOT NULL,
73 revoked BOOLEAN DEFAULT FALSE
74 );"
75 )
76 }
77 fn indices() -> &'static str {
78 const_format::concatcp!(
79 "CREATE INDEX IF NOT EXISTS idx_sessions_user ON ",
80 SESSIONS,
81 " (user_id);
82 CREATE INDEX IF NOT EXISTS idx_sessions_token ON ",
83 SESSIONS,
84 " (token_hash);
85 CREATE INDEX IF NOT EXISTS idx_sessions_expires ON ",
86 SESSIONS,
87 " (expires_at) WHERE NOT revoked;"
88 )
89 }
90 fn copy() -> &'static str {
91 unimplemented!()
92 }
93 fn truncates() -> &'static str {
94 unimplemented!()
95 }
96 fn freeze() -> &'static str {
97 unimplemented!()
98 }
99 }
100}