1use std::fmt::Debug;
2use std::time::SystemTime;
3
4use chimes_utils::AppConfig;
5
6use chrono::offset::Local;
7use chrono::DateTime;
8use jsonwebtoken::{DecodingKey, EncodingKey, Header};
9use serde_derive::{Deserialize, Serialize};
10
11use std::collections::HashMap;
12
13mod auth;
14pub use auth::*;
15
16mod app;
17pub use app::*;
18
19#[allow(dead_code)]
20pub fn num_to_string(n: i64) -> String {
21 let base_codec = [
22 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
23 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '7', '8', '9',
24 ];
25 let len = base_codec.len() as i64;
26 let mut t = n;
27 let mut result = "".to_string();
28 while t > 0 {
29 let idx = (t % len) as usize;
30 let ch = base_codec[idx];
31 t /= len;
32 result.insert(0, ch);
33 }
34 result
35}
36
37#[allow(dead_code)]
38pub fn f32_to_decimal(f: f32) -> Option<rbatis::Decimal> {
39 match rbatis::Decimal::from_str(format!("{:.2}", f).as_str()) {
40 Ok(r) => Some(r),
41 Err(_) => None,
42 }
43}
44
45#[allow(dead_code)]
46pub fn decimal_to_f32(dc: Option<rbatis::Decimal>) -> f32 {
47 match dc {
48 Some(r) => r.to_string().parse::<f32>().unwrap_or(0f32),
49 None => 0f32,
50 }
51}
52
53#[allow(dead_code)]
54pub fn make_decimal_negative(dc: Option<rbatis::Decimal>) -> Option<rbatis::Decimal> {
55 match dc {
56 Some(r) => match r.to_string().parse::<f32>() {
57 Ok(t) => f32_to_decimal(-t),
58 Err(_) => f32_to_decimal(0f32),
59 },
60 None => f32_to_decimal(0f32),
61 }
62}
63
64#[allow(dead_code)]
65pub fn generate_rand_string(len: usize) -> String {
66 let mut retkey = "".to_string();
67
68 while retkey.len() < len {
69 let rng = rand::random::<u16>();
70 let key = num_to_string(rng as i64);
71 retkey += key.as_str();
72 }
73
74 retkey.chars().take(len).collect()
75}
76
77#[allow(dead_code)]
78pub fn get_local_timestamp() -> u64 {
79 let now = SystemTime::now();
80 let date: DateTime<Local> = now.into();
81 date.timestamp_millis() as u64
82}
83
84#[allow(dead_code)]
85pub fn parse_query(query_string: &str) -> HashMap<String, String> {
86 if query_string.is_empty() {
87 return HashMap::new();
88 }
89 let q_a: Vec<&str> = query_string.split('&').collect();
90 let mut res: HashMap<String, String> = HashMap::new();
91 use percent_encoding::percent_decode;
92 for s in q_a {
93 let kv: Vec<&str> = s.split('=').collect();
95 let kvalue = percent_decode(kv[1].as_bytes()).decode_utf8().unwrap();
96 res.insert(kv[0].to_string(), kvalue.to_string());
97 }
98 res
99}
100
101#[allow(dead_code)]
102pub fn get_hash_value(query_params: &HashMap<String, String>, key: &str) -> String {
103 match query_params.get(key) {
104 Some(val) => val.clone(),
105 None => "".to_owned(),
106 }
107}
108
109#[derive(Debug, Serialize, Deserialize)]
110pub struct UserClaims {
111 pub aud: String,
112 pub sub: String,
113 pub exp: usize,
114}
115
116impl UserClaims {
117 pub fn encode(&self) -> Option<String> {
118 let conf = AppConfig::get().lock().unwrap().to_owned();
119
120 match jsonwebtoken::encode(
121 &Header::default(),
122 &self,
123 &EncodingKey::from_secret(conf.webserver_conf.rsa_cert.as_bytes()),
124 ) {
125 Ok(t) => Some(t),
126 Err(_) => None,
127 }
128 }
129
130 pub fn decode(token: &str) -> Option<Self> {
131 let conf = AppConfig::get().lock().unwrap().to_owned();
132 let validation = jsonwebtoken::Validation::new(jsonwebtoken::Algorithm::HS256);
133 match jsonwebtoken::decode::<UserClaims>(
134 token,
135 &DecodingKey::from_secret(conf.webserver_conf.rsa_cert.as_bytes()),
136 &validation,
137 ) {
138 Ok(c) => Some(c.claims),
139 Err(err) => {
140 match *err.kind() {
141 jsonwebtoken::errors::ErrorKind::InvalidToken => {
142 log::error!("Token is invalid")
143 } jsonwebtoken::errors::ErrorKind::InvalidIssuer => {
145 log::error!("Issuer is invalid")
146 } _ => log::error!("Some other errors"),
148 };
149
150 None
151 }
152 }
153 }
154}
155
156fn field_is_none<T>(t: &Option<T>) -> bool {
157 t.is_none()
158}
159
160#[derive(Debug, Clone, Default, Serialize, Deserialize)]
161pub struct MenuMetadata {
162 pub icon: Option<String>,
163 pub no_cache: bool,
164 pub title: Option<String>,
165}
166
167#[derive(Debug, Clone, Default, Serialize, Deserialize)]
168pub struct MenuTreeModel {
169 #[serde(skip_serializing_if = "field_is_none")]
170 pub always_show: Option<bool>,
171 pub id: i64,
172 pub meta: MenuMetadata,
173 pub name: String,
174 pub path: String,
175 pub hidden: bool,
176 pub iframe: bool,
177 pub permission: String,
178 pub component: String,
179 #[serde(skip_serializing_if = "field_is_none")]
180 pub pid: Option<i64>,
181 pub children: Vec<MenuTreeModel>,
182 #[serde(skip_serializing_if = "field_is_none")]
183 pub redirect: Option<String>,
184 pub sort: i32,
185}
186
187#[allow(dead_code)]
188pub fn num_to_string_v2(n: i64) -> String {
189 let base_codec = [
190 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't',
191 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M',
192 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7',
193 '8', '9',
194 ];
195 let len = base_codec.len() as i64;
196 let mut t = n;
197 let mut result = "".to_string();
198 while t > 0 {
199 let idx = (t % len) as usize;
200 let ch = base_codec[idx];
201 t /= len;
202 result.insert(0, ch);
203 }
204 result
205}
206
207#[allow(dead_code)]
208pub fn generate_rand_string_v2(len: usize) -> String {
209 let mut retkey = "".to_string();
210
211 while retkey.len() < len {
212 let rng = rand::random::<u16>();
213 let key = num_to_string_v2(rng as i64);
214 retkey += key.as_str();
215 }
216
217 retkey.chars().take(len).collect()
218}
219
220#[allow(dead_code)]
221pub fn number_to_string(n: i64) -> String {
222 let base_codec = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'];
223 let len = base_codec.len() as i64;
224 let mut t = n;
225 let mut result = "".to_string();
226 while t > 0 {
227 let idx = (t % len) as usize;
228 let ch = base_codec[idx];
229 t /= len;
230 result.insert(0, ch);
231 }
232 result
233}
234
235#[allow(dead_code)]
236pub fn generate_rand_numberstring(len: usize) -> String {
237 let mut retkey = "".to_string();
238
239 while retkey.len() < len {
240 let rng = rand::random::<u16>();
241 let key = number_to_string(rng as i64);
242 retkey += key.as_str();
243 }
244
245 retkey.chars().take(len).collect()
246}