kanidmd_lib/idm/
mod.rs

1//! The Identity Management components that are layered on top of the [QueryServer](crate::server::QueryServer). These allow
2//! rich and expressive events and transformations that are lowered into the correct/relevant
3//! actions in the [QueryServer](crate::server::QueryServer). Generally this is where "Identity Management" policy and code
4//! is implemented.
5
6pub mod account;
7pub(crate) mod accountpolicy;
8pub(crate) mod application;
9pub(crate) mod applinks;
10pub mod audit;
11pub(crate) mod authsession;
12pub mod credupdatesession;
13pub mod delayed;
14pub mod event;
15pub mod group;
16pub mod identityverification;
17pub mod ldap;
18pub mod oauth2;
19pub(crate) mod radius;
20pub(crate) mod reauth;
21pub mod scim;
22pub mod server;
23pub mod serviceaccount;
24
25use crate::server::identity::Source;
26use compact_jwt::JwsCompact;
27use kanidm_lib_crypto::{x509_cert::Certificate, Sha256Digest};
28use kanidm_proto::v1::{AuthAllowed, AuthIssueSession, AuthMech};
29use std::fmt;
30
31pub enum AuthState {
32    Choose(Vec<AuthMech>),
33    Continue(Vec<AuthAllowed>),
34    Denied(String),
35    Success(Box<JwsCompact>, AuthIssueSession),
36}
37
38impl fmt::Debug for AuthState {
39    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40        match self {
41            AuthState::Choose(mechs) => write!(f, "AuthState::Choose({mechs:?})"),
42            AuthState::Continue(allow) => write!(f, "AuthState::Continue({allow:?})"),
43            AuthState::Denied(reason) => write!(f, "AuthState::Denied({reason:?})"),
44            AuthState::Success(_token, issue) => write!(f, "AuthState::Success({issue:?})"),
45        }
46    }
47}
48
49#[derive(Debug, Clone)]
50pub struct ClientAuthInfo {
51    pub source: Source,
52    pub client_cert: Option<ClientCertInfo>,
53    pub bearer_token: Option<JwsCompact>,
54    pub basic_authz: Option<String>,
55}
56
57#[derive(Debug, Clone)]
58pub struct ClientCertInfo {
59    pub public_key_s256: Sha256Digest,
60    pub certificate: Certificate,
61}
62
63#[cfg(test)]
64impl ClientAuthInfo {
65    fn none() -> Self {
66        ClientAuthInfo {
67            source: Source::Internal,
68            client_cert: None,
69            bearer_token: None,
70            basic_authz: None,
71        }
72    }
73}
74
75#[cfg(test)]
76impl From<Source> for ClientAuthInfo {
77    fn from(value: Source) -> ClientAuthInfo {
78        ClientAuthInfo {
79            source: value,
80            client_cert: None,
81            bearer_token: None,
82            basic_authz: None,
83        }
84    }
85}
86
87#[cfg(test)]
88impl From<JwsCompact> for ClientAuthInfo {
89    fn from(value: JwsCompact) -> ClientAuthInfo {
90        ClientAuthInfo {
91            source: Source::Internal,
92            client_cert: None,
93            bearer_token: Some(value),
94            basic_authz: None,
95        }
96    }
97}
98
99#[cfg(test)]
100impl From<ClientCertInfo> for ClientAuthInfo {
101    fn from(value: ClientCertInfo) -> ClientAuthInfo {
102        ClientAuthInfo {
103            source: Source::Internal,
104            client_cert: Some(value),
105            bearer_token: None,
106            basic_authz: None,
107        }
108    }
109}
110
111#[cfg(test)]
112impl From<&str> for ClientAuthInfo {
113    fn from(value: &str) -> ClientAuthInfo {
114        ClientAuthInfo {
115            source: Source::Internal,
116            client_cert: None,
117            bearer_token: None,
118            basic_authz: Some(value.to_string()),
119        }
120    }
121}
122
123#[cfg(test)]
124impl ClientAuthInfo {
125    fn encode_basic(id: &str, secret: &str) -> ClientAuthInfo {
126        use base64::{engine::general_purpose, Engine as _};
127        let value = format!("{id}:{secret}");
128        let value = general_purpose::STANDARD.encode(&value);
129        ClientAuthInfo {
130            source: Source::Internal,
131            client_cert: None,
132            bearer_token: None,
133            basic_authz: Some(value),
134        }
135    }
136}