Skip to main content

reifydb_auth/
error.rs

1// SPDX-License-Identifier: Apache-2.0
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	#[error("public key is required for solana authentication")]
51	MissingPublicKey,
52
53	#[error("invalid public key: {reason}")]
54	InvalidPublicKey {
55		reason: String,
56	},
57
58	#[error("invalid signature: {reason}")]
59	InvalidSignature {
60		reason: String,
61	},
62}
63
64impl IntoDiagnostic for AuthError {
65	fn into_diagnostic(self) -> Diagnostic {
66		match self {
67			AuthError::PasswordRequired => Diagnostic {
68				code: "AU_001".to_string(),
69				statement: None,
70				message: "password is required for password authentication".to_string(),
71				fragment: Fragment::None,
72				label: Some("missing password".to_string()),
73				help: Some("provide a password in the authentication configuration".to_string()),
74				column: None,
75				notes: vec![],
76				cause: None,
77				operator_chain: None,
78			},
79
80			AuthError::MissingHash => Diagnostic {
81				code: "AU_002".to_string(),
82				statement: None,
83				message: "stored authentication is missing hash".to_string(),
84				fragment: Fragment::None,
85				label: Some("missing hash".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::MissingSalt => Diagnostic {
94				code: "AU_003".to_string(),
95				statement: None,
96				message: "stored authentication is missing salt".to_string(),
97				fragment: Fragment::None,
98				label: Some("missing salt".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::MissingToken => Diagnostic {
107				code: "AU_004".to_string(),
108				statement: None,
109				message: "stored authentication is missing token".to_string(),
110				fragment: Fragment::None,
111				label: Some("missing token".to_string()),
112				help: Some("the stored authentication record is corrupted or incomplete".to_string()),
113				column: None,
114				notes: vec![],
115				cause: None,
116				operator_chain: None,
117			},
118
119			AuthError::SerializeProperties {
120				reason,
121			} => Diagnostic {
122				code: "AU_006".to_string(),
123				statement: None,
124				message: format!("failed to serialize authentication properties: {}", reason),
125				fragment: Fragment::None,
126				label: Some("serialization failed".to_string()),
127				help: Some("ensure authentication properties are valid".to_string()),
128				column: None,
129				notes: vec![],
130				cause: None,
131				operator_chain: None,
132			},
133
134			AuthError::UnknownMethod {
135				method,
136			} => Diagnostic {
137				code: "AU_005".to_string(),
138				statement: None,
139				message: format!("unknown authentication method: {}", method),
140				fragment: Fragment::None,
141				label: Some("unknown method".to_string()),
142				help: Some("supported authentication methods are: password, token".to_string()),
143				column: None,
144				notes: vec![],
145				cause: None,
146				operator_chain: None,
147			},
148
149			AuthError::HashingFailed {
150				reason,
151			} => Diagnostic {
152				code: "AU_007".to_string(),
153				statement: None,
154				message: format!("password hashing failed: {}", reason),
155				fragment: Fragment::None,
156				label: Some("hashing failed".to_string()),
157				help: Some("an internal error occurred during password hashing".to_string()),
158				column: None,
159				notes: vec![],
160				cause: None,
161				operator_chain: None,
162			},
163
164			AuthError::InvalidHash {
165				reason,
166			} => Diagnostic {
167				code: "AU_008".to_string(),
168				statement: None,
169				message: format!("stored hash is invalid or corrupted: {}", reason),
170				fragment: Fragment::None,
171				label: Some("invalid hash".to_string()),
172				help: Some("the stored authentication record is corrupted or incomplete".to_string()),
173				column: None,
174				notes: vec![],
175				cause: None,
176				operator_chain: None,
177			},
178
179			AuthError::VerificationFailed {
180				reason,
181			} => Diagnostic {
182				code: "AU_009".to_string(),
183				statement: None,
184				message: format!("password verification failed: {}", reason),
185				fragment: Fragment::None,
186				label: Some("verification failed".to_string()),
187				help: Some("an internal error occurred during password verification".to_string()),
188				column: None,
189				notes: vec![],
190				cause: None,
191				operator_chain: None,
192			},
193
194			AuthError::MissingPublicKey => Diagnostic {
195				code: "AU_010".to_string(),
196				statement: None,
197				message: "public key is required for solana authentication".to_string(),
198				fragment: Fragment::None,
199				label: Some("missing public key".to_string()),
200				help: Some("provide a public_key in the authentication configuration".to_string()),
201				column: None,
202				notes: vec![],
203				cause: None,
204				operator_chain: None,
205			},
206
207			AuthError::InvalidPublicKey {
208				reason,
209			} => Diagnostic {
210				code: "AU_011".to_string(),
211				statement: None,
212				message: format!("invalid public key: {}", reason),
213				fragment: Fragment::None,
214				label: Some("invalid public key".to_string()),
215				help: Some("provide a valid base58-encoded 32-byte Solana public key".to_string()),
216				column: None,
217				notes: vec![],
218				cause: None,
219				operator_chain: None,
220			},
221
222			AuthError::InvalidSignature {
223				reason,
224			} => Diagnostic {
225				code: "AU_012".to_string(),
226				statement: None,
227				message: format!("invalid signature: {}", reason),
228				fragment: Fragment::None,
229				label: Some("invalid signature".to_string()),
230				help: Some("provide a valid base58-encoded 64-byte ed25519 signature".to_string()),
231				column: None,
232				notes: vec![],
233				cause: None,
234				operator_chain: None,
235			},
236		}
237	}
238}
239
240impl From<AuthError> for Error {
241	fn from(err: AuthError) -> Self {
242		Error(err.into_diagnostic())
243	}
244}