Skip to content

Commit

Permalink
LEA -> Move to LeaConfig to opendut-types
Browse files Browse the repository at this point in the history
  • Loading branch information
reimarstier committed Jan 28, 2025
1 parent 60e9056 commit a39349e
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 78 deletions.
2 changes: 1 addition & 1 deletion opendut-carl/src/http/router/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use axum::extract::State;
use axum::Json;
use crate::http::state::LeaConfig;
use opendut_types::lea::LeaConfig;

pub mod cleo;
pub mod edgar;
Expand Down
34 changes: 13 additions & 21 deletions opendut-carl/src/http/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,57 +7,49 @@ use serde::Serialize;
use shadow_rs::formatcp;
use url::Url;
use opendut_auth::confidential::config::ConfidentialClientConfigData;

use opendut_types::lea::{LeaConfig, LeaIdentityProviderConfig};

#[derive(Clone)]
pub struct HttpState {
pub lea_config: LeaConfig,
pub carl_installation_directory: CarlInstallDirectory,
}

#[derive(Clone, Debug, Serialize)]
pub struct LeaIdentityProviderConfig {
client_id: String,
issuer_url: Url,
scopes: String,
}
pub struct LoadableLeaIdentityProviderConfig(pub(crate) LeaIdentityProviderConfig);

