-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocument.go
More file actions
181 lines (156 loc) · 5.74 KB
/
Copy pathdocument.go
File metadata and controls
181 lines (156 loc) · 5.74 KB
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
// Package aeo provides parse, build, and serialization support for
// AEO Protocol v0.1 declaration documents.
//
// Specification: https://github.com/mizcausevic-dev/aeo-protocol-spec
package aeo
import (
"bytes"
"encoding/json"
"fmt"
"os"
)
// ProtocolVersion is the AEO Protocol version this SDK targets.
const ProtocolVersion = "0.1"
// SDKVersion is the version of this SDK module.
const SDKVersion = "0.1.0"
// EntityType enumerates the entity kinds the AEO Protocol defines.
type EntityType string
// Permitted EntityType values.
const (
EntityPerson EntityType = "Person"
EntityOrganization EntityType = "Organization"
EntityProduct EntityType = "Product"
EntityPlace EntityType = "Place"
EntityConcept EntityType = "Concept"
)
// VerificationType enumerates the verification mechanisms an authority block can declare.
type VerificationType string
// Permitted VerificationType values.
const (
VerificationDomain VerificationType = "domain"
VerificationDNS VerificationType = "dns"
VerificationGitHub VerificationType = "github"
VerificationLinkedIn VerificationType = "linkedin"
VerificationGPG VerificationType = "gpg"
VerificationWellKnownURI VerificationType = "well-known-uri"
)
// Confidence enumerates a claim's confidence level.
type Confidence string
// Permitted Confidence values.
const (
ConfidenceHigh Confidence = "high"
ConfidenceMedium Confidence = "medium"
ConfidenceLow Confidence = "low"
)
// AuditMode enumerates the document audit modes.
type AuditMode string
// Permitted AuditMode values.
const (
AuditNone AuditMode = "none"
AuditSignature AuditMode = "signature"
AuditEndpoint AuditMode = "endpoint"
)
// Entity is the subject of an AEO declaration.
type Entity struct {
ID string `json:"id"`
Type EntityType `json:"type"`
Name string `json:"name"`
Aliases []string `json:"aliases,omitempty"`
CanonicalURL string `json:"canonical_url"`
}
// Verification is a proof of ownership or control over an identifier.
type Verification struct {
Type VerificationType `json:"type"`
Value string `json:"value"`
ProofURI string `json:"proof_uri,omitempty"`
}
// Authority captures what the entity considers authoritative about itself.
type Authority struct {
PrimarySources []string `json:"primary_sources"`
EvidenceLinks []string `json:"evidence_links,omitempty"`
Verifications []Verification `json:"verifications,omitempty"`
}
// Claim is a single asserted fact about the entity.
type Claim struct {
ID string `json:"id"`
Predicate string `json:"predicate"`
Value interface{} `json:"value"`
Evidence []string `json:"evidence,omitempty"`
ValidFrom string `json:"valid_from,omitempty"`
ValidUntil *string `json:"valid_until,omitempty"`
Confidence Confidence `json:"confidence,omitempty"`
}
// CitationPreferences expresses how the entity prefers to be cited.
type CitationPreferences struct {
PreferredAttribution string `json:"preferred_attribution,omitempty"`
CanonicalLinks []string `json:"canonical_links,omitempty"`
DoNotCite []string `json:"do_not_cite,omitempty"`
}
// AnswerConstraints expresses soft constraints for answer engines.
type AnswerConstraints struct {
MustInclude []string `json:"must_include,omitempty"`
MustNotInclude []string `json:"must_not_include,omitempty"`
FreshnessWindowDays int `json:"freshness_window_days,omitempty"`
}
// Audit configures the audit surface for the declaration.
type Audit struct {
Mode AuditMode `json:"mode"`
SigningKeyURI string `json:"signing_key_uri,omitempty"`
Signature string `json:"signature,omitempty"`
EndpointURI string `json:"endpoint_uri,omitempty"`
EndpointSchema string `json:"endpoint_schema,omitempty"`
}
// Document is a complete AEO Protocol v0.1 declaration document.
type Document struct {
AEOVersion string `json:"aeo_version"`
Entity Entity `json:"entity"`
Authority Authority `json:"authority"`
Claims []Claim `json:"claims"`
CitationPreferences *CitationPreferences `json:"citation_preferences,omitempty"`
AnswerConstraints *AnswerConstraints `json:"answer_constraints,omitempty"`
Audit *Audit `json:"audit,omitempty"`
}
// ParseDocument parses a byte slice into a Document. It rejects unknown
// top-level fields and unknown fields anywhere in the structure.
func ParseDocument(raw []byte) (*Document, error) {
dec := json.NewDecoder(bytes.NewReader(raw))
dec.DisallowUnknownFields()
var d Document
if err := dec.Decode(&d); err != nil {
return nil, fmt.Errorf("aeo: parse document: %w", err)
}
return &d, nil
}
// ParseDocumentString is a convenience wrapper around ParseDocument.
func ParseDocumentString(raw string) (*Document, error) {
return ParseDocument([]byte(raw))
}
// LoadDocument reads and parses a document from a file path.
func LoadDocument(path string) (*Document, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("aeo: read %s: %w", path, err)
}
return ParseDocument(data)
}
// Marshal serializes the document to pretty-printed JSON.
func (d *Document) Marshal() ([]byte, error) {
return json.MarshalIndent(d, "", " ")
}
// ClaimIDs returns the IDs of all claims in the document.
func (d *Document) ClaimIDs() []string {
ids := make([]string, len(d.Claims))
for i, c := range d.Claims {
ids[i] = c.ID
}
return ids
}
// FindClaim returns a pointer to the claim with the given ID, or nil.
func (d *Document) FindClaim(id string) *Claim {
for i := range d.Claims {
if d.Claims[i].ID == id {
return &d.Claims[i]
}
}
return nil
}