iqps_backend/
env.rs

1//! ### Environment Variables
2//!
3//!  Each field in the struct `EnvVars` corresponds to an environment variable. The environment variable name will be in all capitals. The default values are set using the `arg()` macro of the `clap` crate. Check the source code for the defaults.
4
5use std::path::PathBuf;
6
7use clap::Parser;
8use hmac::{digest::InvalidLength, Hmac, Mac};
9use sha2::Sha256;
10
11use crate::pathutils::Paths;
12
13#[derive(Parser, Clone)]
14pub struct EnvVars {
15    // Database
16    #[arg(env)]
17    /// Database name
18    pub db_name: String,
19    #[arg(env)]
20    /// Database hostname
21    pub db_host: String,
22    #[arg(env)]
23    /// Database port
24    pub db_port: String,
25    #[arg(env)]
26    /// Database username
27    pub db_user: String,
28    #[arg(env)]
29    /// Database password
30    pub db_password: String,
31
32    // Auth
33    #[arg(env)]
34    /// OAuth app client id (public token)
35    pub gh_client_id: String,
36    #[arg(env)]
37    /// An org admin's Github token (with the `read:org` permission)
38    pub gh_org_admin_token: String,
39    #[arg(env)]
40    /// JWT encryption secret (make it a long, randomized string)
41    jwt_secret: String,
42    #[arg(env)]
43    /// OAuth app client secret
44    pub gh_client_secret: String,
45    #[arg(env, default_value = "")]
46    /// Github organization name
47    pub gh_org_name: String,
48    #[arg(env, default_value = "")]
49    /// Github organization team slug (this team has access to admin dashboard)
50    pub gh_org_team_slug: String,
51    #[arg(env, default_value = "")]
52    /// The usernames of the admins (additional to org team members, comma separated)
53    pub gh_admin_usernames: String,
54
55    // Other configs
56    #[arg(env, default_value = "10")]
57    /// Maximum number of papers that can be uploaded at a time
58    pub max_upload_limit: usize,
59    #[arg(env, default_value = "./log/application.log")]
60    /// Location where logs are stored
61    pub log_location: PathBuf,
62
63    // Paths
64    #[arg(env, default_value = "https://static.metakgp.org")]
65    /// The URL of the static files server (odin's vault)
66    static_files_url: String,
67    #[arg(env, default_value = "/srv/static")]
68    /// The path where static files are served from
69    static_file_storage_location: PathBuf,
70    #[arg(env, default_value = "/iqps/uploaded")]
71    /// The path where uploaded papers are stored temporarily, relative to the `static_file_storage_location`
72    uploaded_qps_path: PathBuf,
73    #[arg(env, default_value = "/peqp/qp")]
74    /// The path where library papers (scrapped) are stored, relative to the `static_file_storage_location`
75    library_qps_path: PathBuf,
76
77    // Server
78    #[arg(env, default_value = "8080")]
79    /// The port the server listens on
80    pub server_port: i32,
81
82    // CORS
83    #[arg(env, default_value = "https://qp.metakgp.org,http://localhost:5173")]
84    /// List of origins allowed (as a list of values separated by commas `origin1, origin2`)
85    pub cors_allowed_origins: String,
86
87    #[arg(skip)]
88    /// All paths must be handled using this
89    pub paths: Paths,
90}
91
92impl EnvVars {
93    /// Processes the environment variables after reading.
94    pub fn process(mut self) -> Result<Self, Box<dyn std::error::Error>> {
95        self.paths = Paths::new(
96            &self.static_files_url,
97            &self.static_file_storage_location,
98            &self.uploaded_qps_path,
99            &self.library_qps_path,
100        )?;
101        self.log_location = std::path::absolute(self.log_location)?;
102
103        Ok(self)
104    }
105
106    /// Returns the JWT signing key
107    pub fn get_jwt_key(&self) -> Result<Hmac<Sha256>, InvalidLength> {
108        Hmac::new_from_slice(self.jwt_secret.as_bytes())
109    }
110}