1
use crate::git_signatures::{check_signatures, get_signatures};
2
use git2::Repository;
3
use sequoia_openpgp::Cert;
4
use serde::Serialize;
5
use std::collections::BTreeSet;
6

            
7
type Result<T> = anyhow::Result<T>;
8

            
9
2
#[derive(Serialize, PartialEq)]
10
pub struct RepositoryAnalysis {
11
    #[serde(skip_serializing_if = "BTreeSet::is_empty")]
12
    signatures: BTreeSet<SignatureAnalysis>,
13
    #[serde(skip_serializing_if = "BTreeSet::is_empty")]
14
    missing_keys: BTreeSet<String>,
15
}
16

            
17
#[derive(Serialize, PartialEq, Eq, PartialOrd, Ord)]
18
pub struct SignatureAnalysis {
19
    handle: String,
20
    #[serde(skip_serializing_if = "Vec::is_empty")]
21
    email: Vec<String>,
22
}
23

            
24
10
pub fn analyze_repository(certs: &[Cert], repo: &Repository) -> Result<RepositoryAnalysis> {
25
10
    let signatures = get_signatures(repo)?;
26
10
    let r = check_signatures(certs, signatures)?;
27
10
    let mut signature_analyses = BTreeSet::new();
28
10
    for key in r.found_keys {
29
        let mut analysis = SignatureAnalysis {
30
            handle: format!("{}", key.0),
31
            email: Vec::new(),
32
        };
33
        for id in key.1.userids() {
34
            if let Ok(Some(email)) = id.email_normalized() {
35
                analysis.email.push(email);
36
            }
37
        }
38
        signature_analyses.insert(analysis);
39
    }
40
10
    Ok(RepositoryAnalysis {
41
10
        signatures: signature_analyses,
42
10
        missing_keys: r.missing_keys.iter().map(|k| format!("{}", k)).collect(),
43
10
    })
44
10
}