rustsec_admin/
list_versions.rs1use std::path::PathBuf;
4
5use rustsec::{Advisory, Database};
6use tame_index::index::RemoteGitIndex;
7
8use crate::{error::Error, lock::acquire_cargo_package_lock, prelude::*};
9
10pub struct AffectedVersionLister {
12 crates_index: RemoteGitIndex,
14
15 advisory_db: Database,
17}
18
19impl AffectedVersionLister {
20 pub fn new(repo_path: impl Into<PathBuf>) -> Result<Self, Error> {
22 let repo_path = repo_path.into();
23 let lock = acquire_cargo_package_lock()?;
24 let mut crates_index = RemoteGitIndex::new(
25 tame_index::GitIndex::new(tame_index::IndexLocation::new(
26 tame_index::IndexUrl::CratesIoGit,
27 ))?,
28 &lock,
29 )?;
30 crates_index.fetch(&lock)?;
31 let advisory_db = Database::open(&repo_path)?;
32 Ok(Self {
33 crates_index,
34 advisory_db,
35 })
36 }
37
38 pub fn advisory_db(&self) -> &Database {
40 &self.advisory_db
41 }
42
43 pub fn process_one_advisory(&self, advisory: &Advisory) {
45 status_ok!(
46 "Loaded",
47 "{} for '{}'",
48 advisory.id(),
49 advisory.metadata.package
50 );
51 let crate_name = advisory.metadata.package.as_str();
52 let crate_info = self
53 .crates_index
54 .krate(
55 crate_name.try_into().unwrap(),
56 true,
57 &acquire_cargo_package_lock().unwrap(),
58 )
59 .unwrap()
60 .unwrap_or_else(|| panic!("expected crate {} to exist", crate_name));
61 for version in crate_info.versions {
62 let parsed_version = rustsec::Version::parse(&version.version).unwrap();
63 if advisory.versions.is_vulnerable(&parsed_version) {
64 println!("{} vulnerable", version.version)
65 } else {
66 println!("{} OK", version.version)
67 }
68 }
69 }
70
71 pub fn process_all_advisories(&self) -> Result<(), Error> {
73 for advisory in self.advisory_db.iter() {
74 if advisory.metadata.collection.unwrap() != rustsec::Collection::Crates {
76 continue;
77 }
78 self.process_one_advisory(advisory);
79 }
80 Ok(())
81 }
82}