Skip to content

Commit

Permalink
add critcmp & insert into adapter before model (#77)
Browse files Browse the repository at this point in the history
* add critcmp & insert into adapter before model

* Fix CI.

* Fix. bench PR.
  • Loading branch information
GopherJ authored Apr 5, 2020
1 parent 773a1d1 commit 0cd4e88
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 115 deletions.
21 changes: 20 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ before_script:
script:
- cargo clean
- cargo build
- cargo test
# Todo: https://github.com/rust-lang/cargo/issues/2980
- cargo test --no-default-features --features runtime-async-std,logging
- cargo test --no-default-features --features runtime-tokio,logging
- cargo clippy -- -D warnings
- cargo fmt --all -- --check

Expand All @@ -27,4 +29,21 @@ after_success: |
# upload report to codecov
docker run --security-opt seccomp=unconfined -v "$PWD:/volume" xd009642/tarpaulin sh -c "cargo tarpaulin --out Xml"
bash <(curl -s https://codecov.io/bash)
if [[ "${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" != "master" ]]; then
REMOTE_URL="$(git config --get remote.origin.url)";
# Clone the repository fresh..for some reason checking out master fails
# from a normal PR build's provided directory
cd ${TRAVIS_BUILD_DIR}/.. && \
git clone ${REMOTE_URL} "${TRAVIS_REPO_SLUG}-bench" && \
cd "${TRAVIS_REPO_SLUG}-bench" && \
git fetch origin +refs/pull/${TRAVIS_PULL_REQUEST}/merge
# Bench master
cargo bench -- --save-baseline before && \
# Bench PR
git checkout FETCH_HEAD && \
cargo bench -- --save-baseline after && \
cargo install critcmp --force && \
critcmp before after
fi
fi
11 changes: 6 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "casbin"
version = "0.4.0"
version = "0.4.1"
authors = ["Joey <joey.xf@gmail.com>", "Cheng JIANG <jiang.cheng@vip.163.com>"]
edition = "2018"
license = "Apache-2.0"
Expand All @@ -17,29 +17,30 @@ regex = "1.3.1"
rhai = "0.9.1"
ip_network = "0.3.4"
ttl_cache = "0.5.1"
emitbrown = "0.1.8"
emitbrown = "0.1.9"
lazy_static = "1.4.0"
indexmap = "1.3.1"
async-std = { version = "1.5.0", optional = true }
async-trait = "0.1.24"
log = "0.4.8"
log = { version = "0.4.8", optional = true }
tokio = { version = "0.2.11", optional = true, default-features = false }
globset = "0.4.5"

[features]
default = ["runtime-async-std"]
default = ["runtime-tokio", "logging"]

runtime-tokio = ["tokio/fs", "tokio/io-util", "tokio/stream", "tokio/rt-threaded", "tokio/blocking"]
runtime-async-std = ["async-std"]
logging = ["log"]

[profile.release.build-override]
opt-level = 0

[dev-dependencies]
async-std = { version = "1.5.0", features = [ "attributes" ] }
tokio = { version = "0.2.11", features = [ "full" ] }
cfg-if = "0.1.10"
criterion = "0.3"
cfg-if = "0.1.10"

[lib]
bench = false
Expand Down
4 changes: 2 additions & 2 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.0"
casbin = "0.4.1"
async-std = { version = "1.5.0", features = ["attributes"] }
```

Expand Down Expand Up @@ -53,7 +53,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(vec![sub, obj, act]) {
if let Ok(authorized) = e.enforce(&[sub, obj, act]) {
if authorized {
// permit alice to read data1
} else {
Expand Down
10 changes: 5 additions & 5 deletions src/adapter/file_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl<P: AsRef<Path> + Send + Sync + 'static> Adapter for FileAdapter<P> {

async fn add_policy(&mut self, _sec: &str, _ptype: &str, _rule: Vec<String>) -> Result<bool> {
// this api shouldn't implement, just for convinent
Ok(false)
Ok(true)
}

async fn add_policies(
Expand All @@ -114,7 +114,7 @@ impl<P: AsRef<Path> + Send + Sync + 'static> Adapter for FileAdapter<P> {
_rules: Vec<Vec<String>>,
) -> Result<bool> {
// this api shouldn't implement, just for convinent
Ok(false)
Ok(true)
}

async fn remove_policy(
Expand All @@ -124,7 +124,7 @@ impl<P: AsRef<Path> + Send + Sync + 'static> Adapter for FileAdapter<P> {
_rule: Vec<String>,
) -> Result<bool> {
// this api shouldn't implement, just for convinent
Ok(false)
Ok(true)
}

async fn remove_policies(
Expand All @@ -134,7 +134,7 @@ impl<P: AsRef<Path> + Send + Sync + 'static> Adapter for FileAdapter<P> {
_rule: Vec<Vec<String>>,
) -> Result<bool> {
// this api shouldn't implement, just for convinent
Ok(false)
Ok(true)
}

async fn remove_filtered_policy(
Expand All @@ -145,7 +145,7 @@ impl<P: AsRef<Path> + Send + Sync + 'static> Adapter for FileAdapter<P> {
_field_values: Vec<String>,
) -> Result<bool> {
// this api shouldn't implement, just for convinent
Ok(false)
Ok(true)
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/adapter/memory_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ impl Adapter for MemoryAdapter {
rule.insert(0, ptype.to_owned());
rule.insert(0, sec.to_owned());

Ok(self.policy.insert(rule))
Ok(self.policy.remove(&rule))
}

async fn remove_filtered_policy(
Expand All @@ -136,7 +136,7 @@ impl Adapter for MemoryAdapter {
if sec == rule[0] && ptype == rule[1] {
let mut matched = true;
for (i, field_value) in field_values.iter().enumerate() {
if !field_value.is_empty() && &rule[field_index + i] != field_value {
if !field_value.is_empty() && &rule[field_index + i + 2] != field_value {
matched = false;
break;
}
Expand All @@ -147,6 +147,8 @@ impl Adapter for MemoryAdapter {
} else {
tmp.insert(rule.clone());
}
} else {
tmp.insert(rule.clone());
}
}
self.policy = tmp;
Expand Down
4 changes: 2 additions & 2 deletions src/effector.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub trait Effector: Send + Sync {
fn merge_effects(&self, expr: String, effects: Vec<EffectKind>) -> bool;
fn merge_effects(&self, expr: &str, effects: Vec<EffectKind>) -> bool;
}

#[derive(PartialEq, Clone)]
Expand All @@ -13,7 +13,7 @@ pub enum EffectKind {
pub struct DefaultEffector {}

impl Effector for DefaultEffector {
fn merge_effects(&self, expr: String, effects: Vec<EffectKind>) -> bool {
fn merge_effects(&self, expr: &str, effects: Vec<EffectKind>) -> bool {
if expr == "some(where (p_eft == allow))" {
let mut result = false;
for eft in effects {
Expand Down
41 changes: 32 additions & 9 deletions src/enforcer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub struct Enforcer {
pub(crate) fm: FunctionMap,
pub(crate) eft: Box<dyn Effector>,
pub(crate) rm: Arc<RwLock<dyn RoleManager>>,
pub(crate) enabled: bool,
pub(crate) auto_save: bool,
pub(crate) auto_build_role_links: bool,
pub(crate) watcher: Option<Box<dyn Watcher>>,
Expand All @@ -78,6 +79,7 @@ impl Enforcer {
fm,
eft,
rm,
enabled: true,
auto_save: true,
auto_build_role_links: true,
watcher: None,
Expand Down Expand Up @@ -113,12 +115,22 @@ impl Enforcer {
self.watcher = Some(w);
}

pub async fn set_model(&mut self, m: Box<dyn Model>) -> Result<()> {
self.model = m;
self.load_policy().await?;
Ok(())
}

pub async fn set_adapter(&mut self, a: Box<dyn Adapter>) -> Result<()> {
self.adapter = a;
self.load_policy().await?;
Ok(())
}

pub fn set_effector(&mut self, e: Box<dyn Effector>) {
self.eft = e;
}

/// Enforce decides whether a "subject" can access a "object" with the operation "action",
/// input parameters are usually: (sub, obj, act).
///
Expand All @@ -131,7 +143,7 @@ impl Enforcer {
/// let m = DefaultModel::from_file("examples/basic_model.conf").await.unwrap();
/// let adapter = FileAdapter::new("examples/basic_policy.csv");
/// let e = Enforcer::new(Box::new(m), Box::new(adapter)).await.unwrap();
/// assert_eq!(true, e.enforce(&vec!["alice", "data1", "read"]).unwrap());
/// assert_eq!(true, e.enforce(&["alice", "data1", "read"]).unwrap());
/// }
///
/// #[cfg(feature = "runtime-tokio")]
Expand All @@ -140,14 +152,19 @@ impl Enforcer {
/// let m = DefaultModel::from_file("examples/basic_model.conf").await.unwrap();
/// let adapter = FileAdapter::new("examples/basic_policy.csv");
/// let e = Enforcer::new(Box::new(m), Box::new(adapter)).await.unwrap();
/// assert_eq!(true, e.enforce(&vec!["alice", "data1", "read"]).unwrap());
/// assert_eq!(true, e.enforce(&["alice", "data1", "read"]).unwrap());
/// }
/// #[cfg(all(not(feature = "runtime-async-std"), not(feature = "runtime-tokio")))]
/// fn main() {}
/// ```
pub fn enforce<S: AsRef<str>>(&self, rvals: &[S]) -> Result<bool> {
if !self.enabled {
return Ok(true);
}

let mut engine = Engine::new();
let mut scope: Scope = Vec::new();

let r_ast = self
.model
.get_model()
Expand Down Expand Up @@ -230,22 +247,25 @@ impl Enforcer {
}
}
}
let expstring = m_ast.value.clone();

let expstring = &m_ast.value;
let mut policy_effects: Vec<EffectKind> = vec![];

let policies = self.model.get_policy("p", "p");
let policy_len = policies.len();
if policy_len != 0 {
policy_effects = vec![EffectKind::Allow; policy_len];
policy_effects = vec![EffectKind::Deny; policy_len];
if r_ast.tokens.len() != rvals.len() {
return Ok(false);
}

for (i, pvals) in policies.iter().enumerate() {
if p_ast.tokens.len() != pvals.len() {
return Ok(false);
}

for (pi, ptoken) in p_ast.tokens.iter().enumerate() {
// let p_sub = "alice"; or let p_obj = "resource1"; or let p_sub = "GET";
let scope_exp = format!("let {} = \"{}\";", ptoken.clone(), pvals[pi]);
let scope_exp = format!("let {} = \"{}\";", ptoken, pvals[pi]);
engine.eval_with_scope::<()>(&mut scope, scope_exp.as_str())?;
}

Expand All @@ -254,6 +274,7 @@ impl Enforcer {
policy_effects[i] = EffectKind::Indeterminate;
continue;
}

if let Some(j) = p_ast
.tokens
.iter()
Expand Down Expand Up @@ -287,9 +308,7 @@ impl Enforcer {
}
}

let ee = e_ast.value.clone();

Ok(self.eft.merge_effects(ee, policy_effects))
Ok(self.eft.merge_effects(&e_ast.value, policy_effects))
}

pub fn build_role_links(&mut self) -> Result<()> {
Expand All @@ -312,6 +331,10 @@ impl Enforcer {
self.model.clear_policy();
}

pub fn enable_enforce(&mut self, enabled: bool) {
self.enabled = enabled;
}

pub fn enable_auto_save(&mut self, auto_save: bool) {
self.auto_save = auto_save;
}
Expand Down
Loading

0 comments on commit 0cd4e88

Please sign in to comment.