dubp_documents/identity/
v10.rs1use crate::*;
19
20#[derive(Clone, Debug, Deserialize, Hash, Serialize, PartialEq, Eq)]
24pub struct IdentityDocumentV10 {
25 text: Option<String>,
30
31 currency: String,
33 username: String,
35 blockstamp: Blockstamp,
37 issuer: ed25519::PublicKey,
39 signature: ed25519::Signature,
41}
42
43#[derive(Clone, Debug, Deserialize, Hash, Serialize, PartialEq, Eq)]
44pub struct IdentityDocumentV10Stringified {
46 pub currency: String,
48 pub username: String,
50 pub blockstamp: String,
52 pub issuer: String,
54 pub signature: String,
56}
57
58impl ToStringObject for IdentityDocumentV10 {
59 type StringObject = IdentityDocumentV10Stringified;
60 fn to_string_object(&self) -> IdentityDocumentV10Stringified {
62 IdentityDocumentV10Stringified {
63 currency: self.currency.clone(),
64 username: self.username.clone(),
65 blockstamp: format!("{}", self.blockstamp),
66 issuer: self.issuer.to_base58(),
67 signature: self.signature.to_base64(),
68 }
69 }
70}
71
72impl IdentityDocumentV10 {
73 pub fn username(&self) -> &str {
75 &self.username
76 }
77
78 pub fn reduce(&mut self) {
80 self.text = None;
81 }
82}
83
84impl Document for IdentityDocumentV10 {
85 type PublicKey = ed25519::PublicKey;
86
87 fn as_bytes(&self) -> BeefCow<[u8]> {
88 BeefCow::borrowed(self.as_text().as_bytes())
89 }
90
91 fn currency(&self) -> &str {
92 &self.currency
93 }
94
95 fn blockstamp(&self) -> Blockstamp {
96 self.blockstamp
97 }
98
99 fn issuers(&self) -> SmallVec<[Self::PublicKey; 1]> {
100 svec![self.issuer]
101 }
102
103 fn signatures(&self) -> SmallVec<[<Self::PublicKey as PublicKey>::Signature; 1]> {
104 svec![self.signature]
105 }
106
107 fn version(&self) -> usize {
108 10
109 }
110}
111
112#[derive(Clone, Debug, Deserialize, Hash, Serialize, PartialEq, Eq)]
114pub struct CompactIdentityDocumentV10 {
115 username: String,
117 blockstamp: Blockstamp,
119 pubkey: ed25519::PublicKey,
121 signature: ed25519::Signature,
123}
124
125impl CompactTextDocument for CompactIdentityDocumentV10 {
126 fn as_compact_text(&self) -> String {
127 format!(
128 "{issuer}:{signature}:{blockstamp}:{username}",
129 issuer = self.pubkey,
130 signature = self.signature,
131 blockstamp = self.blockstamp,
132 username = self.username,
133 )
134 }
135}
136
137impl TextDocument for IdentityDocumentV10 {
138 type CompactTextDocument_ = CompactIdentityDocumentV10;
139
140 fn as_text(&self) -> &str {
141 if let Some(ref text) = self.text {
142 text
143 } else {
144 panic!("Try to get text of reduce identity !")
145 }
146 }
147
148 fn to_compact_document(&self) -> Cow<Self::CompactTextDocument_> {
149 Cow::Owned(CompactIdentityDocumentV10 {
150 username: self.username.clone(),
151 blockstamp: self.blockstamp,
152 pubkey: self.issuer,
153 signature: self.signature,
154 })
155 }
156}
157
158#[derive(Debug, Copy, Clone)]
160pub struct IdentityDocumentV10Builder<'a> {
161 pub currency: &'a str,
163 pub username: &'a str,
165 pub blockstamp: Blockstamp,
167 pub issuer: ed25519::PublicKey,
169}
170
171impl<'a> TextDocumentBuilder for IdentityDocumentV10Builder<'a> {
172 type Document = IdentityDocumentV10;
173 type Signator = ed25519::Signator;
174
175 fn build_with_text_and_sigs(
176 self,
177 text: String,
178 signatures: SmallVec<
179 [<<Self::Document as Document>::PublicKey as PublicKey>::Signature; 1],
180 >,
181 ) -> IdentityDocumentV10 {
182 IdentityDocumentV10 {
183 text: Some(text),
184 currency: self.currency.to_string(),
185 username: self.username.to_string(),
186 blockstamp: self.blockstamp,
187 issuer: self.issuer,
188 signature: signatures[0],
189 }
190 }
191
192 fn generate_text(&self) -> String {
193 format!(
194 "Version: 10
195Type: Identity
196Currency: {currency}
197Issuer: {issuer}
198UniqueID: {username}
199Timestamp: {blockstamp}
200",
201 currency = self.currency,
202 issuer = self.issuer,
203 username = self.username,
204 blockstamp = self.blockstamp
205 )
206 }
207}
208
209#[cfg(test)]
210mod tests {
211 use super::*;
212 use smallvec::smallvec;
213 use std::str::FromStr;
214 use unwrap::unwrap;
215
216 #[test]
217 fn generate_real_document() {
218 let keypair = ed25519::KeyPairFromSeed32Generator::generate(unwrap!(
219 Seed32::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV"),
220 "fail to build Seed32"
221 ));
222 let pubkey = keypair.public_key();
223 let signator = keypair.generate_signator();
224
225 let sig = unwrap!(ed25519::Signature::from_base64(
226 "mmFepRsiOjILKnCvEvN3IZScLOfg8+e0JPAl5VkiuTLZRGJKgKhPy8nQlCKbeg0jefQm/2HJ78e/Sj+NMqYLCw==",
227 ), "fail to build Signature");
228
229 let blockstamp = unwrap!(
230 Blockstamp::from_str(
231 "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
232 ),
233 "fail to build Blockstamp"
234 );
235
236 let builder = IdentityDocumentV10Builder {
237 currency: "duniter_unit_test_currency",
238 username: "tic",
239 blockstamp,
240 issuer: pubkey,
241 };
242
243 assert!(builder
244 .build_with_signature(smallvec![sig])
245 .verify_signatures()
246 .is_ok());
247 assert!(builder
248 .build_and_sign(vec![signator])
249 .verify_signatures()
250 .is_ok());
251 }
252}