-
Notifications
You must be signed in to change notification settings - Fork 92
/
Copy pathsession.rs
116 lines (101 loc) · 3.01 KB
/
session.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright (c) 2022 by Rivos Inc.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
use actix_web::cookie::{
time::{Duration, OffsetDateTime},
Cookie,
};
use kbs_types::{Challenge, Request};
use log::warn;
use uuid::Uuid;
pub(crate) static KBS_SESSION_ID: &str = "kbs-session-id";
/// Finite State Machine model for RCAR handshake
pub(crate) enum SessionStatus {
Authed {
request: Request,
challenge: Challenge,
id: String,
timeout: OffsetDateTime,
},
Attested {
token: String,
id: String,
timeout: OffsetDateTime,
},
}
macro_rules! impl_member {
($attr: ident, $typ: ident) => {
pub fn $attr(&self) -> &$typ {
match self {
SessionStatus::Authed { $attr, .. } => $attr,
SessionStatus::Attested { $attr, .. } => $attr,
}
}
};
($attr: ident, $typ: ident, $branch: ident) => {
pub fn $attr(&self) -> &$typ {
match self {
SessionStatus::$branch { $attr, .. } => $attr,
_ => panic!("unexpected status"),
}
}
};
}
impl SessionStatus {
pub fn auth(request: Request, timeout: i64, challenge: Challenge) -> Self {
let id = Uuid::new_v4().as_simple().to_string();
let timeout = OffsetDateTime::now_utc() + Duration::minutes(timeout);
Self::Authed {
request,
challenge,
id,
timeout,
}
}
pub fn cookie<'a>(&self) -> Cookie<'a> {
match self {
SessionStatus::Authed { id, timeout, .. } => Cookie::build(KBS_SESSION_ID, id.clone())
.expires(*timeout)
.finish(),
SessionStatus::Attested { id, timeout, .. } => {
Cookie::build(KBS_SESSION_ID, id.clone())
.expires(*timeout)
.finish()
}
}
}
impl_member!(request, Request, Authed);
impl_member!(challenge, Challenge, Authed);
impl_member!(id, str);
impl_member!(timeout, OffsetDateTime);
pub fn is_expired(&self) -> bool {
return *self.timeout() < OffsetDateTime::now_utc();
}
pub fn attest(&mut self, token: String) {
match self {
SessionStatus::Authed { id, timeout, .. } => {
*self = SessionStatus::Attested {
token,
id: id.clone(),
timeout: *timeout,
};
}
SessionStatus::Attested { .. } => {
warn!("session already attested.");
}
}
}
}
pub(crate) struct SessionMap {
pub sessions: scc::HashMap<String, SessionStatus>,
}
impl SessionMap {
pub fn new() -> Self {
SessionMap {
sessions: scc::HashMap::new(),
}
}
pub fn insert(&self, session: SessionStatus) {
let _ = self.sessions.insert(session.id().to_string(), session);
}
}