1use postcard::{from_bytes, to_allocvec};
4use serde::{Deserialize, Serialize};
5
6extern crate alloc;
7use alloc::vec::Vec;
8
9use crate::{
10 capabilities::{Capabilities, Capability},
11 crypto::PublicKey,
12 timestamp::Timestamp,
13};
14
15#[derive(Clone, Serialize, Deserialize, Debug, Eq, PartialEq)]
16pub struct SessionInfo {
18 version: usize,
19 public_key: PublicKey,
20 created_at: u64,
21 name: String,
23 user_agent: String,
25 capabilities: Vec<Capability>,
26}
27
28impl SessionInfo {
29 pub fn new(
31 public_key: &PublicKey,
32 capabilities: Capabilities,
33 user_agent: Option<String>,
34 ) -> Self {
35 Self {
36 version: 0,
37 public_key: public_key.clone(),
38 created_at: Timestamp::now().as_u64(),
39 capabilities: capabilities.to_vec(),
40 user_agent: user_agent.as_deref().unwrap_or("").to_string(),
41 name: user_agent.as_deref().unwrap_or("").to_string(),
42 }
43 }
44
45 pub fn public_key(&self) -> &PublicKey {
49 &self.public_key
50 }
51
52 pub fn capabilities(&self) -> &[Capability] {
54 &self.capabilities
55 }
56
57 pub fn created_at(&self) -> u64 {
59 self.created_at
60 }
61
62 pub fn set_created_at(&mut self, created_at: u64) -> &mut Self {
66 self.created_at = created_at;
67 self
68 }
69
70 pub fn set_capabilities(&mut self, capabilities: Capabilities) -> &mut Self {
72 self.capabilities = capabilities.to_vec();
73
74 self
75 }
76
77 pub fn serialize(&self) -> Vec<u8> {
81 to_allocvec(self).expect("SessionInfo::serialize")
82 }
83
84 pub fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
86 if bytes.is_empty() {
87 return Err(Error::EmptyPayload);
88 }
89
90 if bytes[0] > 0 {
91 return Err(Error::UnknownVersion);
92 }
93
94 Ok(from_bytes(bytes)?)
95 }
96
97 }
99
100#[derive(thiserror::Error, Debug, PartialEq)]
101pub enum Error {
103 #[error("Empty payload")]
104 EmptyPayload,
106 #[error("Unknown version")]
107 UnknownVersion,
109 #[error(transparent)]
110 Parsing(#[from] postcard::Error),
112}
113
114#[cfg(test)]
115mod tests {
116 use crate::{capabilities::Capability, crypto::Keypair};
117
118 use super::*;
119
120 #[test]
121 fn serialize() {
122 let keypair = Keypair::from_secret(&[0; 32]);
123 let public_key = keypair.public_key();
124 let capabilities = Capabilities::builder().cap(Capability::root()).finish();
125
126 let session = SessionInfo {
127 user_agent: "foo".to_string(),
128 capabilities: capabilities.to_vec(),
129 created_at: 0,
130 public_key,
131 version: 0,
132 name: "".to_string(),
133 };
134
135 let serialized = session.serialize();
136
137 assert_eq!(
138 serialized,
139 [
140 0, 59, 106, 39, 188, 206, 182, 164, 45, 98, 163, 168, 208, 42, 111, 13, 115, 101,
141 50, 21, 119, 29, 226, 67, 166, 58, 192, 72, 161, 139, 89, 218, 41, 0, 0, 3, 102,
142 111, 111, 1, 4, 47, 58, 114, 119
143 ]
144 );
145
146 let deserialized = SessionInfo::deserialize(&serialized).unwrap();
147
148 assert_eq!(deserialized, session)
149 }
150
151 #[test]
152 fn deserialize() {
153 let result = SessionInfo::deserialize(&[]);
154
155 assert_eq!(result, Err(Error::EmptyPayload));
156 }
157}