ICryptoProvider trait
This commit is contained in:
		
							
								
								
									
										143
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										143
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -6,6 +6,7 @@ use std::{
 | 
			
		||||
    collections::BTreeMap,
 | 
			
		||||
    path::{Path, PathBuf},
 | 
			
		||||
    pin::Pin,
 | 
			
		||||
    sync::Arc,
 | 
			
		||||
};
 | 
			
		||||
use tokio::{
 | 
			
		||||
    fs::{self, File},
 | 
			
		||||
@@ -288,61 +289,28 @@ impl VarsFile {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct Certs {
 | 
			
		||||
trait ICryptoProvider {
 | 
			
		||||
    async fn request(&self) -> Result<()>;
 | 
			
		||||
    async fn sign(&self) -> Result<()>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct OpenSSLProvider {
 | 
			
		||||
    vars: BTreeMap<String, String>,
 | 
			
		||||
    base_dir: PathBuf,
 | 
			
		||||
    encoding: String,
 | 
			
		||||
    req_days: u32,
 | 
			
		||||
    openssl_cnf: PathBuf,
 | 
			
		||||
    openssl: String,
 | 
			
		||||
    ca_file: PathBuf,
 | 
			
		||||
    req_file: PathBuf,
 | 
			
		||||
    key_file: PathBuf,
 | 
			
		||||
    cert_file: PathBuf,
 | 
			
		||||
    config_file: PathBuf,
 | 
			
		||||
    template_file: PathBuf,
 | 
			
		||||
    openssl_cnf: PathBuf,
 | 
			
		||||
    openssl: String,
 | 
			
		||||
    vars: BTreeMap<String, String>,
 | 
			
		||||
    req_days: u32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Certs {
 | 
			
		||||
    fn new(cfg: &AppConfig, vars: BTreeMap<String, String>) -> Self {
 | 
			
		||||
        let base_dir = PathBuf::from(&cfg.base_directory);
 | 
			
		||||
        let keys_dir = base_dir.clone().join(cfg.keys_subdir.clone());
 | 
			
		||||
        let config_dir = base_dir.clone().join(cfg.config_subdir.clone());
 | 
			
		||||
 | 
			
		||||
        let mut vars = vars;
 | 
			
		||||
        let name = cfg.name.clone();
 | 
			
		||||
 | 
			
		||||
        vars.insert("KEY_CN".into(), name.clone());
 | 
			
		||||
        vars.insert("KEY_NAME".into(), name.clone());
 | 
			
		||||
        vars.insert("KEY_EMAIL".into(), cfg.email.clone());
 | 
			
		||||
 | 
			
		||||
        Self {
 | 
			
		||||
            base_dir: base_dir.clone(),
 | 
			
		||||
            encoding: cfg.encoding.clone(),
 | 
			
		||||
            req_days: cfg.req_days,
 | 
			
		||||
            ca_file: keys_dir.join(cfg.ca_filename.clone()),
 | 
			
		||||
            req_file: keys_dir.join(format!("{}.csr", &name)),
 | 
			
		||||
            key_file: keys_dir.join(format!("{}.key", &name)),
 | 
			
		||||
            cert_file: keys_dir.join(format!("{}.crt", &name)),
 | 
			
		||||
            config_file: config_dir.join(format!("{}.ovpn", &name)),
 | 
			
		||||
            template_file: base_dir.clone().join(cfg.template_file.clone()),
 | 
			
		||||
            openssl_cnf: base_dir.clone().join(
 | 
			
		||||
                std::env::var(cfg.openssl_cnf_env.clone())
 | 
			
		||||
                    .unwrap_or(cfg.openssl_default_cnf.clone()),
 | 
			
		||||
            ),
 | 
			
		||||
            openssl: cfg.openssl.clone(),
 | 
			
		||||
            vars,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
impl OpenSSLProvider {
 | 
			
		||||
    async fn is_ca_exists(&self) -> bool {
 | 
			
		||||
        is_file_exist(&self.ca_file).await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn is_config_exists(&self) -> bool {
 | 
			
		||||
        is_file_exist(&self.config_file).await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn is_cert_exists(&self) -> bool {
 | 
			
		||||
        is_file_exist(&self.cert_file).await
 | 
			
		||||
    }
 | 
			
		||||
@@ -351,6 +319,39 @@ impl Certs {
 | 
			
		||||
        is_file_exist(&self.req_file).await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn from_cfg(cfg: &AppConfig, vars: BTreeMap<String, String>) -> Self {
 | 
			
		||||
        let base_dir = PathBuf::from(&cfg.base_directory);
 | 
			
		||||
        let keys_dir = base_dir.clone().join(cfg.keys_subdir.clone());
 | 
			
		||||
        let name = cfg.name.clone();
 | 
			
		||||
        let mut vars = vars;
 | 
			
		||||
 | 
			
		||||
        vars.insert("KEY_CN".into(), name.clone());
 | 
			
		||||
        vars.insert("KEY_NAME".into(), name.clone());
 | 
			
		||||
        vars.insert("KEY_EMAIL".into(), cfg.email.clone());
 | 
			
		||||
 | 
			
		||||
        let ca_file = keys_dir.join(cfg.ca_filename.clone());
 | 
			
		||||
        let req_file = keys_dir.join(format!("{}.csr", &name));
 | 
			
		||||
        let key_file = keys_dir.join(format!("{}.key", &name));
 | 
			
		||||
        let cert_file = keys_dir.join(format!("{}.crt", &name));
 | 
			
		||||
        let openssl_cnf = base_dir.clone().join(
 | 
			
		||||
            std::env::var(cfg.openssl_cnf_env.clone()).unwrap_or(cfg.openssl_default_cnf.clone()),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        Self {
 | 
			
		||||
            vars,
 | 
			
		||||
            base_dir,
 | 
			
		||||
            openssl_cnf,
 | 
			
		||||
            openssl: cfg.openssl.clone(),
 | 
			
		||||
            ca_file,
 | 
			
		||||
            req_file,
 | 
			
		||||
            key_file,
 | 
			
		||||
            cert_file,
 | 
			
		||||
            req_days: cfg.req_days,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl ICryptoProvider for OpenSSLProvider {
 | 
			
		||||
    async fn request(&self) -> Result<()> {
 | 
			
		||||
        if self.is_req_exists().await {
 | 
			
		||||
            return Ok(());
 | 
			
		||||
@@ -422,6 +423,57 @@ impl Certs {
 | 
			
		||||
            false => Err(anyhow!("ssl ca execution failed")),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct Certs<T>
 | 
			
		||||
where
 | 
			
		||||
    T: ICryptoProvider,
 | 
			
		||||
{
 | 
			
		||||
    encoding: String,
 | 
			
		||||
    ca_file: PathBuf,
 | 
			
		||||
    key_file: PathBuf,
 | 
			
		||||
    cert_file: PathBuf,
 | 
			
		||||
    config_file: PathBuf,
 | 
			
		||||
    template_file: PathBuf,
 | 
			
		||||
    provider: Arc<T>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn make_certs_provider(cfg: &AppConfig, vars: BTreeMap<String, String>) -> impl ICryptoProvider {
 | 
			
		||||
    OpenSSLProvider::from_cfg(cfg, vars)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T> Certs<T>
 | 
			
		||||
where
 | 
			
		||||
    T: ICryptoProvider,
 | 
			
		||||
{
 | 
			
		||||
    fn new(cfg: &AppConfig, provider: T) -> Self {
 | 
			
		||||
        let base_dir = PathBuf::from(&cfg.base_directory);
 | 
			
		||||
        let keys_dir = base_dir.clone().join(cfg.keys_subdir.clone());
 | 
			
		||||
        let config_dir = base_dir.clone().join(cfg.config_subdir.clone());
 | 
			
		||||
        let name = cfg.name.clone();
 | 
			
		||||
 | 
			
		||||
        Certs {
 | 
			
		||||
            encoding: cfg.encoding.clone(),
 | 
			
		||||
            ca_file: keys_dir.join(cfg.ca_filename.clone()),
 | 
			
		||||
            key_file: keys_dir.join(format!("{}.key", &name)),
 | 
			
		||||
            cert_file: keys_dir.join(format!("{}.crt", &name)),
 | 
			
		||||
            config_file: config_dir.join(format!("{}.ovpn", &name)),
 | 
			
		||||
            template_file: base_dir.clone().join(cfg.template_file.clone()),
 | 
			
		||||
            provider: Arc::new(provider),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn is_config_exists(&self) -> bool {
 | 
			
		||||
        is_file_exist(&self.config_file).await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn request(&self) -> Result<()> {
 | 
			
		||||
        self.provider.request().await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn sign(&self) -> Result<()> {
 | 
			
		||||
        self.provider.sign().await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn build_client_config(&self) -> Result<bool> {
 | 
			
		||||
        if self.is_config_exists().await {
 | 
			
		||||
@@ -470,7 +522,8 @@ async fn main() -> Result<()> {
 | 
			
		||||
    println!("found vars: {}", vars.filepath.to_str().expect("fff"));
 | 
			
		||||
    println!("loaded: {:#?}", &vars.vars);
 | 
			
		||||
 | 
			
		||||
    let certs = Certs::new(&config, vars.vars.unwrap());
 | 
			
		||||
    let provider = make_certs_provider(&config, vars.vars.unwrap());
 | 
			
		||||
    let certs = Certs::new(&config, provider);
 | 
			
		||||
    let created = certs.build_client_config().await?;
 | 
			
		||||
 | 
			
		||||
    let result_file = certs.config_file.to_str().unwrap();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user