use crate::constants::{
data_encryption_algorithm, key_encryption_algorithm, signature_algorithm, transform_algorithm,
MessageSignatureOrder,
};
#[derive(Debug, Clone)]
pub struct EntitySetting {
pub entity_id: Option<String>,
pub request_signature_algorithm: String,
pub data_encryption_algorithm: String,
pub key_encryption_algorithm: String,
pub message_signing_order: MessageSignatureOrder,
pub allow_create: bool,
pub is_assertion_encrypted: bool,
pub relay_state: String,
pub authn_requests_signed: bool,
pub want_assertions_signed: bool,
pub validate_audience: bool,
pub want_message_signed: bool,
pub want_authn_requests_signed: bool,
pub want_logout_request_signed: bool,
pub want_logout_response_signed: bool,
pub name_id_format: Vec<String>,
pub private_key: Option<String>,
pub private_key_pass: Option<String>,
pub signing_cert: Option<String>,
pub encrypt_cert: Option<String>,
pub enc_private_key: Option<String>,
pub enc_private_key_pass: Option<String>,
pub clock_drifts: (i64, i64),
pub tag_prefix_encrypted_assertion: String,
pub login_response_template: Option<crate::template::LoginResponseTemplate>,
pub login_request_template: Option<String>,
pub logout_request_template: Option<String>,
pub logout_response_template: Option<String>,
pub signature_config: Option<SignatureConfig>,
pub transformation_algorithms: Vec<String>,
}
pub type CustomTagReplacement<'a> = &'a dyn Fn(&str) -> (String, String);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum SignatureAction {
#[default]
After,
Before,
Prepend,
Append,
}
#[derive(Debug, Clone)]
pub struct SignatureConfig {
pub prefix: String,
pub reference: Option<String>,
pub action: SignatureAction,
}
impl Default for SignatureConfig {
fn default() -> Self {
Self {
prefix: "ds".to_string(),
reference: None,
action: SignatureAction::After,
}
}
}
impl Default for EntitySetting {
fn default() -> Self {
Self {
entity_id: None,
request_signature_algorithm: signature_algorithm::RSA_SHA256.to_string(),
data_encryption_algorithm: data_encryption_algorithm::AES_256.to_string(),
key_encryption_algorithm: key_encryption_algorithm::RSA_OAEP_MGF1P.to_string(),
message_signing_order: MessageSignatureOrder::SignThenEncrypt,
allow_create: false,
is_assertion_encrypted: false,
relay_state: String::new(),
authn_requests_signed: false,
want_assertions_signed: false,
validate_audience: true,
want_message_signed: false,
want_authn_requests_signed: false,
want_logout_request_signed: false,
want_logout_response_signed: false,
name_id_format: Vec::new(),
private_key: None,
private_key_pass: None,
signing_cert: None,
encrypt_cert: None,
enc_private_key: None,
enc_private_key_pass: None,
clock_drifts: (0, 0),
tag_prefix_encrypted_assertion: "saml".to_string(),
login_response_template: None,
login_request_template: None,
logout_request_template: None,
logout_response_template: None,
signature_config: None,
transformation_algorithms: vec![
transform_algorithm::ENVELOPED_SIGNATURE.to_string(),
transform_algorithm::EXC_C14N.to_string(),
],
}
}
}
pub fn generate_id() -> String {
format!("_{}", uuid::Uuid::new_v4())
}
#[derive(Debug, Clone, Default)]
pub struct User {
pub name_id: String,
pub attributes: Vec<(String, String)>,
pub session_index: Option<String>,
}
impl User {
pub fn new(name_id: impl Into<String>) -> Self {
Self {
name_id: name_id.into(),
..Default::default()
}
}
}
pub fn now_iso8601() -> String {
iso8601_offset(0)
}
pub fn iso8601_offset(seconds: i64) -> String {
let t = time::OffsetDateTime::now_utc() + time::Duration::seconds(seconds);
format!(
"{:04}-{:02}-{:02}T{:02}:{:02}:{:02}Z",
t.year(),
u8::from(t.month()),
t.day(),
t.hour(),
t.minute(),
t.second(),
)
}
#[derive(Debug, Clone)]
pub struct BindingContext {
pub id: String,
pub context: String,
pub relay_state: Option<String>,
pub entity_endpoint: String,
pub binding: crate::constants::Binding,
pub request_type: &'static str,
pub signature: Option<String>,
pub sig_alg: Option<String>,
}
impl BindingContext {
pub fn post_form(&self) -> String {
crate::binding::saml_post_binding_form(
&self.entity_endpoint,
self.request_type,
&self.context,
self.relay_state.as_deref(),
)
}
}