cds-snc / covid-alert-server

Exposure Notification: Diagnosis Server implementation / Notification d’exposition : Mise en œuvre du serveur de diagnostic
Apache License 2.0
298 stars 31 forks source link

feat: add QR outbreak event submission and retrievel endpoint #438

Closed maxneuvians closed 3 years ago

maxneuvians commented 3 years ago

This PR adds the QR outbreak events endpoints to the submission and retrieval server. This will allow the Healthcare portal to upload location ID and time frames for when a possible exposure event has happened. It will also allow the mobile app to download the data using the same format as the TEKs.

Data model

The current data model on the server looks like this:

    originator      VARCHAR(32) NOT NULL,
    location_id     VARCHAR(36) NOT NULL,
    start_time      INT UNSIGNED NOT NULL,
    end_time            INT UNSIGNED NOT NULL,
    created       TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX (location_id),
    INDEX (originator)

this allows us to store the full location UUID as well as the province that uploaded the submission. This is subject to change based on moving requirements.

Authentication

The submission endpoint uses the same authentication mechanism as the /new-key-claim which limits the access to the endpoint to all known bearer tokens issued to provinces.

The retrieval end point uses the same authentication that the TEKs do. This is a bit awkward as part of that authentication requires a signed URL that includes the RSIN for that hour. This makes sense for the TEKs but not necessarily for the outbreak events as they have nothing to do with RSINs. However, keeping the same authentication avoids introducing another authentication mechanism into the server (something we can still iterate towards)

Submision Endpoint

The current endpoint to submit QR codes is POSTing to /qr/new-event. This is flexible and can change if required.

Retrieval Endpoint

This functions exactly the same as the retrieval endpoint for TEKs. However, where a TEK URL looks like this:

/retrieve/302/#{dn}/#{hmac}`

Outbreak events use the following:

/qr/302/#{dn}/#{hmac}`

Again, this URL pattern can be changed if need be.

Submission Payload

To retain consistency with all the other APIs on the server, the payload is encoded using protobufs. The schema is as follows for the request:

message OutbreakEvent {
  optional string location_id = 1;
  optional google.protobuf.Timestamp start_time = 2;
  optional google.protobuf.Timestamp end_time = 3;
}

with the following response message:

message OutbreakEventResponse {
  enum ErrorCode {
    NONE = 0;
    UNKNOWN = 1;
    INVALID_ID = 2;
    MISSING_TIMESTAMP = 3;
    PERIOD_INVALID = 4;
    SERVER_ERROR = 5;
  }
  optional ErrorCode error = 1;
}

A successful submission will return a message with OutbreakEventResponse_NONE

Retrieval Payload

Again to retain consistancy, data is encoded using Profobufs and the placed into a Zip archive with two files:

export.bin
export.sig

export.sig contains a signature of the data using the ECDSA_KEY key used on the server. The mobile client would ideally validate the signature using the public part of the key.

The data model is similar in that the bin files contains an encode Protobuf message of type OutbreakEventExport and the sig file a message of type OutbreakEventExportSignature.

They are defined as follows:

message OutbreakEventExport {
  optional fixed64 start_timestamp = 1;
  optional fixed64 end_timestamp = 2;
  repeated OutbreakEvent locations = 3;
}

message OutbreakEventExportSignature {
  optional bytes signature = 1;
}