giveAccessTo method

  1. @override
Future<DataSample> giveAccessTo(
  1. DataSample dataSample,
  2. String delegatedTo
)
override

Give access to another dataOwner to the DataSample

Parameters:

  • DataSample dataSample to give access to delegateTo
  • 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"));
}