Skip to content

Commit

Permalink
EDGAR: Issue-132 - Edgar uses client secret and client id from provid…
Browse files Browse the repository at this point in the history
…ed setup string and writes those information in its toml file if they are not existent yet.
  • Loading branch information
mtwardawski committed Apr 12, 2024
1 parent 8620c3f commit f26b379
Show file tree
Hide file tree
Showing 13 changed files with 103 additions and 29 deletions.
4 changes: 2 additions & 2 deletions .ci/docker/carl/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ services:
- OPENDUT_CARL_OPENTELEMETRY_ENDPOINT=http://otel-collector:4317
# OIDC
- OPENDUT_CARL_NETWORK_OIDC_ENABLED=true
- OPENDUT_CARL_NETWORK_OIDC_CLIENT_CLIENT_ID=opendut-carl-client
- OPENDUT_CARL_NETWORK_OIDC_CLIENT_CLIENT_SECRET=6754d533-9442-4ee6-952a-97e332eca38e
- OPENDUT_CARL_NETWORK_OIDC_CLIENT_ID=opendut-carl-client
- OPENDUT_CARL_NETWORK_OIDC_CLIENT_SECRET=6754d533-9442-4ee6-952a-97e332eca38e
- OPENDUT_CARL_NETWORK_OIDC_CLIENT_PEER_ID=opendut-edgar-client
- OPENDUT_CARL_NETWORK_OIDC_CLIENT_PEER_SECRET=c7d6ace0-b90f-471a-bb62-a4ecac4150f8
- OPENDUT_CARL_NETWORK_OIDC_CLIENT_ISSUER_URL=https://keycloak/realms/opendut/
Expand Down
16 changes: 8 additions & 8 deletions .ci/docker/edgar/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ services:
- OPENDUT_CLEO_NETWORK_CARL_PORT=443
- OPENDUT_CLEO_NETWORK_TLS_DOMAIN_NAME_OVERRIDE=carl # default developer certificate is only valid for localhost
- OPENDUT_CLEO_NETWORK_OIDC_ENABLED=true
- OPENDUT_CLEO_NETWORK_OIDC_CLIENT_CLIENT_ID=opendut-cleo-client
- OPENDUT_CLEO_NETWORK_OIDC_CLIENT_CLIENT_SECRET=918642e0-4ec4-4ef5-8ae0-ba92de7da3f9
- OPENDUT_CLEO_NETWORK_OIDC_CLIENT_ID=opendut-cleo-client
- OPENDUT_CLEO_NETWORK_OIDC_CLIENT_SECRET=918642e0-4ec4-4ef5-8ae0-ba92de7da3f9
- OPENDUT_CLEO_NETWORK_OIDC_CLIENT_ISSUER_URL=https://keycloak/realms/opendut/
- OPENDUT_CLEO_NETWORK_OIDC_CLIENT_SCOPES=

Expand All @@ -31,8 +31,8 @@ services:
- OPENDUT_EDGAR_NETWORK_CARL_PORT=443
- OPENDUT_EDGAR_NETWORK_TLS_DOMAIN_NAME_OVERRIDE=carl # default developer certificate is only valid for localhost
- OPENDUT_EDGAR_NETWORK_OIDC_ENABLED=true
- OPENDUT_EDGAR_NETWORK_OIDC_CLIENT_CLIENT_ID=opendut-edgar-client
- OPENDUT_EDGAR_NETWORK_OIDC_CLIENT_CLIENT_SECRET=c7d6ace0-b90f-471a-bb62-a4ecac4150f8
- OPENDUT_EDGAR_NETWORK_OIDC_CLIENT_ID=opendut-edgar-client
- OPENDUT_EDGAR_NETWORK_OIDC_CLIENT_SECRET=c7d6ace0-b90f-471a-bb62-a4ecac4150f8
- OPENDUT_EDGAR_NETWORK_OIDC_CLIENT_ISSUER_URL=https://keycloak/realms/opendut/
- OPENDUT_EDGAR_NETWORK_OIDC_CLIENT_SCOPES=
- OPENDUT_EDGAR_OPENTELEMETRY_ENABLED=true
Expand Down Expand Up @@ -73,8 +73,8 @@ services:
- OPENDUT_CLEO_NETWORK_CARL_PORT=443
- OPENDUT_CLEO_NETWORK_TLS_DOMAIN_NAME_OVERRIDE=carl # default developer certificate is only valid for localhost
- OPENDUT_CLEO_NETWORK_OIDC_ENABLED=true
- OPENDUT_CLEO_NETWORK_OIDC_CLIENT_CLIENT_ID=opendut-cleo-client
- OPENDUT_CLEO_NETWORK_OIDC_CLIENT_CLIENT_SECRET=918642e0-4ec4-4ef5-8ae0-ba92de7da3f9
- OPENDUT_CLEO_NETWORK_OIDC_CLIENT_ID=opendut-cleo-client
- OPENDUT_CLEO_NETWORK_OIDC_CLIENT_SECRET=918642e0-4ec4-4ef5-8ae0-ba92de7da3f9
- OPENDUT_CLEO_NETWORK_OIDC_CLIENT_ISSUER_URL=https://keycloak/realms/opendut/
- OPENDUT_CLEO_NETWORK_OIDC_CLIENT_SCOPES=

