Skip to content

Commit

Permalink
feat: add missing policy field (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
wolf4ood authored Sep 28, 2024
1 parent dd9317f commit 34920ea
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 20 deletions.
154 changes: 153 additions & 1 deletion edc-connector-client/src/types/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ pub struct Policy {
#[serde_as(deserialize_as = "OneOrMany<_, PreferMany>")]
#[serde(rename = "permission", alias = "odrl:permission", default)]
permissions: Vec<Permission>,
#[serde(rename = "obligation", alias = "odrl:obligation", default)]
obligations: Vec<Obligation>,
#[serde(rename = "prohibition", alias = "odrl:prohibition", default)]
prohibitions: Vec<Prohibition>,
}

impl Policy {
Expand All @@ -166,6 +170,8 @@ impl Policy {
assigner: None,
target: None,
permissions: vec![],
obligations: vec![],
prohibitions: vec![],
})
}

Expand All @@ -192,6 +198,14 @@ impl Policy {
pub fn permissions(&self) -> &[Permission] {
&self.permissions
}

pub fn obligations(&self) -> &[Obligation] {
&self.obligations
}

pub fn prohibitions(&self) -> &[Prohibition] {
&self.prohibitions
}
}

pub struct PolicyBuilder(Policy);
Expand Down Expand Up @@ -255,7 +269,7 @@ pub struct Permission {
impl Permission {
pub fn builder() -> PermissionBuilder {
PermissionBuilder(Permission {
action: Action::new("http://www.w3.org/ns/odrl/2/use".to_string()),
action: Action::default(),
constraints: vec![],
})
}
Expand All @@ -282,11 +296,116 @@ impl PermissionBuilder {
self
}

pub fn action(mut self, action: Action) -> Self {
self.0.action = action;
self
}

pub fn build(self) -> Permission {
self.0
}
}

#[serde_as]
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
pub struct Obligation {
#[serde_as(deserialize_as = "OneOrMany<_, PreferMany>")]
#[serde(rename = "constraint", alias = "odrl:constraint", default)]
constraints: Vec<Constraint>,
#[serde(alias = "odrl:action")]
action: Action,
}

impl Obligation {
pub fn builder() -> ObligationBuilder {
ObligationBuilder(Obligation {
action: Action::default(),
constraints: vec![],
})
}

pub fn action(&self) -> &Action {
&self.action
}

pub fn constraints(&self) -> &[Constraint] {
&self.constraints
}
}

pub struct ObligationBuilder(Obligation);

impl ObligationBuilder {
pub fn constraints(mut self, constraints: Vec<Constraint>) -> Self {
self.0.constraints = constraints;
self
}

pub fn action(mut self, action: Action) -> Self {
self.0.action = action;
self
}

pub fn constraint(mut self, constraint: Constraint) -> Self {
self.0.constraints.push(constraint);
self
}

pub fn build(self) -> Obligation {
self.0
}
}

#[serde_as]
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
pub struct Prohibition {
#[serde_as(deserialize_as = "OneOrMany<_, PreferMany>")]
#[serde(rename = "constraint", alias = "odrl:constraint", default)]
constraints: Vec<Constraint>,
#[serde(alias = "odrl:action")]
action: Action,
}

impl Prohibition {
pub fn builder() -> ProhibitionBuilder {
ProhibitionBuilder(Prohibition {
action: Action::default(),
constraints: vec![],
})
}

pub fn action(&self) -> &Action {
&self.action
}

pub fn constraints(&self) -> &[Constraint] {
&self.constraints
}
}

pub struct ProhibitionBuilder(Prohibition);

impl ProhibitionBuilder {
pub fn constraints(mut self, constraints: Vec<Constraint>) -> Self {
self.0.constraints = constraints;
self
}

pub fn action(mut self, action: Action) -> Self {
self.0.action = action;
self
}

pub fn constraint(mut self, constraint: Constraint) -> Self {
self.0.constraints.push(constraint);
self
}

pub fn build(self) -> Prohibition {
self.0
}
}

#[derive(Debug, Serialize, PartialEq, Clone, Deserialize)]
#[serde(untagged)]
pub enum Action {
Expand All @@ -297,6 +416,12 @@ pub enum Action {
},
}

impl Default for Action {
fn default() -> Self {
Action::new("http://www.w3.org/ns/odrl/2/use".to_string())
}
}

impl Action {
pub fn id(&self) -> &String {
match self {
Expand All @@ -316,6 +441,25 @@ impl Action {
#[serde(untagged)]
pub enum Constraint {
Atomic(AtomicConstraint),
MultiplicityConstraint(MultiplicityConstraint),
}

impl Constraint {
pub fn atomic(atomic: AtomicConstraint) -> Self {
Constraint::Atomic(atomic)
}

pub fn or(constraints: Vec<Constraint>) -> Self {
Constraint::MultiplicityConstraint(MultiplicityConstraint::Or(constraints))
}

pub fn and(constraints: Vec<Constraint>) -> Self {
Constraint::MultiplicityConstraint(MultiplicityConstraint::And(constraints))
}

pub fn xone(constraints: Vec<Constraint>) -> Self {
Constraint::MultiplicityConstraint(MultiplicityConstraint::Xone(constraints))
}
}

#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
Expand Down Expand Up @@ -348,6 +492,14 @@ pub struct AtomicConstraint {
right_operand: PropertyValue,
}

#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "snake_case")]
pub enum MultiplicityConstraint {
Or(Vec<Constraint>),
And(Vec<Constraint>),
Xone(Vec<Constraint>),
}

#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(untagged)]
pub enum Operator {
Expand Down
71 changes: 52 additions & 19 deletions edc-connector-client/src/types/policy/odrl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,74 @@ mod tests {
#[test]
fn should_deserialize_odrl() {
let json = json!({
"@context": "http://www.w3.org/ns/odrl.jsonld",
"@type": "Set",
"uid": "https://w3c.github.io/odrl/bp/examples/3",
"assigner": "assigner",
"assignee": "assignee",
"target": "target",
"obligation": [{
"action": "display",
"constraint": [{
"leftOperand": "spatial",
"operator": "eq",
"rightOperand": "https://www.wikidata.org/resource/Q183",
}]
}],
"permission": [{
"target": "http://example.com/asset:9898.movie",
"action": "display",
"constraint": [{
"leftOperand": "spatial",
"operator": "eq",
"rightOperand": "https://www.wikidata.org/resource/Q183",
"dct:comment": "i.e Germany"
}]
}],
"prohibition": [{
"action": "display",
"constraint": [{
"leftOperand": "spatial",
"operator": "eq",
"rightOperand": "https://www.wikidata.org/resource/Q183",
}]
}]
});

let policy = serde_json::from_value::<Policy>(json).unwrap();
let policy = serde_json::from_value::<Policy>(json.clone()).unwrap();

assert_eq!(policy.kind(), &PolicyKind::Set);
assert_eq!(policy.permissions().len(), 1);
let serialized = serde_json::to_value(&policy).unwrap();

let permission = &policy.permissions[0];
assert_eq!(&json, &serialized);
}

assert_eq!(permission.action().id(), "display");
assert_eq!(permission.constraints().len(), 1);
#[test]
fn should_deserialize_odrl_with_multiplicity_constraints() {
let json = json!({
"@type":"Set",
"assigner":"assigner",
"assignee":"assignee",
"target":"target",
"obligation":[
{
"action":"display",
"constraint":[{
"and":[
{
"leftOperand":"spatial",
"operator":"eq",
"rightOperand":"https://www.wikidata.org/resource/Q183"
}
]
}]
}
],
"permission":[
],
"prohibition":[
]});

let constraint = &permission.constraints()[0];
let policy = serde_json::from_value::<Policy>(json.clone()).unwrap();

assert_eq!(
constraint,
&Constraint::Atomic(AtomicConstraint::new(
"spatial",
"eq",
"https://www.wikidata.org/resource/Q183"
))
);
let serialized = serde_json::to_value(&policy).unwrap();

assert_eq!(&json, &serialized);
}

#[test]
Expand Down

0 comments on commit 34920ea

Please sign in to comment.