use crate::constants::{Binding, CertUse, ParserType};
use crate::entity::EntitySetting;
use crate::error::SamlError;
use crate::flow::{flow, FlowOptions, FlowResult, HttpRequest};
use crate::metadata::Metadata;
use time::OffsetDateTime;
pub fn parse_logout_request(
self_setting: &EntitySetting,
from_meta: &Metadata,
binding: Binding,
request: &HttpRequest,
) -> Result<FlowResult, SamlError> {
parse_logout_request_inner(
self_setting,
from_meta,
binding,
request,
None,
self_setting.clock_drifts,
)
}
pub(crate) fn parse_logout_request_at(
self_setting: &EntitySetting,
from_meta: &Metadata,
binding: Binding,
request: &HttpRequest,
now: OffsetDateTime,
clock_drifts: (i64, i64),
) -> Result<FlowResult, SamlError> {
parse_logout_request_inner(
self_setting,
from_meta,
binding,
request,
Some(now),
clock_drifts,
)
}
fn parse_logout_request_inner(
self_setting: &EntitySetting,
from_meta: &Metadata,
binding: Binding,
request: &HttpRequest,
now: Option<OffsetDateTime>,
clock_drifts: (i64, i64),
) -> Result<FlowResult, SamlError> {
let signing_certs = from_meta.x509_certificates(CertUse::Signing);
flow(
&FlowOptions {
binding: Some(binding),
parser_type: Some(ParserType::LogoutRequest),
check_signature: self_setting.want_logout_request_signed,
from_issuer: from_meta.get_entity_id(),
signing_certs: &signing_certs,
decrypt_key: None,
decrypt_key_pass: None,
allow_insecure_software_rsa_key_transport_decryption: false,
clock_drifts,
now,
redirect_inflate_max_bytes: self_setting.redirect_inflate_max_bytes,
xml_limits: self_setting.xml_limits,
expected_audience: None,
expected_in_response_to: None,
},
request,
)
}
fn parse_logout_response_inner(
self_setting: &EntitySetting,
from_meta: &Metadata,
binding: Binding,
request: &HttpRequest,
expected_in_response_to: Option<&str>,
now: Option<OffsetDateTime>,
clock_drifts: (i64, i64),
) -> Result<FlowResult, SamlError> {
let signing_certs = from_meta.x509_certificates(CertUse::Signing);
flow(
&FlowOptions {
binding: Some(binding),
parser_type: Some(ParserType::LogoutResponse),
check_signature: self_setting.want_logout_response_signed,
from_issuer: from_meta.get_entity_id(),
signing_certs: &signing_certs,
decrypt_key: None,
decrypt_key_pass: None,
allow_insecure_software_rsa_key_transport_decryption: false,
clock_drifts,
now,
redirect_inflate_max_bytes: self_setting.redirect_inflate_max_bytes,
xml_limits: self_setting.xml_limits,
expected_audience: None,
expected_in_response_to,
},
request,
)
}
pub fn parse_logout_response(
self_setting: &EntitySetting,
from_meta: &Metadata,
binding: Binding,
request: &HttpRequest,
request_id: &str,
) -> Result<FlowResult, SamlError> {
if request_id.is_empty() {
return Err(SamlError::InvalidInResponseTo);
}
parse_logout_response_inner(
self_setting,
from_meta,
binding,
request,
Some(request_id),
None,
self_setting.clock_drifts,
)
}
pub(crate) fn parse_logout_response_at(
self_setting: &EntitySetting,
from_meta: &Metadata,
binding: Binding,
request: &HttpRequest,
request_id: &str,
now: OffsetDateTime,
clock_drifts: (i64, i64),
) -> Result<FlowResult, SamlError> {
if request_id.is_empty() {
return Err(SamlError::InvalidInResponseTo);
}
parse_logout_response_inner(
self_setting,
from_meta,
binding,
request,
Some(request_id),
Some(now),
clock_drifts,
)
}
pub fn parse_logout_response_without_request_id(
self_setting: &EntitySetting,
from_meta: &Metadata,
binding: Binding,
request: &HttpRequest,
) -> Result<FlowResult, SamlError> {
parse_logout_response_inner(
self_setting,
from_meta,
binding,
request,
None,
None,
self_setting.clock_drifts,
)
}