live_kit_token.rs

 1use anyhow::Result;
 2use hmac::{Hmac, Mac};
 3use jwt::SignWithKey;
 4use serde::Serialize;
 5use sha2::Sha256;
 6use std::{
 7    ops::Add,
 8    time::{Duration, SystemTime, UNIX_EPOCH},
 9};
10
11static DEFAULT_TTL: Duration = Duration::from_secs(6 * 60 * 60); // 6 hours
12
13#[derive(Default, Serialize)]
14#[serde(rename_all = "camelCase")]
15struct ClaimGrants<'a> {
16    iss: &'a str,
17    sub: &'a str,
18    iat: u64,
19    exp: u64,
20    nbf: u64,
21    jwtid: &'a str,
22    video: VideoGrant<'a>,
23}
24
25#[derive(Default, Serialize)]
26#[serde(rename_all = "camelCase")]
27struct VideoGrant<'a> {
28    room_create: Option<bool>,
29    room_join: Option<bool>,
30    room_list: Option<bool>,
31    room_record: Option<bool>,
32    room_admin: Option<bool>,
33    room: Option<&'a str>,
34    can_publish: Option<bool>,
35    can_subscribe: Option<bool>,
36    can_publish_data: Option<bool>,
37    hidden: Option<bool>,
38    recorder: Option<bool>,
39}
40
41pub fn create_token(
42    api_key: &str,
43    secret_key: &str,
44    room_name: &str,
45    participant_name: &str,
46) -> Result<String> {
47    let secret_key: Hmac<Sha256> = Hmac::new_from_slice(secret_key.as_bytes())?;
48
49    let now = SystemTime::now();
50
51    let claims = ClaimGrants {
52        iss: api_key,
53        sub: participant_name,
54        iat: now.duration_since(UNIX_EPOCH).unwrap().as_secs(),
55        exp: now
56            .add(DEFAULT_TTL)
57            .duration_since(UNIX_EPOCH)
58            .unwrap()
59            .as_secs(),
60        nbf: 0,
61        jwtid: participant_name,
62        video: VideoGrant {
63            room: Some(room_name),
64            room_join: Some(true),
65            can_publish: Some(true),
66            can_subscribe: Some(true),
67            ..Default::default()
68        },
69    };
70    Ok(claims.sign_with_key(&secret_key)?)
71}