unleash-edge 19.2.1

Unleash edge is a proxy for Unleash. It can return both evaluated feature toggles as well as the raw data from Unleash's client API
use rustls::pki_types::PrivateKeyDer;
use rustls::ServerConfig;
use rustls_pemfile::{certs, pkcs8_private_keys};
use std::path::PathBuf;
use std::{fs, fs::File, io::BufReader};

use crate::cli::TlsOptions;
use crate::error::{CertificateError, EdgeError};
use crate::types::EdgeResult;

pub(crate) fn build_upstream_certificate(
    upstream_certificate: Option<PathBuf>,
) -> EdgeResult<Option<reqwest::tls::Certificate>> {
    upstream_certificate
        .map(|cert| {
            fs::read(cert)
                .map_err(|e| {
                    EdgeError::ClientCertificateError(CertificateError::RootCertificatesError(
                        format!("{e:?}"),
                    ))
                })
                .and_then(|bytes| {
                    reqwest::Certificate::from_pem(&bytes).map_err(|e| {
                        EdgeError::ClientCertificateError(CertificateError::RootCertificatesError(
                            format!("{e:?}"),
                        ))
                    })
                })
                .map(Some)
        })
        .unwrap_or(Ok(None))
}

pub fn config(tls_config: TlsOptions) -> Result<ServerConfig, EdgeError> {
    let config = ServerConfig::builder().with_no_client_auth();
    let mut cert_file = BufReader::new(
        File::open(
            tls_config
                .tls_server_cert
                .expect("No TLS server cert")
                .as_path(),
        )
        .map_err(|_| EdgeError::TlsError)?,
    );
    let mut key_file = BufReader::new(
        File::open(tls_config.tls_server_key.expect("No server key").as_path())
            .expect("Could not read cert file"),
    );
    let cert_chain = certs(&mut cert_file).filter_map(|f| f.ok()).collect();
    let mut keys: Vec<PrivateKeyDer> = pkcs8_private_keys(&mut key_file)
        .filter_map(|f| f.map(PrivateKeyDer::from).ok())
        .collect();
    config
        .with_single_cert(cert_chain, keys.remove(0))
        .map_err(|_e| EdgeError::TlsError)
}