rust-ucenter 0.1.2

rust-ucenter
Documentation
// use deadpool_redis::{Config, Pool, Runtime}; 
use redis::{Commands, Client, Connection};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use thiserror::Error;

// 定义用户信息结构体
#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
pub struct TokenUserInfo {
    pub created: u64,
    pub devId: Option<String>,
    pub distId: i32,
    pub distributorType: i32,
    pub email: String,
    pub frozenAll: i32,
    pub frozenAsset: i32,
    pub frozenCfd: i32,
    pub frozenOtc: i32,
    pub frozenSpot: i32,
    pub invite: Option<String>,
    pub ip: u64,
    pub isMarketMaker: Option<i32>,
    pub mobile: String,
    pub parentId: i64,
    pub parentInvite: Option<String>,
    pub partnerId: i64,
    pub salesId: i32,
    pub status: i32,
    pub userId: i64,
    pub username: Option<String>,
    pub lastIp: Option<String>,
}

#[derive(Debug, Clone)]
pub struct AuthConfig {
    pub redis_url: String,
    pub header_key: String,
}

impl Default for AuthConfig {
    fn default() -> Self {
        Self {
            redis_url: "redis://127.0.0.1/".into(),
            header_key: "X-Authorization".into(),
        }
    }
}

#[derive(Debug, Error)]
pub enum AuthError {
    #[error("Missing auth header")]
    MissingHeader,
    #[error("Redis connection error: {0}")]
    ConnectionError(String),
    #[error("Redis command error: {0}")]
    CommandError(String),
    #[error("Deserialization error: {0}")]
    DeserializationError(String),
}

#[derive(Clone)]
pub struct AuthClient {
    // pub pool: Pool,
    pub client: Client,
    pub config: AuthConfig,
}

impl AuthClient {
    pub fn new(config: AuthConfig) -> Result<Self, AuthError> {
        let client = Client::open(config.redis_url.clone())
            .map_err(|e| AuthError::ConnectionError(e.to_string()))?;
        Ok(Self { client, config })
    }

    fn get_conn(&self) -> Result<Connection, AuthError> {
        self.client.get_connection()
            .map_err(|e| AuthError::ConnectionError(e.to_string()))
    }

    pub fn get_user_data<T: DeserializeOwned>(
        &self,
        token: &str,
    ) -> Result<T, AuthError> {
        let mut conn = self.get_conn()?;

        // 第一层查询:根据token获取user_id
        let redis_key1 = format!("kubiex:session:id:{}", token);
        let user_id: Option<String> = conn.get(&redis_key1)
            .map_err(|e| AuthError::CommandError(e.to_string()))?;

        let data = if let Some(user_id) = user_id {
            // 第二层查询:根据user_id获取用户信息
            let redis_key2 = format!("kubiex:session:user_id:{}", user_id);
            conn.get(&redis_key2)
                .map_err(|e| AuthError::CommandError(e.to_string()))?
        } else {
            // 如果找不到user_id返回空字符串(保持原逻辑)
            String::new()
        };

        serde_json::from_str(&data)
            .map_err(|e| AuthError::DeserializationError(e.to_string()))
    }
    // pub async fn new(config: AuthConfig) -> Result<Self, AuthError> {
    //     let cfg = Config::from_url(config.redis_url.clone());
    //     let pool = cfg.create_pool(Some(Runtime::Tokio1))
    //         .map_err(|e| AuthError::ConnectionError(e.to_string()))?;
        
    //     Ok(Self { pool, config })
    // }

    // pub async fn get_user_data<T: DeserializeOwned + Send + Sync>(
    //     &self,
    //     token: &str,
    // ) -> Result<T, AuthError> {

    //     let mut data = String::new();

    //     let mut redis_key= format!("kubiex:session:id:{}", token);

    //     let mut conn = self.pool.get().await
    //         .map_err(|e| AuthError::ConnectionError(e.to_string()))?;

    //     let user_id_data: Option<String> = conn.get(redis_key).await
    //         .map_err(|e| AuthError::CommandError(e.to_string()))?;
        

    //     if let Some(user_id) = user_id_data {
    //         // 只处理 Some 的情况
    //         println!("-------Received user_id: {}", user_id);

    //         redis_key=format!("kubiex:session:user_id:{}", user_id);
    //         let user_info_option: Option<String> = conn.get(redis_key).await
    //             .map_err(|e| AuthError::CommandError(e.to_string()))?;
    //         println!("Authorization redis_key 2 result: {:?}", user_info_option);
    //         if let Some(user_info) = user_info_option {
    //             data = user_info;
    //             println!("Authorization redis_key 2 result: {:?}", &data);
    //         };
    //     } 
    //     serde_json::from_str(&data)
    //         .map_err(|e| AuthError::DeserializationError(e.to_string()))
    // }




}





#[cfg(test)]
mod tests {
    use super::*;
    

    #[tokio::test]
    async fn test_full_flow() {
        let config = AuthConfig {
            redis_url: "redis://locklevel-redis-dev1-india.8wuaih.ng.0001.apse1.cache.amazonaws.com:6379/0".into(),
            header_key: "X-Authorization".into(),
        };

        let client =  AuthClient::new(config).unwrap();
        let result: Result<TokenUserInfo, _> = client.get_user_data("f4a7afb9e538aa9e7f61646864e20466d5671680266603db6b70141821cf9067");
        if let Ok(user_info) = result {
            println!("Got user info: {:?}", user_info);
        }
        // let client = AuthClient::new(config).await.unwrap();

        // 测试获取数据
        // let result: TokenUserInfo = client.get_user_data("f4a7afb9e538aa9e7f61646864e20466d5671680266603db6b70141821cf9067").await.unwrap();
        
    }
}