use std::sync::Arc;
use tokio::sync::RwLock;
use crate::error::AccessError;
#[async_trait]
pub trait Ownable {
async fn get_owner(&self) -> String;
async fn transfer_ownership(&mut self, new_owner: String) -> Result<(), AccessError>;
async fn renounce_ownership(&mut self) -> Result<(), AccessError>;
}
pub struct OwnableResource {
owner: Arc<RwLock<String>>,
resource_type: String,
resource_id: String,
}
impl OwnableResource {
pub fn new(owner: String, resource_type: &str, resource_id: &str) -> Self {
Self {
owner: Arc::new(RwLock::new(owner)),
resource_type: resource_type.to_string(),
resource_id: resource_id.to_string(),
}
}
pub async fn check_owner(&self, user: &str) -> bool {
let owner = self.owner.read().await;
&*owner == user
}
}
#[async_trait]
impl Ownable for OwnableResource {
async fn get_owner(&self) -> String {
self.owner.read().await.clone()
}
async fn transfer_ownership(&mut self, new_owner: String) -> Result<(), AccessError> {
let mut owner = self.owner.write().await;
if new_owner.is_empty() {
return Err(AccessError::InvalidOwner);
}
*owner = new_owner;
Ok(())
}
async fn renounce_ownership(&mut self) -> Result<(), AccessError> {
let mut owner = self.owner.write().await;
*owner = String::new();
Ok(())
}
}