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()
|
..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!(),
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user