use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use crate::biome::credentials::store::{
error::CredentialsStoreError, Credentials, CredentialsStore, UsernameId,
};
#[derive(Default, Clone)]
pub struct MemoryCredentialsStore {
inner: Arc<Mutex<HashMap<String, Credentials>>>,
}
impl MemoryCredentialsStore {
pub fn new() -> Self {
MemoryCredentialsStore {
inner: Arc::new(Mutex::new(HashMap::new())),
}
}
}
impl CredentialsStore for MemoryCredentialsStore {
fn add_credentials(&self, credentials: Credentials) -> Result<(), CredentialsStoreError> {
let mut inner = self
.inner
.lock()
.map_err(|_| CredentialsStoreError::StorageError {
context: "Cannot access credentials: mutex lock poisoned".to_string(),
source: None,
})?;
inner.insert(credentials.user_id.clone(), credentials);
Ok(())
}
fn update_credentials(
&self,
user_id: &str,
updated_username: &str,
updated_password: &str,
) -> Result<(), CredentialsStoreError> {
let mut inner = self
.inner
.lock()
.map_err(|_| CredentialsStoreError::StorageError {
context: "Cannot access credentials: mutex lock poisoned".to_string(),
source: None,
})?;
if let Some(creds) = inner.get_mut(user_id) {
creds.username = updated_username.to_string();
creds.password = updated_password.to_string();
Ok(())
} else {
Err(CredentialsStoreError::NotFoundError(format!(
"User with user id {} not found",
user_id
)))
}
}
fn remove_credentials(&self, user_id: &str) -> Result<(), CredentialsStoreError> {
let mut inner = self
.inner
.lock()
.map_err(|_| CredentialsStoreError::StorageError {
context: "Cannot access credentials: mutex lock poisoned".to_string(),
source: None,
})?;
if inner.remove(user_id).is_some() {
Ok(())
} else {
Err(CredentialsStoreError::NotFoundError(format!(
"User with user id {} not found",
user_id
)))
}
}
fn fetch_credential_by_user_id(
&self,
user_id: &str,
) -> Result<Credentials, CredentialsStoreError> {
let inner = self
.inner
.lock()
.map_err(|_| CredentialsStoreError::StorageError {
context: "Cannot access credentials: mutex lock poisoned".to_string(),
source: None,
})?;
if let Some(user) = inner.get(user_id) {
Ok(user.clone())
} else {
Err(CredentialsStoreError::NotFoundError(format!(
"User with user_id {} not found.",
user_id
)))
}
}
fn fetch_credential_by_username(
&self,
username: &str,
) -> Result<Credentials, CredentialsStoreError> {
let inner = self
.inner
.lock()
.map_err(|_| CredentialsStoreError::StorageError {
context: "Cannot access credentials: mutex lock poisoned".to_string(),
source: None,
})?;
for (_, v) in inner.iter() {
if v.username == username {
return Ok(v.clone());
}
}
Err(CredentialsStoreError::NotFoundError(format!(
"User with username {} not found.",
username
)))
}
fn fetch_username_by_id(&self, user_id: &str) -> Result<UsernameId, CredentialsStoreError> {
let inner = self
.inner
.lock()
.map_err(|_| CredentialsStoreError::StorageError {
context: "Cannot access credentials: mutex lock poisoned".to_string(),
source: None,
})?;
for (_, v) in inner.iter() {
if v.user_id == user_id {
return Ok(UsernameId {
username: v.username.clone(),
user_id: v.user_id.clone(),
});
}
}
Err(CredentialsStoreError::NotFoundError(format!(
"User with id {} not found.",
user_id
)))
}
fn list_usernames(&self) -> Result<Vec<UsernameId>, CredentialsStoreError> {
let inner = self
.inner
.lock()
.map_err(|_| CredentialsStoreError::StorageError {
context: "Cannot access credentials: mutex lock poisoned".to_string(),
source: None,
})?;
Ok(inner
.iter()
.map(|(_, v)| UsernameId {
username: v.username.clone(),
user_id: v.user_id.clone(),
})
.collect())
}
}