1
use std::path::PathBuf;
2

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

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

            
8
/// Command to manage the server's certificates.
9
91
#[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>(
39
1
        &self,
40
1
        server: &CustomServer<B>,
41
1
    ) -> Result<(), BackendError<B::Error>> {
42
1
        match self {
43
1
            Self::InstallSelfSigned { overwrite } => {
44
10
                server.install_self_signed_certificate(*overwrite).await?;
45
            }
46
            Self::Install {
47
                private_key,
48
                certificate_chain,
49
            } => {
50
                let mut private_key_file = tokio::fs::File::open(&private_key).await?;
51
                let mut private_key = Vec::new();
52
                private_key_file.read_to_end(&mut private_key).await?;
53

            
54
                let mut certificate_chain_file = tokio::fs::File::open(&certificate_chain).await?;
55
                let mut certificate_chain = Vec::new();
56
                certificate_chain_file
57
                    .read_to_end(&mut certificate_chain)
58
                    .await?;
59

            
60
                server
61
                    .install_pem_certificate(&certificate_chain, &private_key)
62
                    .await?;
63
            }
64
        }
65

            
66
1
        Ok(())
67
1
    }
68
}