#![cfg(not(any(feature = "strict-postgres", feature = "strict-mysql")))]
use rullst_orm::Policy;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Serialize, Deserialize, rullst_orm::Orm, rullst_orm::FromRow)]
#[orm(table = "documents", policy = "DocumentPolicy")]
pub struct Document {
pub id: i32,
pub title: String,
pub user_id: i32,
}
pub struct DocumentPolicy;
#[async_trait::async_trait]
impl Policy<Document> for DocumentPolicy {
async fn can_create(model: &Document) -> Result<bool, rullst_orm::Error> {
Ok(model.user_id == 1)
}
async fn can_update(model: &Document) -> Result<bool, rullst_orm::Error> {
Ok(model.title != "locked")
}
async fn can_delete(model: &Document) -> Result<bool, rullst_orm::Error> {
Ok(model.user_id == 1)
}
}
#[tokio::test]
async fn test_policy_enforcement() {
let _ = std::fs::remove_file("policy.db");
let _ = rullst_orm::Orm::init("sqlite://policy.db?mode=rwc").await;
let pool = rullst_orm::Orm::pool();
rullst_orm::_sqlx::query(
"CREATE TABLE documents (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
user_id INTEGER NOT NULL
)",
)
.execute(pool)
.await
.unwrap();
let mut doc_fail = Document {
id: 0,
title: "Test".to_string(),
user_id: 2, };
let res = doc_fail.save().await;
assert!(res.is_err());
assert_eq!(
res.unwrap_err().to_string(),
"Validation error: Policy prevents creation of this record"
);
let mut doc_ok = Document {
id: 0,
title: "Test".to_string(),
user_id: 1,
};
doc_ok.save().await.unwrap();
doc_ok.title = "locked".to_string();
let res = doc_ok.save().await;
assert!(res.is_err());
assert_eq!(
res.unwrap_err().to_string(),
"Validation error: Policy prevents updating this record"
);
doc_ok.title = "unlocked".to_string();
doc_ok.save().await.unwrap();
doc_ok.user_id = 2; let res = doc_ok.delete().await;
assert!(res.is_err());
assert_eq!(
res.unwrap_err().to_string(),
"Validation error: Policy prevents deleting this record"
);
doc_ok.user_id = 1;
doc_ok.delete().await.unwrap();
}
pub struct DefaultPolicy;
#[async_trait::async_trait]
impl Policy<Document> for DefaultPolicy {}
#[tokio::test]
async fn test_default_policy() {
let doc = Document {
id: 0,
title: "A".to_string(),
user_id: 1,
};
assert!(DefaultPolicy::can_create(&doc).await.unwrap());
assert!(DefaultPolicy::can_update(&doc).await.unwrap());
assert!(DefaultPolicy::can_delete(&doc).await.unwrap());
assert!(DefaultPolicy::can_restore(&doc).await.unwrap());
assert!(DefaultPolicy::can_force_delete(&doc).await.unwrap());
}