diff --git a/Cargo.toml b/Cargo.toml index f1c77a3..58594c8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,3 +28,6 @@ zstd = "0.13.0" tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", features = ["time"] } + +chrono = "0.4.33" +base64 = "0.21.7" diff --git a/src/config.rs b/src/config.rs index 378cfcb..fae0f2c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -25,7 +25,6 @@ pub struct Config { pub cluster_secret: String, /// NO_DEMAON pub no_demaon: bool, - /// NO OPEN /// 同步时是否使用 openbmclapi 还是使用 center 和 sync only pub no_open: bool, /// cache dir diff --git a/src/utils.rs b/src/utils.rs index cbf9b4f..52e99ec 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,11 +1,13 @@ use crate::cluster::SyncFile; use std::io::Cursor; +use std::path::PathBuf; +use std::collections::HashMap; use apache_avro::{from_avro_datum, from_value, types::Value}; +use base64::Engine; use md5::{Digest, Md5}; use sha1::Sha1; -use std::path::PathBuf; use tracing::{info, warn}; /// import {join} from 'path' @@ -52,6 +54,34 @@ pub fn validate_file(buffer: &[u8], check_sum: &str) -> bool { } } +/// export function checkSign(hash: string, secret: string, query: NodeJS.Dict): boolean { +/// const {s, e} = query +/// if (!s || !e) return false +/// const sha1 = createHash('sha1') +/// const toSign = [secret, hash, e] +/// for (const str of toSign) { +/// sha1.update(str) +/// } +/// const sign = sha1.digest('base64url') +/// return sign === s && Date.now() < parseInt(e, 36) +/// } +pub fn check_sign(hash: &str, secret: &str, query: &HashMap) -> bool { + if !query.contains_key("s") || !query.contains_key("e") { + return false; + } + let s = query.get("s").unwrap(); + let e = query.get("e").unwrap(); + let mut hasher = Sha1::new(); + hasher.update(secret); + hasher.update(hash); + hasher.update(e); + let result = hasher.finalize(); + let result_str = base64::engine::general_purpose::URL_SAFE.encode(&result); + // 1970 年 1 月 1 日 00:00:00 (UTC) 到当前时间的毫秒数。 + let now = chrono::Utc::now().timestamp_millis(); + &result_str == s && now < i64::from_str_radix(e, 36).unwrap() +} + /// BYD avro 格式的文件列表 pub const SYNC_FILE_LIST_SCHEMA: &str = r#" { @@ -111,6 +141,11 @@ pub fn avro_data_to_file_list(data: Vec) -> Option> { /// 此时,展开的宏代码应当是 /// error!("error"); /// panic!("something wrong"); +/// 如果只传入一个参数 +/// fatal!("error"); +/// 则展开的宏代码应当是 +/// error!("error"); +/// panic!("error"); #[macro_export] macro_rules! fatal {