1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
//! ### Background //! The practice of implementing Data Usage Agreements addresses the following Privacy Design Strategies: //! - Inform //! - Control //! - Enforce //! - Demonstrate //! //! Whenever data is passed between Actors (e.g.: data collection between an online portal and the backend service to order the product), //! it is important to ensure that the owners' consent for how the data wil be used doesn't become _lost in translation_. //! //! A privacy engineering practice that supports this _promise_ to adhere how the data may be used is defined in the Data Usage Agreements //! that are sent with the data. //! //! ### Usage //! 1. The requestor adds a HTTP header `Data-Usage-Agreement` with the json array of the DUA objects //! //! > *JSON Structure* //! > //! > [ //! > { //! > "agreement_name": String, //! > "location": String, //! > "agreed_dtm": Unix Epoch Number //! > } //! > ] //! > //! > *HTTP Header* //! > //! > Data-Usage-Agreement: [{"agreement_name":"billing","location":"www.dua.org/billing.pdf","agreed_dtm": 1553988607}] //! //! //! //! --- //! //! One way is to incorporate the use of DUA objects is directly in the code. //! ``` //! extern crate pbd; //! //! use pbd::dua::DUA; //! //! fn main() { //! let serialized = r#"{ "agreement_name": "For Billing Purpose", "location": "www.dua.org/billing.pdf", "agreed_dtm": 1553988607 }"#; //! let dua = DUA::from_serialized(&serialized); //! //! match dua.agreement_name.as_ref() { //! "For Billing Purpose" => println!("We can use the data for sending a bill."), //! _ => println!("Oops: We can't use the data this way!") //! } //! //! // Addtionally, check which version of the agreement aligns with the agreed_dtm (if the agreement is under version control). //! } //! ``` //! /// The standard header attribute for list (array) of the Data Usage Agreements pub static DUA_HEADER: &str = "Data-Usage-Agreement"; /// Represents a Data Usage Agreement (DUA) #[derive(Serialize, Deserialize, Debug, Clone)] pub struct DUA { /// The common name of the Data Usage Agreement, (e.g.: For Billing Purpose) pub agreement_name: String, /// The URI where the version of the DUA can be found, (e.g.: https://iStore.example.org/dua/v2/billing.pdf) pub location: String, /// The Unix Epoch time when the DUA was agreed to pub agreed_dtm: u64, } impl DUA { /// Constructs a DUA object /// /// # Arguments /// /// * agreement: String - The common name of the Data Usage Agreement, (e.g.: For Billing Purpose).</br> /// * uri: String - The URI where the version of the DUA can be found, (e.g.: https://iStore.example.org/dua/v2/billing.pdf).</br> /// * agreed_on: String - The Unix Epoch time when the DUA was agreed to.</br> /// /// #Example /// /// ``` /// extern crate pbd; /// /// use pbd::dua::DUA; /// /// fn main() { /// let dua = DUA::new("For Billing Purpose".to_string(), "www.dua.org/billing.pdf".to_string(), 1553988607); /// /// match dua.agreement_name.as_ref() { /// "For Billing Purpose" => println!("We can use the data for sending a bill."), /// _ => println!("Oops: We can't use the data this way!") /// } /// } /// ``` pub fn new(agreement: String, uri: String, agreed_on: u64) -> DUA { DUA { agreement_name: agreement, location: uri, agreed_dtm: agreed_on, } } /// Constructs a DUA object from a serialized string /// /// # Arguments /// /// * serialized: &str - The string that represents the serialized object.</br> /// /// #Example /// /// ``` /// extern crate pbd; /// /// use pbd::dua::DUA; /// /// fn main() { /// let serialized = r#"{ "agreement_name": "billing", "location": "www.dua.org/billing.pdf", "agreed_dtm": 1553988607 }"#; /// let usage_agreement = DUA::from_serialized(&serialized); /// /// println!("{:?}", usage_agreement); /// } /// ``` pub fn from_serialized(serialized: &str) -> DUA { serde_json::from_str(&serialized).unwrap() } /// Serialize a DUA object /// /// # Arguments /// /// * serialized: &str - The string that represents the serialized object.</br> /// /// #Example /// /// ``` /// extern crate pbd; /// /// use pbd::dua::DUA; /// /// fn main() { /// let serialized = r#"{ "agreement_name": "billing", "location": "www.dua.org/billing.pdf", "agreed_dtm": 1553988607 }"#; /// let mut dua = DUA { /// agreement_name: "billing".to_string(), /// location: "www.dua.org/billing.pdf".to_string(), /// agreed_dtm: 1553988607, /// }; /// /// let usage_agreement = dua.serialize(); /// /// println!("{:?}", usage_agreement); /// } /// ``` pub fn serialize(&mut self) -> String { serde_json::to_string(&self).unwrap() } } pub mod error; pub mod extractor; pub mod middleware; // Unit Tests #[cfg(test)] mod tests { use super::*; fn get_dua() -> Vec<DUA>{ let mut v = Vec::new(); v.push( DUA { agreement_name: "billing".to_string(), location: "www.dua.org/billing.pdf".to_string(), agreed_dtm: 1553988607, }); v } #[test] fn test_dua_from_serialized_ok() { let serialized = r#"{"agreement_name":"billing","location":"www.dua.org/billing.pdf","agreed_dtm":1553988607}"#; let dua = DUA::from_serialized(serialized); assert_eq!(dua.agreement_name, "billing".to_string()); assert_eq!(dua.location, "www.dua.org/billing.pdf".to_string()); assert_eq!(dua.agreed_dtm, 1553988607); } #[test] fn test_dua_serialize_ok() { let serialized = r#"{"agreement_name":"billing","location":"www.dua.org/billing.pdf","agreed_dtm":1553988607}"#; let dua = &mut get_dua()[0]; assert_eq!(dua.serialize(), serialized); } }