forked from globalsign/hvclient
-
Notifications
You must be signed in to change notification settings - Fork 0
/
claims.go
330 lines (276 loc) · 8.41 KB
/
claims.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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
/*
Copyright (c) 2019-2021 GMO GlobalSign Pte. Ltd.
Licensed under the MIT License (the "License"); you may not use this file except
in compliance with the License. You may obtain a copy of the License at
https://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package hvclient
import (
"encoding/json"
"fmt"
"strings"
"time"
)
// ClaimStatus is the pending/verified status of a domain claim.
type ClaimStatus int
// ClaimLogEntry is a domain claim verification log entry.
type ClaimLogEntry struct {
Status ClaimLogEntryStatus
Description string
TimeStamp time.Time
}
// jsonClaimLogEntry is used internally for JSON marshalling/unmarshalling.
type jsonClaimLogEntry struct {
Status ClaimLogEntryStatus `json:"status"`
Description string `json:"description"`
TimeStamp int64 `json:"timestamp"`
}
// ClaimLogEntryStatus is the success/error status of a domain claim
// verification log entry.
type ClaimLogEntryStatus int
// Claim is a domain claim.
type Claim struct {
ID string
Status ClaimStatus
Domain string
CreatedAt time.Time
ExpiresAt time.Time
AssertBy time.Time
Log []ClaimLogEntry
}
// jsonClaim is used internally for JSON marshalling/unmarshalling.
type jsonClaim struct {
ID string `json:"id"`
Status ClaimStatus `json:"status"`
Domain string `json:"domain"`
CreatedAt int64 `json:"created_at"`
ExpiresAt int64 `json:"expires_at"`
AssertBy int64 `json:"assert_by"`
Log []ClaimLogEntry `json:"log"`
}
// ClaimAssertionInfo contains information for making a domain claim.
type ClaimAssertionInfo struct {
Token string
AssertBy time.Time
ID string
}
// jsonClaimAssertionInfo is used internally for JSON marshalling/unmarshalling.
type jsonClaimAssertionInfo struct {
Token string `json:"token"`
AssertBy int64 `json:"assert_by"`
ID string `json:"id"`
}
// Domain claim status constants.
const (
StatusPending ClaimStatus = iota + 1
StatusVerified
)
// Claim log entry status constants.
const (
VerificationSuccess ClaimLogEntryStatus = iota + 1
VerificationError
VerificationInfo
)
// claimStatusNames maps claim status values to their descriptions.
var claimStatusNames = [...]string{
StatusPending: "PENDING",
StatusVerified: "VERIFIED",
}
// claimsStatusCodes maps claim status descriptions to their values.
var claimStatusCodes = map[string]ClaimStatus{
"PENDING": StatusPending,
"VERIFIED": StatusVerified,
}
// claimLogEntryStatusNames maps domain claim verification log entry status
// values to their descriptions.
var claimLogEntryStatusNames = [...]string{
VerificationSuccess: "SUCCESS",
VerificationError: "ERROR",
VerificationInfo: "INFO",
}
// claimLogEntryStatusCodes maps domain claim verification log entry status
// descriptions to their values.
var claimLogEntryStatusCodes = map[string]ClaimLogEntryStatus{
"SUCCESS": VerificationSuccess,
"ERROR": VerificationError,
"INFO": VerificationInfo,
}
// isValid checks if a claims status value is within a valid range.
func (s ClaimStatus) isValid() bool {
return s >= StatusPending && s <= StatusVerified
}
// String returns a description of the claim status.
func (s ClaimStatus) String() string {
if !s.isValid() {
return "ERROR: UNKNOWN STATUS"
}
return claimStatusNames[s]
}
// MarshalJSON returns the JSON encoding of a claim status value.
func (s ClaimStatus) MarshalJSON() ([]byte, error) {
if !s.isValid() {
return nil, fmt.Errorf("invalid claim status value: %d", s)
}
return json.Marshal(s.String())
}
// UnmarshalJSON parses a JSON-encoded claim status value and stores the
// result in the object.
func (s *ClaimStatus) UnmarshalJSON(b []byte) error {
var data string
var err = json.Unmarshal(b, &data)
if err != nil {
return err
}
var result, ok = claimStatusCodes[strings.ToUpper(data)]
if !ok {
return fmt.Errorf("invalid claim status value: %s", data)
}
*s = result
return nil
}
// isValid checks if a claims status value is within a valid range.
func (s ClaimLogEntryStatus) isValid() bool {
return s >= VerificationSuccess && s <= VerificationInfo
}
// String returns a description of the claim status.
func (s ClaimLogEntryStatus) String() string {
if !s.isValid() {
return "ERROR: UNKNOWN STATUS"
}
return claimLogEntryStatusNames[s]
}
// MarshalJSON returns the JSON encoding of a domain claim verification log
// entry status value.
func (s ClaimLogEntryStatus) MarshalJSON() ([]byte, error) {
if !s.isValid() {
return nil, fmt.Errorf("invalid claim log entry status value: %d", s)
}
return json.Marshal(s.String())
}
// UnmarshalJSON parses a JSON-encoded domain claim verification log entry
// status value and stores the result in the object.
func (s *ClaimLogEntryStatus) UnmarshalJSON(b []byte) error {
var data string
var err = json.Unmarshal(b, &data)
if err != nil {
return err
}
var result, ok = claimLogEntryStatusCodes[strings.ToUpper(data)]
if !ok {
return fmt.Errorf("invalid claim log entry status value: %s", data)
}
*s = result
return nil
}
// Equal checks if two domain claims are equivalent.
func (c Claim) Equal(other Claim) bool {
if len(c.Log) != len(other.Log) {
return false
}
for i := range c.Log {
if !c.Log[i].Equal(other.Log[i]) {
return false
}
}
return c.ID == other.ID &&
c.Status == other.Status &&
c.Domain == other.Domain &&
c.CreatedAt.Equal(other.CreatedAt) &&
c.ExpiresAt.Equal(other.ExpiresAt) &&
c.AssertBy.Equal(other.AssertBy)
}
// MarshalJSON returns the JSON encoding of a domain claim and stores the
// result in the object.
func (c Claim) MarshalJSON() ([]byte, error) {
return json.Marshal(jsonClaim{
ID: c.ID,
Status: c.Status,
Domain: c.Domain,
CreatedAt: c.CreatedAt.Unix(),
ExpiresAt: c.ExpiresAt.Unix(),
AssertBy: c.AssertBy.Unix(),
Log: c.Log,
})
}
// UnmarshalJSON parses a JSON-encoded domain claim and stores the result in
// the object.
func (c *Claim) UnmarshalJSON(b []byte) error {
var data jsonClaim
if err := json.Unmarshal(b, &data); err != nil {
return err
}
*c = Claim{
ID: data.ID,
Status: data.Status,
Domain: data.Domain,
CreatedAt: time.Unix(data.CreatedAt, 0).UTC(),
ExpiresAt: time.Unix(data.ExpiresAt, 0).UTC(),
AssertBy: time.Unix(data.AssertBy, 0).UTC(),
Log: data.Log,
}
return nil
}
// Equal checks if two domain claim verification log entries are
// equivalent.
func (l ClaimLogEntry) Equal(other ClaimLogEntry) bool {
return l.Status == other.Status &&
l.Description == other.Description &&
l.TimeStamp.Equal(other.TimeStamp)
}
// MarshalJSON returns the JSON encoding of a domain claim verification log
// entry.
func (l ClaimLogEntry) MarshalJSON() ([]byte, error) {
return json.Marshal(jsonClaimLogEntry{
Status: l.Status,
Description: l.Description,
TimeStamp: l.TimeStamp.Unix(),
})
}
// UnmarshalJSON parses a JSON-encoded domain claim verification log entry
// and stores the result in the object.
func (l *ClaimLogEntry) UnmarshalJSON(b []byte) error {
var data jsonClaimLogEntry
if err := json.Unmarshal(b, &data); err != nil {
return err
}
*l = ClaimLogEntry{
Status: data.Status,
Description: data.Description,
TimeStamp: time.Unix(data.TimeStamp, 0).UTC(),
}
return nil
}
// Equal checks if two domain claim assertion info objects are equivalent.
func (c ClaimAssertionInfo) Equal(other ClaimAssertionInfo) bool {
return c.Token == other.Token &&
c.AssertBy.Equal(other.AssertBy) &&
c.ID == other.ID
}
// MarshalJSON returns the JSON encoding of a domain claim assertion info
// object.
func (c ClaimAssertionInfo) MarshalJSON() ([]byte, error) {
return json.Marshal(jsonClaimAssertionInfo{
Token: c.Token,
AssertBy: c.AssertBy.Unix(),
ID: c.ID,
})
}
// UnmarshalJSON parses a JSON-encoded domain claim assertion info object
// and stores the result in the object.
func (c *ClaimAssertionInfo) UnmarshalJSON(b []byte) error {
var data jsonClaimAssertionInfo
if err := json.Unmarshal(b, &data); err != nil {
return err
}
*c = ClaimAssertionInfo{
Token: data.Token,
AssertBy: time.Unix(data.AssertBy, 0).UTC(),
ID: data.ID,
}
return nil
}