Expand All @@ -83,8 +83,8 @@ services:
- OPENDUT_EDGAR_NETWORK_CARL_PORT=443
- OPENDUT_EDGAR_NETWORK_TLS_DOMAIN_NAME_OVERRIDE=carl # default developer certificate is only valid for localhost
- OPENDUT_EDGAR_NETWORK_OIDC_ENABLED=true
- OPENDUT_EDGAR_NETWORK_OIDC_CLIENT_CLIENT_ID=opendut-edgar-client
- OPENDUT_EDGAR_NETWORK_OIDC_CLIENT_CLIENT_SECRET=c7d6ace0-b90f-471a-bb62-a4ecac4150f8
- OPENDUT_EDGAR_NETWORK_OIDC_CLIENT_ID=opendut-edgar-client
- OPENDUT_EDGAR_NETWORK_OIDC_CLIENT_SECRET=c7d6ace0-b90f-471a-bb62-a4ecac4150f8
- OPENDUT_EDGAR_NETWORK_OIDC_CLIENT_ISSUER_URL=https://keycloak/realms/opendut/
- OPENDUT_EDGAR_NETWORK_OIDC_CLIENT_SCOPES=
- OPENDUT_EDGAR_OPENTELEMETRY_ENABLED=true
Expand Down
4 changes: 2 additions & 2 deletions .ci/docker/theo/src/core/resources/carl.environment.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ OPENDUT_CARL_NETWORK_TLS_KEY=resources/development/tls/carl.key
OPENDUT_CARL_NETWORK_TLS_CA=resources/development/tls/insecure-development-ca.pem

OPENDUT_CARL_NETWORK_OIDC_ENABLED=true
OPENDUT_CARL_NETWORK_OIDC_CLIENT_CLIENT_ID=opendut-carl-client
OPENDUT_CARL_NETWORK_OIDC_CLIENT_CLIENT_SECRET=6754d533-9442-4ee6-952a-97e332eca38e
OPENDUT_CARL_NETWORK_OIDC_CLIENT_ID=opendut-carl-client
OPENDUT_CARL_NETWORK_OIDC_CLIENT_SECRET=6754d533-9442-4ee6-952a-97e332eca38e
OPENDUT_CARL_NETWORK_OIDC_CLIENT_ISSUER_URL=http://localhost:8081/realms/opendut/
OPENDUT_CARL_NETWORK_OIDC_CLIENT_ISSUER_REMOTE_URL=https://keycloak/realms/opendut/
OPENDUT_CARL_NETWORK_OIDC_CLIENT_SCOPES=""
Expand Down
4 changes: 2 additions & 2 deletions .ci/docker/theo/src/core/resources/carl.toml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ ca = "resources/development/tls/insecure-development-ca.pem"
enabled = true

