/
builder.go
159 lines (137 loc) · 4.05 KB
/
builder.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
package did
import (
"reflect"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/TBD54566975/ssi-sdk/util"
)
// DIDDocumentBuilder contexts and types are kept to avoid having cast to/from any values
type DIDDocumentBuilder struct {
contexts []string
types []string
*Document
}
const (
DIDDocumentLDContext string = "https://w3id.org/did/v1"
DIDDocumentType string = "Document"
BuilderEmptyError string = "builder cannot be empty"
)
// NewDIDDocumentBuilder Creates a new DID Document Builder
func NewDIDDocumentBuilder() DIDDocumentBuilder {
contexts := []string{DIDDocumentLDContext}
types := []string{DIDDocumentType}
return DIDDocumentBuilder{
contexts: contexts,
types: types,
Document: &Document{
ID: uuid.NewString(),
Context: contexts,
},
}
}
// Build builds the DID Document
func (builder *DIDDocumentBuilder) Build() (*Document, error) {
if builder.IsEmpty() {
return nil, errors.New(BuilderEmptyError)
}
if err := builder.Document.IsValid(); err != nil {
return nil, errors.Wrap(err, "did doc not valid")
}
return builder.Document, nil
}
func (builder *DIDDocumentBuilder) IsEmpty() bool {
if builder == nil || builder.Document == nil {
return true
}
return reflect.DeepEqual(builder, &DIDDocumentBuilder{})
}
func (builder *DIDDocumentBuilder) AddContext(context any) error {
if builder.IsEmpty() {
return errors.New(BuilderEmptyError)
}
res, err := util.InterfaceToStrings(context)
if err != nil {
return errors.Wrap(err, "malformed context")
}
uniqueContexts := util.MergeUniqueValues(builder.contexts, res)
builder.contexts = uniqueContexts
builder.Context = uniqueContexts
return nil
}
func (builder *DIDDocumentBuilder) SetID(id string) error {
if builder.IsEmpty() {
return errors.New(BuilderEmptyError)
}
builder.ID = id
return nil
}
func (builder *DIDDocumentBuilder) SetAlsoKnownAs(name string) error {
if builder.IsEmpty() {
return errors.New(BuilderEmptyError)
}
builder.AlsoKnownAs = name
return nil
}
func (builder *DIDDocumentBuilder) SetController(controller string) error {
if builder.IsEmpty() {
return errors.New(BuilderEmptyError)
}
builder.Controller = controller
return nil
}
// AddVerificationMethod Note: Not thread safe
func (builder *DIDDocumentBuilder) AddVerificationMethod(m VerificationMethod) error {
if builder.IsEmpty() {
return errors.New(BuilderEmptyError)
}
builder.VerificationMethod = append(builder.VerificationMethod, m)
return nil
}
// AddAuthenticationMethod Note: Not thread safe
func (builder *DIDDocumentBuilder) AddAuthenticationMethod(m VerificationMethodSet) error {
if builder.IsEmpty() {
return errors.New(BuilderEmptyError)
}
builder.Authentication = append(builder.Authentication, m)
return nil
}
// AddAssertionMethod Note: Not thread safe
func (builder *DIDDocumentBuilder) AddAssertionMethod(m VerificationMethodSet) error {
if builder.IsEmpty() {
return errors.New(BuilderEmptyError)
}
builder.AssertionMethod = append(builder.AssertionMethod, m)
return nil
}
// AddKeyAgreement Note: Not thread safe
func (builder *DIDDocumentBuilder) AddKeyAgreement(m VerificationMethodSet) error {
if builder.IsEmpty() {
return errors.New(BuilderEmptyError)
}
builder.KeyAgreement = append(builder.KeyAgreement, m)
return nil
}
// AddCapabilityInvocation Note: Not thread safe
func (builder *DIDDocumentBuilder) AddCapabilityInvocation(m VerificationMethodSet) error {
if builder.IsEmpty() {
return errors.New(BuilderEmptyError)
}
builder.CapabilityInvocation = append(builder.CapabilityInvocation, m)
return nil
}
// AddCapabilityDelegation Note: Not thread safe
func (builder *DIDDocumentBuilder) AddCapabilityDelegation(m VerificationMethodSet) error {
if builder.IsEmpty() {
return errors.New(BuilderEmptyError)
}
builder.CapabilityDelegation = append(builder.CapabilityDelegation, m)
return nil
}
// AddService Note: Not thread safe
func (builder *DIDDocumentBuilder) AddService(s Service) error {
if builder.IsEmpty() {
return errors.New(BuilderEmptyError)
}
builder.Services = append(builder.Services, s)
return nil
}