Skip to main content

reifydb_auth/
error.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4use reifydb_type::{
5	error::{Diagnostic, Error, IntoDiagnostic},
6	fragment::Fragment,
7};
8
9pub type Result<T> = std::result::Result<T, Error>;
10
11#[derive(Debug, thiserror::Error)]
12pub enum AuthError {
13	#[error("password is required for password authentication")]
14	PasswordRequired,
15
16	#[error("stored authentication is missing hash")]
17	MissingHash,
18
19	#[error("stored authentication is missing salt")]
20	MissingSalt,
21
22	#[error("stored authentication is missing token")]
23	MissingToken,
24
25	#[error("unknown authentication method: {method}")]
26	UnknownMethod {
27		method: String,
28	},
29
30	#[error("failed to serialize authentication properties: {reason}")]
31	SerializeProperties {
32		reason: String,
33	},
34
35	#[error("password hashing failed: {reason}")]
36	HashingFailed {
37		reason: String,
38	},
39
40	#[error("stored hash is invalid or corrupted: {reason}")]
41	InvalidHash {
42		reason: String,
43	},
44
45	#[error("password verification failed: {reason}")]
46	VerificationFailed {
47		reason: String,
48	},
49}
50
51impl IntoDiagnostic for AuthError {
52	fn into_diagnostic(self) -> Diagnostic {
53		match self {
54			AuthError::PasswordRequired => Diagnostic {
55				code: "AU_001".to_string(),
56				statement: None,
57				message: "password is required for password authentication".to_string(),
58				fragment: Fragment::None,
59				label: Some("missing password".to_string()),
60				help: Some("provide a password in the authentication configuration".to_string()),
61				column: None,
62				notes: vec![],
63				cause: None,
64				operator_chain: None,
65			},
66
67			AuthError::MissingHash => Diagnostic {
68				code: "AU_002".to_string(),
69				statement: None,
70				message: "stored authentication is missing hash".to_string(),
71				fragment: Fragment::None,
72				label: Some("missing hash".to_string()),
73				help: Some("the stored authentication record is corrupted or incomplete".to_string()),
74				column: None,
75				notes: vec![],
76				cause: None,
77				operator_chain: None,
78			},
79
80			AuthError::MissingSalt => Diagnostic {
81				code: "AU_003".to_string(),
82				statement: None,
83				message: "stored authentication is missing salt".to_string(),
84				fragment: Fragment::None,
85				label: Some("missing salt".to_string()),
86				help: Some("the stored authentication record is corrupted or incomplete".to_string()),
87				column: None,
88				notes: vec![],
89				cause: None,
90				operator_chain: None,
91			},
92
93			AuthError::MissingToken => Diagnostic {
94				code: "AU_004".to_string(),
95				statement: None,
96				message: "stored authentication is missing token".to_string(),
97				fragment: Fragment::None,
98				label: Some("missing token".to_string()),
99				help: Some("the stored authentication record is corrupted or incomplete".to_string()),
100				column: None,
101				notes: vec![],
102				cause: None,
103				operator_chain: None,
104			},
105
106			AuthError::SerializeProperties {
107				reason,
108			} => Diagnostic {
109				code: "AU_006".to_string(),
110				statement: None,
111				message: format!("failed to serialize authentication properties: {}", reason),
112				fragment: Fragment::None,
113				label: Some("serialization failed".to_string()),
114				help: Some("ensure authentication properties are valid".to_string()),
115				column: None,
116				notes: vec![],
117				cause: None,
118				operator_chain: None,
119			},
120
121			AuthError::UnknownMethod {
122				method,
123			} => Diagnostic {
124				code: "AU_005".to_string(),
125				statement: None,
126				message: format!("unknown authentication method: {}", method),
127				fragment: Fragment::None,
128				label: Some("unknown method".to_string()),
129				help: Some("supported authentication methods are: password, token".to_string()),
130				column: None,
131				notes: vec![],
132				cause: None,
133				operator_chain: None,
134			},
135
136			AuthError::HashingFailed {
137				reason,
138			} => Diagnostic {
139				code: "AU_007".to_string(),
140				statement: None,
141				message: format!("password hashing failed: {}", reason),
142				fragment: Fragment::None,
143				label: Some("hashing failed".to_string()),
144				help: Some("an internal error occurred during password hashing".to_string()),
145				column: None,
146				notes: vec![],
147				cause: None,
148				operator_chain: None,
149			},
150
151			AuthError::InvalidHash {
152				reason,
153			} => Diagnostic {
154				code: "AU_008".to_string(),
155				statement: None,
156				message: format!("stored hash is invalid or corrupted: {}", reason),
157				fragment: Fragment::None,
158				label: Some("invalid hash".to_string()),
159				help: Some("the stored authentication record is corrupted or incomplete".to_string()),
160				column: None,
161				notes: vec![],
162				cause: None,
163				operator_chain: None,
164			},
165
166			AuthError::VerificationFailed {
167				reason,
168			} => Diagnostic {
169				code: "AU_009".to_string(),
170				statement: None,
171				message: format!("password verification failed: {}", reason),
172				fragment: Fragment::None,
173				label: Some("verification failed".to_string()),
174				help: Some("an internal error occurred during password verification".to_string()),
175				column: None,
176				notes: vec![],
177				cause: None,
178				operator_chain: None,
179			},
180		}
181	}
182}
183
184impl From<AuthError> for Error {
185	fn from(err: AuthError) -> Self {
186		Error(err.into_diagnostic())
187	}
188}