use oxidite_db::sqlx;
use oxidite_db::sqlx::FromRow;
#[derive(FromRow, Clone, Debug)]
pub struct Role {
pub id: i64,
pub name: String,
pub description: Option<String>,
pub created_at: i64,
pub updated_at: i64,
}
#[derive(FromRow, Clone, Debug)]
pub struct Permission {
pub id: i64,
pub name: String,
pub resource: String,
pub action: String,
pub description: Option<String>,
pub created_at: i64,
pub updated_at: i64,
}
impl Role {
pub async fn permissions(&self, db: &impl oxidite_db::Database) -> oxidite_db::Result<Vec<Permission>> {
let query = oxidite_db::sqlx::query(
"SELECT p.* FROM permissions p
INNER JOIN role_permissions rp ON p.id = rp.permission_id
WHERE rp.role_id = ?"
)
.bind(self.id);
let rows = db.fetch_all(query).await?;
let mut permissions = Vec::new();
for row in rows {
permissions.push(sqlx::FromRow::from_row(&row)?);
}
Ok(permissions)
}
pub async fn has_permission(&self, db: &impl oxidite_db::Database, permission_name: &str) -> oxidite_db::Result<bool> {
let query = oxidite_db::sqlx::query(
"SELECT 1 FROM permissions p
INNER JOIN role_permissions rp ON p.id = rp.permission_id
WHERE rp.role_id = ? AND p.name = ?
LIMIT 1"
)
.bind(self.id)
.bind(permission_name);
Ok(db.fetch_one(query).await?.is_some())
}
}
impl Permission {
pub fn matches(&self, resource: &str, action: &str) -> bool {
self.resource == resource && self.action == action
}
}