feat: provider configuration/initializiation

This commit is contained in:
mikoto 2024-02-18 16:49:35 +00:00
parent 903cfc40c9
commit 552afb66d9
3 changed files with 50 additions and 36 deletions

View file

@ -83,7 +83,7 @@ pub struct Config {
#[serde(default)]
pub macaroon_key: Option<String>,
#[serde(default)]
pub oidc_provider: Option<Vec<ProviderConfig>>,
pub oidc: Vec<ProviderConfig>,
pub emergency_password: Option<String>,

View file

@ -2,28 +2,30 @@ use serde::Deserialize;
#[derive(Clone, Debug, Deserialize)]
pub struct ProviderConfig {
id: String,
name: String,
icon: Option<String>,
pub id: String,
pub name: String,
pub icon: Option<String>,
client: ClientConfig,
scopes: Vec<String>,
pub scopes: Vec<String>,
pub issuer: url::Url,
pub redirect_url: url::Url,
endpoint: EndpointConfig,
// pub discover: bool, ???
pub backchannel_logout: bool,
discover_url: Option<url::Url>,
backchannel_logout: bool,
pub client: ClientConfig,
pub endpoint: EndpointConfig,
}
#[derive(Clone, Debug, Deserialize)]
pub struct ClientConfig {
id: String,
secret: String,
pub id: String,
pub secret: String,
}
#[derive(Clone, Debug, Default, Deserialize)]
pub struct EndpointConfig {
authorization: Option<url::Url>,
token: Option<url::Url>,
userinfo: Option<url::Url>,
pub authorization: Option<url::Url>,
pub token: Option<url::Url>,
pub userinfo: Option<url::Url>,
}

View file

@ -8,7 +8,7 @@ use ruma::{
use crate::api::server_server::FedDest;
use crate::{services, Config, Error, Result};
use futures_util::FutureExt;
use futures_util::{future, FutureExt, TryFutureExt};
use hyper::{
client::connect::dns::{GaiResolver, Name},
service::Service as HyperService,
@ -25,7 +25,7 @@ use std::{
collections::{BTreeMap, HashMap},
error::Error as StdError,
fs,
future::{self, Future},
future::Future,
iter,
net::{IpAddr, SocketAddr},
path::PathBuf,
@ -76,7 +76,7 @@ pub struct Service {
pub shutdown: AtomicBool,
pub oidc: Option<openid::DiscoveredClient>,
pub oidc: HashMap<String, openid::DiscoveredClient>,
pub macaroon: Option<macaroon::MacaroonKey>,
}
@ -185,26 +185,37 @@ impl Service {
// Experimental, partially supported room versions
let unstable_room_versions = vec![RoomVersionId::V3, RoomVersionId::V4, RoomVersionId::V5];
let openid_client = match config.openid.as_ref() {
Some(openid) => {
let mut key_bytes: [u8; 32] = [0; 32];
key_bytes.copy_from_slice(&base64::decode(&openid.macaroon_key).unwrap());
let secret_key: macaroon::MacaroonKey = key_bytes.into();
let macaroon = config
.macaroon_key
.as_ref()
.map(|s| macaroon::MacaroonKey::generate(s.as_bytes()));
let r = (
secret_key,
openid::DiscoveredClient::discover(
openid.client_id.to_owned(),
openid.secret.to_owned(),
Some(openid.redirect_url.to_owned()),
openid.discover_url.to_owned(),
)
.await
.unwrap(),
);
Some(r)
let oidc = {
let discover_all = config.oidc.iter().map(|provider| {
openid::DiscoveredClient::discover_with_client(
default_client.clone(),
provider.client.id.clone(),
provider.client.secret.clone(),
Some(provider.redirect_url.to_string()),
provider.issuer.clone(),
).map_ok(|client| (provider.id.clone(), client))
});
let pairs = future::try_join_all(discover_all).await.map_err(|e| {
error!("failed to discover one or more OIDC providers: {}", e);
Error::bad_config("failed to discover one or more OIDC providers.")
})?;
let mut result = HashMap::with_capacity(config.oidc.len());
for (id, client) in pairs {
let None = result.insert(id, client) else {
error!("OIDC providers must have unique IDs.");
return Err(Error::bad_config("OIDC providers must have unique IDs."));
};
}
None => None,
result
};
let mut s = Self {
@ -237,7 +248,8 @@ impl Service {
sync_receivers: RwLock::new(HashMap::new()),
rotate: RotationHandler::new(),
shutdown: AtomicBool::new(false),
openid_client,
macaroon,
oidc,
};
fs::create_dir_all(s.get_media_folder())?;