Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve/inheritance #103

Merged
merged 6 commits into from
Apr 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "casbin"
version = "0.4.4"
version = "0.5.0"
authors = ["Joey <joey.xf@gmail.com>", "Cheng JIANG <jiang.cheng@vip.163.com>"]
edition = "2018"
license = "Apache-2.0"
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Add this package to `Cargo.toml` of your project. (Check https://crates.io/crate

```toml
[dependencies]
casbin = "0.4.4"
casbin = "0.5.0"
async-std = { version = "1.5.0", features = ["attributes"] }
```

Expand All @@ -39,7 +39,7 @@ use casbin::prelude::*;

#[async_std::main]
async fn main() {
let e = Enforcer::new("path/to/model.conf", "path/to/policy.csv").await?;
let mut e = Enforcer::new("path/to/model.conf", "path/to/policy.csv").await?;
}
```

Expand All @@ -50,7 +50,7 @@ async fn main() {
obj = "data1"; // the resource that is going to be accessed.
act = "read"; // the operation that the user performs on the resource.

if let Ok(authorized) = e.enforce(&[sub, obj, act]) {
if let Ok(authorized) = e.enforce(&[sub, obj, act]).await {
if authorized {
// permit alice to read data1
} else {
Expand Down
14 changes: 6 additions & 8 deletions benches/casbin.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use casbin::{DefaultModel, Enforcer, FileAdapter, MemoryAdapter, Model, RbacApi};
use casbin::prelude::*;
use criterion::{criterion_group, criterion_main, Criterion};

#[cfg(feature = "runtime-async-std")]
Expand Down Expand Up @@ -64,7 +64,7 @@ fn enforcer_create(b: &mut Criterion) {
let adpt = FileAdapter::new("examples/basic_model.conf");

// what we want to measure
let _e = await_future(Enforcer::new(Box::new(m), Box::new(adpt))).unwrap();
let _e = await_future(Enforcer::new(m, adpt)).unwrap();
});
});
}
Expand All @@ -81,13 +81,11 @@ fn enforcer_enforce(b: &mut Criterion) {
"r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)",
);
let adapter = FileAdapter::new("examples/keymatch_policy.csv");
let e = await_future(Enforcer::new(Box::new(m), Box::new(adapter))).unwrap();
let mut e = await_future(Enforcer::new(m, adapter)).unwrap();

b.iter(|| {
e.enforce(&vec!["alice", "/alice_data/resource1", "GET"])
.unwrap();
e.enforce(&vec!["alice", "/alice_data/resource1", "POST"])
.unwrap();
await_future(e.enforce(&vec!["alice", "/alice_data/resource1", "GET"])).unwrap();
await_future(e.enforce(&vec!["alice", "/alice_data/resource1", "POST"])).unwrap();
})
});
}
Expand All @@ -106,7 +104,7 @@ fn enforcer_add_permission(b: &mut Criterion) {
);

let adapter = MemoryAdapter::default();
let mut e = await_future(Enforcer::new(Box::new(m), Box::new(adapter))).unwrap();
let mut e = await_future(Enforcer::new(m, adapter)).unwrap();

b.iter(|| {
await_future(e.add_permission_for_user(
Expand Down
9 changes: 3 additions & 6 deletions src/adapter/file_adapter.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
use crate::adapter::Adapter;
use crate::error::ModelError;
use crate::model::Model;
use crate::Result;

use std::convert::AsRef;
use crate::{adapter::Adapter, error::ModelError, model::Model, Result};

#[cfg(feature = "runtime-async-std")]
use async_std::{
Expand All @@ -28,6 +23,8 @@ use tokio::{

use async_trait::async_trait;

use std::convert::AsRef;

pub struct FileAdapter<P> {
file_path: P,
}
Expand Down
7 changes: 2 additions & 5 deletions src/adapter/memory_adapter.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
use crate::adapter::Adapter;
use crate::model::Model;
use crate::Result;

use indexmap::IndexSet;
use crate::{adapter::Adapter, model::Model, Result};

use async_trait::async_trait;
use indexmap::IndexSet;

#[derive(Default)]
pub struct MemoryAdapter {
Expand Down
9 changes: 9 additions & 0 deletions src/cached_api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use crate::cache::Cache;

use std::time::Duration;

pub trait CachedApi: Sized + Send + Sync {
fn set_cache(&mut self, cache: Box<dyn Cache<Vec<String>, bool>>);
fn set_ttl(&mut self, ttl: Duration);
fn set_capacity(&mut self, cap: usize);
}
155 changes: 128 additions & 27 deletions src/cached_enforcer.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,37 @@
use crate::cache::{Cache, DefaultCache};
use crate::convert::{TryIntoAdapter, TryIntoModel};
use crate::emitter::{Event, CACHED_EMITTER};
use crate::enforcer::Enforcer;
use crate::Result;
use crate::{
adapter::Adapter,
cache::{Cache, DefaultCache},
cached_api::CachedApi,
convert::{TryIntoAdapter, TryIntoModel},
core_api::CoreApi,
effector::Effector,
emitter::{Event, CACHED_EMITTER},
enforcer::Enforcer,
model::Model,
rbac::RoleManager,
watcher::Watcher,
Result,
};

#[cfg(feature = "runtime-async-std")]
use async_std::task;

use async_trait::async_trait;
use emitbrown::Events;

use std::ops::{Deref, DerefMut};
use std::time::Duration;
use std::{
sync::{Arc, RwLock},
time::Duration,
};

pub struct CachedEnforcer {
pub(crate) enforcer: Enforcer,
pub(crate) cache: Box<dyn Cache<Vec<String>, bool>>,
}

impl CachedEnforcer {
#[async_trait]
impl CoreApi for CachedEnforcer {
#[cfg(feature = "runtime-async-std")]
pub async fn new<M: TryIntoModel, A: TryIntoAdapter>(m: M, a: A) -> Result<CachedEnforcer> {
async fn new<M: TryIntoModel, A: TryIntoAdapter>(m: M, a: A) -> Result<CachedEnforcer> {
let cached_enforcer = CachedEnforcer {
enforcer: Enforcer::new(m, a).await?,
cache: Box::new(DefaultCache::new(1000)) as Box<dyn Cache<Vec<String>, bool>>,
Expand All @@ -40,7 +52,7 @@ impl CachedEnforcer {
}

#[cfg(feature = "runtime-tokio")]
pub async fn new<M: TryIntoModel, A: TryIntoAdapter>(m: M, a: A) -> Result<CachedEnforcer> {
async fn new<M: TryIntoModel, A: TryIntoAdapter>(m: M, a: A) -> Result<CachedEnforcer> {
let cached_enforcer = CachedEnforcer {
enforcer: Enforcer::new(m, a).await?,
cache: Box::new(DefaultCache::new(1000)) as Box<dyn Cache<Vec<String>, bool>>,
Expand All @@ -66,42 +78,131 @@ impl CachedEnforcer {
Ok(cached_enforcer)
}

pub fn set_cache(&mut self, cache: Box<dyn Cache<Vec<String>, bool>>) {
self.cache = cache;
#[inline]
fn add_function(&mut self, fname: &str, f: fn(String, String) -> bool) {
self.enforcer.fm.add_function(fname, f);
}

pub fn set_ttl(&mut self, ttl: Duration) {
self.cache.set_ttl(ttl);
#[inline]
fn get_model(&self) -> &dyn Model {
self.enforcer.get_model()
}

pub fn set_capacity(&mut self, cap: usize) {
self.cache.set_capacity(cap);
#[inline]
fn get_mut_model(&mut self) -> &mut dyn Model {
self.enforcer.get_mut_model()
}

#[inline]
fn get_adapter(&self) -> &dyn Adapter {
self.enforcer.get_adapter()
}

#[inline]
fn get_mut_adapter(&mut self) -> &mut dyn Adapter {
self.enforcer.get_mut_adapter()
}

#[inline]
fn set_watcher(&mut self, w: Box<dyn Watcher>) {
self.enforcer.set_watcher(w);
}

#[inline]
fn get_role_manager(&self) -> Arc<RwLock<dyn RoleManager>> {
self.enforcer.get_role_manager()
}

#[inline]
fn set_role_manager(&mut self, rm: Arc<RwLock<dyn RoleManager>>) {
self.enforcer.set_role_manager(rm);
}

#[inline]
fn add_matching_fn(&mut self, f: fn(String, String) -> bool) -> Result<()> {
self.enforcer.add_matching_fn(f)
}

#[inline]
async fn set_model<M: TryIntoModel>(&mut self, m: M) -> Result<()> {
self.enforcer.set_model(m).await
}

#[inline]
async fn set_adapter<A: TryIntoAdapter>(&mut self, a: A) -> Result<()> {
self.enforcer.set_adapter(a).await
}

#[inline]
fn set_effector(&mut self, e: Box<dyn Effector>) {
self.enforcer.set_effector(e);
}

pub async fn enforce<S: AsRef<str>>(&mut self, rvals: &[S]) -> Result<bool> {
async fn enforce<S: AsRef<str> + Send + Sync>(&mut self, rvals: &[S]) -> Result<bool> {
let key: Vec<String> = rvals.iter().map(|x| String::from(x.as_ref())).collect();

if let Some(result) = self.cache.get(&key).await {
Ok(*result)
} else {
let result = self.enforcer.enforce(&rvals)?;
let result = self.enforcer.enforce(rvals).await?;
self.cache.set(key, result).await;
Ok(result)
}
}
}

impl Deref for CachedEnforcer {
type Target = Enforcer;
#[inline]
fn build_role_links(&mut self) -> Result<()> {
self.enforcer.build_role_links()
}

#[inline]
async fn load_policy(&mut self) -> Result<()> {
self.enforcer.load_policy().await
}

#[inline]
async fn save_policy(&mut self) -> Result<()> {
self.enforcer.save_policy().await
}

fn deref(&self) -> &Self::Target {
&self.enforcer
#[inline]
fn clear_policy(&mut self) {
self.enforcer.clear_policy();
}

#[inline]
fn enable_enforce(&mut self, enabled: bool) {
self.enforcer.enable_enforce(enabled);
}

#[inline]
fn enable_auto_save(&mut self, auto_save: bool) {
self.enforcer.enable_auto_save(auto_save);
}

#[inline]
fn enable_auto_build_role_links(&mut self, auto_build_role_links: bool) {
self.enforcer
.enable_auto_build_role_links(auto_build_role_links);
}

#[inline]
fn has_auto_save_enabled(&self) -> bool {
self.enforcer.has_auto_save_enabled()
}
}

impl DerefMut for CachedEnforcer {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.enforcer
impl CachedApi for CachedEnforcer {
fn set_cache(&mut self, cache: Box<dyn Cache<Vec<String>, bool>>) {
self.cache = cache;
}

fn set_ttl(&mut self, ttl: Duration) {
self.cache.set_ttl(ttl);
}

fn set_capacity(&mut self, cap: usize) {
self.cache.set_capacity(cap);
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use crate::Result;

use std::collections::HashMap;
use std::convert::AsRef;

#[cfg(feature = "runtime-async-std")]
use async_std::{
fs::File,
Expand All @@ -19,6 +16,8 @@ use tokio::{
io::{AsyncBufReadExt, AsyncReadExt, BufReader, Error as IoError, ErrorKind},
};

use std::collections::HashMap;

const DEFAULT_SECTION: &str = "default";
const DEFAULT_COMMENT: &str = "#";
const DEFAULT_COMMENT_SEM: &str = ";";
Expand Down
4 changes: 2 additions & 2 deletions src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ use crate::{Adapter, DefaultModel, FileAdapter, Model, Result};
use async_trait::async_trait;

#[async_trait]
pub trait TryIntoModel {
pub trait TryIntoModel: Send + Sync {
async fn try_into_model(self) -> Result<Box<dyn Model>>;
}

#[async_trait]
pub trait TryIntoAdapter {
pub trait TryIntoAdapter: Send + Sync {
async fn try_into_adapter(self) -> Result<Box<dyn Adapter>>;
}

Expand Down
31 changes: 31 additions & 0 deletions src/core_api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use crate::{Adapter, Effector, Model, Result, RoleManager, TryIntoAdapter, TryIntoModel, Watcher};

use async_trait::async_trait;

use std::sync::{Arc, RwLock};

#[async_trait]
pub trait CoreApi: Sized + Send + Sync {
async fn new<M: TryIntoModel, A: TryIntoAdapter>(m: M, a: A) -> Result<Self>;
fn add_function(&mut self, fname: &str, f: fn(String, String) -> bool);
fn get_model(&self) -> &dyn Model;
fn get_mut_model(&mut self) -> &mut dyn Model;
fn get_adapter(&self) -> &dyn Adapter;
fn get_mut_adapter(&mut self) -> &mut dyn Adapter;
fn set_watcher(&mut self, w: Box<dyn Watcher>);
fn get_role_manager(&self) -> Arc<RwLock<dyn RoleManager>>;
fn set_role_manager(&mut self, rm: Arc<RwLock<dyn RoleManager>>);
fn add_matching_fn(&mut self, f: fn(String, String) -> bool) -> Result<()>;
async fn set_model<M: TryIntoModel>(&mut self, m: M) -> Result<()>;
async fn set_adapter<A: TryIntoAdapter>(&mut self, a: A) -> Result<()>;
fn set_effector(&mut self, e: Box<dyn Effector>);
async fn enforce<S: AsRef<str> + Send + Sync>(&mut self, rvals: &[S]) -> Result<bool>;
fn build_role_links(&mut self) -> Result<()>;
async fn load_policy(&mut self) -> Result<()>;
async fn save_policy(&mut self) -> Result<()>;
fn clear_policy(&mut self);
fn enable_auto_save(&mut self, auto_save: bool);
fn enable_enforce(&mut self, enabled: bool);
fn enable_auto_build_role_links(&mut self, auto_build_role_links: bool);
fn has_auto_save_enabled(&self) -> bool;
}
3 changes: 1 addition & 2 deletions src/emitter.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::cached_enforcer::CachedEnforcer;
use crate::enforcer::Enforcer;
use crate::{cached_enforcer::CachedEnforcer, enforcer::Enforcer};

use emitbrown::Emitter;
use lazy_static::lazy_static;
Expand Down
Loading