Files
account/daemon/accountd/src/auth.rs
T
sisungo bfcc98b50e initial commit
Signed-off-by: sisungo <[email protected]>
2026-07-18 20:30:39 +08:00

58 lines
1.5 KiB
Rust

use anyhow::anyhow;
use semios_account::auth::{AuthCli, AuthMethodInfo};
use std::{
path::{Path, PathBuf},
process::Stdio,
};
#[derive(Debug)]
pub struct AuthExec(PathBuf);
impl AuthExec {
pub fn from_path_buf(path_buf: PathBuf) -> Self {
Self(path_buf)
}
pub fn name(&self) -> anyhow::Result<String> {
let err = || anyhow!("invalid auth exec \"{}\"", self.0.display());
self.0
.file_name()
.ok_or_else(err)?
.to_string_lossy()
.strip_prefix("auth_")
.ok_or_else(err)
.map(Into::into)
}
pub async fn info(&self) -> anyhow::Result<AuthMethodInfo> {
let wait = tokio::process::Command::new(&self.0)
.args(AuthCli::QueryInformation.compose())
.stdout(Stdio::piped())
.spawn()?
.wait_with_output()
.await?;
if !wait.status.success() {
return Err(anyhow!(
"process \"{}\" exited with status code {}",
self.0.display(),
wait.status
));
}
let parsed: AuthMethodInfo = serde_json::from_slice(&wait.stdout)?;
if parsed.name != self.name()? {
return Err(anyhow!(
"mismatched filename \"{}\" for auth method \"{}\"",
self.name()?,
parsed.name
));
}
Ok(parsed)
}
pub fn path(&self) -> &Path {
&self.0
}
}