Grcov report - list_keys.rs

1

    use std::fs::{

2

      self,

3

      File,

4

    };

5

    use std::path::Path;

6

7

    use clap::Args;

8

    use console::style;

9

    use pgp::types::PublicKeyTrait;

10

    use pgp::{

11

      Deserializable as _,

12

      SignedSecretKey,

13

    };

14

    use prettytable::format::consts;

15

    use prettytable::{

16

      row,

17

      Table,

18

    };

19

20

    use crate::secrets::context::Context;

21

22

    use super::KEY_LOCATION_HELP;

23

24

    #[derive(Debug, Args)]

25

    pub struct ListKeys {

26

      /// The location to store the private key

27

      #[arg(short, long, help = KEY_LOCATION_HELP)]

28

      location: Option<String>,

29

    }

30

31

    impl ListKeys {

32

      pub fn execute(&self, context: &Context) -> anyhow::Result<()> {

33

        let location: &str = &self.location.clone().unwrap_or_else(|| context.keys_location());

34

35

        assert!(!location.is_empty(), "Location must be provided");

36

37

        let path = Path::new(location);

38

        if path.exists() && path.is_dir() {

39

          let entries = fs::read_dir(path)?

40

            .filter_map(Result::ok)

41

            .filter(|entry| entry.path().extension().and_then(|ext| ext.to_str()) == Some("key"))

42

            .map(|entry| {

43

              entry

44

                .path()

45

                .file_stem()

46

                .and_then(|stem| stem.to_str())

47

                .unwrap_or("")

48

                .to_string()

49

            })

50

            .collect::<Vec<_>>();

51

52

          if entries.is_empty() {

53

            println!("No keys found in location");

54

            return Ok(());

55

          }

56

57

          let mut table = Table::new();

58

          table.set_format(*consts::FORMAT_CLEAN);

59

          table.set_titles(row![Fbb->"Name", Fbb->"Key ID", Fbb->"Fingerprint"]);

60

          for entry in entries {

61

            let key_name: &str = &entry.clone();

62

            let filename_with_ext = format!("{key_name}.key");

63

            let key_path = Path::new(location).join(filename_with_ext);

64

            let mut secret_key_string = File::open(key_path)?;

65

            let (signed_secret_key, _) = SignedSecretKey::from_armor_single(&mut secret_key_string)?;

66

            signed_secret_key.verify()?;

67

68

            let key_id = hex::encode(signed_secret_key.key_id());

69

            let fingerprint = hex::encode(signed_secret_key.fingerprint().as_bytes());

70

71

            table.add_row(row![b->&key_name, Fg->&key_id, Fg->&fingerprint]);

72

          }

73

          let msg = style("Available keys:").bold().cyan();

74

          println!();

75

          println!("{msg}");

76

          println!();

77

          table.printstd();

78

        } else {

79

          println!("Location does not exist or is not a directory");

80

        }

81

82

        Ok(())

83

      }

84

    }