trustchain_http/
config.rs

1//! Trustchain HTTP configuration types and utilities.
2use lazy_static::lazy_static;
3use serde::{Deserialize, Serialize};
4use std::fs;
5use std::{
6    net::{IpAddr, SocketAddr},
7    str::FromStr,
8};
9use toml;
10use trustchain_core::verifier::Timestamp;
11use trustchain_core::TRUSTCHAIN_CONFIG;
12
13const DEFAULT_HOST: &str = "127.0.0.1";
14const DEFAULT_PORT: u16 = 8081;
15
16/// HTTP configuration.
17#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
18pub struct HTTPConfig {
19    /// Host address for server.
20    /// machine running emulator.
21    pub host: IpAddr,
22    /// Hostname display in QR codes. For example, if using local server with an Android emulator
23    /// `10.0.2.2` refers to `127.0.0.1` of machine
24    /// running emulator.
25    pub host_display: String,
26    /// Port for server
27    pub port: u16,
28    /// ION host
29    pub ion_host: IpAddr,
30    /// ION port
31    pub ion_port: u16,
32    /// Optional server DID if issuing or verifying
33    pub server_did: Option<String>,
34    /// Flag indicating whether server uses https
35    pub https: bool,
36    /// Path containing certificate and key necessary for https
37    pub https_path: Option<String>,
38    /// Display downstream DIDs (instead of URLs) in QR codes for verifiable endpoint retrieval
39    /// (`None` by default and unwrapped as `true`)
40    pub verifiable_endpoints: Option<bool>,
41    /// Root event time for verifier.
42    pub root_event_time: Option<Timestamp>,
43}
44
45impl std::fmt::Display for HTTPConfig {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        writeln!(f, "{:?}", self)
48    }
49}
50
51impl Default for HTTPConfig {
52    fn default() -> Self {
53        Self {
54            host: IpAddr::from_str(DEFAULT_HOST).unwrap(),
55            host_display: DEFAULT_HOST.to_string(),
56            port: DEFAULT_PORT,
57            ion_host: IpAddr::from_str(DEFAULT_HOST).unwrap(),
58            ion_port: 3000,
59            server_did: None,
60            https: false,
61            https_path: None,
62            verifiable_endpoints: None,
63            root_event_time: None,
64        }
65    }
66}
67
68impl HTTPConfig {
69    /// Provides formatted string of server config address.
70    pub fn to_address(&self) -> String {
71        format!("{}:{}", self.host, self.port).parse().unwrap()
72    }
73    /// Provides `SocketAdd` of server config address.
74    pub fn to_socket_address(&self) -> SocketAddr {
75        format!("{}:{}", self.host, self.port)
76            .parse::<SocketAddr>()
77            .unwrap()
78    }
79    /// Provide "http" or "https" according to config.
80    pub fn http_scheme(&self) -> &str {
81        if self.https {
82            "https"
83        } else {
84            "http"
85        }
86    }
87}
88
89lazy_static! {
90    /// Lazy static reference to core configuration loaded from `trustchain_config.toml`.
91    pub static ref HTTP_CONFIG: HTTPConfig = parse_toml(
92        &fs::read_to_string(std::env::var(TRUSTCHAIN_CONFIG).unwrap().as_str())
93        .expect("Error reading trustchain_config.toml"));
94}
95
96/// Parses and returns core configuration.
97fn parse_toml(toml_str: &str) -> HTTPConfig {
98    toml::from_str::<Config>(toml_str)
99        .expect("Error parsing trustchain_config.toml")
100        .http
101}
102
103/// Gets `trustchain-http` configuration variables.
104pub fn http_config() -> &'static HTTP_CONFIG {
105    &HTTP_CONFIG
106}
107
108/// Wrapper struct for parsing the `http` config table.
109#[derive(Serialize, Deserialize, Debug, Clone)]
110struct Config {
111    /// HTTP configuration data.
112    http: HTTPConfig,
113}
114
115#[cfg(test)]
116mod tests {
117    use super::*;
118
119    #[test]
120    fn test_deserialize() {
121        let config_string = r#"
122        [http]
123        host = "127.0.0.1"
124        host_display = "127.0.0.1"
125        port = 8081
126        ion_host = "127.0.0.1"
127        ion_port = 3000
128        server_did = "did:ion:test:EiBcLZcELCKKtmun_CUImSlb2wcxK5eM8YXSq3MrqNe5wA"
129        https = false
130
131        [non_http]
132        key = "value"
133        "#;
134
135        let config: HTTPConfig = parse_toml(config_string);
136        assert!(config.verifiable_endpoints.is_none());
137        assert_eq!(
138            config,
139            HTTPConfig {
140                server_did: Some(
141                    "did:ion:test:EiBcLZcELCKKtmun_CUImSlb2wcxK5eM8YXSq3MrqNe5wA".to_string()
142                ),
143                ..HTTPConfig::default()
144            }
145        );
146    }
147}