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

add critcmp & insert into adapter before model #77

Merged
merged 3 commits into from
Apr 5, 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
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 <[email protected]>", "Cheng JIANG <[email protected]>"]
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