Skip to content

Commit

Permalink
working on issue #17
Browse files Browse the repository at this point in the history
  • Loading branch information
dsietziapp committed Jan 3, 2020
1 parent 84f9d0f commit 8e80366
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 8 deletions.
9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ path = "src/lib.rs"
maintenance = {status = "actively-developed"}

[features]
default = ["dua"]
dua = ["actix-web","actix-service","futures", "rayon", "reqwest"] # Data Usae Agreement funcitonality
default = ["dua", "dtc"]
dua = ["actix-web","actix-service","futures", "rayon", "reqwest"] # Data Usage Agreement funcitonality
dtc =["pow_sha256"] # Data Tracker Chain functionality

[dependencies]
env_logger = "0.6"
log = "0.4"
serde ="1.0"
serde_derive = "1.0"
Expand All @@ -39,4 +41,5 @@ reqwest = { version = "0.9", optional = true }
actix-web = { version = "1.0.9", optional = true }
actix-service = { version = "0.4.2", optional = true }
futures = { version = "0.1", optional = true }
rayon = { version = "1.2.1", optional = true }
rayon = { version = "1.2.1", optional = true }
pow_sha256 = { version = "0.2", optional = true }
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ For software development teams who implement Privacy by Design practices, this P

## What's New

Here's whats new in 0.0.6:
Here's whats new in 0.0.7:

This project and codebase for this crate has change
1. Updated Data Usage Agreement feature
- actix-web middleware now checks the uri of the DUA to ensure they are valid (issue #14)
1. Introduced the concept of Data Tracker Chains
- MarkerChain traits (issue #17)

## Features

- Data Usage Agreements
- Data Tracker Chain

## About

Expand Down
37 changes: 37 additions & 0 deletions src/dtc/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//! Data Tracker Chain specific Errors

use std::error;
use derive_more::Display;
use actix_web::ResponseError;

#[derive(Debug, Clone, Display)]
pub enum Error {
/// Bad Data Uasage Agreement
#[display(fmt = "Invalid or Currupt Marker")]
BadMarker,
/// Bad format of Data Uasage Agreement
#[display(fmt = "Invalid Marker Chain")]
BadChain,
}

impl error::Error for Error{}

impl ResponseError for Error{}


#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_error_marker_bad() {
let err = Error::BadMarker;
assert_eq!(format!("{}", err), "Invalid or Currupt Marker");
}

#[test]
fn test_error_chain_bad() {
let err = Error::BadChain;
assert_eq!(format!("{}", err), "Invalid Marker Chain");
}
}
206 changes: 206 additions & 0 deletions src/dtc/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
//! ### Background
//! The practice of implementing Data Tracker Chains addresses the following Privacy Design Strategies:
//! - Inform
//! - Control
//! - Demonstrate
//!
//! Whenever data is passed through Actors (e.g.: data collection between an online portal and the backend service to order the product),
//! it is important to ensure that data lineage is tracked and retained.
//!
//! A privacy engineering practice that supports the real-time recording of data ineage is to implement a Data Tracking Chain that lives with the data.
//!
//! ### Usage

extern crate pow_sha256;

use pow_sha256::PoW;

pub static DIFFICULTY: u128 = 5;

/// Represents a MarkerIdentifier
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct MarkerIdentifier {
/// The unique identifier of the the data being tracked, (e.g.: order~clothing~iStore~15150)
pub data_id: String,
/// The sequanece number of the Marker in the Data Tracker Chain, (e.g.: 0,1,2,3)
pub index: usize,
// The date and time (Unix timestamp) the data came into posession of the Actor, (1578071239)
pub timestamp: u64,
/// The unique identifier of the Actor who touched the data, (e.g.: notifier~billing~receipt~email)
pub actor_id: String,
}

impl MarkerIdentifier {
pub fn serialize(&self) -> String {
serde_json::to_string(&self).unwrap()
}
}


/// Represents a Marker
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Marker {
/// The unique identifier of the the data being tracked, (e.g.: order~clothing~iStore~15150)
pub identifier: MarkerIdentifier,
/// The identifying hash of the Marker
pub hash: String,
/// The identifying hash of the previous Marker in the Data Tracker Chain
pub previous_hash: String,
/// The difficulty of the Proof of Work
nonce: u128,
}

