Added proper tests (but more should be addedgit add --all :/)
This commit is contained in:
parent
792a821de0
commit
70178cb8d6
@ -1,4 +1,5 @@
|
|||||||
use crate::exporter_error::PeerEntryParseError;
|
use crate::exporter_error::PeerEntryParseError;
|
||||||
|
use log::debug;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
@ -22,82 +23,96 @@ fn after_char(s: &str, c_split: char) -> &str {
|
|||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_peer_entry<'a>(lines: &[&'a str]) -> Result<PeerEntry<'a>, PeerEntryParseError> {
|
impl<'a> TryFrom<&[&'a str]> for PeerEntry<'a> {
|
||||||
let mut public_key = "";
|
type Error = PeerEntryParseError;
|
||||||
let mut allowed_ips = "";
|
|
||||||
let mut name = None;
|
|
||||||
|
|
||||||
for line in lines {
|
fn try_from(lines: &[&'a str]) -> Result<PeerEntry<'a>, Self::Error> {
|
||||||
if line.starts_with("PublicKey") {
|
let mut public_key = "";
|
||||||
public_key = after_char(line, '=').trim();
|
let mut allowed_ips = "";
|
||||||
} else if line.starts_with("AllowedIPs") {
|
let mut name = None;
|
||||||
allowed_ips = after_char(line, '=').trim();
|
|
||||||
} else if line.starts_with("#") {
|
for line in lines {
|
||||||
name = Some(line[1..].trim());
|
if line.starts_with("PublicKey") {
|
||||||
|
public_key = after_char(line, '=').trim();
|
||||||
|
} else if line.starts_with("AllowedIPs") {
|
||||||
|
allowed_ips = after_char(line, '=').trim();
|
||||||
|
} else if line.starts_with("#") {
|
||||||
|
// since the pound sign is 1 byte the below slice will work
|
||||||
|
name = Some(line[1..].trim());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
if public_key == "" {
|
// If there are more than one PublicKey or AllowedIPs we won't catch it. But
|
||||||
let lines_owned: Vec<String> = lines.into_iter().map(|line| line.to_string()).collect();
|
// WireGuard won't be working either so we can live with this simplification.
|
||||||
Err(PeerEntryParseError::PublicKeyNotFound { lines: lines_owned })
|
if public_key == "" {
|
||||||
} else if allowed_ips == "" {
|
// we return a owned String for ergonomics. This will allocate but it's ok since it's not supposed
|
||||||
let lines_owned: Vec<String> = lines.into_iter().map(|line| line.to_string()).collect();
|
// to happen :)
|
||||||
Err(PeerEntryParseError::AllowedIPsEntryNotFound { lines: lines_owned })
|
let lines_owned: Vec<String> = lines.into_iter().map(|line| line.to_string()).collect();
|
||||||
} else {
|
Err(PeerEntryParseError::PublicKeyNotFound { lines: lines_owned })
|
||||||
Ok(PeerEntry {
|
} else if allowed_ips == "" {
|
||||||
public_key,
|
let lines_owned: Vec<String> = lines.into_iter().map(|line| line.to_string()).collect();
|
||||||
allowed_ips,
|
Err(PeerEntryParseError::AllowedIPsEntryNotFound { lines: lines_owned })
|
||||||
name, // name can be None
|
} else {
|
||||||
})
|
Ok(PeerEntry {
|
||||||
|
public_key,
|
||||||
|
allowed_ips,
|
||||||
|
name, // name can be None
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn parse<'a>(
|
#[derive(Debug, Default, Clone)]
|
||||||
txt: &'a str,
|
pub(crate) struct PeerEntryHashMap<'a>(HashMap<&'a str, PeerEntry<'a>>);
|
||||||
) -> Result<HashMap<&'a str, PeerEntry<'a>>, PeerEntryParseError> {
|
|
||||||
let mut ht = HashMap::new();
|
|
||||||
|
|
||||||
let mut v_blocks = Vec::new();
|
impl<'a> TryFrom<&'a str> for PeerEntryHashMap<'a> {
|
||||||
let mut cur_block: Option<Vec<&str>> = None;
|
type Error = PeerEntryParseError;
|
||||||
|
|
||||||
for line in txt.lines().into_iter() {
|
fn try_from(txt: &'a str) -> Result<PeerEntryHashMap, Self::Error> {
|
||||||
if line.starts_with("[") {
|
let mut hm = HashMap::new();
|
||||||
if let Some(inner_cur_block) = cur_block {
|
|
||||||
// close the block
|
|
||||||
v_blocks.push(inner_cur_block);
|
|
||||||
cur_block = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
if line == "[Peer]" {
|
let mut v_blocks = Vec::new();
|
||||||
// start a new block
|
let mut cur_block: Option<Vec<&str>> = None;
|
||||||
cur_block = Some(Vec::new());
|
|
||||||
}
|
for line in txt.lines().into_iter() {
|
||||||
} else {
|
if line.starts_with("[") {
|
||||||
// push the line if we are in a block (only if not empty)
|
if let Some(inner_cur_block) = cur_block {
|
||||||
if let Some(inner_cur_block) = &mut cur_block {
|
// close the block
|
||||||
if line != "" {
|
v_blocks.push(inner_cur_block);
|
||||||
inner_cur_block.push(line);
|
cur_block = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if line == "[Peer]" {
|
||||||
|
// start a new block
|
||||||
|
cur_block = Some(Vec::new());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// push the line if we are in a block (only if not empty)
|
||||||
|
if let Some(inner_cur_block) = &mut cur_block {
|
||||||
|
if line != "" {
|
||||||
|
inner_cur_block.push(line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(cur_block) = cur_block {
|
||||||
|
// we have a leftover block
|
||||||
|
v_blocks.push(cur_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug!("v_blocks == {:?}", v_blocks);
|
||||||
|
|
||||||
|
for block in &v_blocks {
|
||||||
|
let p: PeerEntry = PeerEntry::try_from(&block as &[&str])?;
|
||||||
|
hm.insert(p.public_key, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug!("hm == {:?}", hm);
|
||||||
|
|
||||||
|
Ok(PeerEntryHashMap(hm))
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(cur_block) = cur_block {
|
|
||||||
// we have a leftover block
|
|
||||||
v_blocks.push(cur_block);
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("v_blocks == {:?}", v_blocks);
|
|
||||||
|
|
||||||
for block in &v_blocks {
|
|
||||||
let p = parse_peer_entry(block)?;
|
|
||||||
ht.insert(p.public_key, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("ht == {:?}", ht);
|
|
||||||
|
|
||||||
Ok(ht)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -139,14 +154,69 @@ AllowedIPs = 10.70.0.40/32
|
|||||||
# OnePlus 5T
|
# OnePlus 5T
|
||||||
PublicKey = 928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=
|
PublicKey = 928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=
|
||||||
AllowedIPs = 10.70.0.80/32
|
AllowedIPs = 10.70.0.80/32
|
||||||
|
";
|
||||||
|
|
||||||
|
const TEXT_NOPK: &'static str = "
|
||||||
|
ListenPort = 51820
|
||||||
|
PrivateKey = my_super_secret_private_key
|
||||||
|
# PreUp = iptables -t nat -A POSTROUTING -s 10.70.0.0/24 -o enp7s0 -j MASQUERADE
|
||||||
|
# PostDown = iptables -t nat -D POSTROUTING -s 10.70.0.0/24 -o enp7s0 -j MASQUERADE
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
# OnePlus 6T
|
||||||
|
PublicKey = 2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=
|
||||||
|
AllowedIPs = 10.70.0.2/32
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
# varch.local (laptop)
|
||||||
|
AllowedIPs = 10.70.0.3/32
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
# cantarch
|
||||||
|
PublicKey = L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=
|
||||||
|
AllowedIPs = 10.70.0.4/32
|
||||||
|
";
|
||||||
|
|
||||||
|
const TEXT_AIP: &'static str = "
|
||||||
|
ListenPort = 51820
|
||||||
|
PrivateKey = my_super_secret_private_key
|
||||||
|
# PreUp = iptables -t nat -A POSTROUTING -s 10.70.0.0/24 -o enp7s0 -j MASQUERADE
|
||||||
|
# PostDown = iptables -t nat -D POSTROUTING -s 10.70.0.0/24 -o enp7s0 -j MASQUERADE
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
# OnePlus 6T
|
||||||
|
PublicKey = 2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=
|
||||||
|
AllowedIPs = 10.70.0.2/32
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
# varch.local (laptop)
|
||||||
|
AllowedIPs = 10.70.0.3/32
|
||||||
|
PublicKey = 6S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
# cantarch
|
||||||
|
PublicKey = L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=
|
||||||
";
|
";
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse() {
|
fn test_parse_ok() {
|
||||||
let a = parse(TEXT);
|
let a: PeerEntryHashMap = PeerEntryHashMap::try_from(TEXT).unwrap();
|
||||||
println!("{:?}", a);
|
println!("{:?}", a);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_and_serialize() {}
|
#[should_panic(
|
||||||
|
expected = "PublicKeyNotFound { lines: [\"# varch.local (laptop)\", \"AllowedIPs = 10.70.0.3/32\"] }"
|
||||||
|
)]
|
||||||
|
fn test_parse_no_public_key() {
|
||||||
|
let _: PeerEntryHashMap = PeerEntryHashMap::try_from(TEXT_NOPK).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(
|
||||||
|
expected = "AllowedIPsEntryNotFound { lines: [\"# cantarch\", \"PublicKey = L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=\"] }"
|
||||||
|
)]
|
||||||
|
fn test_parse_no_allowed_ips() {
|
||||||
|
let _: PeerEntryHashMap = PeerEntryHashMap::try_from(TEXT_AIP).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user