giveAccessTo method
Give access to another dataOwner to the DataSample
Parameters:
DataSample
dataSample to give access todelegateTo
- String delegatedTo: dataOwnerId to give access to
Data owner id can be either a:
- healthcarePartyId,
- patientId
- deviceId
Implementation
@override
Future<DataSample> giveAccessTo(DataSample dataSample, String delegatedTo) async {
final localCrypto = api.crypto;
final currentUser = (await api.baseUserApi.getCurrentUser())
?? (throw StateError("There is no user currently logged in. You must call this method from an authenticated MedTechApi"));
// Check if delegatedBy has access
final contact = (await _getContactOfDataSample(localCrypto, currentUser, dataSample, bypassCache: true)).item2!;
final myId = currentUser.dataOwnerId()!;
final newSecretIds = await localCrypto.findAndDecryptPotentiallyUnknownKeysForDelegate(myId, delegatedTo, contact.delegations);
final newEncryptionKeys = await localCrypto.findAndDecryptPotentiallyUnknownKeysForDelegate(myId, delegatedTo, contact.encryptionKeys);
final newCfks = await localCrypto.findAndDecryptPotentiallyUnknownKeysForDelegate(myId, delegatedTo, contact.cryptedForeignKeys);
if (newSecretIds.isEmpty && newEncryptionKeys.isEmpty && newCfks.isEmpty) {
return dataSample;
}
final ccContact = contactCryptoConfig(currentUser, localCrypto);
final newSecretIdsDelegations = await Future.wait(newSecretIds.map((clearKey) =>
createDelegationBasedOn(localCrypto, myId, delegatedTo, contact.id, clearKey.formatAsKey())
));
final newEncryptionKeysDelegations = await Future.wait(newEncryptionKeys.map((clearKey) =>
createDelegationBasedOn(localCrypto, myId, delegatedTo, contact.id, clearKey.formatAsKey())
));
final newCfksDelegations = await Future.wait(newCfks.map((clearKey) =>
createDelegationBasedOn(localCrypto, myId, delegatedTo, contact.id, clearKey.formatAsKey())
));
final existingDelegationsForDelegate = contact.delegations[delegatedTo] ?? {};
contact.delegations[delegatedTo] = {...existingDelegationsForDelegate, ...newSecretIdsDelegations};
final existingEncryptionKeysForDelegate = contact.encryptionKeys[delegatedTo] ?? {};
contact.encryptionKeys[delegatedTo] = {...existingEncryptionKeysForDelegate, ...newEncryptionKeysDelegations};
final existingCfksForDelegate = contact.cryptedForeignKeys[delegatedTo] ?? {};
contact..cryptedForeignKeys[delegatedTo] = {...existingCfksForDelegate, ...newCfksDelegations};
final updatedContact = await api.baseContactApi.modifyContact(currentUser, contact, ccContact);
return updatedContact?.services.where((e) => e.id == dataSample.id).firstOrNull?.toDataSample(updatedContact.id)
?? (throw StateError("Impossible to give access to ${delegatedTo} to data sample ${dataSample.id} information"));
}