1
use std::path::PathBuf;
2

            
3
use clap::Subcommand;
4
use tokio::io::AsyncReadExt;
5

            
6
use crate::{Backend, CustomServer, Error};
7

            
8
/// Command to manage the server's certificates.
9
126
#[derive(Subcommand, Debug)]
10
pub enum Command {
11
    /// Installs a self-signed certificate into the server. The server can only
12
    /// have one global self-signed certificate. If `overwrite` is true, any
13
    /// existing certificate will be overwritten. If `overwrite` is false and a
14
    /// certificate already exists,
15
    /// [`Error::Configuration`](bonsaidb_core::Error::Configuration) is
16
    /// returned.
17
    InstallSelfSigned {
18
        /// If an existing certificate exists, an error will be returned unless
19
        /// `overwrite` is true.
20
        #[clap(short, long)]
21
        overwrite: bool,
22
    },
23
    /// Installs a X.509 certificate and associated private key in PEM format.
24
    ///
25
    /// This command reads the files `private_key` and `certificate` and
26
    /// executes
27
    /// [`Server::install_certificate()`](crate::CustomServer::install_certificate).
28
    Install {
29
        /// A private key used to generate `certificate` in the ASCII PEM format.
30
        private_key: PathBuf,
31
        /// The X.509 certificate chain in the ASCII PEM format.
32
        certificate_chain: PathBuf,
33
    },
34
}
35

            
36
impl Command {
37
    /// Executes the command.
38
1
    pub async fn execute<B: Backend>(&self, server: &CustomServer<B>) -> Result<(), Error> {
39
1
        match self {
40
1
            Self::InstallSelfSigned { overwrite } => {
41
8
                server.install_self_signed_certificate(*overwrite).await?;
42
            }
43
            Self::Install {
44
                private_key,
45
                certificate_chain,
46
            } => {
47
                let mut private_key_file = tokio::fs::File::open(&private_key).await?;
48
                let mut private_key = Vec::new();
49
                private_key_file.read_to_end(&mut private_key).await?;
50

            
51
                let mut certificate_chain_file = tokio::fs::File::open(&certificate_chain).await?;
52
                let mut certificate_chain = Vec::new();
53
                certificate_chain_file
54
                    .read_to_end(&mut certificate_chain)
55
                    .await?;
56

            
57
                server
58
                    .install_pem_certificate(&certificate_chain, &private_key)
59
                    .await?;
60
            }
61
        }
62

            
63
1
        Ok(())
64
1
    }
65
}