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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use crate::env::{global_config, ConcreteConfig};
use chrono::Utc;
use jsonwebtoken::{encode, EncodingKey, Header};
use std::sync::Arc;
const AUTHENTICATED_USER: &'static str = "admin";
const JWT_ISSUER: &'static str = "telescope";
#[derive(Serialize, Clone, Debug)]
pub struct ApiJwtClaims {
iss: &'static str,
sub: Option<String>,
iat: i64,
#[serde(rename = "https://hasura.io/jwt/claims")]
hasura_claims: HasuraJwtClaims,
}
#[derive(Serialize, Clone, Debug)]
struct HasuraJwtClaims {
#[serde(rename = "x-hasura-allowed-roles")]
allowed_roles: Vec<&'static str>,
#[serde(rename = "x-hasura-default-role")]
default_role: &'static str,
#[serde(rename = "x-hasura-user-id")]
#[serde(skip_serializing_if = "Option::is_none")]
user_id: Option<String>,
}
impl ApiJwtClaims {
pub fn new(subject: Option<String>) -> String {
let config: Arc<ConcreteConfig> = global_config();
let jwt_secret: &[u8] = config.jwt_secret.as_bytes();
let jwt = ApiJwtClaims {
iss: JWT_ISSUER,
sub: subject.clone(),
iat: Utc::now().timestamp(),
hasura_claims: HasuraJwtClaims {
default_role: AUTHENTICATED_USER,
allowed_roles: vec![AUTHENTICATED_USER],
user_id: subject,
},
};
return encode(
&Header::default(),
&jwt,
&EncodingKey::from_secret(jwt_secret),
)
.expect("Could not encode JWT");
}
}