impl Marker {
/// Constructs a Marker object
///
/// # Arguments
///
/// * idx: usize - The sequanece number of the Marker in the Data Tracker Chain, (e.g.: 0,1,2,3).</br>
/// * tmstp: String - The date and time (Unix timestamp) the data came into posession of the Actor.</br>
/// * act_id: String - The Unix Epoch time when the DUA was agreed to.</br>
/// * dat_id: String - The unique identifier of the the data being tracked.</br>
/// * prev_hash: String - The identifying hash of the previous Marker in the Data Tracker Chain</br>
///
/// #Example
///
/// ```
/// extern crate pbd;
///
/// use pbd::dtc::Marker;
///
/// fn main() {
/// let marker = Marker::new(1, 1578071239, "notifier~billing~receipt~email".to_string(), "order~clothing~iStore~15150".to_string(), "123456".to_string());
///
/// println!("{} has touched the data object {}", marker.identifier.actor_id, marker.identifier.data_id);
/// }
/// ```
pub fn new(idx: usize, tmstp: u64, act_id: String, dat_id: String, prev_hash: String) -> Marker {
let idfy = MarkerIdentifier {
data_id: dat_id,
index: idx,
timestamp: tmstp,
actor_id: act_id,
};

Marker {
identifier: idfy.clone(),
hash: Marker::calculate_hash(idfy, DIFFICULTY).result,
previous_hash: prev_hash,
nonce: DIFFICULTY,
}
}

fn calculate_hash(idfy: MarkerIdentifier, difficulty: u128) -> PoW<MarkerIdentifier> {
PoW::prove_work(&idfy, difficulty).unwrap()
}

/// Constructs the first Marker (a.k.a. Genesis Black)
///
/// # Arguments
///
/// * dat_id: String - The unique identifier of the the data being tracked.</br>
///
/// #Example
///
/// ```
/// extern crate pbd;
///
/// use pbd::dtc::Marker;
///
/// fn main() {
/// let marker = Marker::genesis("order~clothing~iStore~15150".to_string());
///
/// assert_eq!(marker.identifier.index, 0);
/// }
/// ```
pub fn genesis(dat_id: String) -> Marker {
let idfy = MarkerIdentifier {
data_id: dat_id,
index: 0,
timestamp: 0,
actor_id: "".to_string(),
};

Marker {
identifier: idfy.clone(),
hash: Marker::calculate_hash(idfy, DIFFICULTY).result,
previous_hash: "0".to_string(),
nonce: DIFFICULTY,
}
}
}

/// Represents a MarkerChain
type Tracker = Vec<Marker>;

trait MarkerChain {
fn is_valid(&self) -> bool{
debug!("Validating chain ...");

for m in 0..self.len() {
let marker = self.get(m);

if marker.hash != Marker::calculate_hash(marker.identifier, DIFFICULTY).result {
return false;
}
}

true
}
}

impl MarkerChain for Tracker {
}



pub mod error;


// Unit Tests
#[cfg(test)]
mod tests {
use super::*;

fn get_marker() -> Marker {
Marker::new(1, 1578071239, "notifier~billing~receipt~email".to_string(), "order~clothing~iStore~15150".to_string(), "123456".to_string())
}

#[test]
fn test_calc_hash() {
let _ = env_logger::builder().is_test(true).try_init();
let marker = get_marker();
let pw = Marker::calculate_hash(marker.identifier, marker.nonce);

assert!(pw.is_sufficient_difficulty(marker.nonce));
}

#[test]
fn test_marker_new() {
let mkr = get_marker();
assert_eq!(mkr.identifier.index, 1);
}

#[test]
fn test_marker_genesis() {
let mkr = Marker::genesis("order~clothing~iStore~15150".to_string());
assert_eq!(mkr.identifier.index, 0);
}

#[test]
fn test_markerchain_new() {
let mut mkrchn = Tracker::new();
mkrchn.push(Marker::genesis("order~clothing~iStore~15150".to_string()));

assert_eq!(mkrchn.len(), 1);
}

#[test]
fn test_markerchain_invalid() {
let mut mkrchn = Tracker::new();
mkrchn.push(Marker::genesis("order~clothing~iStore~15150".to_string()));
mkrchn.push(get_marker());

assert!(mkrchn.is_valid());
}
}
2 changes: 1 addition & 1 deletion src/dua/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! - Inform
//! - Control
//! - Enforce
//! - Deomnstrate
//! - 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_.
Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
//!
//!
//!

extern crate env_logger;
#[macro_use] extern crate log;
#[macro_use] extern crate serde_derive;
extern crate serde_json;
Expand All @@ -35,6 +35,7 @@ extern crate json;
// Modules
#[cfg(feature = "dua")]
pub mod dua;
pub mod dtc;

// Unit Tests
#[cfg(test)]
Expand Down

0 comments on commit 8e80366

Please sign in to comment.