kanidmd_lib/idm/
mod.rs
1pub 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::prelude::OperationError;
26use crate::server::identity::Source;
27use compact_jwt::JwsCompact;
28use kanidm_lib_crypto::{x509_cert::Certificate, Sha256Digest};
29use kanidm_proto::{
30 internal::UserAuthToken,
31 v1::{AuthAllowed, AuthIssueSession, AuthMech},
32};
33use std::fmt;
34
35pub enum AuthState {
36 Choose(Vec<AuthMech>),
37 Continue(Vec<AuthAllowed>),
38 Denied(String),
39 Success(Box<JwsCompact>, AuthIssueSession),
40}
41
42impl fmt::Debug for AuthState {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 match self {
45 AuthState::Choose(mechs) => write!(f, "AuthState::Choose({mechs:?})"),
46 AuthState::Continue(allow) => write!(f, "AuthState::Continue({allow:?})"),
47 AuthState::Denied(reason) => write!(f, "AuthState::Denied({reason:?})"),
48 AuthState::Success(_token, issue) => write!(f, "AuthState::Success({issue:?})"),
49 }
50 }
51}
52
53#[derive(Debug, Clone, Default)]
54pub(crate) enum PreValidatedTokenStatus {
55 #[default]
56 None,
57 Valid(Box<UserAuthToken>),
58 NotAuthenticated,
59 SessionExpired,
60}
61
62#[derive(Debug, Clone)]
63pub struct ClientAuthInfo {
64 pub(crate) source: Source,
65 pub(crate) client_cert: Option<ClientCertInfo>,
66 pub(crate) bearer_token: Option<JwsCompact>,
67 pub(crate) basic_authz: Option<String>,
68 pre_validated_token: PreValidatedTokenStatus,
70}
71
72impl ClientAuthInfo {
73 pub fn new(
74 source: Source,
75 client_cert: Option<ClientCertInfo>,
76 bearer_token: Option<JwsCompact>,
77 basic_authz: Option<String>,
78 ) -> Self {
79 Self {
80 source,
81 client_cert,
82 bearer_token,
83 basic_authz,
84 pre_validated_token: Default::default(),
85 }
86 }
87
88 pub fn bearer_token(&self) -> Option<&JwsCompact> {
89 self.bearer_token.as_ref()
90 }
91
92 pub fn pre_validated_uat(&self) -> Result<&UserAuthToken, OperationError> {
93 match &self.pre_validated_token {
94 PreValidatedTokenStatus::Valid(uat) => Ok(uat),
95 PreValidatedTokenStatus::None => Err(OperationError::AU0008ClientAuthInfoPrevalidation),
96 PreValidatedTokenStatus::NotAuthenticated => Err(OperationError::NotAuthenticated),
97 PreValidatedTokenStatus::SessionExpired => Err(OperationError::SessionExpired),
98 }
99 }
100
101 pub(crate) fn set_pre_validated_uat(&mut self, status: PreValidatedTokenStatus) {
102 self.pre_validated_token = status
103 }
104}
105
106#[derive(Debug, Clone)]
107pub struct ClientCertInfo {
108 pub public_key_s256: Sha256Digest,
109 pub certificate: Certificate,
110}
111
112#[cfg(test)]
113impl ClientAuthInfo {
114 fn none() -> Self {
115 ClientAuthInfo {
116 source: Source::Internal,
117 client_cert: None,
118 bearer_token: None,
119 basic_authz: None,
120 pre_validated_token: Default::default(),
121 }
122 }
123}
124
125#[cfg(test)]
126impl From<Source> for ClientAuthInfo {
127 fn from(value: Source) -> ClientAuthInfo {
128 ClientAuthInfo {
129 source: value,
130 client_cert: None,
131 bearer_token: None,
132 basic_authz: None,
133 pre_validated_token: Default::default(),
134 }
135 }
136}
137
138#[cfg(test)]
139impl From<JwsCompact> for ClientAuthInfo {
140 fn from(value: JwsCompact) -> ClientAuthInfo {
141 ClientAuthInfo {
142 source: Source::Internal,
143 client_cert: None,
144 bearer_token: Some(value),
145 basic_authz: None,
146 pre_validated_token: Default::default(),
147 }
148 }
149}
150
151#[cfg(test)]
152impl From<ClientCertInfo> for ClientAuthInfo {
153 fn from(value: ClientCertInfo) -> ClientAuthInfo {
154 ClientAuthInfo {
155 source: Source::Internal,
156 client_cert: Some(value),
157 bearer_token: None,
158 basic_authz: None,
159 pre_validated_token: Default::default(),
160 }
161 }
162}
163
164#[cfg(test)]
165impl From<&str> for ClientAuthInfo {
166 fn from(value: &str) -> ClientAuthInfo {
167 ClientAuthInfo {
168 source: Source::Internal,
169 client_cert: None,
170 bearer_token: None,
171 basic_authz: Some(value.to_string()),
172 pre_validated_token: Default::default(),
173 }
174 }
175}
176
177#[cfg(test)]
178impl ClientAuthInfo {
179 fn encode_basic(id: &str, secret: &str) -> ClientAuthInfo {
180 use base64::{engine::general_purpose, Engine as _};
181 let value = format!("{id}:{secret}");
182 let value = general_purpose::STANDARD.encode(&value);
183 ClientAuthInfo {
184 source: Source::Internal,
185 client_cert: None,
186 bearer_token: None,
187 basic_authz: Some(value),
188 pre_validated_token: Default::default(),
189 }
190 }
191}