Grcov report - export_key.rs

1

    use std::fs::File;

2

    use std::io::Write as _;

3

    use std::path::Path;

4

5

    use clap::Args;

6

    use pgp::{

7

      ArmorOptions,

8

      Deserializable as _,

9

      SignedSecretKey,

10

    };

11

12

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

13

14

    use super::KEY_LOCATION_HELP;

15

16

    #[derive(Debug, Args)]

17

    pub struct ExportKey {

18

      #[arg(short, long, help = "The output file")]

19

      output: String,

20

21

      /// The location to store the private key

22

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

23

      location: Option<String>,

24

25

      /// If not provided, the key will be named "default"

26

      #[arg(short, long, help = "The key name")]

27

      name: Option<String>,

28

    }

29

30

    impl ExportKey {

31

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

32

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

33

        let name: &str = &self.name.clone().unwrap_or_else(|| context.key_name());

34

        let output: &str = &self.output.clone();

35

36

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

37

        assert!(!name.is_empty(), "Key name must be provided");

38

        assert!(!output.is_empty(), "Output file must be provided");

39

40

        let filename_with_ext: &str = &format!("{name}.key");

41

42

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

43

        if path.exists() {

44

          // We opt to parse it rather than copy it directly to verify if it is a valid key

45

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

46

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

47

          signed_secret_key.verify()?;

48

49

          // Save the armored private key to a file

50

          let mut file = File::open(output)?;

51

          signed_secret_key.to_armored_writer(&mut file, ArmorOptions::default())?;

52

          file.flush()?;

53

54

          println!("Key {name} exported to {output}.");

55

        } else {

56

          println!("Key {name} does not exist.");

57

        }

58

59

        Ok(())

60

      }

61

    }