[network.oidc.client]
client.id = "opendut-carl-client"
client.secret = "6754d533-9442-4ee6-952a-97e332eca38e"
id = "opendut-carl-client"
secret = "6754d533-9442-4ee6-952a-97e332eca38e"
issuer.url = "http://localhost:8081/realms/opendut/"
issuer.remote.url = "https://keycloak/realms/opendut/"
scopes = ""
Expand Down
4 changes: 2 additions & 2 deletions opendut-carl/carl.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ ca = "/etc/opendut/tls/ca.pem"
enabled = false

[network.oidc.client]
client.id = "tbd"
client.secret = "tbd"
id = "tbd"
secret = "tbd"
# issuer url that CARL uses
issuer.url = "https://keycloak/realms/opendut/"
# issuer url that CARL tells the clients to use (required in test environment)
Expand Down
4 changes: 2 additions & 2 deletions opendut-carl/opendut-carl-api/src/carl/auth/auth_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ pub struct OidcIdentityProviderConfig {

const OIDC_CLIENT_CONFIG_PREFIX: &str = "network.oidc.client";
impl OidcIdentityProviderConfig {
const CLIENT_ID: &'static str = formatcp!("{OIDC_CLIENT_CONFIG_PREFIX}.client.id");
const CLIENT_SECRET: &'static str = formatcp!("{OIDC_CLIENT_CONFIG_PREFIX}.client.secret");
const CLIENT_ID: &'static str = formatcp!("{OIDC_CLIENT_CONFIG_PREFIX}.id");
const CLIENT_SECRET: &'static str = formatcp!("{OIDC_CLIENT_CONFIG_PREFIX}.secret");
const ISSUER_URL: &'static str = formatcp!("{OIDC_CLIENT_CONFIG_PREFIX}.issuer.url");
const SCOPES: &'static str = formatcp!("{OIDC_CLIENT_CONFIG_PREFIX}.scopes");

Expand Down
4 changes: 2 additions & 2 deletions opendut-carl/src/peer/oidc_client_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ impl TryFrom<&Config> for CarlIdentityProviderConfig {
}

impl CarlIdentityProviderConfig {
const CLIENT_ID: &'static str = formatcp!("{CARL_OIDC_CONFIG_PREFIX}.client.id");
const CLIENT_SECRET: &'static str = formatcp!("{CARL_OIDC_CONFIG_PREFIX}.client.secret");
const CLIENT_ID: &'static str = formatcp!("{CARL_OIDC_CONFIG_PREFIX}.id");
const CLIENT_SECRET: &'static str = formatcp!("{CARL_OIDC_CONFIG_PREFIX}.secret");
const COMMON_PEER_ID: &'static str = formatcp!("{CARL_OIDC_CONFIG_PREFIX}.peer.id");
const COMMON_PEER_SECRET: &'static str = formatcp!("{CARL_OIDC_CONFIG_PREFIX}.peer.secret");
const ISSUER_URL: &'static str = formatcp!("{CARL_OIDC_CONFIG_PREFIX}.issuer.url");
Expand Down
2 changes: 1 addition & 1 deletion opendut-cleo/cleo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ enabled = false

[network.oidc.client]
id = "opendut-cleo-client"
issuer_url = "https://keycloak/realms/opendut/"
issuer.url = "https://keycloak/realms/opendut/"
scopes = "openid,profile,email,roles,groups"
secret = "<tbd>"
4 changes: 2 additions & 2 deletions opendut-edgar/edgar.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ ca = "/etc/opendut/tls/ca.pem"
domain.name.override = ""

[network.oidc]
enabled = false
enabled = true

[network.oidc.client]
id = "opendut-edgar-client"
issuer_url = "https://keycloak/realms/opendut/"
issuer.url = "https://keycloak/realms/opendut/"
scopes = "openid,profile,email,roles,groups"
secret = "<tbd>"

Expand Down
11 changes: 7 additions & 4 deletions opendut-edgar/src/setup/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ pub async fn managed(run_mode: RunMode, no_confirm: bool, setup_string: String,
let mut tasks: Vec<Box<dyn Task>> = vec![
Box::new(tasks::WriteCaCertificate { certificate: peer_setup.ca }),
Box::new(tasks::CheckOsRequirements),
Box::new(tasks::WriteConfiguration::with_override(write_configuration::ConfigOverride {
peer_id: peer_setup.id,
carl_url: peer_setup.carl,
})),
Box::new(tasks::WriteConfiguration::with_override(
write_configuration::ConfigOverride {
peer_id: peer_setup.id,
carl_url: peer_setup.carl,
auth_config: peer_setup.auth_config,
}),
),
Box::new(tasks::CheckCarlReachable),
Box::new(tasks::CopyExecutable),
Box::new(tasks::LoadKernelModules::default()),
Expand Down
68 changes: 66 additions & 2 deletions opendut-edgar/src/setup/tasks/write_configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use tracing::{debug, error};
use url::Url;

use opendut_types::peer::PeerId;
use opendut_types::util::net::AuthConfig;

use crate::common::settings;
use crate::setup::constants;
Expand All @@ -16,6 +17,7 @@ use crate::setup::task::{Success, Task, TaskFulfilled};
pub struct ConfigOverride {
pub peer_id: PeerId,
pub carl_url: Url,
pub auth_config: AuthConfig,
}

pub struct WriteConfiguration {
Expand Down Expand Up @@ -44,6 +46,9 @@ impl Task for WriteConfiguration {
let peer_id = self.config_override.peer_id.to_string();
let carl_host = self.config_override.carl_url.host_str().expect("Host name should be defined in CARL URL.");
let carl_port = self.config_override.carl_url.port().unwrap_or(443);
let network_oidc_client_id = self.config_override.auth_config.client_id.clone().value();
let network_oidc_client_secret = self.config_override.auth_config.client_secret.clone().value();
let auth_config = self.config_override.auth_config.clone();

if new_settings.get("peer").is_none() {
new_settings["peer"] = toml_edit::table();
Expand All @@ -58,7 +63,24 @@ impl Task for WriteConfiguration {
new_settings["network"]["carl"]["host"] = toml_edit::value(carl_host);
new_settings["network"]["carl"]["port"] = toml_edit::value(i64::from(carl_port));

if new_settings.get("network").and_then(|network| network.get("oidc")).is_none() {
new_settings["network"]["oidc"] = toml_edit::table();
}
new_settings["network"]["oidc"]["enabled"] = toml_edit::value(auth_config.is_oidc_enabled());


if new_settings.get("network")
.and_then(|network| network.get("oidc"))
.and_then(|network| network.get("client"))
.is_none() {

new_settings["network"]["oidc"]["client"] = toml_edit::table();
}
new_settings["network"]["oidc"]["client"]["id"] = toml_edit::value(network_oidc_client_id);
new_settings["network"]["oidc"]["client"]["secret"] = toml_edit::value(network_oidc_client_secret);

new_settings.to_string()

};

if original_settings.to_string() == new_settings_string {
Expand Down Expand Up @@ -136,13 +158,17 @@ mod tests {
use predicates::prelude::predicate;
use uuid::uuid;
use googletest::prelude::*;
use opendut_types::util::net::{ClientId, ClientSecret, OAuthScope};

use crate::setup::runner;

use super::*;

const HOST: &str = "example.com";
const PORT: u16 = 1234;
const CLIENT_ID: &str = "ClientId";
const CLIENT_SECRET: &str = "ClientSecret";
const OIDC_NOT_ENABLED: bool = false;

#[test]
fn should_write_a_fresh_configuration() -> anyhow::Result<()> {
Expand All @@ -158,6 +184,12 @@ mod tests {
config_override: ConfigOverride {
peer_id: new_peer_id,
carl_url: Url::parse("https://example.com:1234").unwrap(),
auth_config: AuthConfig {
issuer_url: Url::parse("https://test.com:1234").unwrap(),
client_secret: ClientSecret(CLIENT_SECRET.to_string()),
client_id: ClientId(CLIENT_ID.to_string()),
scopes: vec![OAuthScope("test".to_string())],
},
},
};

Expand All @@ -175,20 +207,31 @@ mod tests {
[network]
carl.host = "example.com"
carl.port = 1234
[network.oidc]
enabled = false
[network.oidc.client]
id = "ClientId"
secret = "ClientSecret"
"#)));

Ok(())
}

#[test]
fn should_provide_an_merge_suggestion_for_an_already_existing_configuration() -> anyhow::Result<()> {
fn should_provide_an_merge_suggestion_for_an_already_existing_configuration_but_should_not_delete_existing_unknown_keys() -> anyhow::Result<()> {
let temp = TempDir::new()?;
let config_file = temp.child("edgar.toml");
let config_merge_suggestion_file = temp.child("edgar-merge-suggestion.toml");

config_file.write_str(indoc!(r#"
[peer]
id = "eef8997e-56a0-4d8d-978e-40d1f2e68db0"
[peer.unknown]
key = "value"
[Hallo.Welt]
key = "value"
"#))?;

let new_peer_id = PeerId::random();
Expand All @@ -199,6 +242,12 @@ mod tests {
config_override: ConfigOverride {
peer_id: new_peer_id,
carl_url: Url::parse("https://example.com:1234").unwrap(),
auth_config: AuthConfig {
issuer_url: Url::parse("https://test.com:1234").unwrap(),
client_secret: ClientSecret(CLIENT_SECRET.to_string()),
client_id: ClientId(CLIENT_ID.to_string()),
scopes: vec![OAuthScope("test".to_string())],
},
},
};

Expand All @@ -212,6 +261,8 @@ mod tests {
assert!(predicate::path::exists().eval(&config_merge_suggestion_file));
let merge_suggestion = fs::read_to_string(config_merge_suggestion_file)?;
assert!(predicate::str::contains(new_peer_id.to_string()).eval(&merge_suggestion));
assert!(predicate::str::contains("[peer.unknown]".to_string()).eval(&merge_suggestion));
assert!(predicate::str::contains("[Hallo.Welt]".to_string()).eval(&merge_suggestion));

Ok(())
}
Expand All @@ -231,14 +282,27 @@ mod tests {
[network.carl]
host = "{}"
port = {}
"#), new_peer_id, HOST, PORT))?;
[network.oidc]
enabled = {}
[network.oidc.client]
id = "{}"
secret = "{}"
"#), new_peer_id, HOST, PORT, OIDC_NOT_ENABLED, CLIENT_ID, CLIENT_SECRET))?;

let task = WriteConfiguration {
config_file_to_write_to: config_file.to_path_buf(),
config_merge_suggestion_file: config_merge_suggestion_file.to_path_buf(),
config_override: ConfigOverride {
peer_id: new_peer_id,
carl_url: Url::parse(&format!("https://{HOST}:{PORT}")).unwrap(),
auth_config: AuthConfig {
issuer_url: Url::parse("https://test.com:1234").unwrap(),
client_secret: ClientSecret(CLIENT_SECRET.to_string()),
client_id: ClientId(CLIENT_ID.to_string()),
scopes: vec![OAuthScope("test".to_string())],
},
},
};

Expand Down
5 changes: 5 additions & 0 deletions opendut-types/src/util/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,4 +409,9 @@ impl AuthConfig {
scopes: vec![],
}
}

// TODO: This should be enhanced or refactored, once OIDC and Authentication is fully implemented. Also this may not be the right place for these functions at all.
pub fn is_oidc_enabled(&self) -> bool {
self.client_id.0 != "disabled"
}
}
2 changes: 2 additions & 0 deletions tests/src/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ async fn register_edgar_carl() -> Result<()> {
.set_override("network.remote.host", "localhost")?
.set_override("vpn.enabled", false)?
.set_override("serve.ui.presence_check", false)?
.set_override("network.oidc.enabled", false)?
// ensure the development certificates are used
// even if ~/.config/opendut/carl/config.toml is present with different values for the test environment in opendut-vm
.set_override("network.tls.certificate", "resources/development/tls/insecure-development-carl.pem")?
Expand All @@ -37,6 +38,7 @@ async fn register_edgar_carl() -> Result<()> {
.set_override(opendut_edgar::common::settings::key::peer::id, PeerId::random().to_string())?
.set_override("network.carl.port", carl_port)?
.set_override("network.connect.retries", 100)?
.set_override("network.oidc.enabled", false)?
.build()?;
let edgar_config = opendut_edgar::common::settings::load_with_overrides(settings_overrides).unwrap();

Expand Down

0 comments on commit f26b379

Please sign in to comment.