Skip to main content

reifydb_auth/method/
token.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use std::collections::HashMap;
5
6use reifydb_core::interface::auth::{AuthStep, AuthenticationProvider};
7use reifydb_runtime::context::rng::Rng;
8use reifydb_type::{Result, error::Error};
9use subtle::ConstantTimeEq;
10
11use crate::error::AuthError;
12
13pub struct TokenProvider;
14
15impl AuthenticationProvider for TokenProvider {
16	fn method(&self) -> &str {
17		"token"
18	}
19
20	fn create(&self, rng: &Rng, config: &HashMap<String, String>) -> Result<HashMap<String, String>> {
21		let token = if let Some(explicit) = config.get("token") {
22			explicit.clone()
23		} else {
24			let bytes = rng.bytes_32();
25			bytes.iter().map(|b| format!("{:02x}", b)).collect()
26		};
27
28		Ok(HashMap::from([("token".into(), token)]))
29	}
30
31	fn authenticate(
32		&self,
33		stored: &HashMap<String, String>,
34		credentials: &HashMap<String, String>,
35	) -> Result<AuthStep> {
36		let credential = credentials.get("token").ok_or_else(|| Error::from(AuthError::MissingToken))?;
37		let token = stored.get("token").ok_or_else(|| Error::from(AuthError::MissingToken))?;
38
39		// Constant-time comparison
40		if token.as_bytes().ct_eq(credential.as_bytes()).into() {
41			Ok(AuthStep::Authenticated)
42		} else {
43			Ok(AuthStep::Failed)
44		}
45	}
46}