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