Include OAuth public endpoint in PACC responses

This commit is contained in:
Maurus Decimus
2026-04-19 14:35:06 +02:00
parent 47d21dd03d
commit eaf0601742
22 changed files with 791 additions and 2630 deletions

View File

@@ -7,7 +7,7 @@
use crate::Directory;
use crate::backend::oidc::lookup::fetch_jwks_keys;
use crate::backend::oidc::{
DiscoveryDocument, JwksCache, OidcError, OpenIdConfig, OpenIdDirectory,
DiscoveryDocument, JwksCache, OidcConfig, OidcDiscovery, OidcError, OpenIdDirectory,
};
use registry::schema::structs;
use reqwest::Client;
@@ -17,7 +17,7 @@ use trc::AuthEvent;
impl OpenIdDirectory {
pub async fn open(config: structs::OidcDirectory) -> Result<Directory, String> {
Self::new(OpenIdConfig {
Self::new(OidcConfig {
issue_url: config.issuer_url,
require_aud: config.require_audience,
require_scopes: config.require_scopes.into_inner(),
@@ -31,7 +31,7 @@ impl OpenIdDirectory {
.map_err(|err| err.to_string())
}
pub async fn new(config: OpenIdConfig) -> Result<Self, OidcError> {
pub async fn new(config: OidcConfig) -> Result<Self, OidcError> {
let http = Client::builder()
.user_agent("Stalwart/1.0")
.timeout(Duration::from_secs(30))
@@ -133,8 +133,11 @@ impl OpenIdDirectory {
});
Ok(Self {
discovery: OidcDiscovery {
url: config.issue_url.clone(),
document: discovery,
},
config,
discovery,
http,
cache,
})

View File

@@ -63,7 +63,7 @@ impl OpenIdDirectory {
validation.validate_aud = false;
}
validation.set_issuer(&[&self.discovery.issuer]);
validation.set_issuer(&[&self.discovery.document.issuer]);
validation.leeway = 60;
match decode::<serde_json::Value>(token, dk, &validation) {
@@ -115,7 +115,7 @@ impl OpenIdDirectory {
}
}
let new_keys = fetch_jwks_keys(&self.http, &self.discovery.jwks_uri).await?;
let new_keys = fetch_jwks_keys(&self.http, &self.discovery.document.jwks_uri).await?;
{
let mut guard = self.cache.write().await;
guard.keys = new_keys;
@@ -146,7 +146,7 @@ impl OpenIdDirectory {
async fn fetch_userinfo(&self, token: &str) -> Result<serde_json::Value, OidcError> {
let resp = self
.http
.get(&self.discovery.userinfo_endpoint)
.get(&self.discovery.document.userinfo_endpoint)
.bearer_auth(token)
.send()
.await

View File

@@ -14,7 +14,7 @@ use utils::Client;
pub mod config;
pub mod lookup;
pub struct OpenIdConfig {
pub struct OidcConfig {
pub issue_url: String,
pub require_aud: Option<String>,
pub require_scopes: Vec<String>,
@@ -24,6 +24,11 @@ pub struct OpenIdConfig {
pub default_domain: Option<String>,
}
pub struct OidcDiscovery {
pub url: String,
pub document: DiscoveryDocument,
}
#[derive(Deserialize, Serialize)]
pub struct DiscoveryDocument {
pub issuer: String,
@@ -52,8 +57,8 @@ struct JwksCache {
}
pub struct OpenIdDirectory {
config: OpenIdConfig,
pub discovery: DiscoveryDocument,
config: OidcConfig,
pub discovery: OidcDiscovery,
http: Client,
cache: RwLock<JwksCache>,
}

View File

@@ -4,7 +4,7 @@
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use crate::{Account, Credentials, Directory, Recipient, backend::oidc::DiscoveryDocument};
use crate::{Account, Credentials, Directory, Recipient, backend::oidc::OidcDiscovery};
use trc::AddContext;
impl Directory {
@@ -34,7 +34,7 @@ impl Directory {
!matches!(self, Directory::OpenId(_))
}
pub fn oidc_discovery_document(&self) -> Option<&DiscoveryDocument> {
pub fn oidc_discovery_document(&self) -> Option<&OidcDiscovery> {
match &self {
Directory::OpenId(directory) => Some(&directory.discovery),
_ => None,

View File

@@ -28,6 +28,7 @@ pub enum Credentials {
},
}
#[allow(clippy::large_enum_variant)]
pub enum Directory {
Ldap(LdapDirectory),
Sql(SqlDirectory),