Skip to main content

wot_network_rpgpie/
lib.rs

1#![doc = include_str!("../README.md")]
2
3mod third;
4mod util;
5
6use std::{fs::File, path::Path};
7
8use chrono::{DateTime, Utc};
9use rpgpie::certificate::{Certificate, Checked};
10use wot_network::Network;
11
12use crate::{
13    third::{ThirdPartyLookup, handle_dks_third_party, handle_userid_third_party},
14    util::{to_certificate, to_identity, user_id_valid},
15};
16
17/// Initialize a [`Network`] from a set of OpenPGP certificates in a file
18pub fn from_file(path: &Path, reference_time: DateTime<Utc>) -> Result<Network, rpgpie::Error> {
19    let mut file = File::open(path)?;
20    let certs = Certificate::load(&mut file)?;
21
22    log::debug!(
23        "Loaded {} certificates from source file {:?}",
24        certs.len(),
25        path
26    );
27
28    Ok(from_certs(&certs, reference_time))
29}
30
31/// Initialize a [`Network`] from a list of OpenPGP [`Certificate`]s
32pub fn from_certs(certs: &[Certificate], reference_time: DateTime<Utc>) -> Network {
33    let ccerts: Vec<Checked> = certs.iter().map(Into::into).collect();
34    let tplookup = ThirdPartyLookup::new(&ccerts);
35
36    let mut net = Network::new();
37
38    for checked in &ccerts {
39        add_cert_to_net(&mut net, &tplookup, checked, &reference_time);
40    }
41
42    net
43}
44
45/// Add all edges for the certificate `checked` to the Network `net`
46fn add_cert_to_net(
47    net: &mut Network,
48    tplookup: &ThirdPartyLookup,
49    checked: &Checked,
50    reference_time: &DateTime<Utc>,
51) {
52    // Produce no edges that point to an invalid certificate
53    if !checked.primary_valid_at(reference_time).unwrap_or(false) {
54        return;
55    }
56
57    // Handle first-party certifications
58    for user in checked.user_ids() {
59        // Add a self-certification edge for each valid id
60        if user_id_valid(user, reference_time) {
61            // to_identity returns Some if "id" is UTF-8
62            if let Some(id) = to_identity(&user.id) {
63                let cert = to_certificate(checked);
64                net.add_binding(cert.clone(), cert, id);
65            };
66        }
67    }
68
69    // Handle third-party user id certifications
70    for (user, sigs) in checked.user_id_third_party_certifications() {
71        handle_userid_third_party(net, tplookup, checked, &user, &sigs, reference_time);
72    }
73
74    // Handle third-party direct key signatures
75    handle_dks_third_party(
76        net,
77        tplookup,
78        checked,
79        &checked.direct_third_party_certifications(),
80        reference_time,
81    );
82}