wot-network-rpgpie 0.0.2

Transform OpenPGP certificate sets into a wot-network structure
Documentation
#![doc = include_str!("../README.md")]

mod third;
mod util;

use std::{fs::File, path::Path};

use chrono::{DateTime, Utc};
use rpgpie::certificate::{Certificate, Checked};
use wot_network::Network;

use crate::{
    third::{ThirdPartyLookup, handle_dks_third_party, handle_userid_third_party},
    util::{to_certificate, to_identity, user_id_valid},
};

/// Initialize a [`Network`] from a set of OpenPGP certificates in a file
pub fn from_file(path: &Path, reference_time: DateTime<Utc>) -> Result<Network, rpgpie::Error> {
    let mut file = File::open(path)?;
    let certs = Certificate::load(&mut file)?;

    log::debug!(
        "Loaded {} certificates from source file {:?}",
        certs.len(),
        path
    );

    Ok(from_certs(&certs, reference_time))
}

/// Initialize a [`Network`] from a list of OpenPGP [`Certificate`]s
pub fn from_certs(certs: &[Certificate], reference_time: DateTime<Utc>) -> Network {
    let ccerts: Vec<Checked> = certs.iter().map(Into::into).collect();
    let tplookup = ThirdPartyLookup::new(&ccerts);

    let mut net = Network::new();

    for checked in &ccerts {
        add_cert_to_net(&mut net, &tplookup, checked, &reference_time);
    }

    net
}

/// Add all edges for the certificate `checked` to the Network `net`
fn add_cert_to_net(
    net: &mut Network,
    tplookup: &ThirdPartyLookup,
    checked: &Checked,
    reference_time: &DateTime<Utc>,
) {
    // Produce no edges that point to an invalid certificate
    if !checked.primary_valid_at(reference_time).unwrap_or(false) {
        return;
    }

    // Handle first-party certifications
    for user in checked.user_ids() {
        // Add a self-certification edge for each valid id
        if user_id_valid(user, reference_time) {
            // to_identity returns Some if "id" is UTF-8
            if let Some(id) = to_identity(&user.id) {
                let cert = to_certificate(checked);
                net.add_binding(cert.clone(), cert, id);
            };
        }
    }

    // Handle third-party user id certifications
    for (user, sigs) in checked.user_id_third_party_certifications() {
        handle_userid_third_party(net, tplookup, checked, &user, &sigs, reference_time);
    }

    // Handle third-party direct key signatures
    handle_dks_third_party(
        net,
        tplookup,
        checked,
        &checked.direct_third_party_certifications(),
        reference_time,
    );
}