116 lines
3.0 KiB
Rust
116 lines
3.0 KiB
Rust
use crate::sh;
|
|
use serde::Deserialize;
|
|
use std::io::{Error, ErrorKind};
|
|
|
|
const EXECUTABLE: &str = "bw";
|
|
|
|
#[derive(Deserialize, Clone)]
|
|
pub struct Item {
|
|
pub id: String,
|
|
pub name: String,
|
|
#[serde(rename = "passwordHistory")]
|
|
pub password_history: Vec<PasswordHistoryItem>,
|
|
#[serde(rename = "revisionDate")]
|
|
pub revision_date: String,
|
|
#[serde(rename = "creationDate")]
|
|
pub creation_date: String,
|
|
pub object: String,
|
|
#[serde(rename = "type")]
|
|
pub type_: u16,
|
|
pub notes: Option<String>,
|
|
pub favorite: bool,
|
|
pub fields: Vec<ItemField>,
|
|
pub login: Login,
|
|
}
|
|
|
|
#[derive(Deserialize, Clone)]
|
|
pub struct PasswordHistoryItem {
|
|
#[serde(rename = "lastUsedDate")]
|
|
pub last_used_date: String,
|
|
pub password: String,
|
|
}
|
|
|
|
#[derive(Deserialize, Clone)]
|
|
pub struct ItemField {
|
|
pub name: String,
|
|
pub value: String,
|
|
#[serde(rename = "type")]
|
|
pub type_: u16,
|
|
}
|
|
|
|
#[derive(Deserialize, Clone)]
|
|
pub struct Login {
|
|
pub uris: Vec<LoginUri>,
|
|
pub username: String,
|
|
pub password: String,
|
|
pub totp: Option<String>,
|
|
#[serde(rename = "passwordRevisionDate")]
|
|
pub password_revision_date: Option<String>,
|
|
#[serde(rename = "fido2Credentials")]
|
|
pub fido2_credentials: Vec<Fido2Credential>,
|
|
}
|
|
|
|
#[derive(Deserialize, Clone)]
|
|
pub struct LoginUri {
|
|
pub uri: String,
|
|
}
|
|
|
|
#[derive(Deserialize, Clone)]
|
|
pub struct Fido2Credential {
|
|
#[serde(rename = "credentialId")]
|
|
pub credential_id: String,
|
|
#[serde(rename = "keyType")]
|
|
pub key_type: String,
|
|
#[serde(rename = "keyAlgorithm")]
|
|
pub key_algorithm: String,
|
|
#[serde(rename = "keyCurve")]
|
|
pub key_curve: String,
|
|
#[serde(rename = "keyValue")]
|
|
pub key_value: String,
|
|
#[serde(rename = "rpId")]
|
|
pub rp_id: String,
|
|
#[serde(rename = "userHandle")]
|
|
pub user_handle: String,
|
|
#[serde(rename = "userName")]
|
|
pub user_name: String,
|
|
pub counter: String,
|
|
#[serde(rename = "rpName")]
|
|
pub rp_name: String,
|
|
#[serde(rename = "userDisplayName")]
|
|
pub user_display_name: String,
|
|
pub discoverable: String,
|
|
#[serde(rename = "creationDate")]
|
|
pub creation_date: String,
|
|
}
|
|
|
|
pub fn check_bw() -> Result<String, Error> {
|
|
let which = sh::sh(format!("which {}", EXECUTABLE));
|
|
if which.is_empty() {
|
|
return Err(Error::new(
|
|
ErrorKind::Other,
|
|
format!("{} is not installed", EXECUTABLE),
|
|
));
|
|
}
|
|
|
|
let session = sh::sh(format!("{} unlock", EXECUTABLE));
|
|
if session.is_empty() {
|
|
return Err(Error::new(
|
|
ErrorKind::Other,
|
|
format!("{} couldn't unlock", EXECUTABLE),
|
|
));
|
|
}
|
|
|
|
Ok(session)
|
|
}
|
|
|
|
pub fn get_items(session: String) -> Result<Vec<Item>, Error> {
|
|
let items_raw = sh::sh(format!("BW_SESSION={} {} list --raw", session, EXECUTABLE));
|
|
match serde_json::from_str(items_raw.as_str()) {
|
|
Ok(val) => Ok(val),
|
|
Err(e) => Err(Error::new(
|
|
ErrorKind::Other,
|
|
format!("Couldn't get items: {e}"),
|
|
)),
|
|
}
|
|
}
|