2025-02-02 00:46:04 +01:00
|
|
|
use std::{env, result};
|
2025-02-02 20:25:22 +01:00
|
|
|
use std::array::TryFromSliceError;
|
|
|
|
|
use std::net::{Ipv4Addr};
|
2025-02-02 00:46:04 +01:00
|
|
|
use once_cell::sync::Lazy;
|
|
|
|
|
use thiserror::Error;
|
|
|
|
|
use tonic::metadata::{Ascii, MetadataValue};
|
2025-02-02 20:25:22 +01:00
|
|
|
use tonic::{Request, transport};
|
2025-02-02 00:46:04 +01:00
|
|
|
use tonic::codegen::InterceptedService;
|
|
|
|
|
use tonic::transport::Channel;
|
2025-02-02 20:25:22 +01:00
|
|
|
use crate::grpc::InterceptorFunc;
|
2025-02-02 00:46:04 +01:00
|
|
|
use crate::grpc::protobufs::account::account_client::AccountClient;
|
2025-02-05 16:02:32 +01:00
|
|
|
use crate::grpc::protobufs::account::{GetNexPasswordRequest, GetUserDataRequest, GetUserDataResponse};
|
2025-02-02 00:46:04 +01:00
|
|
|
|
|
|
|
|
static API_KEY: Lazy<MetadataValue<Ascii>> = Lazy::new(||{
|
|
|
|
|
let key = env::var("ACCOUNT_GRPC_API_KEY")
|
|
|
|
|
.expect("no public ip specified");
|
|
|
|
|
|
|
|
|
|
key.parse().expect("unable to parse metadata value")
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
static PORT: Lazy<u16> = Lazy::new(||{
|
|
|
|
|
env::var("ACCOUNT_GRPC_PORT")
|
|
|
|
|
.ok()
|
|
|
|
|
.and_then(|s| s.parse().ok())
|
|
|
|
|
.unwrap_or(7071)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
static IP: Lazy<Ipv4Addr> = Lazy::new(||{
|
|
|
|
|
env::var("ACCOUNT_GRPC_IP")
|
|
|
|
|
.ok()
|
|
|
|
|
.and_then(|s| s.parse().ok())
|
|
|
|
|
.expect("no public ip specified")
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
static CLIENT_URI: Lazy<String> = Lazy::new(||{
|
|
|
|
|
format!("http://{}:{}", *IP, *PORT)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
#[derive(Error, Debug)]
|
|
|
|
|
pub enum Error{
|
|
|
|
|
#[error(transparent)]
|
|
|
|
|
Transport(#[from] transport::Error),
|
|
|
|
|
#[error(transparent)]
|
2025-02-02 20:25:22 +01:00
|
|
|
Status(#[from] tonic::Status),
|
|
|
|
|
#[error("invalid password size: {0}")]
|
|
|
|
|
PasswordConversion(#[from] TryFromSliceError)
|
2025-02-02 00:46:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub type Result<T> = result::Result<T, Error>;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub struct Client(AccountClient<InterceptedService<Channel, InterceptorFunc>>);
|
|
|
|
|
|
|
|
|
|
impl Client{
|
|
|
|
|
pub async fn new() -> Result<Self>{
|
|
|
|
|
let channel = Channel::from_static(&*CLIENT_URI).connect().await?;
|
|
|
|
|
|
|
|
|
|
let func = Box::new(&|mut req: Request<()>|{
|
|
|
|
|
req.metadata_mut().insert("x-api-key", API_KEY.clone());
|
|
|
|
|
Ok(req)
|
|
|
|
|
}) as InterceptorFunc;
|
|
|
|
|
|
|
|
|
|
let client = AccountClient::with_interceptor(channel, func);
|
|
|
|
|
Ok(Self(client))
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-02 20:25:22 +01:00
|
|
|
pub async fn get_nex_password(&mut self , pid: u32) -> Result<[u8; 16]>{
|
2025-02-02 00:46:04 +01:00
|
|
|
let req = Request::new(GetNexPasswordRequest{
|
|
|
|
|
pid
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let response = self.0.get_nex_password(req).await?.into_inner();
|
|
|
|
|
|
2025-02-02 20:25:22 +01:00
|
|
|
Ok(response.password.as_bytes().try_into()?)
|
2025-02-02 00:46:04 +01:00
|
|
|
}
|
2025-02-05 16:02:32 +01:00
|
|
|
|
|
|
|
|
pub async fn get_user_data(&mut self , pid: u32) -> Result<GetUserDataResponse>{
|
|
|
|
|
let req = Request::new(GetUserDataRequest{
|
|
|
|
|
pid
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let response = self.0.get_user_data(req).await?.into_inner();
|
|
|
|
|
|
|
|
|
|
Ok(response)
|
|
|
|
|
}
|
2025-02-02 00:46:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod test{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|