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    #[arg(env, default_value = "")]
55    /// URL of Slack webhook for sending notifications
56    pub slack_webhook_url: String, 
57
58    // Other configs
59    #[arg(env, default_value = "10")]
60    /// Maximum number of papers that can be uploaded at a time
61    pub max_upload_limit: usize,
62    #[arg(env, default_value = "./log/application.log")]
63    /// Location where logs are stored
64    pub log_location: PathBuf,
65
66    // Paths
67    #[arg(env, default_value = "https://static.metakgp.org")]
68    /// The URL of the static files server (odin's vault)
69    static_files_url: String,
70    #[arg(env, default_value = "/srv/static")]
71    /// The path where static files are served from
72    static_file_storage_location: PathBuf,
73    #[arg(env, default_value = "/iqps/uploaded")]
74    /// The path where uploaded papers are stored temporarily, relative to the `static_file_storage_location`
75    uploaded_qps_path: PathBuf,
76    #[arg(env, default_value = "/peqp/qp")]
77    /// The path where library papers (scrapped) are stored, relative to the `static_file_storage_location`
78    library_qps_path: PathBuf,
79
80    // Server
81    #[arg(env, default_value = "8080")]
82    /// The port the server listens on
83    pub server_port: i32,
84
85    // CORS
86    #[arg(env, default_value = "https://qp.metakgp.org,http://localhost:5173")]
87    /// List of origins allowed (as a list of values separated by commas `origin1, origin2`)
88    pub cors_allowed_origins: String,
89
90    #[arg(skip)]
91    /// All paths must be handled using this
92    pub paths: Paths,
93}
94
95impl EnvVars {
96    /// Processes the environment variables after reading.
97    pub fn process(mut self) -> Result<Self, Box<dyn std::error::Error>> {
98        self.paths = Paths::new(
99            &self.static_files_url,
100            &self.static_file_storage_location,
101            &self.uploaded_qps_path,
102            &self.library_qps_path,
103        )?;
104        self.log_location = std::path::absolute(self.log_location)?;
105
106        Ok(self)
107    }
108
109    /// Returns the JWT signing key
110    pub fn get_jwt_key(&self) -> Result<Hmac<Sha256>, InvalidLength> {
111        Hmac::new_from_slice(self.jwt_secret.as_bytes())
112    }
113}