Skip to main content

flp_saml2/
sp.rs

1// This library provides SAML2 implementation in Rust
2// Copyright (C) 2026  Hakukaze Shikano
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program.  If not, see <https://www.gnu.org/licenses/>.
16
17use 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}