cadsus-client 0.0.18

Wrapper for execute requests in cadsus
Documentation
use http::{Method, StatusCode};
use reqwest::{Client as HttpClient, Identity, Request, Url};
use serde::{Deserialize, Serialize};

use crate::client::osb::OsbTokenError::{InvalidPem, UnknownError};

const TOKEN_ENDPOINT: &str = "https://ehr-auth.saude.gov.br/api/osb/token";

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct OsbTokenResponse {
    pub access_token: String,
    pub scope: String,
    pub token_type: String,
    pub expires_in: i64,
}

#[derive(Debug, Clone)]
pub enum OsbTokenError {
    InvalidPem(String),
    TlsError(String),
    FailedRequest(String),
    UnknownError(String),
}

pub async fn get_osb_token_from_pem(pem_file: Vec<u8>) -> Result<OsbTokenResponse, OsbTokenError> {
    let identity = Identity::from_pem(&pem_file).map_err(
        |e| InvalidPem(format!("Falha ao criar a identidade: {:?}", e))
    )?;
    let client = HttpClient::builder()
        .use_rustls_tls()
        .tls_built_in_root_certs(true)
        .identity(identity)
        .https_only(true)
        .tls_info(true)
        .connection_verbose(true)
        .build()
        .map_err(
            |e| {
                OsbTokenError::TlsError(format!("Falha ao criar o cliente: {:?}", e))
            }
        )?;

    let request = Request::new(Method::GET, Url::parse(TOKEN_ENDPOINT).map_err(
        |e| {
            UnknownError(
                format!("Falha ao criar a url: {:?}", e)
            )
        }
    )?);
    let response = client.execute(request).await;

    return match response {
        Ok(response) => {
            let status = response.status();
            if status == StatusCode::OK {
                let body: OsbTokenResponse = response.json().await.map_err(
                    |e| {
                        OsbTokenError::FailedRequest(
                            format!("Falha ao deserializar o corpo da resposta: {:?}", e)
                        )
                    }
                )?;
                Ok(body)
            } else {
                Err(OsbTokenError::FailedRequest(format!("Falha na requisição: {:?}", status)))
            }
        }
        Err(e) => {
            return Err(OsbTokenError::FailedRequest(format!("Falha na requisição: {:?}", e)))
        }
    };
}