encryptPatient method

Future<PatientDto> encryptPatient(
  1. String dataOwnerId,
  2. Set<String> delegations,
  3. DecryptedPatientDto patient
)

Implementation

Future<PatientDto> encryptPatient(String dataOwnerId, Set<String> delegations, DecryptedPatientDto patient) async {
  var t = await this.marshaller(patient);

  PatientDto sanitizedPatient = t.item1;
  final Uint8List? marshalledData = t.item2;

  if (marshalledData != null) {
    var eks = patient.encryptionKeys;
    Uint8List? secret;

    if (!eks.entries.any((s) => s.value.isNotEmpty)) {
      secret = Uint8List.fromList(List<int>.generate(32, (i) => random.nextInt(256)));
      DataOwnerDto? dataOwner = null;

      final secretForDelegates = await Future.wait((<String>{...delegations, dataOwnerId}).map((String d) async {
        final keyAndOwner = await this.crypto.encryptAESKeyForHcp(dataOwnerId, d, patient.id, secret!.toHexString());
        dataOwner = keyAndOwner.item2 ?? dataOwner;
        return Tuple2(d, keyAndOwner);
      }));

      //If we have added keys to the current patient
      if (dataOwner != null && dataOwner!.dataOwnerId == patient.id) {
        sanitizedPatient.rev = dataOwner!.rev;
        sanitizedPatient.hcPartyKeys = dataOwner!.hcPartyKeys;
      }

      eks = {...eks, ...Map.fromEntries(secretForDelegates.map((t) =>
          MapEntry(t.item1, <DelegationDto>{DelegationDto(
              owner: dataOwnerId, delegatedTo: t.item1, key: t.item2.item1
          )})))};
      sanitizedPatient.encryptionKeys = eks;
    } else {
      secret = (await this.crypto.decryptEncryptionKeys(dataOwnerId, patient.encryptionKeys)).firstOrNull?.formatAsKey().fromHexString();
      if (secret == null) {
        throw FormatException("Cannot get encryption key for ${patient.id} and hcp $dataOwnerId");
      }
    }
    sanitizedPatient.encryptedSelf = base64.encoder.convert(marshalledData.encryptAES(secret));
  } else {
    sanitizedPatient.encryptedSelf = null;
  }

  return sanitizedPatient;
}