Assorted improvements, mostly suggested by clippy

This commit is contained in:
Vecna 2024-05-29 13:20:56 -04:00
parent f245ee21f9
commit 461d7d4ce5
7 changed files with 102 additions and 117 deletions

View File

@ -23,7 +23,7 @@ impl EciesCiphertext {
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let secret = EphemeralSecret::random_from_rng(&mut rng); let secret = EphemeralSecret::random_from_rng(&mut rng);
let client_pubkey = PublicKey::from(&secret); let client_pubkey = PublicKey::from(&secret);
let shared_secret = secret.diffie_hellman(&receiver_pubkey); let shared_secret = secret.diffie_hellman(receiver_pubkey);
// Compute key // Compute key
let hk = Hkdf::<Sha3_256>::new(None, shared_secret.as_bytes()); let hk = Hkdf::<Sha3_256>::new(None, shared_secret.as_bytes());
@ -39,11 +39,11 @@ impl EciesCiphertext {
let key: Key<Aes256Gcm> = symmetric_key.into(); let key: Key<Aes256Gcm> = symmetric_key.into();
let cipher = Aes256Gcm::new(&key); let cipher = Aes256Gcm::new(&key);
let nonce = Aes256Gcm::generate_nonce(&mut rng); let nonce = Aes256Gcm::generate_nonce(&mut rng);
match cipher.encrypt(&nonce, &*message) { match cipher.encrypt(&nonce, message) {
Ok(ct) => Ok(EciesCiphertext { Ok(ct) => Ok(EciesCiphertext {
pubkey: client_pubkey, pubkey: client_pubkey,
nonce: nonce.to_vec(), nonce: nonce.to_vec(),
ct: ct, ct,
}), }),
Err(_) => Err("Failed to encrypt".to_string()), Err(_) => Err("Failed to encrypt".to_string()),
} }

View File

@ -60,7 +60,7 @@ impl ExtraInfo {
let date_str = if entry.contains_key("bridge-stats-end") { let date_str = if entry.contains_key("bridge-stats-end") {
let line = entry.get("bridge-stats-end").unwrap(); let line = entry.get("bridge-stats-end").unwrap();
// Parse out (86400 s) from end of line // Parse out (86400 s) from end of line
&line[..line.find("(").unwrap() - 1] &line[..line.find('(').unwrap() - 1]
} else { } else {
entry.get("published").unwrap().as_str() entry.get("published").unwrap().as_str()
}; };
@ -77,7 +77,7 @@ impl ExtraInfo {
let mut bridge_ips: BTreeMap<String, u32> = BTreeMap::new(); let mut bridge_ips: BTreeMap<String, u32> = BTreeMap::new();
let countries: Vec<&str> = bridge_ips_str.split(',').collect(); let countries: Vec<&str> = bridge_ips_str.split(',').collect();
for country in countries { for country in countries {
if country != "" { if !country.is_empty() {
// bridge-ips may be empty // bridge-ips may be empty
let (cc, count) = country.split_once('=').unwrap(); let (cc, count) = country.split_once('=').unwrap();
bridge_ips.insert(cc.to_string(), count.parse::<u32>().unwrap()); bridge_ips.insert(cc.to_string(), count.parse::<u32>().unwrap());
@ -94,46 +94,43 @@ impl ExtraInfo {
/// Accepts a downloaded extra-infos file as a big string, returns a set of /// Accepts a downloaded extra-infos file as a big string, returns a set of
/// the ExtraInfos represented by the file. /// the ExtraInfos represented by the file.
pub fn parse_file<'a>(extra_info_str: &str) -> HashSet<Self> { pub fn parse_file(extra_info_str: &str) -> HashSet<Self> {
let mut set = HashSet::<Self>::new(); let mut set = HashSet::<Self>::new();
let mut entry = HashMap::<String, String>::new(); let mut entry = HashMap::<String, String>::new();
for line in extra_info_str.lines() { for line in extra_info_str.lines() {
let line = line;
if line.starts_with("@type bridge-extra-info ") { if line.starts_with("@type bridge-extra-info ") {
if !entry.is_empty() { if !entry.is_empty() {
let extra_info = Self::from_map(&entry); let extra_info = Self::from_map(&entry);
if extra_info.is_ok() { if let Ok(ei) = extra_info {
set.insert(extra_info.unwrap()); set.insert(ei);
} else { } else {
// Just print the error and continue. // Just print the error and continue.
println!("{}", extra_info.err().unwrap()); println!("{}", extra_info.err().unwrap());
} }
entry = HashMap::<String, String>::new(); entry = HashMap::<String, String>::new();
} }
} else { } else if line.starts_with("extra-info ") {
if line.starts_with("extra-info ") { // extra-info line has format:
// extra-info line has format: // extra-info <nickname> <fingerprint>
// extra-info <nickname> <fingerprint> let line_split: Vec<&str> = line.split(' ').collect();
let line_split: Vec<&str> = line.split(' ').collect(); if line_split.len() != 3 {
if line_split.len() != 3 { println!("Misformed extra-info line");
println!("Misformed extra-info line");
} else {
entry.insert("nickname".to_string(), line_split[1].to_string());
entry.insert("fingerprint".to_string(), line_split[2].to_string());
}
} else { } else {
let (key, value) = match line.split_once(' ') { entry.insert("nickname".to_string(), line_split[1].to_string());
Some((k, v)) => (k, v), entry.insert("fingerprint".to_string(), line_split[2].to_string());
None => (line, ""),
};
entry.insert(key.to_string(), value.to_string());
} }
} else {
let (key, value) = match line.split_once(' ') {
Some((k, v)) => (k, v),
None => (line, ""),
};
entry.insert(key.to_string(), value.to_string());
} }
} }
// Do for the last one // Do for the last one
let extra_info = Self::from_map(&entry); let extra_info = Self::from_map(&entry);
if extra_info.is_ok() { if let Ok(ei) = extra_info {
set.insert(extra_info.unwrap()); set.insert(ei);
} else { } else {
println!("{}", extra_info.err().unwrap()); println!("{}", extra_info.err().unwrap());
} }
@ -168,7 +165,7 @@ impl fmt::Display for ExtraInfo {
str.push_str(format!("{}={}", cc, count,).as_str()); str.push_str(format!("{}={}", cc, count,).as_str());
first_cc = false; first_cc = false;
} }
str.push_str("\n"); str.push('\n');
write!(f, "{}", str) write!(f, "{}", str)
} }

View File

@ -7,7 +7,7 @@ use lazy_static::lazy_static;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sled::Db; use sled::Db;
use std::{ use std::{
collections::{BTreeMap, HashMap, HashSet}, collections::{btree_map, hash_map, BTreeMap, HashMap, HashSet},
fmt, fmt,
}; };
use x25519_dalek::{PublicKey, StaticSecret}; use x25519_dalek::{PublicKey, StaticSecret};
@ -130,7 +130,7 @@ pub struct BridgeInfo {
impl BridgeInfo { impl BridgeInfo {
pub fn new(fingerprint: [u8; 20], nickname: &String) -> Self { pub fn new(fingerprint: [u8; 20], nickname: &String) -> Self {
Self { Self {
fingerprint: fingerprint, fingerprint,
nickname: nickname.to_string(), nickname: nickname.to_string(),
info_by_country: HashMap::<String, BridgeCountryInfo>::new(), info_by_country: HashMap::<String, BridgeCountryInfo>::new(),
} }
@ -182,13 +182,17 @@ impl BridgeCountryInfo {
Self { Self {
info_by_day: BTreeMap::<u32, BTreeMap<BridgeInfoType, u32>>::new(), info_by_day: BTreeMap::<u32, BTreeMap<BridgeInfoType, u32>>::new(),
blocked: false, blocked: false,
first_seen: first_seen, first_seen,
first_pr: None, first_pr: None,
} }
} }
pub fn add_info(&mut self, info_type: BridgeInfoType, date: u32, count: u32) { pub fn add_info(&mut self, info_type: BridgeInfoType, date: u32, count: u32) {
if self.info_by_day.contains_key(&date) { if let btree_map::Entry::Vacant(e) = self.info_by_day.entry(date) {
let mut info = BTreeMap::<BridgeInfoType, u32>::new();
info.insert(info_type, count);
e.insert(info);
} else {
let info = self.info_by_day.get_mut(&date).unwrap(); let info = self.info_by_day.get_mut(&date).unwrap();
if !info.contains_key(&info_type) { if !info.contains_key(&info_type) {
info.insert(info_type, count); info.insert(info_type, count);
@ -202,10 +206,6 @@ impl BridgeCountryInfo {
let new_count = info.get(&info_type).unwrap() + count; let new_count = info.get(&info_type).unwrap() + count;
info.insert(info_type, new_count); info.insert(info_type, new_count);
} }
} else {
let mut info = BTreeMap::<BridgeInfoType, u32>::new();
info.insert(info_type, count);
self.info_by_day.insert(date, info);
} }
// If this is the first instance of positive reports, save the date // If this is the first instance of positive reports, save the date
@ -229,18 +229,18 @@ impl fmt::Display for BridgeCountryInfo {
for date in self.info_by_day.keys() { for date in self.info_by_day.keys() {
let info = self.info_by_day.get(date).unwrap(); let info = self.info_by_day.get(date).unwrap();
let ip_count = match info.get(&BridgeInfoType::BridgeIps) { let ip_count = match info.get(&BridgeInfoType::BridgeIps) {
Some(v) => v, Some(&v) => v,
None => &0, None => 0,
}; };
let nr_count = match info.get(&BridgeInfoType::NegativeReports) { let nr_count = match info.get(&BridgeInfoType::NegativeReports) {
Some(v) => v, Some(&v) => v,
None => &0, None => 0,
}; };
let pr_count = match info.get(&BridgeInfoType::PositiveReports) { let pr_count = match info.get(&BridgeInfoType::PositiveReports) {
Some(v) => v, Some(&v) => v,
None => &0, None => 0,
}; };
if ip_count > &0 || nr_count > &0 || pr_count > &0 { if ip_count > 0 || nr_count > 0 || pr_count > 0 {
str.push_str( str.push_str(
format!( format!(
"\n date: {}\n connections: {}\n negative reports: {}\n positive reports: {}", "\n date: {}\n connections: {}\n negative reports: {}\n positive reports: {}",
@ -319,7 +319,7 @@ pub fn add_extra_info_to_db(db: &Db, extra_info: ExtraInfo) {
let mut bridge_info = match db.get(fingerprint).unwrap() { let mut bridge_info = match db.get(fingerprint).unwrap() {
Some(v) => bincode::deserialize(&v).unwrap(), Some(v) => bincode::deserialize(&v).unwrap(),
None => { None => {
add_bridge_to_db(&db, fingerprint); add_bridge_to_db(db, fingerprint);
BridgeInfo::new(fingerprint, &extra_info.nickname) BridgeInfo::new(fingerprint, &extra_info.nickname)
} }
}; };
@ -402,7 +402,7 @@ pub async fn update_extra_infos(
// Add new extra-infos data to database // Add new extra-infos data to database
for extra_info in new_extra_infos { for extra_info in new_extra_infos {
add_extra_info_to_db(&db, extra_info); add_extra_info_to_db(db, extra_info);
} }
// Store which files we've already downloaded and processed // Store which files we've already downloaded and processed
@ -429,16 +429,16 @@ pub fn new_negative_report_key(db: &Db, date: u32) -> Option<PublicKey> {
Err(_) => BTreeMap::<u32, StaticSecret>::new(), Err(_) => BTreeMap::<u32, StaticSecret>::new(),
} }
}; };
if nr_keys.contains_key(&date) { if let btree_map::Entry::Vacant(_e) = nr_keys.entry(date) {
None let rng = rand::thread_rng();
} else { let secret = StaticSecret::random_from_rng(rng);
let mut rng = rand::thread_rng();
let secret = StaticSecret::random_from_rng(&mut rng);
let public = PublicKey::from(&secret); let public = PublicKey::from(&secret);
nr_keys.insert(date, secret); nr_keys.insert(date, secret);
db.insert("nr-keys", bincode::serialize(&nr_keys).unwrap()) db.insert("nr-keys", bincode::serialize(&nr_keys).unwrap())
.unwrap(); .unwrap();
Some(public) Some(public)
} else {
None
} }
} }
@ -465,23 +465,16 @@ pub fn get_negative_report_secret_key(db: &Db, date: u32) -> Option<StaticSecret
/// If we have a key for the requested day, return the public part. /// If we have a key for the requested day, return the public part.
pub fn get_negative_report_public_key(db: &Db, date: u32) -> Option<PublicKey> { pub fn get_negative_report_public_key(db: &Db, date: u32) -> Option<PublicKey> {
match get_negative_report_secret_key(&db, date) { get_negative_report_secret_key(db, date).map(|secret| PublicKey::from(&secret))
Some(secret) => Some(PublicKey::from(&secret)),
None => None,
}
} }
/// Receive an encrypted negative report. Attempt to decrypt it and if /// Receive an encrypted negative report. Attempt to decrypt it and if
/// successful, add it to the database to be processed later. /// successful, add it to the database to be processed later.
pub fn handle_encrypted_negative_report(db: &Db, enc_report: EncryptedNegativeReport) { pub fn handle_encrypted_negative_report(db: &Db, enc_report: EncryptedNegativeReport) {
match get_negative_report_secret_key(&db, enc_report.date) { if let Some(secret) = get_negative_report_secret_key(db, enc_report.date) {
Some(secret) => match enc_report.decrypt(&secret) { if let Ok(nr) = enc_report.decrypt(&secret) {
Ok(nr) => { save_negative_report_to_process(db, nr);
save_negative_report_to_process(&db, nr); }
}
Err(_) => {}
},
None => {}
} }
} }
@ -508,19 +501,18 @@ pub fn save_negative_report_to_process(db: &Db, nr: NegativeReport) {
// Store to-be-processed reports with key [fingerprint]_[country]_[date] // Store to-be-processed reports with key [fingerprint]_[country]_[date]
let map_key = format!( let map_key = format!(
"{}_{}_{}", "{}_{}_{}",
array_bytes::bytes2hex("", &nr.fingerprint), array_bytes::bytes2hex("", nr.fingerprint),
&nr.country, &nr.country,
&nr.date, &nr.date,
); );
if reports.contains_key(&map_key) { if let btree_map::Entry::Vacant(e) = reports.entry(map_key.clone()) {
let nrs = vec![nr.to_serializable_report()];
e.insert(nrs);
} else {
reports reports
.get_mut(&map_key) .get_mut(&map_key)
.unwrap() .unwrap()
.push(nr.to_serializable_report()); .push(nr.to_serializable_report());
} else {
let mut nrs = Vec::<SerializableNegativeReport>::new();
nrs.push(nr.to_serializable_report());
reports.insert(map_key, nrs);
} }
// Commit changes to database // Commit changes to database
db.insert("nrs-to-process", bincode::serialize(&reports).unwrap()) db.insert("nrs-to-process", bincode::serialize(&reports).unwrap())
@ -580,7 +572,7 @@ pub async fn update_negative_reports(db: &Db, distributors: &BTreeMap<BridgeDist
let fingerprint = first_report.fingerprint; let fingerprint = first_report.fingerprint;
let date = first_report.date; let date = first_report.date;
let country = first_report.country.clone(); let country = first_report.country.clone();
let count_valid = verify_negative_reports(&distributors, reports).await; let count_valid = verify_negative_reports(distributors, reports).await;
// If we have new historical data, re-evaluate this bridge // If we have new historical data, re-evaluate this bridge
if count_valid > 0 && date < today { if count_valid > 0 && date < today {
@ -600,22 +592,23 @@ pub async fn update_negative_reports(db: &Db, distributors: &BTreeMap<BridgeDist
None => { None => {
// This case shouldn't happen unless the bridge hasn't // This case shouldn't happen unless the bridge hasn't
// published any bridge stats. // published any bridge stats.
add_bridge_to_db(&db, fingerprint); add_bridge_to_db(db, fingerprint);
BridgeInfo::new(fingerprint, &String::default()) BridgeInfo::new(fingerprint, &String::default())
} }
}; };
// Add the new report count to it // Add the new report count to it
if bridge_info.info_by_country.contains_key(&country) { if let hash_map::Entry::Vacant(_e) = bridge_info.info_by_country.entry(country.clone())
let bridge_country_info = bridge_info.info_by_country.get_mut(&country).unwrap(); {
bridge_country_info.add_info(BridgeInfoType::NegativeReports, date, count_valid);
} else {
// No existing entry; make a new one. // No existing entry; make a new one.
let mut bridge_country_info = BridgeCountryInfo::new(date); let mut bridge_country_info = BridgeCountryInfo::new(date);
bridge_country_info.add_info(BridgeInfoType::NegativeReports, date, count_valid); bridge_country_info.add_info(BridgeInfoType::NegativeReports, date, count_valid);
bridge_info bridge_info
.info_by_country .info_by_country
.insert(country, bridge_country_info); .insert(country, bridge_country_info);
} else {
let bridge_country_info = bridge_info.info_by_country.get_mut(&country).unwrap();
bridge_country_info.add_info(BridgeInfoType::NegativeReports, date, count_valid);
} }
// Commit changes to database // Commit changes to database
db.insert(fingerprint, bincode::serialize(&bridge_info).unwrap()) db.insert(fingerprint, bincode::serialize(&bridge_info).unwrap())
@ -648,19 +641,18 @@ pub fn save_positive_report_to_process(db: &Db, pr: PositiveReport) {
// Store to-be-processed reports with key [fingerprint]_[country]_[date] // Store to-be-processed reports with key [fingerprint]_[country]_[date]
let map_key = format!( let map_key = format!(
"{}_{}_{}", "{}_{}_{}",
array_bytes::bytes2hex("", &pr.fingerprint), array_bytes::bytes2hex("", pr.fingerprint),
&pr.country, &pr.country,
&pr.date, &pr.date,
); );
if reports.contains_key(&map_key) { if let btree_map::Entry::Vacant(e) = reports.entry(map_key.clone()) {
let prs = vec![pr.to_serializable_report()];
e.insert(prs);
} else {
reports reports
.get_mut(&map_key) .get_mut(&map_key)
.unwrap() .unwrap()
.push(pr.to_serializable_report()); .push(pr.to_serializable_report());
} else {
let mut prs = Vec::<SerializablePositiveReport>::new();
prs.push(pr.to_serializable_report());
reports.insert(map_key, prs);
} }
// Commit changes to database // Commit changes to database
db.insert("prs-to-process", bincode::serialize(&reports).unwrap()) db.insert("prs-to-process", bincode::serialize(&reports).unwrap())
@ -719,7 +711,7 @@ pub async fn update_positive_reports(db: &Db, distributors: &BTreeMap<BridgeDist
let fingerprint = first_report.fingerprint; let fingerprint = first_report.fingerprint;
let date = first_report.date; let date = first_report.date;
let country = first_report.country.clone(); let country = first_report.country.clone();
let count_valid = verify_positive_reports(&distributors, reports).await; let count_valid = verify_positive_reports(distributors, reports).await;
// If we have new historical data, re-evaluate this bridge // If we have new historical data, re-evaluate this bridge
if count_valid > 0 && date < today { if count_valid > 0 && date < today {
@ -739,22 +731,20 @@ pub async fn update_positive_reports(db: &Db, distributors: &BTreeMap<BridgeDist
None => { None => {
// This case shouldn't happen unless the bridge hasn't // This case shouldn't happen unless the bridge hasn't
// published any bridge stats. // published any bridge stats.
add_bridge_to_db(&db, fingerprint); add_bridge_to_db(db, fingerprint);
BridgeInfo::new(fingerprint, &String::default()) BridgeInfo::new(fingerprint, &String::default())
} }
}; };
// Add the new report count to it // Add the new report count to it
if bridge_info.info_by_country.contains_key(&country) { if let hash_map::Entry::Vacant(e) = bridge_info.info_by_country.entry(country.clone()) {
let bridge_country_info = bridge_info.info_by_country.get_mut(&country).unwrap();
bridge_country_info.add_info(BridgeInfoType::PositiveReports, date, count_valid);
} else {
// No existing entry; make a new one. // No existing entry; make a new one.
let mut bridge_country_info = BridgeCountryInfo::new(date); let mut bridge_country_info = BridgeCountryInfo::new(date);
bridge_country_info.add_info(BridgeInfoType::PositiveReports, date, count_valid); bridge_country_info.add_info(BridgeInfoType::PositiveReports, date, count_valid);
bridge_info e.insert(bridge_country_info);
.info_by_country } else {
.insert(country, bridge_country_info); let bridge_country_info = bridge_info.info_by_country.get_mut(&country).unwrap();
bridge_country_info.add_info(BridgeInfoType::PositiveReports, date, count_valid);
} }
// Commit changes to database // Commit changes to database
db.insert(fingerprint, bincode::serialize(&bridge_info).unwrap()) db.insert(fingerprint, bincode::serialize(&bridge_info).unwrap())
@ -806,7 +796,7 @@ pub fn guess_blockages(
let mut bridge_info: BridgeInfo = let mut bridge_info: BridgeInfo =
bincode::deserialize(&db.get(fingerprint).unwrap().unwrap()).unwrap(); bincode::deserialize(&db.get(fingerprint).unwrap().unwrap()).unwrap();
let mut new_blockages = HashSet::<String>::new(); let mut new_blockages = HashSet::<String>::new();
let fpr_str = array_bytes::bytes2hex("", &fingerprint); let fpr_str = array_bytes::bytes2hex("", fingerprint);
let first_date = if bridges_to_re_evaluate.contains_key(&fpr_str) { let first_date = if bridges_to_re_evaluate.contains_key(&fpr_str) {
*bridges_to_re_evaluate.get(&fpr_str).unwrap() *bridges_to_re_evaluate.get(&fpr_str).unwrap()
} else { } else {
@ -871,12 +861,12 @@ pub async fn report_blockages(
let mut blockages_str = HashMap::<String, HashSet<String>>::new(); let mut blockages_str = HashMap::<String, HashSet<String>>::new();
for (fingerprint, countries) in blockages { for (fingerprint, countries) in blockages {
let fpr_string = array_bytes::bytes2hex("", fingerprint); let fpr_string = array_bytes::bytes2hex("", fingerprint);
if countries.len() > 0 { if !countries.is_empty() {
blockages_str.insert(fpr_string, countries); blockages_str.insert(fpr_string, countries);
} }
} }
if blockages_str.len() > 0 { if !blockages_str.is_empty() {
// Report blocked bridges to bridge distributor // Report blocked bridges to bridge distributor
let client = Client::new(); let client = Client::new();
let req = Request::builder() let req = Request::builder()

View File

@ -24,7 +24,7 @@ use tokio::{
sync::{broadcast, mpsc, oneshot}, sync::{broadcast, mpsc, oneshot},
time::sleep, time::sleep,
}; };
#[cfg(not(features = "simulation"))] #[cfg(not(feature = "simulation"))]
use tokio_cron::{Job, Scheduler}; use tokio_cron::{Job, Scheduler};
async fn shutdown_signal() { async fn shutdown_signal() {
@ -95,22 +95,20 @@ async fn update_daily_info(
min_historical_days: u32, min_historical_days: u32,
max_historical_days: u32, max_historical_days: u32,
) -> HashMap<[u8; 20], HashSet<String>> { ) -> HashMap<[u8; 20], HashSet<String>> {
update_extra_infos(&db, &extra_infos_base_url) update_extra_infos(db, extra_infos_base_url).await.unwrap();
.await update_negative_reports(db, distributors).await;
.unwrap(); update_positive_reports(db, distributors).await;
update_negative_reports(&db, &distributors).await;
update_positive_reports(&db, &distributors).await;
let new_blockages = guess_blockages( let new_blockages = guess_blockages(
&db, db,
&analysis::NormalAnalyzer::new(max_threshold, scaling_factor), &analysis::NormalAnalyzer::new(max_threshold, scaling_factor),
confidence, confidence,
min_historical_days, min_historical_days,
max_historical_days, max_historical_days,
); );
report_blockages(&distributors, new_blockages.clone()).await; report_blockages(distributors, new_blockages.clone()).await;
// Generate tomorrow's key if we don't already have it // Generate tomorrow's key if we don't already have it
new_negative_report_key(&db, get_date() + 1); new_negative_report_key(db, get_date() + 1);
// Return new detected blockages // Return new detected blockages
new_blockages new_blockages
@ -177,7 +175,7 @@ async fn context_manager(
let blockages = update_daily_info( let blockages = update_daily_info(
&db, &db,
&distributors, &distributors,
&extra_infos_base_url, extra_infos_base_url,
confidence, confidence,
max_threshold, max_threshold,
scaling_factor, scaling_factor,

View File

@ -148,7 +148,7 @@ impl NegativeReport {
/// Deserializes the report from slice, eliding the underlying process /// Deserializes the report from slice, eliding the underlying process
pub fn from_slice(slice: &[u8]) -> Result<Self, NegativeReportError> { pub fn from_slice(slice: &[u8]) -> Result<Self, NegativeReportError> {
match serde_json::from_slice::<SerializableNegativeReport>(&slice) { match serde_json::from_slice::<SerializableNegativeReport>(slice) {
Ok(v) => v.to_report(), Ok(v) => v.to_report(),
Err(_) => Err(NegativeReportError::FailedToDeserialize), Err(_) => Err(NegativeReportError::FailedToDeserialize),
} }
@ -163,7 +163,7 @@ impl NegativeReport {
} }
ProofOfBridgeKnowledge::HashOfBucket(pok) => { ProofOfBridgeKnowledge::HashOfBucket(pok) => {
for b in &bridge_info.buckets { for b in &bridge_info.buckets {
let hash = HashOfBucket::new(&b, self.date, self.nonce); let hash = HashOfBucket::new(b, self.date, self.nonce);
if hash == pok { if hash == pok {
return true; return true;
} }
@ -188,7 +188,7 @@ pub struct SerializableNegativeReport {
impl SerializableNegativeReport { impl SerializableNegativeReport {
pub fn to_report(self) -> Result<NegativeReport, NegativeReportError> { pub fn to_report(self) -> Result<NegativeReport, NegativeReportError> {
if self.country == "" { if self.country.is_empty() {
return Err(NegativeReportError::MissingCountryCode); return Err(NegativeReportError::MissingCountryCode);
} }
if !COUNTRY_CODES.contains(self.country.as_str()) { if !COUNTRY_CODES.contains(self.country.as_str()) {
@ -205,7 +205,7 @@ impl SerializableNegativeReport {
fingerprint: self.fingerprint, fingerprint: self.fingerprint,
bridge_pok: self.bridge_pok, bridge_pok: self.bridge_pok,
country: self.country.to_string(), country: self.country.to_string(),
date: self.date.try_into().unwrap(), date: self.date,
nonce: self.nonce, nonce: self.nonce,
distributor: self.distributor, distributor: self.distributor,
}) })
@ -224,7 +224,7 @@ pub struct EncryptedNegativeReport {
impl EncryptedNegativeReport { impl EncryptedNegativeReport {
pub fn decrypt(self, secret: &StaticSecret) -> Result<NegativeReport, NegativeReportError> { pub fn decrypt(self, secret: &StaticSecret) -> Result<NegativeReport, NegativeReportError> {
match self.ciphertext.decrypt(&secret) { match self.ciphertext.decrypt(secret) {
Ok(m) => match bincode::deserialize::<SerializableNegativeReport>(&m) { Ok(m) => match bincode::deserialize::<SerializableNegativeReport>(&m) {
Ok(ser_report) => ser_report.to_report(), Ok(ser_report) => ser_report.to_report(),
Err(_) => Err(NegativeReportError::FailedToDeserialize), Err(_) => Err(NegativeReportError::FailedToDeserialize),

View File

@ -93,7 +93,7 @@ impl PositiveReport {
}; };
SerializablePositiveReport { SerializablePositiveReport {
fingerprint: self.fingerprint, fingerprint: self.fingerprint,
bridge_token: bridge_token, bridge_token,
lox_proof: self.lox_proof, lox_proof: self.lox_proof,
country: self.country, country: self.country,
date: self.date, date: self.date,
@ -115,7 +115,7 @@ impl PositiveReport {
/// Deserializes the report from slice, eliding the underlying process /// Deserializes the report from slice, eliding the underlying process
pub fn from_slice(slice: &[u8]) -> Result<Self, PositiveReportError> { pub fn from_slice(slice: &[u8]) -> Result<Self, PositiveReportError> {
match serde_json::from_slice::<SerializablePositiveReport>(&slice) { match serde_json::from_slice::<SerializablePositiveReport>(slice) {
Ok(v) => v.to_report(), Ok(v) => v.to_report(),
Err(_) => Err(PositiveReportError::FailedToDeserialize), Err(_) => Err(PositiveReportError::FailedToDeserialize),
} }
@ -152,7 +152,7 @@ impl PositiveReport {
let BP = self.lox_proof.BP; let BP = self.lox_proof.BP;
for bucket in buckets { for bucket in buckets {
if bucket * Htable == BP { if bucket * Htable == BP {
return la.handle_positive_report(self.lox_proof, &Htable).is_ok(); return la.handle_positive_report(self.lox_proof, Htable).is_ok();
} }
} }
false false
@ -177,7 +177,7 @@ impl SerializablePositiveReport {
if REQUIRE_BRIDGE_TOKEN && self.bridge_token.is_none() { if REQUIRE_BRIDGE_TOKEN && self.bridge_token.is_none() {
return Err(PositiveReportError::MissingBridgeToken); return Err(PositiveReportError::MissingBridgeToken);
} }
if self.country == "" { if self.country.is_empty() {
return Err(PositiveReportError::MissingCountryCode); return Err(PositiveReportError::MissingCountryCode);
} }
if !COUNTRY_CODES.contains(self.country.as_str()) { if !COUNTRY_CODES.contains(self.country.as_str()) {
@ -209,7 +209,7 @@ impl SerializablePositiveReport {
}; };
Ok(PositiveReport { Ok(PositiveReport {
fingerprint: self.fingerprint, fingerprint: self.fingerprint,
bridge_token: bridge_token, bridge_token,
lox_proof: self.lox_proof, lox_proof: self.lox_proof,
country: self.country, country: self.country,
date: self.date, date: self.date,
@ -275,9 +275,9 @@ pub struct SerializableUnsignedBridgeToken {
impl SerializableUnsignedBridgeToken { impl SerializableUnsignedBridgeToken {
pub fn to_unsigned_bridge_token(self) -> Result<UnsignedBridgeToken, PositiveReportError> { pub fn to_unsigned_bridge_token(self) -> Result<UnsignedBridgeToken, PositiveReportError> {
if self.country == "" if self.country.is_empty()
|| !COUNTRY_CODES.contains(self.country.as_str()) || !COUNTRY_CODES.contains(self.country.as_str())
|| self.date > get_date().into() || self.date > get_date()
{ {
return Err(PositiveReportError::InvalidBridgeToken); return Err(PositiveReportError::InvalidBridgeToken);
} }
@ -345,7 +345,7 @@ impl SerializableBridgeToken {
pub fn to_bridge_token(self) -> Result<BridgeToken, PositiveReportError> { pub fn to_bridge_token(self) -> Result<BridgeToken, PositiveReportError> {
let unsigned_bridge_token = self.unsigned_bridge_token.to_unsigned_bridge_token()?; let unsigned_bridge_token = self.unsigned_bridge_token.to_unsigned_bridge_token()?;
Ok(BridgeToken { Ok(BridgeToken {
unsigned_bridge_token: unsigned_bridge_token, unsigned_bridge_token,
sig: self.sig, sig: self.sig,
}) })
} }

View File

@ -48,7 +48,7 @@ pub async fn handle(db: &Db, req: Request<Body>) -> Result<Response<Body>, Infal
return Ok(prepare_header(val)); return Ok(prepare_header(val));
} }
}; };
handle_encrypted_negative_report(&db, enr); handle_encrypted_negative_report(db, enr);
prepare_header("OK".to_string()) prepare_header("OK".to_string())
}), }),
(&Method::POST, "/positivereport") => Ok::<_, Infallible>({ (&Method::POST, "/positivereport") => Ok::<_, Infallible>({
@ -61,7 +61,7 @@ pub async fn handle(db: &Db, req: Request<Body>) -> Result<Response<Body>, Infal
return Ok(prepare_header(val)); return Ok(prepare_header(val));
} }
}; };
save_positive_report_to_process(&db, pr); save_positive_report_to_process(db, pr);
prepare_header("OK".to_string()) prepare_header("OK".to_string())
}), }),
_ => { _ => {