Skip to content

Instantly share code, notes, and snippets.

@sify21
Created August 31, 2020 13:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sify21/9bb804adafc8dd68321123f8d839d6b8 to your computer and use it in GitHub Desktop.
Save sify21/9bb804adafc8dd68321123f8d839d6b8 to your computer and use it in GitHub Desktop.
#[cfg(test)]
mod test {
use casbin::{CoreApi, DefaultModel, Enforcer, MemoryAdapter, MgmtApi};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct Claims {
pub id: i64,
pub username: String,
pub resources: Vec<String>,
pub groups: Vec<String>,
pub exp: usize,
}
#[tokio::test]
async fn test_custom_func() {
let model = DefaultModel::from_str("
[request_definition]
r = sub, url, act
[policy_definition]
p = res, url, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = keyMatch2(r.url, p.url) && regexMatch(r.act, p.act) && verify_sub(r.sub, p.res)").await.unwrap();
let mut e = Enforcer::new(model, MemoryAdapter::default())
.await
.unwrap();
e.add_policy(vec![
String::from("logout"),
String::from("/test/logout"),
String::from("GET"),
])
.await
.unwrap();
e.add_function("verify_sub", |sub, resource| -> bool {
let claims: Claims = serde_json::from_str(&sub).unwrap();
if claims.id == 1 {
return true;
}
claims
.resources
.iter()
.any(|i| i.contains(resource.as_str()))
});
let claim = Claims {
id: 2,
resources: vec![String::from("logout.aa"), String::from("bb")],
..Default::default()
};
assert_eq!(
true,
e.enforce(&[
serde_json::to_string(&claim).unwrap().as_str(),
"/test/logout",
"GET"
])
.unwrap()
);
}
}
@GopherJ
Copy link

GopherJ commented Aug 31, 2020


use casbin::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, Clone, Default, Hash)]
pub struct Claims {
    pub id: i64,
    pub username: String,
    pub resources: Vec<String>,
    pub groups: Vec<String>,
    pub exp: usize,
}

#[tokio::main]
async fn main() -> Result<()> {
    let model = DefaultModel::from_str(
        "
[request_definition]
r = sub, url, act

[policy_definition]
p = res, url, act

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = keyMatch2(r.url, p.url) && regexMatch(r.act, p.act) && (r.sub.id == 1 || p.res in r.sub.resources)",
    )
    .await?;

    let mut e = Enforcer::new(model, MemoryAdapter::default())
        .await
        .unwrap();
    e.add_policy(vec![
        String::from("logout"),
        String::from("/test/logout"),
        String::from("GET"),
    ])
    .await?;

    e.add_function("verify_sub", |sub, resource| -> bool {
        let claims: Claims = serde_json::from_str(&sub).unwrap();
        if claims.id == 1 {
            return true;
        }
        claims
            .resources
            .iter()
            .any(|i| i.contains(resource.as_str()))
    });
    let claim1 = Claims {
        id: 1,
        resources: vec![String::from("logout.aa"), String::from("bb")],
        ..Default::default()
    };
    assert_eq!(true, e.enforce((claim1, "/test/logout", "GET")).unwrap());

    let claim2 = Claims {
        id: 2,
        resources: vec![String::from("logout"), String::from("bb")],
        ..Default::default()
    };
    assert_eq!(true, e.enforce((claim2, "/test/logout", "GET")).unwrap());

    Ok(())
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment