chore(core): fix pre-existing clippy warnings (-D warnings gate)
Resolves pre-existing lint issues in imgsecret.rs, time.rs, totp.rs, and crypto.rs that blocked the cargo clippy --workspace -D warnings gate. No logic changes: loop-index → iterator, manual div_ceil → .div_ceil(), manual range contains → .contains(), auto-deref cleanup. Also fixes pre-existing warnings in relicario-cli (main.rs, session.rs, device.rs, gitea.rs, helpers.rs, test helpers): dead_code suppression, too_many_arguments, literal_with_empty_format_string, manual_char_cmp, map_or → is_none_or, and repeat().take() → vec! in test helpers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -91,6 +91,7 @@ pub fn store_device_keys(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Load the signing private key for a device.
|
/// Load the signing private key for a device.
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn load_signing_key(name: &str) -> Result<Zeroizing<String>> {
|
pub fn load_signing_key(name: &str) -> Result<Zeroizing<String>> {
|
||||||
let path = device_dir(name)?.join("signing.key");
|
let path = device_dir(name)?.join("signing.key");
|
||||||
let key = fs::read_to_string(&path)
|
let key = fs::read_to_string(&path)
|
||||||
@@ -99,6 +100,7 @@ pub fn load_signing_key(name: &str) -> Result<Zeroizing<String>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Load the deploy private key for a device.
|
/// Load the deploy private key for a device.
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn load_deploy_key(name: &str) -> Result<Zeroizing<String>> {
|
pub fn load_deploy_key(name: &str) -> Result<Zeroizing<String>> {
|
||||||
let path = device_dir(name)?.join("deploy.key");
|
let path = device_dir(name)?.join("deploy.key");
|
||||||
let key = fs::read_to_string(&path)
|
let key = fs::read_to_string(&path)
|
||||||
@@ -115,6 +117,7 @@ pub fn load_gitea_key_id(name: &str) -> Result<u64> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Delete the local key directory for a device.
|
/// Delete the local key directory for a device.
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn delete_device_keys(name: &str) -> Result<()> {
|
pub fn delete_device_keys(name: &str) -> Result<()> {
|
||||||
let dir = device_dir(name)?;
|
let dir = device_dir(name)?;
|
||||||
if dir.exists() {
|
if dir.exists() {
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ struct CreateKeyRequest<'a> {
|
|||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct DeployKey {
|
pub struct DeployKey {
|
||||||
pub id: u64,
|
pub id: u64,
|
||||||
|
#[allow(dead_code)]
|
||||||
pub title: String,
|
pub title: String,
|
||||||
|
#[allow(dead_code)]
|
||||||
pub key: String,
|
pub key: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,6 +91,7 @@ impl GiteaClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// List all deploy keys.
|
/// List all deploy keys.
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn list_deploy_keys(&self) -> Result<Vec<DeployKey>> {
|
pub fn list_deploy_keys(&self) -> Result<Vec<DeployKey>> {
|
||||||
let url = format!(
|
let url = format!(
|
||||||
"{}/repos/{}/{}/keys",
|
"{}/repos/{}/{}/keys",
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ pub fn vault_dir() -> Result<PathBuf> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Path to the `.relicario/` configuration directory within the vault.
|
/// Path to the `.relicario/` configuration directory within the vault.
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn relicario_dir() -> Result<PathBuf> {
|
pub fn relicario_dir() -> Result<PathBuf> {
|
||||||
Ok(vault_dir()?.join(".relicario"))
|
Ok(vault_dir()?.join(".relicario"))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -540,7 +540,7 @@ fn cmd_init(image: PathBuf, output: PathBuf) -> Result<()> {
|
|||||||
};
|
};
|
||||||
let carrier = fs::read(&image)
|
let carrier = fs::read(&image)
|
||||||
.with_context(|| format!("failed to read carrier image {}", image.display()))?;
|
.with_context(|| format!("failed to read carrier image {}", image.display()))?;
|
||||||
let stego = imgsecret::embed(&carrier, &*image_secret)?;
|
let stego = imgsecret::embed(&carrier, &image_secret)?;
|
||||||
fs::write(&output, &stego)
|
fs::write(&output, &stego)
|
||||||
.with_context(|| format!("failed to write reference image {}", output.display()))?;
|
.with_context(|| format!("failed to write reference image {}", output.display()))?;
|
||||||
|
|
||||||
@@ -550,7 +550,7 @@ fn cmd_init(image: PathBuf, output: PathBuf) -> Result<()> {
|
|||||||
let params = KdfParams { argon2_m: 65536, argon2_t: 3, argon2_p: 4 };
|
let params = KdfParams { argon2_m: 65536, argon2_t: 3, argon2_p: 4 };
|
||||||
|
|
||||||
// Derive master key, then persist an empty Manifest + default VaultSettings.
|
// Derive master key, then persist an empty Manifest + default VaultSettings.
|
||||||
let master_key = derive_master_key(passphrase.as_bytes(), &*image_secret, &salt, ¶ms)?;
|
let master_key = derive_master_key(passphrase.as_bytes(), &image_secret, &salt, ¶ms)?;
|
||||||
|
|
||||||
fs::create_dir_all(&relicario_dir)?;
|
fs::create_dir_all(&relicario_dir)?;
|
||||||
fs::create_dir_all(root.join("items"))?;
|
fs::create_dir_all(root.join("items"))?;
|
||||||
@@ -645,6 +645,7 @@ fn cmd_add(kind: AddKind) -> Result<()> {
|
|||||||
// (for attachment-cap settings + writing the encrypted blob alongside
|
// (for attachment-cap settings + writing the encrypted blob alongside
|
||||||
// the item).
|
// the item).
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn build_login_item(
|
fn build_login_item(
|
||||||
title: Option<String>,
|
title: Option<String>,
|
||||||
username: Option<String>,
|
username: Option<String>,
|
||||||
@@ -860,6 +861,7 @@ fn build_document_item(
|
|||||||
Ok(item)
|
Ok(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn build_totp_item(
|
fn build_totp_item(
|
||||||
title: Option<String>,
|
title: Option<String>,
|
||||||
issuer: Option<String>,
|
issuer: Option<String>,
|
||||||
@@ -924,7 +926,7 @@ fn prompt_optional(label: &str) -> Result<Option<String>> {
|
|||||||
|
|
||||||
fn parse_month_year(s: &str) -> Result<relicario_core::MonthYear> {
|
fn parse_month_year(s: &str) -> Result<relicario_core::MonthYear> {
|
||||||
// Accepts MM/YYYY or MM-YYYY or MM/YY.
|
// Accepts MM/YYYY or MM-YYYY or MM/YY.
|
||||||
let (m_str, y_str) = s.split_once(|c: char| c == '/' || c == '-')
|
let (m_str, y_str) = s.split_once(['/', '-'])
|
||||||
.ok_or_else(|| anyhow::anyhow!("expected MM/YYYY"))?;
|
.ok_or_else(|| anyhow::anyhow!("expected MM/YYYY"))?;
|
||||||
let month: u8 = m_str.parse().context("invalid month")?;
|
let month: u8 = m_str.parse().context("invalid month")?;
|
||||||
let year: u16 = if y_str.len() == 2 {
|
let year: u16 = if y_str.len() == 2 {
|
||||||
@@ -998,12 +1000,12 @@ fn cmd_get(query: String, show: bool, copy: bool) -> Result<()> {
|
|||||||
if let Some(u) = &l.url { println!("URL: {u}"); }
|
if let Some(u) = &l.url { println!("URL: {u}"); }
|
||||||
if let Some(t) = &l.totp {
|
if let Some(t) = &l.totp {
|
||||||
if show {
|
if show {
|
||||||
println!("TOTP: {}", data_encoding::BASE32.encode(&*t.secret));
|
println!("TOTP: {}", data_encoding::BASE32.encode(&t.secret));
|
||||||
} else {
|
} else {
|
||||||
println!("TOTP: **** (use --show to reveal)");
|
println!("TOTP: **** (use --show to reveal)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(p) = &l.password { Some(p.clone()) } else { None }
|
l.password.clone()
|
||||||
}
|
}
|
||||||
ItemCore::SecureNote(n) => {
|
ItemCore::SecureNote(n) => {
|
||||||
if show { println!("Body:\n{}", n.body.as_str()); }
|
if show { println!("Body:\n{}", n.body.as_str()); }
|
||||||
@@ -1125,8 +1127,8 @@ fn cmd_list(
|
|||||||
Some(t) => e.r#type == t,
|
Some(t) => e.r#type == t,
|
||||||
None => true,
|
None => true,
|
||||||
})
|
})
|
||||||
.filter(|e| group_filter.as_ref().map_or(true, |g| e.group.as_deref() == Some(g.as_str())))
|
.filter(|e| group_filter.as_ref().is_none_or(|g| e.group.as_deref() == Some(g.as_str())))
|
||||||
.filter(|e| tag_filter.as_ref().map_or(true, |t| e.tags.iter().any(|x| x == t)))
|
.filter(|e| tag_filter.as_ref().is_none_or(|t| e.tags.iter().any(|x| x == t)))
|
||||||
.collect();
|
.collect();
|
||||||
entries.sort_by(|a, b| a.title.to_lowercase().cmp(&b.title.to_lowercase()));
|
entries.sort_by(|a, b| a.title.to_lowercase().cmp(&b.title.to_lowercase()));
|
||||||
|
|
||||||
@@ -1135,7 +1137,7 @@ fn cmd_list(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("{:<16} {:<14} {:<6} {}", "ID", "TYPE", "FAV", "TITLE");
|
println!("{:<16} {:<14} {:<6} TITLE", "ID", "TYPE", "FAV");
|
||||||
for e in entries {
|
for e in entries {
|
||||||
let fav = if e.favorite { " *" } else { "" };
|
let fav = if e.favorite { " *" } else { "" };
|
||||||
println!("{:<16} {:<14} {:<6} {}", e.id.as_str(), format!("{:?}", e.r#type), fav, e.title);
|
println!("{:<16} {:<14} {:<6} {}", e.id.as_str(), format!("{:?}", e.r#type), fav, e.title);
|
||||||
@@ -1973,7 +1975,7 @@ fn cmd_attachments(query: String) -> Result<()> {
|
|||||||
let entry = resolve_query(&manifest, &query)?;
|
let entry = resolve_query(&manifest, &query)?;
|
||||||
let item = vault.load_item(&entry.id)?;
|
let item = vault.load_item(&entry.id)?;
|
||||||
if item.attachments.is_empty() { eprintln!("(no attachments)"); return Ok(()); }
|
if item.attachments.is_empty() { eprintln!("(no attachments)"); return Ok(()); }
|
||||||
println!("{:<17} {:>12} {:<22} {}", "AID", "SIZE", "MIME", "FILENAME");
|
println!("{:<17} {:>12} {:<22} FILENAME", "AID", "SIZE", "MIME");
|
||||||
for a in &item.attachments {
|
for a in &item.attachments {
|
||||||
println!("{:<17} {:>12} {:<22} {}", a.id.as_str(), a.size, a.mime_type, a.filename);
|
println!("{:<17} {:>12} {:<22} {}", a.id.as_str(), a.size, a.mime_type, a.filename);
|
||||||
}
|
}
|
||||||
@@ -2541,7 +2543,7 @@ fn cmd_device(action: DeviceAction) -> Result<()> {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("{:<20} {:<20} {}", "NAME", "ADDED", "SIGNING KEY (prefix)");
|
println!("{:<20} {:<20} SIGNING KEY (prefix)", "NAME", "ADDED");
|
||||||
println!("{}", "-".repeat(72));
|
println!("{}", "-".repeat(72));
|
||||||
for d in &devices {
|
for d in &devices {
|
||||||
let marker = if d.name == current { " *" } else { "" };
|
let marker = if d.name == current { " *" } else { "" };
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ impl UnlockedVault {
|
|||||||
|
|
||||||
let master_key = derive_master_key(
|
let master_key = derive_master_key(
|
||||||
passphrase.as_bytes(),
|
passphrase.as_bytes(),
|
||||||
&*image_secret,
|
&image_secret,
|
||||||
&salt,
|
&salt,
|
||||||
¶ms,
|
¶ms,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ fn detach_removes_attachment_and_blob() {
|
|||||||
// Encrypted blob file is gone.
|
// Encrypted blob file is gone.
|
||||||
let blob_path = v.path()
|
let blob_path = v.path()
|
||||||
.join("attachments")
|
.join("attachments")
|
||||||
.join(stdout.lines().nth(1).is_some().then_some("").unwrap_or(""));
|
.join("");
|
||||||
let item_attach_dir = std::fs::read_dir(v.path().join("attachments"))
|
let item_attach_dir = std::fs::read_dir(v.path().join("attachments"))
|
||||||
.unwrap().next().unwrap().unwrap().path();
|
.unwrap().next().unwrap().unwrap().path();
|
||||||
let blob = item_attach_dir.join(format!("{aid}.enc"));
|
let blob = item_attach_dir.join(format!("{aid}.enc"));
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ impl TestVault {
|
|||||||
cmd.output().unwrap()
|
cmd.output().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn run_with_backup_pass(&self, args: &[&str], backup_pass: &str) -> std::process::Output {
|
pub fn run_with_backup_pass(&self, args: &[&str], backup_pass: &str) -> std::process::Output {
|
||||||
let mut cmd = Command::cargo_bin("relicario").unwrap();
|
let mut cmd = Command::cargo_bin("relicario").unwrap();
|
||||||
cmd.current_dir(self.dir.path())
|
cmd.current_dir(self.dir.path())
|
||||||
@@ -91,6 +92,7 @@ impl TestVault {
|
|||||||
cmd.output().unwrap()
|
cmd.output().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn run_with_input(&self, args: &[&str], extra: &[&str]) -> std::process::Output {
|
pub fn run_with_input(&self, args: &[&str], extra: &[&str]) -> std::process::Output {
|
||||||
let mut cmd = Command::cargo_bin("relicario").unwrap();
|
let mut cmd = Command::cargo_bin("relicario").unwrap();
|
||||||
cmd.current_dir(self.dir.path())
|
cmd.current_dir(self.dir.path())
|
||||||
|
|||||||
@@ -408,7 +408,7 @@ mod tests {
|
|||||||
blob.extend_from_slice(&[0u8; 16]);
|
blob.extend_from_slice(&[0u8; 16]);
|
||||||
|
|
||||||
let key = Zeroizing::new([0u8; 32]);
|
let key = Zeroizing::new([0u8; 32]);
|
||||||
let err = decrypt(&*key, &blob).expect_err("v1 blob should fail decrypt");
|
let err = decrypt(&key, &blob).expect_err("v1 blob should fail decrypt");
|
||||||
match err {
|
match err {
|
||||||
RelicarioError::UnsupportedFormatVersion { found, expected } => {
|
RelicarioError::UnsupportedFormatVersion { found, expected } => {
|
||||||
assert_eq!(found, 0x01);
|
assert_eq!(found, 0x01);
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ const BITS_PER_BLOCK: usize = 12; // EMBED_POSITIONS.len()
|
|||||||
|
|
||||||
/// Number of 8x8 blocks needed to hold one complete copy of the 256-bit secret.
|
/// Number of 8x8 blocks needed to hold one complete copy of the 256-bit secret.
|
||||||
/// ceil(256 / 12) = 22 blocks per copy.
|
/// ceil(256 / 12) = 22 blocks per copy.
|
||||||
const BLOCKS_PER_COPY: usize = (SECRET_BITS + BITS_PER_BLOCK - 1) / BITS_PER_BLOCK; // 22
|
const BLOCKS_PER_COPY: usize = SECRET_BITS.div_ceil(BITS_PER_BLOCK); // 22
|
||||||
|
|
||||||
/// Mid-frequency DCT coefficient positions for embedding, specified as
|
/// Mid-frequency DCT coefficient positions for embedding, specified as
|
||||||
/// (row, col) indices into the 8x8 DCT coefficient matrix.
|
/// (row, col) indices into the 8x8 DCT coefficient matrix.
|
||||||
@@ -302,9 +302,9 @@ fn read_block_abs(y: &YChannel, px: usize, py: usize) -> Option<[[f64; 8]; 8]> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let mut block = [[0.0f64; 8]; 8];
|
let mut block = [[0.0f64; 8]; 8];
|
||||||
for row in 0..8 {
|
for (row, block_row) in block.iter_mut().enumerate() {
|
||||||
for col in 0..8 {
|
for (col, cell) in block_row.iter_mut().enumerate() {
|
||||||
block[row][col] = y.get(px + col, py + row);
|
*cell = y.get(px + col, py + row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(block)
|
Some(block)
|
||||||
@@ -323,9 +323,9 @@ fn read_block(y: &YChannel, bx: usize, by: usize, region: &EmbedRegion) -> [[f64
|
|||||||
fn write_block(y: &mut YChannel, bx: usize, by: usize, region: &EmbedRegion, block: &[[f64; 8]; 8]) {
|
fn write_block(y: &mut YChannel, bx: usize, by: usize, region: &EmbedRegion, block: &[[f64; 8]; 8]) {
|
||||||
let start_x = region.x_offset + bx * BLOCK_SIZE;
|
let start_x = region.x_offset + bx * BLOCK_SIZE;
|
||||||
let start_y = region.y_offset + by * BLOCK_SIZE;
|
let start_y = region.y_offset + by * BLOCK_SIZE;
|
||||||
for row in 0..8 {
|
for (row, block_row) in block.iter().enumerate() {
|
||||||
for col in 0..8 {
|
for (col, &cell) in block_row.iter().enumerate() {
|
||||||
y.set(start_x + col, start_y + row, block[row][col]);
|
y.set(start_x + col, start_y + row, cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -349,17 +349,17 @@ fn write_block(y: &mut YChannel, bx: usize, by: usize, region: &EmbedRegion, blo
|
|||||||
/// where c(0) = sqrt(1/8) and c(k) = sqrt(2/8) for k > 0.
|
/// where c(0) = sqrt(1/8) and c(k) = sqrt(2/8) for k > 0.
|
||||||
fn dct1d(input: &[f64; 8]) -> [f64; 8] {
|
fn dct1d(input: &[f64; 8]) -> [f64; 8] {
|
||||||
let mut output = [0.0f64; 8];
|
let mut output = [0.0f64; 8];
|
||||||
for k in 0..8 {
|
for (k, out_k) in output.iter_mut().enumerate() {
|
||||||
let ck = if k == 0 {
|
let ck = if k == 0 {
|
||||||
(1.0 / 8.0_f64).sqrt()
|
(1.0 / 8.0_f64).sqrt()
|
||||||
} else {
|
} else {
|
||||||
(2.0 / 8.0_f64).sqrt()
|
(2.0 / 8.0_f64).sqrt()
|
||||||
};
|
};
|
||||||
let mut sum = 0.0;
|
let mut sum = 0.0;
|
||||||
for i in 0..8 {
|
for (i, &x) in input.iter().enumerate() {
|
||||||
sum += input[i] * ((2 * i + 1) as f64 * k as f64 * PI / 16.0).cos();
|
sum += x * ((2 * i + 1) as f64 * k as f64 * PI / 16.0).cos();
|
||||||
}
|
}
|
||||||
output[k] = ck * sum;
|
*out_k = ck * sum;
|
||||||
}
|
}
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
@@ -370,17 +370,17 @@ fn dct1d(input: &[f64; 8]) -> [f64; 8] {
|
|||||||
/// x[i] = sum_{k=0}^{7} c(k) * X[k] * cos((2i+1)*k*pi/16)
|
/// x[i] = sum_{k=0}^{7} c(k) * X[k] * cos((2i+1)*k*pi/16)
|
||||||
fn idct1d(input: &[f64; 8]) -> [f64; 8] {
|
fn idct1d(input: &[f64; 8]) -> [f64; 8] {
|
||||||
let mut output = [0.0f64; 8];
|
let mut output = [0.0f64; 8];
|
||||||
for i in 0..8 {
|
for (i, out_i) in output.iter_mut().enumerate() {
|
||||||
let mut sum = 0.0;
|
let mut sum = 0.0;
|
||||||
for k in 0..8 {
|
for (k, &x) in input.iter().enumerate() {
|
||||||
let ck = if k == 0 {
|
let ck = if k == 0 {
|
||||||
(1.0 / 8.0_f64).sqrt()
|
(1.0 / 8.0_f64).sqrt()
|
||||||
} else {
|
} else {
|
||||||
(2.0 / 8.0_f64).sqrt()
|
(2.0 / 8.0_f64).sqrt()
|
||||||
};
|
};
|
||||||
sum += ck * input[k] * ((2 * i + 1) as f64 * k as f64 * PI / 16.0).cos();
|
sum += ck * x * ((2 * i + 1) as f64 * k as f64 * PI / 16.0).cos();
|
||||||
}
|
}
|
||||||
output[i] = sum;
|
*out_i = sum;
|
||||||
}
|
}
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
@@ -501,7 +501,7 @@ fn bytes_to_bits(bytes: &[u8]) -> Vec<u8> {
|
|||||||
///
|
///
|
||||||
/// Pads the last byte with zeros if the bit count is not a multiple of 8.
|
/// Pads the last byte with zeros if the bit count is not a multiple of 8.
|
||||||
fn bits_to_bytes(bits: &[u8]) -> Vec<u8> {
|
fn bits_to_bytes(bits: &[u8]) -> Vec<u8> {
|
||||||
let mut bytes = Vec::with_capacity((bits.len() + 7) / 8);
|
let mut bytes = Vec::with_capacity(bits.len().div_ceil(8));
|
||||||
for chunk in bits.chunks(8) {
|
for chunk in bits.chunks(8) {
|
||||||
let mut byte = 0u8;
|
let mut byte = 0u8;
|
||||||
for (i, &bit) in chunk.iter().enumerate() {
|
for (i, &bit) in chunk.iter().enumerate() {
|
||||||
|
|||||||
@@ -52,18 +52,15 @@ pub enum TotpAlgorithm {
|
|||||||
Sha512,
|
Sha512,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum TotpKind {
|
pub enum TotpKind {
|
||||||
|
#[default]
|
||||||
Totp,
|
Totp,
|
||||||
Hotp { counter: u64 },
|
Hotp { counter: u64 },
|
||||||
Steam,
|
Steam,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TotpKind {
|
|
||||||
fn default() -> Self { TotpKind::Totp }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compute a TOTP/Steam code for `config` at the given Unix timestamp.
|
/// Compute a TOTP/Steam code for `config` at the given Unix timestamp.
|
||||||
///
|
///
|
||||||
/// For TOTP and Steam: counter = `now_unix_seconds / period_seconds`.
|
/// For TOTP and Steam: counter = `now_unix_seconds / period_seconds`.
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ impl MonthYear {
|
|||||||
if !(1..=12).contains(&month) {
|
if !(1..=12).contains(&month) {
|
||||||
return Err("month must be 1..=12");
|
return Err("month must be 1..=12");
|
||||||
}
|
}
|
||||||
if year < 2000 || year > 2099 {
|
if !(2000..=2099).contains(&year) {
|
||||||
return Err("year must be 2000..=2099");
|
return Err("year must be 2000..=2099");
|
||||||
}
|
}
|
||||||
Ok(Self { month, year })
|
Ok(Self { month, year })
|
||||||
|
|||||||
@@ -51,12 +51,12 @@ fn raw_tar_with_path(raw_path: &[u8], content: &[u8]) -> Vec<u8> {
|
|||||||
// Pad to 512-byte boundary.
|
// Pad to 512-byte boundary.
|
||||||
let remainder = content.len() % 512;
|
let remainder = content.len() % 512;
|
||||||
if remainder != 0 {
|
if remainder != 0 {
|
||||||
out.extend(std::iter::repeat(0u8).take(512 - remainder));
|
out.extend(vec![0u8; 512 - remainder]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Two zero blocks = end-of-archive.
|
// Two zero blocks = end-of-archive.
|
||||||
out.extend(std::iter::repeat(0u8).take(1024));
|
out.extend(vec![0u8; 1024]);
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ fn raw_symlink_tar() -> Vec<u8> {
|
|||||||
buf[148..156].copy_from_slice(cksum_str.as_bytes());
|
buf[148..156].copy_from_slice(cksum_str.as_bytes());
|
||||||
|
|
||||||
let mut out = buf;
|
let mut out = buf;
|
||||||
out.extend(std::iter::repeat(0u8).take(1024)); // end-of-archive
|
out.extend(vec![0u8; 1024]); // end-of-archive
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user