aboutsummaryrefslogtreecommitdiff
path: root/src/utils/cookie.rs
blob: 0d7a64a38cda5e33675cb21aae44b56309e3cb75 (plain)
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(";")
}