Files
db/heromodels/src/models/access/access.rs
2025-06-27 12:11:04 +03:00

144 lines
4.0 KiB
Rust

use crate::db::{Collection, Db, hero::OurDB};
use crate::models::Circle;
use heromodels_core::BaseModelData;
use heromodels_derive::model;
use std::sync::Arc;
// Temporarily removed to fix compilation issues
// use rhai_autobind_macros::rhai_model_export;
use rhai::{CustomType, TypeBuilder};
use serde::{Deserialize, Serialize};
/// Represents an event in a contact
#[model]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, CustomType, Default)]
pub struct Access {
/// Base model data
pub base_data: BaseModelData,
#[index]
pub object_type: String,
#[index]
pub object_id: u32,
#[index]
pub circle_pk: String,
#[index]
pub contact_id: u32,
#[index]
pub group_id: u32,
pub expires_at: Option<u64>,
}
impl Access {
pub fn new() -> Self {
Access {
base_data: BaseModelData::new(),
object_id: 0,
object_type: String::new(),
circle_pk: String::new(),
contact_id: 0,
group_id: 0,
expires_at: None,
}
}
pub fn object_type(mut self, object_type: String) -> Self {
self.object_type = object_type;
self
}
pub fn object_id(mut self, object_id: u32) -> Self {
self.object_id = object_id;
self
}
pub fn contact_id(mut self, contact_id: u32) -> Self {
self.contact_id = contact_id;
self
}
pub fn group_id(mut self, group_id: u32) -> Self {
self.group_id = group_id;
self
}
pub fn circle_pk(mut self, circle_pk: String) -> Self {
self.circle_pk = circle_pk;
self
}
pub fn expires_at(mut self, expires_at: Option<u64>) -> Self {
self.expires_at = expires_at;
self
}
}
/// Checks if a caller has permission to access a specific resource.
/// Access is granted if the caller is a super admin or if an `Access` record exists
/// granting them `can_access = true` for the given resource type and ID.
///
/// # Arguments
/// * `db`: An `Arc<OurDB>` for database interaction.
/// * `public_key`: The public key of the caller.
/// * `_resource_id_to_check`: The ID of the resource being accessed (now unused).
/// * `_resource_type_to_check`: The type of the resource (e.g., "Collection", "Image") (now unused).
///
/// # Errors
/// Returns `Err(EvalAltResult::ErrorRuntime)` if there's a database error during the check.
pub fn can_access_resource(
db: Arc<OurDB>,
public_key: &str,
object_id: u32,
_object_type: &str,
) -> bool {
let circle = db
.collection::<Circle>()
.expect("Failed to get Circle collection")
.get_all()
.unwrap()[0]
.clone();
// Circle members can access everything
if circle.members.contains(&public_key.to_string()) {
return true;
}
println!("Checking access for public key: {}", public_key);
// get all access records for object
let access_records = match db
.collection::<Access>()
.expect("Failed to get Access collection")
.get::<access_index::object_id, _>(&object_id)
{
Ok(records) => records,
Err(_e) => {
// Optionally log the error for debugging purposes.
// For example: log::warn!("Error fetching access records for public key {}: {:?}", public_key, e);
// If database query fails, assume access is not granted.
return false;
}
};
println!("Access records: {:#?}", access_records);
// if circle_pk is in access records true
return access_records
.iter()
.any(|record| record.circle_pk == public_key);
}
pub fn is_circle_member(db: Arc<OurDB>, public_key: &str) -> bool {
let circle = db
.collection::<Circle>()
.expect("Failed to get Circle collection")
.get_all()
.unwrap()[0]
.clone();
// Circle members can access everything
if circle.members.contains(&public_key.to_string()) {
return true;
}
return false;
}