Skip to main content

saml_rs/api/
mod.rs

1//! Typed high-level API contract for `saml-rs`.
2//!
3//! Artifact binding is not part of the high-level browser SSO request binding
4//! contract.
5//!
6//! ```compile_fail
7//! use saml_rs::SsoRequestBinding;
8//!
9//! let binding = SsoRequestBinding::Artifact;
10//! ```
11//!
12//! ```compile_fail
13//! use saml_rs::{AuthnRequest, Received, RespondSso, Saml, Sp, SpDescriptor, Subject};
14//!
15//! let sp: Saml<Sp> = unreachable!();
16//! let peer: SpDescriptor = unreachable!();
17//! let request: Received<AuthnRequest> = unreachable!();
18//! let subject: Subject = unreachable!();
19//!
20//! let _ = sp.respond_sso(&peer, &request, subject, RespondSso::post());
21//! ```
22//!
23//! ```compile_fail
24//! use saml_rs::{Idp, IdpDescriptor, Saml, StartSso};
25//!
26//! let idp: Saml<Idp> = unreachable!();
27//! let peer: IdpDescriptor = unreachable!();
28//!
29//! let _ = idp.start_sso(&peer, StartSso::post());
30//! ```
31
32mod idp;
33mod options;
34mod raw_mapping;
35mod slo;
36mod sp;
37
38use crate::config::{validated_idp_issuance_lifetime, IdpConfig, SpConfig};
39use crate::entity::EntitySetting;
40use crate::error::SamlError as Error;
41use crate::idp::IdentityProvider;
42use crate::sp::ServiceProvider;
43
44use raw_mapping::{raw_idp_metadata_config, raw_sp_metadata_config};
45
46pub use options::{ForceAuthn, LogoutSigning, RespondSlo, RespondSso, StartSlo, StartSso};
47
48/// Typed SAML facade for high-level browser SSO/SLO flows.
49pub struct Saml<Role = Unknown>(Role);
50
51/// Marker role used before a facade has been configured as an SP or IdP.
52pub enum Unknown {}
53
54/// Marker role for a Service Provider facade.
55pub struct Sp {
56    service_provider: ServiceProvider,
57}
58
59/// Marker role for an Identity Provider facade.
60pub struct Idp {
61    identity_provider: IdentityProvider,
62    issuance_lifetime: time::Duration,
63}
64
65/// Error type returned by the typed SAML API.
66pub type SamlError = Error;
67
68impl Saml {
69    /// Build a typed Service Provider facade.
70    ///
71    /// # Errors
72    ///
73    /// Returns [`SamlError`] when the SP config cannot be converted into raw
74    /// settings or metadata, including missing metadata, missing keys, or
75    /// unsupported crypto configuration.
76    pub fn sp(config: SpConfig) -> Result<Saml<Sp>, SamlError> {
77        let setting = EntitySetting::try_from(&config)?;
78        let raw_config = raw_sp_metadata_config(&config);
79        let service_provider = ServiceProvider::from_config(&raw_config, setting)?;
80        Ok(Saml(Sp { service_provider }))
81    }
82
83    /// Build a typed Identity Provider facade.
84    ///
85    /// # Errors
86    ///
87    /// Returns [`SamlError`] when the IdP config cannot be converted into raw
88    /// settings or metadata, including an invalid issuance lifetime, missing
89    /// metadata, missing keys, or unsupported crypto configuration.
90    pub fn idp(config: IdpConfig) -> Result<Saml<Idp>, SamlError> {
91        let issuance_lifetime = validated_idp_issuance_lifetime(config.issuance_lifetime)?;
92        let setting = EntitySetting::try_from(&config)?;
93        let raw_config = raw_idp_metadata_config(&config);
94        let identity_provider = IdentityProvider::from_config(&raw_config, setting)?;
95        Ok(Saml(Idp {
96            identity_provider,
97            issuance_lifetime,
98        }))
99    }
100}