krn_auth/
lib.rs

1extern crate base64;
2extern crate openssl;
3extern crate serde_json;
4
5use jsonwebtoken::{decode, DecodingKey, Validation};
6use serde::{Deserialize, Serialize};
7use std::str;
8
9use self::openssl::symm::*;
10
11//Global error + conversions
12#[derive(Serialize, Deserialize, Debug)]
13pub enum KRNAuthErrors {
14    TokenInvalid,
15}
16
17#[derive(Debug, Serialize, Deserialize)]
18struct KRNClaims {
19    aud: String,
20    sub: String,
21    exp: usize,
22    iat: usize,
23    jti: String,
24    payload: String,
25}
26
27#[derive(Debug, Serialize, Deserialize)]
28pub struct KRNAuth {
29    pub name: String,
30    pub crypt_key: String,
31    pub hmac_secret: String,
32    pub rest_key: String,
33    pub rsa_key: String,
34}
35
36#[derive(Debug, Serialize, Deserialize)]
37pub struct KRNUser {
38    pub nick_name: String,
39    pub email: String,
40    pub first_name: String,
41    pub last_name: String,
42    pub flags: i64,
43    pub id: String,
44    pub int_id: i64,
45}
46
47impl KRNAuth {
48    pub fn deep_validate(&self, passport: String) -> Result<String, KRNAuthErrors> {
49        let url = format!(
50            "https://trinity.krone.at/deep-validate?token={}",
51            passport
52        );
53        let client = reqwest::blocking::Client::new();
54        let resp = client.post(url).send().unwrap();
55
56        if resp.status() == 200 {
57            Ok(resp.text().unwrap().to_string())
58        } else {
59            Err(KRNAuthErrors::TokenInvalid)
60        }
61    }
62    pub fn validate(self, passport: String) -> Result<KRNUser, KRNAuthErrors> {
63        let token_parts: Vec<&str> = passport.split(":").collect();
64
65        let decoded = decode::<KRNClaims>(
66            &token_parts[1],
67            &DecodingKey::from_secret(self.hmac_secret.as_ref()),
68            &Validation::default(),
69        )
70        .unwrap();
71
72        let payload = self
73            .decode_payload(decoded.claims.payload.to_string())
74            .unwrap();
75        Ok(payload)
76    }
77    pub fn decode_payload(self, payload: String) -> Result<KRNUser, KRNAuthErrors> {
78        let payload_base64 = base64::decode(&payload).unwrap();
79
80        let iv_size = 16;
81        let iv = &payload_base64[0..iv_size];
82        let enc_data = &payload_base64[iv_size..];
83        let mut decrypter = Crypter::new(
84            Cipher::aes_256_cbc(),
85            Mode::Decrypt,
86            &self.crypt_key.as_bytes(),
87            Some(&iv),
88        )
89        .unwrap();
90        decrypter.pad(false);
91        let mut decrypted = vec![0u8; 400];
92        decrypter
93            .update(&enc_data, decrypted.as_mut_slice())
94            .unwrap();
95
96        let decrypted_json = str::from_utf8(&decrypted[0..enc_data.len()]).unwrap();
97
98        // WHAT IS THIS?
99        let s = decrypted_json.replace("\u{6}", "");
100
101        let v: serde_json::Value = serde_json::from_str(&s).unwrap();
102
103        let u = KRNUser {
104            nick_name: v["NickName"].to_string(),
105            email: v["Email"].to_string(),
106            first_name: v["FirstName"].to_string(),
107            last_name: v["LastName"].to_string(),
108            flags: v["Flags"].as_i64().unwrap(),
109            int_id: v["IntID"].as_i64().unwrap(),
110            id: v["ID"].to_string(),
111        };
112        Ok(u)
113    }
114}