const LEA_OIDC_CONFIG_PREFIX: &str = "network.oidc.lea";
impl TryFrom<&Config> for LeaIdentityProviderConfig {
impl TryFrom<&Config> for LoadableLeaIdentityProviderConfig {
type Error = anyhow::Error;

fn try_from(config: &Config) -> anyhow::Result<Self> {

let client_id = config.get_string(LeaIdentityProviderConfig::CLIENT_ID)
.map_err(|error| anyhow!("Failed to find configuration for `{}`. {}", LeaIdentityProviderConfig::CLIENT_ID, error))?;
let issuer = config.get_string(LeaIdentityProviderConfig::ISSUER_URL)
.map_err(|error| anyhow!("Failed to find configuration for `{}`. {}", LeaIdentityProviderConfig::ISSUER_URL, error))?;
let client_id = config.get_string(LoadableLeaIdentityProviderConfig::CLIENT_ID)
.map_err(|error| anyhow!("Failed to find configuration for `{}`. {}", LoadableLeaIdentityProviderConfig::CLIENT_ID, error))?;
let issuer = config.get_string(LoadableLeaIdentityProviderConfig::ISSUER_URL)
.map_err(|error| anyhow!("Failed to find configuration for `{}`. {}", LoadableLeaIdentityProviderConfig::ISSUER_URL, error))?;

let issuer_url = Url::parse(&issuer)
.context(format!("Failed to parse OIDC issuer URL `{}`.", issuer))?;

let lea_raw_scopes = config.get_string(LeaIdentityProviderConfig::SCOPES)
.map_err(|error| anyhow!("Failed to find configuration for `{}`. {}", LeaIdentityProviderConfig::SCOPES, error))?;
let lea_raw_scopes = config.get_string(LoadableLeaIdentityProviderConfig::SCOPES)
.map_err(|error| anyhow!("Failed to find configuration for `{}`. {}", LoadableLeaIdentityProviderConfig::SCOPES, error))?;

let scopes = ConfidentialClientConfigData::parse_scopes(&client_id, lea_raw_scopes).into_iter()
.map(|scope| scope.to_string())
.collect::<Vec<_>>()
.join(" "); // Required by leptos_oidc

Ok(Self { client_id, issuer_url, scopes })
Ok(LoadableLeaIdentityProviderConfig(
LeaIdentityProviderConfig { client_id, issuer_url, scopes }
))
}
}
impl LeaIdentityProviderConfig {
impl LoadableLeaIdentityProviderConfig {
const CLIENT_ID: &'static str = formatcp!("{LEA_OIDC_CONFIG_PREFIX}.client.id");
const ISSUER_URL: &'static str = formatcp!("{LEA_OIDC_CONFIG_PREFIX}.issuer.url");
const SCOPES: &'static str = formatcp!("{LEA_OIDC_CONFIG_PREFIX}.scopes");
}

#[derive(Clone, Serialize)]
pub struct LeaConfig {
pub(crate) carl_url: Url,
pub(crate) idp_config: Option<LeaIdentityProviderConfig>,
}

impl FromRef<HttpState> for LeaConfig {
fn from_ref(app_state: &HttpState) -> Self {
Expand Down
7 changes: 4 additions & 3 deletions opendut-carl/src/startup/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ use config::Config;
use tower_http::services::{ServeDir, ServeFile};
use tracing::info;
use opendut_auth::registration::resources::ResourceHomeUrl;
use opendut_types::lea::LeaConfig;
use opendut_util::project;
use crate::http::router;
use crate::http::state::{CarlInstallDirectory, HttpState, LeaConfig, LeaIdentityProviderConfig};
use crate::http::state::{CarlInstallDirectory, HttpState, LoadableLeaIdentityProviderConfig};


pub fn create_http_service(settings: &Config) -> anyhow::Result<axum::Router<HttpState>> {
Expand Down Expand Up @@ -57,7 +58,7 @@ pub fn create_http_state(

let oidc_enabled = settings.get_bool("network.oidc.enabled").unwrap_or(false);
let lea_idp_config = if oidc_enabled {
let lea_idp_config = LeaIdentityProviderConfig::try_from(settings)
let lea_idp_config = LoadableLeaIdentityProviderConfig::try_from(settings)
.expect("Failed to create LeaIdentityProviderConfig from settings.");
info!("OIDC is enabled.");
Some(lea_idp_config)
Expand All @@ -69,7 +70,7 @@ pub fn create_http_state(
let http_state = HttpState {
lea_config: LeaConfig {
carl_url: carl_url.value(),
idp_config: lea_idp_config,
idp_config: lea_idp_config.map(|LoadableLeaIdentityProviderConfig(config)| config),
},
carl_installation_directory
};
Expand Down
52 changes: 8 additions & 44 deletions opendut-lea/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ use tracing::{error, info};
use url::Url;
use opendut_auth::public::Authentication;
use opendut_carl_api::carl::wasm::CarlClient;

use opendut_types::lea::LeaConfig;
use crate::components::{AppGlobalsResource, Toaster};
use crate::nav::Navbar;
use crate::routing::AppRoutes;
use crate::user::{provide_authentication_signals_in_context, AuthenticationConfigSwitch};

#[derive(Clone, Debug)]
pub struct AppGlobals {
#[allow(dead_code)]
pub config: AppConfig,
pub client: CarlClient,
pub auth: Authentication,
Expand All @@ -27,40 +28,23 @@ pub fn use_app_globals() -> AppGlobals {
.expect("The AppGlobals should be provided in the context.")
}

#[derive(Clone, Debug, Deserialize)]
pub struct LeaIdpConfig {
pub client_id: String,
pub issuer_url: Url,
pub scopes: String,
}


// TODO: RawAppConfig==LeaConfig(opendut-carl/src/http/state.rs), move to opendut-types
#[derive(Clone, Debug, Deserialize)]
pub struct RawAppConfig {
pub carl_url: Url,
pub idp_config: Option<LeaIdpConfig>,
}

#[derive(Clone, Debug)]
pub struct AppConfig {
pub carl_url: Url,
pub idp_config: Option<LeaIdpConfig>,
pub auth_parameters: Option<AuthParameters>,
}

impl<'de> Deserialize<'de> for AppConfig {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
let raw_app_config: RawAppConfig = Deserialize::deserialize(deserializer)?;
let lea_config: LeaConfig = Deserialize::deserialize(deserializer)?;

match raw_app_config.idp_config {
match lea_config.idp_config {
Some(idp_config) => {
let redirect_uri = raw_app_config.carl_url.to_string();
let post_logout_redirect_uri = raw_app_config.carl_url.to_string();
let redirect_uri = lea_config.carl_url.to_string();
let post_logout_redirect_uri = lea_config.carl_url.to_string();

Ok(AppConfig {
carl_url: raw_app_config.carl_url,
idp_config: Some(idp_config.clone()),
carl_url: lea_config.carl_url,
auth_parameters: Some(AuthParameters {
// Issuer URL is expected to have no trailing slash
issuer: idp_config.issuer_url.to_string().trim_end_matches('/').to_string(),
Expand All @@ -74,8 +58,7 @@ impl<'de> Deserialize<'de> for AppConfig {
})
},
None => Ok(AppConfig {
carl_url: raw_app_config.carl_url,
idp_config: None,
carl_url: lea_config.carl_url,
auth_parameters: None,
})
}
Expand Down Expand Up @@ -106,25 +89,6 @@ pub fn LoadingApp() -> impl IntoView {
Some(ref auth_parameters) => {
info!("Auth parameters: {auth_parameters:?}");
let _ = Auth::init(auth_parameters.clone());
//let result = await_auth.loaded().await;
// match result {
// Ok(auth) => Authentication::Enabled(auth),
// Err(error) => {
// let error_message = format!("Error while initializing the authentication stack: {error}");
// error!(error_message);
//
// navigate_to(
// WellKnownRoutes::ErrorPage {
// title: String::from("Initialization error"),
// text: error_message,
// details: None,
// },
// use_navigate()
// );
// let auth = use_context::<AuthSignal>().expect("AuthSignal should be provided in app_globals.");
// Authentication::Enabled(auth)
// }
// }
let auth = use_context::<AuthSignal>().expect("AuthSignal should be provided in app_globals.");
Authentication::Enabled(auth)
},
Expand Down
4 changes: 2 additions & 2 deletions opendut-lea/src/components/toast/container.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use leptos::prelude::*;
use tracing::debug;
use tracing::trace;

use crate::components::toast::notification::Notification;
use crate::components::toast::ToastMap;
Expand All @@ -9,7 +9,7 @@ pub fn Container(
toasts: RwSignal<ToastMap>
) -> impl IntoView {

debug!("Creating toast container.");
trace!("Creating toast container.");

let remove_toast = move |key| {
toasts.update(|toasts| {
Expand Down
4 changes: 2 additions & 2 deletions opendut-lea/src/components/toast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use leptos::prelude::*;
use leptos_use::use_interval_fn;
use leptos_use::utils::Pausable;
use slotmap::{DefaultKey, SlotMap};
use tracing::{debug, info};
use tracing::{debug, info, trace};

use crate::components::toast::builder::ToastBuilder;
use crate::components::toast::container::Container;
Expand Down Expand Up @@ -68,7 +68,7 @@ impl Toaster {

pub fn new() -> Self {

debug!("Creating toaster.");
trace!("Creating toaster.");

let toasts: RwSignal<ToastMap> = RwSignal::new(ToastMap::new());

Expand Down
9 changes: 4 additions & 5 deletions opendut-lea/src/user/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,10 @@ pub(crate) fn provide_authentication_signals_in_context() -> AuthSignal {
Effect::new(move || {
let auth = auth.get();
let auth_config_switch = auth_config_switch.get();
tracing::debug!("Running auth effect: {auth:?}");
tracing::debug!("Running auth effect switch: {auth_config_switch:?} auth: {auth:?}");

match auth_config_switch {
AuthenticationConfigSwitch::Loading => {
tracing::debug!("user loading");
user_auth.set(UserAuthentication::default());
}
AuthenticationConfigSwitch::Disabled => {
Expand All @@ -54,17 +53,17 @@ pub(crate) fn provide_authentication_signals_in_context() -> AuthSignal {
AuthenticationConfigSwitch::Enabled => {
match auth {
Auth::Loading => {
tracing::debug!("user still loading");
tracing::trace!("user still loading");
user_auth.set(UserAuthentication::Loading);
}
Auth::Unauthenticated(_) => {
tracing::debug!("user loaded, unauthenticated");
tracing::trace!("user loaded, unauthenticated");
user_auth.set(UserAuthentication::Unauthenticated);
}
Auth::Authenticated(auth) => {
tracing::debug!("user authenticated");
let token = auth.decoded_access_token::<Claims>(Algorithm::RS256, &[DEFAULT_TOKEN_AUDIENCE])
.map(|token| Box::new(token));
.map(Box::new);
user_auth.set(UserAuthentication::Authenticated(token));
}
Auth::Error(error) => {
Expand Down
16 changes: 16 additions & 0 deletions opendut-types/src/lea/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use serde::{Deserialize, Serialize};
use url::Url;



#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct LeaIdentityProviderConfig {
pub client_id: String,
pub issuer_url: Url,
pub scopes: String,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct LeaConfig {
pub carl_url: Url,
pub idp_config: Option<LeaIdentityProviderConfig>,
}
1 change: 1 addition & 0 deletions opendut-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub mod cleo;

#[cfg(feature = "specs")]
pub mod specs;
pub mod lea;

pub trait ShortName {
fn short_name(&self) -> &'static str;
Expand Down

0 comments on commit a39349e

Please sign in to comment.