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
|
use hex;
use rand::Rng;
use crate::model::config::Config;
// We consider that it’s unfeasible to guess a token from 128 bit long (=16 bytes) to 256 bit (=32 bytes) with safe margin.
const TOKEN_BYTES: usize = 32;
pub fn login(config: &Config, token: &str) -> Result<String, String> {
Ok(cookie(config, token, 365 * 24 * 60 * 60))
}
pub fn logout(config: &Config) -> String {
cookie(config, "", 0)
}
pub fn extract_token(cookie: &str) -> Result<String, String> {
let mut xs = cookie.split('=');
if xs.next() != Some("TOKEN") {
Err("Error extracting cookie".to_string())
} else {
let token = xs.next().ok_or("Error extracting cookie")?;
Ok(token.to_string())
}
}
pub fn generate_token() -> String {
let mut token = [0u8; TOKEN_BYTES];
let mut rng = rand::rng();
rng.fill_bytes(&mut token);
hex::encode(token)
}
fn cookie(config: &Config, token: &str, max_age_seconds: i32) -> String {
let mut xs = vec![
format!("TOKEN={token}"),
"SameSite=Strict".to_string(),
"HttpOnly".to_string(),
format!("Max-Age={}", max_age_seconds),
];
if config.secure_cookies {
xs.push("Secure".to_string())
}
xs.join(";")
}
|