amqp_api_server/api/input/
token.rs

1use std::collections::HashMap;
2
3use jsonwebtoken::TokenData;
4use serde_json::Value;
5
6use crate::error::{Error, ErrorKind};
7
8const PERMISSIONS_CLAIM: &str = "permissions";
9/// Custom claim used in order to support easy assignations of permissions to users
10/// without having to figure out a way to edit Auth0's permissions claim.
11/// USED ONLY WHENEVER THE AUTH0'S PERMISSIONS CLAIM IS EMPTY.
12const CUSTOM_PERMISSIONS_CLAIM: &str = "permission";
13
14pub const USER_ID_CLAIM: &str = "sub";
15pub const ORGANIZATION_ID_CLAIM: &str = "organization_id";
16
17#[derive(Debug)]
18pub struct Token {
19    token_data: TokenData<HashMap<String, Value>>,
20    permissions: Vec<String>,
21}
22
23impl Token {
24    pub fn try_new(token_data: TokenData<HashMap<String, Value>>) -> Result<Token, Error> {
25        let mut permissions = get_permissions_from_claim(&token_data, PERMISSIONS_CLAIM)?;
26
27
28        if permissions.is_empty() {
29            let mut custom_permissions = get_permissions_from_claim(&token_data, CUSTOM_PERMISSIONS_CLAIM)?;
30
31            permissions.append(&mut custom_permissions);
32        }
33
34        Ok(Token {
35            token_data,
36            permissions,
37        })
38    }
39
40    pub fn has_permission(&self, permission: &String) -> Result<(), Error> {
41        if !self.permissions.contains(permission) {
42            return Err(Error::new(
43                ErrorKind::PermissionNotFound,
44                format!("permission '{}' could not be found", permission),
45            ));
46        }
47
48        Ok(())
49    }
50
51    pub fn get(&self, key: &str) -> Option<&Value> {
52        self.token_data.claims.get(key)
53    }
54}
55
56fn get_permissions_from_claim(
57    token_data: &TokenData<HashMap<String, Value>>,
58    claim: &str,
59) -> Result<Vec<String>, Error> {
60    let permissions = match token_data.claims.get(claim) {
61        Some(permissions) => match serde_json::from_value::<Vec<String>>(permissions.clone()) {
62            Ok(permissions) => permissions,
63            Err(error) => {
64                return Err(Error::new(
65                    ErrorKind::MalformedToken,
66                    format!(
67                        "failed to deserialize permissions as a strings vector: {}",
68                        error
69                    ),
70                ))
71            }
72        },
73        None => {
74            return Err(Error::new(
75                ErrorKind::MalformedToken,
76                "'permissions' claim is missing",
77            ))
78        }
79    };
80
81    Ok(permissions)
82}