identity_credential/credential/
policy.rs

1// Copyright 2020-2021 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use serde::Deserialize;
5use serde::Serialize;
6
7use identity_core::common::Object;
8use identity_core::common::OneOrMany;
9use identity_core::common::Url;
10
11/// Information used to express obligations, prohibitions, and permissions about
12/// a [`Credential`][crate::credential::Credential] or [`Presentation`][crate::presentation::Presentation].
13///
14/// [More Info](https://www.w3.org/TR/vc-data-model/#terms-of-use)
15#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
16pub struct Policy {
17  /// The instance id of the credential terms-of-use.
18  #[serde(skip_serializing_if = "Option::is_none")]
19  pub id: Option<Url>,
20  /// The type(s) of the credential terms-of-use.
21  #[serde(rename = "type")]
22  pub types: OneOrMany<String>,
23  /// Additional properties of the credential terms-of-use.
24  #[serde(flatten)]
25  pub properties: Object,
26}
27
28impl Policy {
29  /// Creates a new `Policy` instance.
30  pub fn new<T>(types: T) -> Self
31  where
32    T: Into<OneOrMany<String>>,
33  {
34    Self {
35      id: None,
36      types: types.into(),
37      properties: Object::new(),
38    }
39  }
40
41  /// Creates a new `Policy` instance with the given `id`.
42  pub fn with_id<T>(types: T, id: Url) -> Self
43  where
44    T: Into<OneOrMany<String>>,
45  {
46    Self {
47      id: Some(id),
48      types: types.into(),
49      properties: Object::new(),
50    }
51  }
52
53  /// Creates a new `Policy` instance with the given `properties`.
54  pub fn with_properties<T>(types: T, properties: Object) -> Self
55  where
56    T: Into<OneOrMany<String>>,
57  {
58    Self {
59      id: None,
60      types: types.into(),
61      properties,
62    }
63  }
64
65  /// Creates a new `Policy` instance with the given `id` and `properties`.
66  pub fn with_id_and_properties<T>(types: T, id: Url, properties: Object) -> Self
67  where
68    T: Into<OneOrMany<String>>,
69  {
70    Self {
71      id: Some(id),
72      types: types.into(),
73      properties,
74    }
75  }
76}
77
78#[cfg(test)]
79mod tests {
80  use identity_core::convert::FromJson;
81
82  use crate::credential::Policy;
83
84  const JSON1: &str = include_str!("../../tests/fixtures/policy-1.json");
85  const JSON2: &str = include_str!("../../tests/fixtures/policy-2.json");
86
87  #[test]
88  fn test_from_json() {
89    let policy: Policy = Policy::from_json(JSON1).unwrap();
90    assert_eq!(policy.id.unwrap(), "http://example.com/policies/credential/4");
91    assert_eq!(policy.types.as_slice(), ["IssuerPolicy"]);
92    assert_eq!(policy.properties["profile"], "http://example.com/profiles/credential");
93    assert_eq!(
94      policy.properties["prohibition"][0]["assigner"],
95      "https://example.edu/issuers/14"
96    );
97    assert_eq!(policy.properties["prohibition"][0]["assignee"], "AllVerifiers");
98    assert_eq!(
99      policy.properties["prohibition"][0]["target"],
100      "http://example.edu/credentials/3732"
101    );
102    assert_eq!(policy.properties["prohibition"][0]["action"][0], "Archival");
103
104    let policy: Policy = Policy::from_json(JSON2).unwrap();
105    assert_eq!(policy.id.unwrap(), "http://example.com/policies/credential/6");
106    assert_eq!(policy.types.as_slice(), ["HolderPolicy"]);
107    assert_eq!(policy.properties["profile"], "http://example.com/profiles/credential");
108    assert_eq!(
109      policy.properties["prohibition"][0]["assigner"],
110      "did:example:ebfeb1f712ebc6f1c276e12ec21"
111    );
112    assert_eq!(
113      policy.properties["prohibition"][0]["assignee"],
114      "https://wineonline.example.org/"
115    );
116    assert_eq!(
117      policy.properties["prohibition"][0]["target"],
118      "http://example.edu/credentials/3732"
119    );
120    assert_eq!(policy.properties["prohibition"][0]["action"][0], "3rdPartyCorrelation");
121  }
122}