aboutsummaryrefslogtreecommitdiff
path: root/src/utils/cookie.rs
blob: 826efa9c58840612c6b153c2ac897fd578292251 (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
use hex;
use rand_core::{OsRng, RngCore};

use crate::crypto::signed;
use crate::model::config::Config;

const TOKEN_BYTES: usize = 20;

pub fn login(config: &Config, token: &str) -> Result<String, String> {
    let signed_token = signed::sign(&config.auth_secret, token)?;
    Ok(cookie(config, &signed_token, 24 * 60 * 60))
}

pub fn logout(config: &Config) -> String {
    cookie(config, "", 0)
}

pub fn extract_token(config: &Config, cookie: &str) -> Result<String, String> {
    let mut xs = cookie.split('=');
    xs.next();
    let signed_cookie = xs.next().ok_or("Error extracting cookie")?;
    signed::verify(&config.auth_secret, signed_cookie)
}

pub fn generate_token() -> String {
    let mut token = [0u8; TOKEN_BYTES];
    OsRng.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(";")
}