Add Prd Request handling
This commit is contained in:
parent
e92384fc93
commit
c0adce2b31
110
src/api.rs
110
src/api.rs
@ -997,6 +997,116 @@ fn handle_prd(
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
PrdType::Request => {
|
||||
// We are being requested encrypted data for one or more states, to be uploaded on storage
|
||||
let states: Vec<[u8; 32]> = serde_json::from_str(&prd.payload)?;
|
||||
let requester: Member = serde_json::from_str(&prd.sender)?;
|
||||
|
||||
// diffs will trigger upload of the encrypted data on storage
|
||||
let mut diffs = vec![];
|
||||
// This will notify the requester and provide relevant information if needed
|
||||
let mut ciphers = vec![];
|
||||
|
||||
for state_id in states {
|
||||
let state = match relevant_process.get_state_for_id(&state_id.to_lower_hex_string()) {
|
||||
Ok(state) => state,
|
||||
Err(_) => {
|
||||
debug!("Ignoring request for unknown state {}", state_id.to_lower_hex_string());
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let decrypted_map = state.decrypt_pcd()?;
|
||||
|
||||
let roles = Value::Object(decrypted_map.clone()).extract_roles()?;
|
||||
|
||||
let local_device = lock_local_device()?;
|
||||
|
||||
let sp_wallet = local_device.get_wallet();
|
||||
let local_address = sp_wallet.get_client().get_receiving_address();
|
||||
|
||||
let mut relevant_fields: HashSet<String> = HashSet::new();
|
||||
let shared_secrets = lock_shared_secrets()?;
|
||||
for (name, role) in &roles {
|
||||
if !role.members.contains(&requester) {
|
||||
// This role doesn't concern requester
|
||||
continue;
|
||||
}
|
||||
let fields: Vec<String> = role
|
||||
.validation_rules
|
||||
.iter()
|
||||
.flat_map(|rule| rule.fields.clone())
|
||||
.collect();
|
||||
if let Some(no_secret_address) = requester.get_addresses().iter()
|
||||
.find(|a| shared_secrets.get_secret_for_address(a.as_str().try_into().unwrap()).is_none())
|
||||
{
|
||||
// We ignore it if we don't have a secret with ourselves
|
||||
if *no_secret_address != local_address {
|
||||
// for now we return an error to keep it simple
|
||||
return Err(AnyhowError::msg(format!("No shared secret for all addresses of {:?}\nPlease first connect", requester)));
|
||||
}
|
||||
}
|
||||
relevant_fields.extend(fields);
|
||||
}
|
||||
|
||||
let sender: Member = local_device
|
||||
.to_member();
|
||||
|
||||
let mut full_prd = Prd::new_update(
|
||||
outpoint,
|
||||
sender,
|
||||
roles,
|
||||
state.keys.clone(),
|
||||
state.pcd_commitment.clone(),
|
||||
);
|
||||
|
||||
full_prd.filter_keys(&relevant_fields);
|
||||
let prd_msg = full_prd.to_network_msg(sp_wallet)?;
|
||||
|
||||
let addresses = requester.get_addresses();
|
||||
for sp_address in addresses.into_iter() {
|
||||
// We skip our own device address, no point sending ourself a cipher
|
||||
if sp_address == local_address {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We shouldn't ever have error here since we already checked above
|
||||
let shared_secret = shared_secrets.get_secret_for_address(sp_address.as_str().try_into()?).unwrap();
|
||||
|
||||
let cipher = encrypt_with_key(shared_secret.as_byte_array(), prd_msg.as_bytes())?;
|
||||
ciphers.push(cipher.to_lower_hex_string());
|
||||
}
|
||||
|
||||
let pcd_commitment: HashMap<String, String> = serde_json::from_value(state.pcd_commitment.clone())?;
|
||||
for (field, hash) in pcd_commitment {
|
||||
// We only need field that are visible by requester
|
||||
if !relevant_fields.contains(&field) {
|
||||
continue;
|
||||
}
|
||||
let diff = UserDiff {
|
||||
process_id: outpoint.to_string(),
|
||||
state_id: state_id.to_lower_hex_string(),
|
||||
value_commitment: hash,
|
||||
new_value: decrypted_map[&field].clone(),
|
||||
field,
|
||||
..Default::default()
|
||||
};
|
||||
diffs.push(diff);
|
||||
}
|
||||
}
|
||||
|
||||
let updated_process = Some(UpdatedProcess {
|
||||
process_id: outpoint,
|
||||
current_process: relevant_process.clone(),
|
||||
diffs,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
return Ok(ApiReturn {
|
||||
updated_process,
|
||||
ciphers_to_send: ciphers,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user