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
use serde::{Deserialize, Serialize};

pub use crate::proof::*;
use crate::{CreateKeyChange, EventIdentifier, ProfileEventAttributes, RotateKeyChange};

/// Pre-defined keys in [`ProfileEventAttributes`] map
#[non_exhaustive]
pub struct ProfileEventAttributeKey;

impl ProfileEventAttributeKey {
    /// Human-readable name
    pub const FRIENDLY_NAME: &'static str = "OCKAM_FN";
    /// UTC timestamp
    pub const CREATION_DATE: &'static str = "OCKAM_CD";
}

/// Individual change applied to profile. [`ProfileChangeEvent`] consists of one or more such changes
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ProfileChange {
    version: u8,
    // TODO: Check attributes serialization
    attributes: ProfileEventAttributes,
    change_type: ProfileChangeType,
}

impl ProfileChange {
    /// Protocol version
    pub fn version(&self) -> u8 {
        self.version
    }
    /// User-specified attributes that will be saved with change
    pub fn attributes(&self) -> &ProfileEventAttributes {
        &self.attributes
    }
    /// Type of change along with type-specific data
    pub fn change_type(&self) -> &ProfileChangeType {
        &self.change_type
    }
}

impl ProfileChange {
    pub(crate) fn new(
        version: u8,
        attributes: ProfileEventAttributes,
        change_type: ProfileChangeType,
    ) -> Self {
        Self {
            version,
            attributes,
            change_type,
        }
    }
}

/// Possible types of [`crate::Profile`] changes
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum ProfileChangeType {
    /// Create key
    CreateKey(CreateKeyChange),
    /// Rotate key
    RotateKey(RotateKeyChange),
}

/// Profile changes with a given event identifier
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChangeSet {
    prev_event_id: EventIdentifier,
    data: Vec<ProfileChange>,
}

impl ChangeSet {
    /// [`EventIdentifier`] of previous event
    pub fn previous_event_identifier(&self) -> &EventIdentifier {
        &self.prev_event_id
    }
    /// Set of changes been applied
    pub fn data(&self) -> &[ProfileChange] {
        &self.data
    }
}

impl ChangeSet {
    /// Create new Changes
    pub fn new(prev_event_id: EventIdentifier, data: Vec<ProfileChange>) -> Self {
        ChangeSet {
            prev_event_id,
            data,
        }
    }
}

/// [`crate::Profile`]s are modified using change events mechanism. One event may have 1 or more [`ProfileChange`]s
/// Proof is used to check whether this event comes from a party authorized to perform such updated
/// Individual changes may include additional proofs, if needed
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ProfileChangeEvent {
    identifier: EventIdentifier,
    changes: ChangeSet,
    proof: ProfileChangeProof,
}

pub type Changes = Vec<ProfileChangeEvent>;

impl ProfileChangeEvent {
    /// Unique [`EventIdentifier`]
    pub fn identifier(&self) -> &EventIdentifier {
        &self.identifier
    }
    /// Set of changes been applied
    pub fn changes(&self) -> &ChangeSet {
        &self.changes
    }
    /// Proof is used to check whether this event comes from a party authorized to perform such updated
    /// Individual changes may include additional proofs, if needed
    pub fn proof(&self) -> &ProfileChangeProof {
        &self.proof
    }
}

impl ProfileChangeEvent {
    /// Create a new profile change event
    pub fn new(identifier: EventIdentifier, changes: ChangeSet, proof: ProfileChangeProof) -> Self {
        ProfileChangeEvent {
            identifier,
            changes,
            proof,
        }
    }
}