use crate::domain::ProtocolVersion;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub enum ClientRegistration {
#[default]
None,
Dynamic,
DynamicOrMetadataDocument,
MetadataDocument,
}
impl ClientRegistration {
#[must_use]
pub const fn supports_dynamic(self) -> bool {
matches!(
self,
Self::Dynamic | Self::DynamicOrMetadataDocument | Self::MetadataDocument
)
}
#[must_use]
pub const fn supports_metadata_document(self) -> bool {
matches!(
self,
Self::DynamicOrMetadataDocument | Self::MetadataDocument
)
}
#[must_use]
pub const fn preferred(self) -> Option<Self> {
match self {
Self::None => None,
Self::Dynamic => Some(Self::Dynamic),
Self::DynamicOrMetadataDocument | Self::MetadataDocument => {
Some(Self::MetadataDocument)
}
}
}
#[must_use]
pub const fn fallback(self) -> Option<Self> {
match self {
Self::DynamicOrMetadataDocument | Self::MetadataDocument => Some(Self::Dynamic),
Self::Dynamic | Self::None => None,
}
}
#[must_use]
pub const fn application_type_required(self) -> bool {
matches!(self, Self::MetadataDocument)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct AuthorizationModel {
pub specified: bool,
pub protected_resource_metadata: bool,
pub resource_indicators_required: bool,
pub oidc_discovery: bool,
pub incremental_scope_consent: bool,
pub issuer_parameter: bool,
pub credentials_bound_to_issuer: bool,
pub client_registration: ClientRegistration,
}
impl AuthorizationModel {
#[must_use]
pub const fn audience_bound(self) -> bool {
self.specified
}
}
#[must_use]
pub const fn authorization_model(version: ProtocolVersion) -> AuthorizationModel {
let mut model = AuthorizationModel {
specified: false,
protected_resource_metadata: false,
resource_indicators_required: false,
oidc_discovery: false,
incremental_scope_consent: false,
issuer_parameter: false,
credentials_bound_to_issuer: false,
client_registration: ClientRegistration::None,
};
match version {
ProtocolVersion::V2024_11_05 | ProtocolVersion::Unknown(_) => {}
ProtocolVersion::V2025_03_26 => {
model.specified = true;
model.client_registration = ClientRegistration::Dynamic;
}
ProtocolVersion::V2025_06_18 => {
model.specified = true;
model.protected_resource_metadata = true;
model.resource_indicators_required = true;
model.client_registration = ClientRegistration::Dynamic;
}
ProtocolVersion::V2025_11_25 => {
model.specified = true;
model.protected_resource_metadata = true;
model.resource_indicators_required = true;
model.oidc_discovery = true;
model.incremental_scope_consent = true;
model.client_registration = ClientRegistration::DynamicOrMetadataDocument;
}
ProtocolVersion::V2026_07_28 => {
model.specified = true;
model.protected_resource_metadata = true;
model.resource_indicators_required = true;
model.oidc_discovery = true;
model.incremental_scope_consent = true;
model.issuer_parameter = true;
model.credentials_bound_to_issuer = true;
model.client_registration = ClientRegistration::MetadataDocument;
}
}
model
}
#[cfg(test)]
#[path = "authorization/tests.rs"]
mod tests;