dynamic_token/
from_key.rs1use simple_string_patterns::{ToSegments,ToSegmentsFromChars};
2use crate::utils::*;
3use crate::valid_auth_token::ValidAuthToken;
4use crate::auth_status::*;
5use crate::auth_options::*;
6use crate::MIN_VALID_UUID_LENGTH;
7
8pub fn from_dynamic_key(
10 sample: &str,
11 options: &AuthOptions,
12) -> ValidAuthToken {
13 let mut uuid: Option<String> = None;
14 let mut valid = false;
15 let api_key = options.key();
16 let mut status = AuthStatus::None;
17 let decoded_string = decode_base64(sample);
18 let first_char = decoded_string.chars().nth(0).unwrap_or('-');
19 let mut age: Option<i64> = None;
20 if first_char.is_alphanumeric() {
21 let decoded_int = base_36_to_u8(&first_char).unwrap_or(0);
22 let offset = (decoded_int % 6) + 2;
23 let api_key_index = decoded_string.find(api_key).unwrap_or(255) as u8;
24 if api_key_index == offset {
25 let parts = decoded_string.to_parts("__");
26 if options.should_check_uuid() && parts.len() > 1 {
28 if let Some(long_str) = parts.last() {
29 let (first, second) = long_str.to_head_tail("_");
30 if second.len() > 6 {
31 let (tail_end, int_str) = second.to_head_tail_on_any_char(&options.rand_chars());
32 let uid_str = [
33 base_36_parts_to_hex_dec(&first),
34 base_36_parts_to_hex_dec(&tail_end)
35 ].into_iter().map(|opt| opt.unwrap_or("".to_string())).collect::<Vec<String>>().concat();
36 let rand_int = base_36_str_to_u64(&int_str);
37 if uid_str.len() >= MIN_VALID_UUID_LENGTH {
38 uuid = Some(uid_str.clone());
39 valid = rand_int.is_some();
40 status = if valid {
41 AuthStatus::Ok
42 } else {
43 AuthStatus::UuidRequired
44 };
45 }
46 }
47 }
48 } else {
49 valid = true;
50 status = AuthStatus::Ok;
51 }
52 let base_str = parts.get(0).unwrap();
54 let ts_parts = base_str.to_parts(api_key);
55 let (ts_str, base_suffix) = ts_parts.concat().to_head_tail_on_any_char(&options.rand_chars());
58 if valid {
59 valid = ts_str.chars().all(|c| c.is_alphanumeric());
61 if !valid {
62 status = AuthStatus::InvalidTimestamp;
63 }
64 }
65 if valid {
67 if let Some(_suffix_int) = base_36_str_to_u64(&base_suffix) {
68 let characters: String = ts_str.chars().rev().collect();
70 let ts = base_36_str_to_u64(&characters).unwrap_or(0) as i64;
72 let curr_ts = milliseconds_now();
73 let age_ms = curr_ts - ts;
74 let max_age_ms = options.tolerance();
75 let min_age_ms = 0 - max_age_ms;
76 valid = age_ms >= min_age_ms && age_ms <= max_age_ms;
78 age = Some(age_ms);
80 status = if valid {
82 AuthStatus::Ok
83 } else {
84 AuthStatus::TimedOut
85 };
86 }
87 }
88 }
89 }
90 ValidAuthToken(valid, uuid, age, status)
91}