commit abdaebd3a58a4b85526c79405a580bc3e71a930f
parent 1e1b7469f38554b2e5c871071bc25df2bbedb0bb
Author: Henrique Chan Carvalho Machado <henriqueccmachado@tecnico.ulisboa.pt>
Date: Sun, 26 Oct 2025 00:33:09 +0200
oauth2_gateway: omit hardcoded Client/Verifier config; will move to DB
Diffstat:
2 files changed, 149 insertions(+), 48 deletions(-)
diff --git a/oauth2_gateway/config.example.ini b/oauth2_gateway/config.example.ini
@@ -1,11 +1,12 @@
+# OAuth2 Gateway Configuration
+#
+# NOTE: Client-specific configuration (notification URLs, verifier URLs) is stored
+# in the database, not in this file.
+
[server]
host = 127.0.0.1
port = 8080
-[exchange]
-base_url = https://exchange.example.com
-notification_endpoint = /oauth2gw/kyc/notify
-
-[verifier]
-base_url = https://verifier.example.com
-management_api_path = /management/api/verifications
+[database]
+# PostgreSQL connection string
+url = postgresql://oauth2gw:password@localhost/oauth2gw
+\ No newline at end of file
diff --git a/oauth2_gateway/src/config.rs b/oauth2_gateway/src/config.rs
@@ -6,8 +6,7 @@ use std::path::Path;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub server: ServerConfig,
- pub exchange: ExchangeConfig,
- pub verifier: VerifierConfig,
+ pub database: DatabaseConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -17,15 +16,8 @@ pub struct ServerConfig {
}
#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct ExchangeConfig {
- pub base_url: String,
- pub notification_endpoint: String,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct VerifierConfig {
- pub base_url: String,
- pub management_api_path: String,
+pub struct DatabaseConfig {
+ pub url: String,
}
impl Config {
@@ -50,42 +42,149 @@ impl Config {
.context("Invalid port")?,
};
- // Exchange section
- let exchange_section = ini
- .section(Some("exchange"))
- .context("Missing [exchange] section")?;
+ // Database section
+ let database_section = ini
+ .section(Some("database"))
+ .context("Missing [database] section")?;
- let exchange = ExchangeConfig {
- base_url: exchange_section
- .get("base_url")
- .context("Missing exchange.base_url")?
- .to_string(),
- notification_endpoint: exchange_section
- .get("notification_endpoint")
- .unwrap_or("/oauth2gw/kyc/notify")
- .to_string(),
- };
-
- // Verifier section
- let verifier_section = ini
- .section(Some("verifier"))
- .context("Missing [verifier] section")?;
-
- let verifier = VerifierConfig {
- base_url: verifier_section
- .get("base_url")
- .context("Missing verifier.base_url")?
- .to_string(),
- management_api_path: verifier_section
- .get("management_api_path")
- .unwrap_or("/management/api/verifications")
+ let database = DatabaseConfig {
+ url: database_section
+ .get("url")
+ .context("Missing database.url")?
.to_string(),
};
Ok(Config {
server,
- exchange,
- verifier,
+ database,
})
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use std::io::Write;
+ use tempfile::NamedTempFile;
+
+ #[test]
+ fn test_config_load_valid() {
+ let mut temp_file = NamedTempFile::new().unwrap();
+ writeln!(
+ temp_file,
+ r#"
+[server]
+host = 0.0.0.0
+port = 3000
+
+[database]
+url = postgresql://localhost/oauth2gw_test
+"#
+ )
+ .unwrap();
+
+ let config = Config::from_file(temp_file.path()).unwrap();
+
+ assert_eq!(config.server.host, "0.0.0.0");
+ assert_eq!(config.server.port, 3000);
+ assert_eq!(config.database.url, "postgresql://localhost/oauth2gw_test");
+ }
+
+ #[test]
+ fn test_config_defaults() {
+ let mut temp_file = NamedTempFile::new().unwrap();
+ writeln!(
+ temp_file,
+ r#"
+[server]
+# host and port not specified, should use defaults
+
+[database]
+url = postgresql://localhost/oauth2gw
+"#
+ )
+ .unwrap();
+
+ let config = Config::from_file(temp_file.path()).unwrap();
+
+ assert_eq!(config.server.host, "127.0.0.1");
+ assert_eq!(config.server.port, 8080);
+ }
+
+ #[test]
+ fn test_config_missing_server_section() {
+ let mut temp_file = NamedTempFile::new().unwrap();
+ writeln!(
+ temp_file,
+ r#"
+[database]
+url = postgresql://localhost/oauth2gw
+"#
+ )
+ .unwrap();
+
+ let result = Config::from_file(temp_file.path());
+ assert!(result.is_err());
+ assert!(result.unwrap_err().to_string().contains("server"));
+ }
+
+ #[test]
+ fn test_config_missing_database_section() {
+ let mut temp_file = NamedTempFile::new().unwrap();
+ writeln!(
+ temp_file,
+ r#"
+[server]
+host = 127.0.0.1
+port = 8080
+"#
+ )
+ .unwrap();
+
+ let result = Config::from_file(temp_file.path());
+ assert!(result.is_err());
+ assert!(result.unwrap_err().to_string().contains("database"));
+ }
+
+ #[test]
+ fn test_config_missing_database_url() {
+ let mut temp_file = NamedTempFile::new().unwrap();
+ writeln!(
+ temp_file,
+ r#"
+[server]
+host = 127.0.0.1
+port = 8080
+
+[database]
+# url is missing
+"#
+ )
+ .unwrap();
+
+ let result = Config::from_file(temp_file.path());
+ assert!(result.is_err());
+ assert!(result.unwrap_err().to_string().contains("database.url"));
+ }
+
+ #[test]
+ fn test_config_invalid_port() {
+ let mut temp_file = NamedTempFile::new().unwrap();
+ writeln!(
+ temp_file,
+ r#"
+[server]
+host = 127.0.0.1
+port = not_a_number
+
+[database]
+url = postgresql://localhost/oauth2gw
+"#
+ )
+ .unwrap();
+
+ let result = Config::from_file(temp_file.path());
+ assert!(result.is_err());
+ assert!(result.unwrap_err().to_string().contains("port"));
+ }
+}