Skip to content

Commit a5dd27c

Browse files
authored
Add signer_identity_proof to bills, local override for removed and rejected, Add notification for Company Invite, Add verification and warning for invalid proofs (#753)
1 parent c45fd95 commit a5dd27c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1358
-714
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
* API to accept/reject company invites
3131
* Restructured company persistence - `company` table is now a cache, calculated from the chain (similar to bills)
3232
* Added possibility to locally hide past invites
33+
* Add notification when being invited to a company
34+
* Add `signer_identity_proof` to bill block data and verify it
35+
* Add Contact Handshake
3336

3437
# 0.4.12
3538

crates/bcr-ebill-api/src/service/bill_service/blocks.rs

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use bcr_ebill_core::{
2626
},
2727
};
2828

29-
use crate::util::validate_node_id_network;
29+
use crate::{get_config, util::validate_node_id_network};
3030

3131
use super::{BillAction, Result, error::Error, service::BillService};
3232

@@ -56,6 +56,14 @@ impl BillService {
5656
BillParticipant::Ident(_) => false,
5757
};
5858

59+
let identity_proof = self
60+
.get_signer_identity_proof(
61+
signer_public_data,
62+
identity,
63+
&get_config().mint_config.default_mint_node_id,
64+
)
65+
.await?;
66+
5967
let block = match bill_action {
6068
// has to be ident to accept
6169
BillAction::Accept => {
@@ -65,6 +73,11 @@ impl BillService {
6573
signatory: signing_keys.signatory_identity,
6674
signing_timestamp: timestamp,
6775
signing_address: signer.postal_address.clone(),
76+
signer_identity_proof: identity_proof
77+
.ok_or(Error::Protocol(
78+
ProtocolValidationError::NoSignerIdentityProof.into(),
79+
))?
80+
.into(),
6881
};
6982
// nothing to validate - all checked via type system
7083
BillBlock::create_block_for_accept(
@@ -95,6 +108,11 @@ impl BillService {
95108
signatory: signing_keys.signatory_identity,
96109
signing_timestamp: timestamp,
97110
signing_address: signer_public_data.postal_address(),
111+
signer_identity_proof: if holder_is_anon {
112+
None
113+
} else {
114+
identity_proof.map(|sp| sp.into())
115+
},
98116
acceptance_deadline_timestamp: *acceptance_deadline_timestamp,
99117
};
100118
block_data.validate()?;
@@ -122,6 +140,11 @@ impl BillService {
122140
signatory: signing_keys.signatory_identity,
123141
signing_timestamp: timestamp,
124142
signing_address: signer_public_data.postal_address(),
143+
signer_identity_proof: if holder_is_anon {
144+
None
145+
} else {
146+
identity_proof.map(|sp| sp.into())
147+
},
125148
payment_deadline_timestamp: *payment_deadline_timestamp,
126149
};
127150
block_data.validate()?;
@@ -164,6 +187,11 @@ impl BillService {
164187
signatory: signing_keys.signatory_identity,
165188
signing_timestamp: timestamp,
166189
signing_address: signer_public_data.postal_address(),
190+
signer_identity_proof: if holder_is_anon {
191+
None
192+
} else {
193+
identity_proof.map(|sp| sp.into())
194+
},
167195
recourse_deadline_timestamp: *recourse_deadline_timestamp,
168196
};
169197
block_data.validate()?;
@@ -198,6 +226,11 @@ impl BillService {
198226
signatory: signing_keys.signatory_identity,
199227
signing_timestamp: timestamp,
200228
signing_address: signer_public_data.postal_address(),
229+
signer_identity_proof: if holder_is_anon {
230+
None
231+
} else {
232+
identity_proof.map(|sp| sp.into())
233+
},
201234
};
202235
block_data.validate()?;
203236
BillBlock::create_block_for_recourse(
@@ -226,6 +259,11 @@ impl BillService {
226259
signatory: signing_keys.signatory_identity,
227260
signing_timestamp: timestamp,
228261
signing_address: signer_public_data.postal_address(),
262+
signer_identity_proof: if holder_is_anon {
263+
None
264+
} else {
265+
identity_proof.map(|sp| sp.into())
266+
},
229267
};
230268
block_data.validate()?;
231269
BillBlock::create_block_for_mint(
@@ -259,6 +297,11 @@ impl BillService {
259297
signatory: signing_keys.signatory_identity,
260298
signing_timestamp: timestamp,
261299
signing_address: signer_public_data.postal_address(),
300+
signer_identity_proof: if holder_is_anon {
301+
None
302+
} else {
303+
identity_proof.map(|sp| sp.into())
304+
},
262305
buying_deadline_timestamp: *buying_deadline_timestamp,
263306
};
264307
block_data.validate()?;
@@ -289,6 +332,11 @@ impl BillService {
289332
signatory: signing_keys.signatory_identity,
290333
signing_timestamp: timestamp,
291334
signing_address: signer_public_data.postal_address(),
335+
signer_identity_proof: if holder_is_anon {
336+
None
337+
} else {
338+
identity_proof.map(|sp| sp.into())
339+
},
292340
};
293341
block_data.validate()?;
294342
BillBlock::create_block_for_sell(
@@ -316,6 +364,11 @@ impl BillService {
316364
signatory: signing_keys.signatory_identity,
317365
signing_timestamp: timestamp,
318366
signing_address: signer_public_data.postal_address(),
367+
signer_identity_proof: if holder_is_anon {
368+
None
369+
} else {
370+
identity_proof.map(|sp| sp.into())
371+
},
319372
};
320373
block_data.validate()?;
321374
BillBlock::create_block_for_endorse(
@@ -337,6 +390,11 @@ impl BillService {
337390
signatory: signing_keys.signatory_identity,
338391
signing_timestamp: timestamp,
339392
signing_address: signer.postal_address.clone(),
393+
signer_identity_proof: identity_proof
394+
.ok_or(Error::Protocol(
395+
ProtocolValidationError::NoSignerIdentityProof.into(),
396+
))?
397+
.into(),
340398
};
341399
// nothing to validate - all checked via type system
342400
BillBlock::create_block_for_reject_to_accept(
@@ -367,6 +425,11 @@ impl BillService {
367425
signatory: signing_keys.signatory_identity,
368426
signing_timestamp: timestamp,
369427
signing_address: signer_public_data.postal_address(),
428+
signer_identity_proof: if holder_is_anon {
429+
None
430+
} else {
431+
identity_proof.map(|sp| sp.into())
432+
},
370433
};
371434
// nothing to validate - all checked via type system
372435
BillBlock::create_block_for_reject_to_buy(
@@ -388,6 +451,11 @@ impl BillService {
388451
signatory: signing_keys.signatory_identity,
389452
signing_timestamp: timestamp,
390453
signing_address: signer.postal_address.clone(),
454+
signer_identity_proof: identity_proof
455+
.ok_or(Error::Protocol(
456+
ProtocolValidationError::NoSignerIdentityProof.into(),
457+
))?
458+
.into(),
391459
};
392460
// nothing to validate - all checked via type system
393461
BillBlock::create_block_for_reject_to_pay(
@@ -414,6 +482,11 @@ impl BillService {
414482
signatory: signing_keys.signatory_identity,
415483
signing_timestamp: timestamp,
416484
signing_address: signer.postal_address.clone(),
485+
signer_identity_proof: identity_proof
486+
.ok_or(Error::Protocol(
487+
ProtocolValidationError::NoSignerIdentityProof.into(),
488+
))?
489+
.into(),
417490
};
418491
// nothing to validate - all checked via type system
419492
BillBlock::create_block_for_reject_to_pay_recourse(

crates/bcr-ebill-api/src/service/bill_service/data_fetching.rs

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use crate::get_config;
2+
13
use super::service::BillService;
24
use super::{Error, Result};
35
use bcr_common::core::{BillId, NodeId};
@@ -6,12 +8,12 @@ use bcr_ebill_core::application::bill::{
68
PaymentState,
79
};
810
use bcr_ebill_core::application::contact::Contact;
9-
use bcr_ebill_core::protocol::Sum;
1011
use bcr_ebill_core::protocol::Timestamp;
1112
use bcr_ebill_core::protocol::Validate;
1213
use bcr_ebill_core::protocol::blockchain::Block;
1314
use bcr_ebill_core::protocol::blockchain::bill::BillValidateActionData;
1415
use bcr_ebill_core::protocol::{Date, ProtocolValidationError};
16+
use bcr_ebill_core::protocol::{EmailIdentityProofData, SignedIdentityProof, Sum};
1517
use bcr_ebill_core::{
1618
application::bill::{
1719
BillAcceptanceStatus, BillCurrentWaitingState, BillData, BillParticipants,
@@ -143,6 +145,60 @@ impl BillService {
143145
}
144146
}
145147

148+
/// Get the signer's identity proof
149+
/// If they are Anon - return None
150+
/// If it's an identified person - return the email confirmation for the witness and identity
151+
/// If it's a company - return the email confirmation for the witness, company and signatory
152+
/// If we're in dev mode and mandatory email confirmations are disabled, we accept self-signing
153+
pub(super) async fn get_signer_identity_proof(
154+
&self,
155+
signer_public_data: &BillParticipant,
156+
signatory_identity: &IdentityWithAll,
157+
witness: &NodeId,
158+
) -> Result<Option<(SignedIdentityProof, EmailIdentityProofData)>> {
159+
Ok(match signer_public_data {
160+
BillParticipant::Ident(identified) => match identified.t {
161+
ContactType::Person => self
162+
.identity_store
163+
.get_email_confirmations()
164+
.await?
165+
.iter()
166+
.find(|ec| {
167+
&ec.0.witness
168+
== if get_config()
169+
.dev_mode_config
170+
.disable_mandatory_email_confirmations
171+
{
172+
&identified.node_id
173+
} else {
174+
witness
175+
}
176+
})
177+
.cloned(),
178+
ContactType::Company => self
179+
.company_store
180+
.get_email_confirmations(&identified.node_id)
181+
.await?
182+
.iter()
183+
.find(|ec| {
184+
&ec.0.witness
185+
== if get_config()
186+
.dev_mode_config
187+
.disable_mandatory_email_confirmations
188+
{
189+
&signatory_identity.identity.node_id
190+
} else {
191+
witness
192+
}
193+
&& ec.1.node_id == signatory_identity.identity.node_id
194+
})
195+
.cloned(),
196+
ContactType::Anon => None,
197+
},
198+
BillParticipant::Anon(_) => None,
199+
})
200+
}
201+
146202
pub(super) async fn calculate_full_bill(
147203
&self,
148204
chain: &BillBlockchain,
@@ -1006,7 +1062,8 @@ pub mod tests {
10061062
use crate::{
10071063
service::bill_service::test_utils::{bill_keys, get_baseline_bill, get_genesis_chain},
10081064
tests::tests::{
1009-
bill_id_test, bill_identified_participant_only_node_id, empty_address, private_key_test,
1065+
bill_id_test, bill_identified_participant_only_node_id, empty_address,
1066+
private_key_test, signed_identity_proof_test, test_ts,
10101067
},
10111068
};
10121069

@@ -1021,7 +1078,7 @@ pub mod tests {
10211078
let endorsee: Option<NodeId> = None;
10221079
let maturity_date = bill.maturity_date.clone();
10231080
let bill_keys = bill_keys();
1024-
let timestamp = Timestamp::new(1731593928).unwrap();
1081+
let timestamp = test_ts();
10251082

10261083
let is_paid = false;
10271084
let is_waiting_for_req_to_pay = false;
@@ -1095,6 +1152,7 @@ pub mod tests {
10951152
signatory: None,
10961153
signing_timestamp: latest_block.timestamp + 1,
10971154
signing_address: Some(empty_address()),
1155+
signer_identity_proof: Some(signed_identity_proof_test().into()),
10981156
acceptance_deadline_timestamp: latest_block.timestamp
10991157
+ 1
11001158
+ 2 * ACCEPT_DEADLINE_SECONDS,
@@ -1168,6 +1226,7 @@ pub mod tests {
11681226
signatory: None,
11691227
signing_timestamp: latest_block.timestamp + 1,
11701228
signing_address: empty_address(),
1229+
signer_identity_proof: signed_identity_proof_test().into(),
11711230
},
11721231
&BcrKeys::new(),
11731232
None,

crates/bcr-ebill-api/src/service/bill_service/issue.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,23 @@ impl BillService {
209209
&data.drawer_keys,
210210
&identity,
211211
)?;
212+
let Some(identity_proof) = self
213+
.get_signer_identity_proof(
214+
&data.drawer_public_data,
215+
&identity,
216+
&get_config().mint_config.default_mint_node_id,
217+
)
218+
.await?
219+
else {
220+
return Err(Error::Protocol(
221+
ProtocolValidationError::NoSignerIdentityProof.into(),
222+
));
223+
};
212224
let block_data = BillIssueBlockData::from(
213225
bill.clone(),
214226
signing_keys.signatory_identity,
215227
data.timestamp,
228+
identity_proof,
216229
);
217230
block_data.validate()?;
218231

0 commit comments

Comments
 (0)