Skip to content
Snippets Groups Projects
Commit 5a0e9b21 authored by nanocryk's avatar nanocryk
Browse files

[enh] MembershipDocumentParser

parent 9b5425a6
Branches
Tags
1 merge request!17Resolve "Add Membership document structure, building and parsing"
...@@ -23,6 +23,16 @@ use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedD ...@@ -23,6 +23,16 @@ use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedD
use blockchain::v10::documents::{StandardTextDocumentParser, TextDocument, TextDocumentBuilder, use blockchain::v10::documents::{StandardTextDocumentParser, TextDocument, TextDocumentBuilder,
V10Document, V10DocumentParsingError}; V10Document, V10DocumentParsingError};
lazy_static! {
static ref MEMBERSHIP_REGEX: Regex = Regex::new(
"^Issuer: (?P<issuer>[1-9A-Za-z][^OIl]{43,44})\n\
Block: (?P<blockstamp>[0-9]+-[0-9A-F]{64})\n\
Membership: (?P<membership>(IN|OUT))\n\
UserID: (?P<ity_user>[[:alnum:]_-]+)\n\
CertTS: (?P<ity_block>[0-9]+-[0-9A-F]{64})\n$"
).unwrap();
}
/// Type of a Membership. /// Type of a Membership.
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum MembershipType { pub enum MembershipType {
...@@ -138,7 +148,7 @@ impl<'a> MembershipDocumentBuilder<'a> { ...@@ -138,7 +148,7 @@ impl<'a> MembershipDocumentBuilder<'a> {
membership: self.membership, membership: self.membership,
identity_username: self.identity_username.to_string(), identity_username: self.identity_username.to_string(),
identity_blockstamp: *self.identity_blockstamp, identity_blockstamp: *self.identity_blockstamp,
signatures signatures,
} }
} }
} }
...@@ -182,6 +192,55 @@ CertTS: {ity_blockstamp} ...@@ -182,6 +192,55 @@ CertTS: {ity_blockstamp}
} }
} }
/// Membership document parser
#[derive(Debug, Clone, Copy)]
pub struct MembershipDocumentParser;
impl StandardTextDocumentParser for MembershipDocumentParser {
fn parse_standard(
doc: &str,
body: &str,
currency: &str,
signatures: Vec<ed25519::Signature>,
) -> Result<V10Document, V10DocumentParsingError> {
if let Some(caps) = MEMBERSHIP_REGEX.captures(body) {
let issuer = &caps["issuer"];
let blockstamp = &caps["blockstamp"];
let membership = &caps["membership"];
let username = &caps["ity_user"];
let ity_block = &caps["ity_block"];
// Regex match so should not fail.
// TODO : Test it anyway
let issuer = ed25519::PublicKey::from_base58(issuer).unwrap();
let blockstamp = Blockstamp::from_string(blockstamp).unwrap();
let membership = match membership {
"IN" => MembershipType::In(),
"OUT" => MembershipType::Out(),
_ => panic!("Invalid membership type {}", membership),
};
let ity_block = Blockstamp::from_string(ity_block).unwrap();
Ok(V10Document::Membership(MembershipDocument {
text: doc.to_owned(),
issuers: vec![issuer],
currency: currency.to_owned(),
blockstamp: blockstamp,
membership,
identity_username: username.to_owned(),
identity_blockstamp: ity_block,
signatures,
}))
} else {
Err(V10DocumentParsingError::InvalidInnerFormat(
"Identity".to_string(),
))
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
...@@ -226,4 +285,44 @@ mod tests { ...@@ -226,4 +285,44 @@ mod tests {
VerificationResult::Valid() VerificationResult::Valid()
); );
} }
#[test]
fn membership_standard_regex() {
assert!(MEMBERSHIP_REGEX.is_match(
"Issuer: DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV
Block: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
Membership: IN
UserID: tic
CertTS: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
"
));
}
#[test]
fn membership_identity_document() {
let doc = "Version: 10
Type: Membership
Currency: duniter_unit_test_currency
Issuer: DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV
Block: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
Membership: IN
UserID: tic
CertTS: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
s2hUbokkibTAWGEwErw6hyXSWlWFQ2UWs2PWx8d/kkElAyuuWaQq4Tsonuweh1xn4AC1TVWt4yMR3WrDdkhnAw==";
let body = "Issuer: DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV
Block: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
Membership: IN
UserID: tic
CertTS: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
";
let currency = "duniter_unit_test_currency";
let signatures = vec![Signature::from_base64(
"s2hUbokkibTAWGEwErw6hyXSWlWFQ2UWs2PWx8d/kkElAyuuWaQq4Tsonuweh1xn4AC1TVWt4yMR3WrDdkhnAw=="
).unwrap(),];
let _ = MembershipDocumentParser::parse_standard(doc, body, currency, signatures).unwrap();
}
} }
...@@ -24,7 +24,7 @@ pub mod identity; ...@@ -24,7 +24,7 @@ pub mod identity;
pub mod membership; pub mod membership;
pub use blockchain::v10::documents::identity::{IdentityDocument, IdentityDocumentBuilder}; pub use blockchain::v10::documents::identity::{IdentityDocument, IdentityDocumentBuilder};
pub use blockchain::v10::documents::membership::MembershipDocument; pub use blockchain::v10::documents::membership::{MembershipDocument, MembershipDocumentParser};
// Use of lazy_static so the regex is only compiled at first use. // Use of lazy_static so the regex is only compiled at first use.
lazy_static! { lazy_static! {
...@@ -166,6 +166,7 @@ impl<'a> DocumentParser<&'a str, V10Document, V10DocumentParsingError> for V10Do ...@@ -166,6 +166,7 @@ impl<'a> DocumentParser<&'a str, V10Document, V10DocumentParsingError> for V10Do
match doctype { match doctype {
"Identity" => IdentityDocumentParser::parse_standard(doc, body, currency, sigs), "Identity" => IdentityDocumentParser::parse_standard(doc, body, currency, sigs),
"Membership" => MembershipDocumentParser::parse_standard(doc, body, currency, sigs),
_ => Err(V10DocumentParsingError::UnknownDocumentType( _ => Err(V10DocumentParsingError::UnknownDocumentType(
doctype.to_string(), doctype.to_string(),
)), )),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment