This repository has been archived by the owner on Oct 31, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
structs.go
183 lines (155 loc) · 7.44 KB
/
structs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package api
import (
"context"
"encoding/base64"
"github.com/covid19cz/erouska-backend/internal/logging"
keyserverapi "github.com/google/exposure-notifications-server/pkg/api/v1"
verifserverapi "github.com/google/exposure-notifications-verification-server/pkg/api"
"strconv"
"strings"
"time"
)
//ExpKey The exposure key.
type ExpKey = keyserverapi.ExposureKey
//ExpKeyBatch Batch (array) of exposure keys.
type ExpKeyBatch = []ExpKey
//IssueCodeRequest Issue code request to the Verification server
type IssueCodeRequest = verifserverapi.IssueCodeRequest
//IssueCodeResponse Issue code response from the Verification server
type IssueCodeResponse = verifserverapi.IssueCodeResponse
//VerifyRequest Verify request to the Verification server
type VerifyRequest = verifserverapi.VerifyCodeRequest
//VerifyResponse Verify response from the Verification server
type VerifyResponse = verifserverapi.VerifyCodeResponse
//CertificateRequest Certificate request to the Verification server
type CertificateRequest = verifserverapi.VerificationCertificateRequest
//CertificateResponse Certificate response to the Verification server
type CertificateResponse = verifserverapi.VerificationCertificateResponse
//DownloadBatchResponse Response for download batch call to EFGS
type DownloadBatchResponse struct {
Keys []DiagnosisKey `json:"keys"`
}
var mapReportTypeInt = map[int]ReportType{
0: ReportType_UNKNOWN,
1: ReportType_CONFIRMED_TEST,
2: ReportType_CONFIRMED_CLINICAL_DIAGNOSIS,
3: ReportType_SELF_REPORT,
4: ReportType_RECURSIVE,
5: ReportType_REVOKED,
}
var mapReportTypeString = map[string]ReportType{
"UNKNOWN": ReportType_UNKNOWN,
"CONFIRMED_TEST": ReportType_CONFIRMED_TEST,
"CONFIRMED_CLINICAL_DIAGNOSIS": ReportType_CONFIRMED_CLINICAL_DIAGNOSIS,
"SELF_REPORT": ReportType_SELF_REPORT,
"RECURSIVE": ReportType_RECURSIVE,
"REVOKED": ReportType_REVOKED,
}
//UnmarshalJSON Accepts ReportType in both integer and string form.
func (s *ReportType) UnmarshalJSON(data []byte) error {
str := strings.TrimLeft(strings.TrimRight(string(data), "\""), "\"")
number, err := strconv.Atoi(str)
if err == nil {
*s = mapReportTypeInt[number]
} else {
*s = mapReportTypeString[str]
}
return nil
}
//UploadBatchResponse Response for upload batch call to EFGS
type UploadBatchResponse struct {
StatusCode int `json:"code,omitempty"`
Error []int `json:"500"`
Duplicate []int `json:"409"`
Success []int `json:"201"`
}
//BatchDownloadParams Struct holding download input data.
type BatchDownloadParams struct {
Date string `json:"date" validate:"required"`
BatchTag string `json:"batchTag"`
}
//BatchImportParams Struct for transferring downloaded keys
type BatchImportParams struct {
HAID string `json:"haid"`
Keys ExpKeyBatch `json:"keys"`
}
//DiagnosisKeyWrapper map json response from EFGS to local DiagnosisKey structure
type DiagnosisKeyWrapper struct {
tableName struct{} `pg:"diagnosis_keys,alias:dk"`
ID int32 `pg:",pk" json:"id"`
CreatedAt time.Time `pg:"default:now()" json:"created_at"`
KeyData string `pg:",notnull,unique" json:"keyData,omitempty"`
RollingStartIntervalNumber uint32 `pg:",use_zero" json:"rollingStartIntervalNumber,omitempty"`
RollingPeriod uint32 `pg:",use_zero" json:"rollingPeriod,omitempty"`
TransmissionRiskLevel int32 `pg:",use_zero" json:"transmissionRiskLevel,omitempty"`
VisitedCountries []string `json:"visitedCountries,omitempty"`
Origin string `pg:"default:'CZ'" json:"origin,omitempty"`
ReportType ReportType `pg:",use_zero" json:"reportType,omitempty"`
DaysSinceOnsetOfSymptoms int32 `pg:",use_zero" json:"days_since_onset_of_symptoms,omitempty"`
Retries int `pg:"default:0,use_zero" json:"retries,omitempty"`
IsUploaded bool `pg:"default:False,notnull,use_zero" json:"isUploaded,omitempty"`
}
//ToData convert struct from DiagnosisKeyWrapper to DiagnosisKey.
func (wrappedKey *DiagnosisKeyWrapper) ToData() *DiagnosisKey {
var ctx = context.Background()
logger := logging.FromContext(ctx).Named("DiagnosisKeyWrapper.ToData")
rt := wrappedKey.TransmissionRiskLevel
if rt > 8 || rt < 0 {
// This is a sad story of how EFGS has put this into their protocol and then recommended to not use it because the value meaning can
// be different across different countries. Because it cannot be unused in fact, the final recommendation is to put max value possible
// there. That works for others but, because we put those keys into the Key server, not for us - the Key server doesn't like it so we
// have to adjust the value to basically anything consumable. The value itself is not used at all for anything and even though it's
// said to be optional in comments, the Key server requires it and fails when the value is not there or is invalid.
// Sad story.
//
rt = 0 // This is an override for putting 0x7fffffff there
}
byteKeyData, err := base64.StdEncoding.DecodeString(wrappedKey.KeyData)
if err != nil {
logger.Errorf("Invalid keyData in DiagnosisKeyWrapper: %s", wrappedKey.KeyData)
panic(err)
}
return &DiagnosisKey{
KeyData: byteKeyData,
RollingStartIntervalNumber: wrappedKey.RollingStartIntervalNumber,
RollingPeriod: wrappedKey.RollingPeriod,
TransmissionRiskLevel: rt,
Origin: wrappedKey.Origin,
DaysSinceOnsetOfSymptoms: wrappedKey.DaysSinceOnsetOfSymptoms,
VisitedCountries: wrappedKey.VisitedCountries,
ReportType: wrappedKey.ReportType,
}
}
//ToExposureKey convert struct from DiagnosisKeyWrapper to DiagnosisKey
func (key *DiagnosisKey) ToExposureKey() keyserverapi.ExposureKey {
rt := key.TransmissionRiskLevel
if rt > 8 || rt < 0 {
// This is a sad story of how EFGS has put this into their protocol and then recommended to not use it because the value meaning can
// be different across different countries. Because it cannot be unused in fact, the final recommendation is to put max value possible
// there. That works for others but, because we put those keys into the Key server, not for us - the Key server doesn't like it so we
// have to adjust the value to basically anything consumable. The value itself is not used at all for anything and even though it's
// said to be optional in comments, the Key server requires it and fails when the value is not there or is invalid.
// Sad story.
//
rt = 0 // This is an override for putting 0x7fffffff there
}
return keyserverapi.ExposureKey{
Key: base64.StdEncoding.EncodeToString(key.KeyData),
IntervalNumber: int32(key.RollingStartIntervalNumber),
IntervalCount: int32(key.RollingPeriod),
TransmissionRisk: int(rt),
}
}
//ToWrapper convert struct from DiagnosisKey to DiagnosisKeyWrapper
func (key *DiagnosisKey) ToWrapper() *DiagnosisKeyWrapper {
return &DiagnosisKeyWrapper{
KeyData: base64.StdEncoding.EncodeToString(key.KeyData),
RollingStartIntervalNumber: key.RollingStartIntervalNumber,
RollingPeriod: key.RollingPeriod,
TransmissionRiskLevel: key.TransmissionRiskLevel,
VisitedCountries: key.VisitedCountries,
Origin: key.Origin,
ReportType: key.ReportType,
DaysSinceOnsetOfSymptoms: key.DaysSinceOnsetOfSymptoms,
}
}