1use openssl::{
18 pkey::{PKey, Private},
19 rsa::Rsa,
20 x509::X509,
21};
22use std::{fs::read, path::Path};
23use url::Url;
24
25use crate::error::Result;
26
27pub mod authn_redirect;
28pub mod logout_redirect;
29pub mod metadata;
30
31#[derive(Clone, Debug)]
32pub struct ServiceProvider {
33 pub entity_id: Url,
34 pub private_key: PKey<Private>,
35 pub certificate: X509,
36 pub assert_login: Url,
37 pub assert_logout: Url,
38 pub relay_state: Option<String>,
39 pub name_id_format: Option<String>,
40 pub authn_context: Option<authn_redirect::RequestedAuthnContext>,
41}
42
43impl ServiceProvider {
44 pub fn new(
45 entity_id: Url,
46 private_key: PKey<Private>,
47 certificate: X509,
48 assert_login: Url,
49 assert_logout: Url,
50 ) -> Self {
51 Self {
52 entity_id,
53 private_key,
54 certificate,
55 assert_login,
56 assert_logout,
57 relay_state: None,
58 name_id_format: None,
59 authn_context: None,
60 }
61 }
62
63 pub fn new_from_files(
64 entity_id: Url,
65 private_key_path: &Path,
66 certificate_path: &Path,
67 assert_login: Url,
68 assert_logout: Url,
69 ) -> Result<Self> {
70 Ok(Self::new(
71 entity_id,
72 PKey::from_rsa(Rsa::private_key_from_pem(
73 read(private_key_path)?.as_slice(),
74 )?)?,
75 X509::from_pem(read(certificate_path)?.as_slice())?,
76 assert_login,
77 assert_logout,
78 ))
79 }
80
81 pub fn with_relay_state(mut self, relay_state: String) -> Self {
82 self.relay_state = Some(relay_state);
83 self
84 }
85
86 pub fn with_name_id_format(mut self, name_id_format: String) -> Self {
87 self.name_id_format = Some(name_id_format);
88 self
89 }
90
91 pub fn with_auth_context(
92 mut self,
93 auth_context: authn_redirect::RequestedAuthnContext,
94 ) -> Self {
95 self.authn_context = Some(auth_context);
96 self
97 }
98}