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::{
47 ForceAuthn, IsPassive, LogoutSigning, RespondSlo, RespondSso, StartSlo, StartSso,
48};
49
50/// Typed SAML facade for high-level browser SSO/SLO flows.
51pub struct Saml<Role = Unknown>(Role);
52
53/// Marker role used before a facade has been configured as an SP or IdP.
54pub enum Unknown {}
55
56/// Marker role for a Service Provider facade.
57pub struct Sp {
58 service_provider: ServiceProvider,
59}
60
61/// Marker role for an Identity Provider facade.
62pub struct Idp {
63 identity_provider: IdentityProvider,
64 issuance_lifetime: time::Duration,
65}
66
67/// Error type returned by the typed SAML API.
68pub type SamlError = Error;
69
70impl Saml {
71 /// Build a typed Service Provider facade.
72 ///
73 /// # Errors
74 ///
75 /// Returns [`SamlError`] when the SP config cannot be converted into raw
76 /// settings or metadata, including missing metadata, missing keys, or
77 /// unsupported crypto configuration.
78 pub fn sp(config: SpConfig) -> Result<Saml<Sp>, SamlError> {
79 let setting = EntitySetting::try_from(&config)?;
80 let raw_config = raw_sp_metadata_config(&config);
81 let service_provider = ServiceProvider::from_config(&raw_config, setting)?;
82 Ok(Saml(Sp { service_provider }))
83 }
84
85 /// Build a typed Identity Provider facade.
86 ///
87 /// # Errors
88 ///
89 /// Returns [`SamlError`] when the IdP config cannot be converted into raw
90 /// settings or metadata, including an invalid issuance lifetime, missing
91 /// metadata, missing keys, or unsupported crypto configuration.
92 pub fn idp(config: IdpConfig) -> Result<Saml<Idp>, SamlError> {
93 let issuance_lifetime = validated_idp_issuance_lifetime(config.issuance_lifetime)?;
94 let setting = EntitySetting::try_from(&config)?;
95 let raw_config = raw_idp_metadata_config(&config);
96 let identity_provider = IdentityProvider::from_config(&raw_config, setting)?;
97 Ok(Saml(Idp {
98 identity_provider,
99 issuance_lifetime,
100 }))
101 }
102}