tor-keymgr, tor-hsservice: deser for ArtiPathComponent and HsNickname

This commit is contained in:
Ian Jackson 2023-08-23 15:30:45 +01:00
parent 89c019e04f
commit 8596d42372
6 changed files with 51 additions and 0 deletions

2
Cargo.lock generated
View File

@ -4641,6 +4641,7 @@ dependencies = [
"rand_core 0.6.4",
"safelog",
"serde",
"serde_json",
"thiserror",
"tor-async-utils",
"tor-basic-utils",
@ -4674,6 +4675,7 @@ dependencies = [
"rand 0.8.5",
"sec1",
"serde",
"serde_json",
"ssh-key",
"tempfile",
"thiserror",

View File

@ -61,4 +61,5 @@ void = "1"
[dev-dependencies]
humantime = "2"
serde_json = "1.0.104"
tor-rtmock = { path = "../tor-rtmock", version = "0.9.0" }

View File

@ -1,6 +1,7 @@
//! `HsNickname` module itself is private, but `HsNickname` etc. are re-exported
use derive_more::{Display, From, Into};
use serde::{Deserialize, Serialize};
use thiserror::Error;
use tor_keymgr::ArtiPathComponent;
@ -19,6 +20,8 @@ use tor_keymgr::ArtiPathComponent;
/// (These are the same rules as [`tor_keymgr::ArtiPathComponent`]
#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
#[derive(Display, From, Into)]
#[derive(Serialize, Deserialize)]
#[serde(try_from = "String", into = "String")]
pub struct HsNickname(ArtiPathComponent);
/// Local nickname for Tor Hidden Service (`.onion` service) was syntactically invalid
@ -85,4 +88,22 @@ mod test {
assert_eq!(HsNickname::new("_c".into()), Err(InvalidNickname {}));
assert_eq!(&HsNickname::new("x".into()).unwrap().to_string(), "x");
}
#[test]
fn serde() {
// TODO HSS clone-and-hack with tor_keymgr::::key_specifier::test::serde
#[derive(Serialize, Deserialize, Debug)]
struct T {
n: HsNickname,
}
let j = serde_json::from_str(r#"{ "n": "x" }"#).unwrap();
let t: T = serde_json::from_value(j).unwrap();
assert_eq!(&t.n.to_string(), "x");
assert_eq!(&serde_json::to_string(&t).unwrap(), r#"{"n":"x"}"#);
let j = serde_json::from_str(r#"{ "n": "!" }"#).unwrap();
let e = serde_json::from_value::<T>(j).unwrap_err();
assert!(e.to_string().contains("Invalid syntax"), "wrong msg {e:?}");
}
}

View File

@ -51,6 +51,7 @@ tor-llcrypto = { path = "../tor-llcrypto", version = "0.5.2", features = ["keymg
zeroize = "1"
[dev-dependencies]
serde_json = "1.0.104"
tempfile = "3"
tor-basic-utils = { path = "../tor-basic-utils", version = "0.7.3" }

View File

@ -6,3 +6,4 @@ BREAKING: ssh-key is bumped to 0.6.0 (we re-export `ssh_key`)
ADDED: ArtiPathComponent is TryFrom<String>
ADDED: ArtiPathComponent is AsRef<str>
ADDED: ArtiPathComponent is Hash, Eq, PartialEq, Ord, PartialOrd
ADDED: ArtiPathComponent is Serialize, Deserialize

View File

@ -2,6 +2,7 @@
use crate::Result;
use derive_more::{Deref, DerefMut, Display, Into};
use serde::{Deserialize, Serialize};
use tor_error::internal;
/// The path of a key in the Arti key store.
@ -50,6 +51,8 @@ impl ArtiPath {
Clone, Debug, derive_more::Deref, derive_more::DerefMut, derive_more::Into, derive_more::Display,
)]
#[derive(Hash, Eq, PartialEq, Ord, PartialOrd)]
#[derive(Serialize, Deserialize)]
#[serde(try_from = "String", into = "String")]
pub struct ArtiPathComponent(String);
impl ArtiPathComponent {
@ -206,4 +209,26 @@ mod test {
check_valid!(ArtiPath, &path, true);
check_valid!(ArtiPathComponent, &path, false);
}
#[test]
fn serde() {
// TODO HSS clone-and-hack with tor_hsservice::::nickname::test::serde
// perhaps there should be some utility in tor-basic-utils for testing
// validated string newtypes, or something
#[derive(Serialize, Deserialize, Debug)]
struct T {
n: ArtiPathComponent,
}
let j = serde_json::from_str(r#"{ "n": "x" }"#).unwrap();
let t: T = serde_json::from_value(j).unwrap();
assert_eq!(&t.n.to_string(), "x");
assert_eq!(&serde_json::to_string(&t).unwrap(), r#"{"n":"x"}"#);
let j = serde_json::from_str(r#"{ "n": "!" }"#).unwrap();
let e = serde_json::from_value::<T>(j).unwrap_err();
// TODO HSS this is the wrong error message, this might not be a bug;
// it could be bad config or something
assert!(e.to_string().contains("internal error"), "wrong msg {e:?}");
}
}