forked from go-acme/lego
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathregistar.go
167 lines (135 loc) · 4.78 KB
/
registar.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
package registration
import (
"errors"
"net/http"
"github.com/go-acme/lego/v4/acme"
"github.com/go-acme/lego/v4/acme/api"
"github.com/go-acme/lego/v4/log"
)
// Resource represents all important information about a registration
// of which the client needs to keep track itself.
// WARNING: will be removed in the future (acme.ExtendedAccount), https://github.com/go-acme/lego/issues/855.
type Resource struct {
Body acme.Account `json:"body,omitempty"`
URI string `json:"uri,omitempty"`
}
type RegisterOptions struct {
TermsOfServiceAgreed bool
}
type RegisterEABOptions struct {
TermsOfServiceAgreed bool
Kid string
HmacEncoded string
}
type Registrar struct {
core *api.Core
user User
}
func NewRegistrar(core *api.Core, user User) *Registrar {
return &Registrar{
core: core,
user: user,
}
}
// Register the current account to the ACME server.
func (r *Registrar) Register(options RegisterOptions) (*Resource, error) {
if r == nil || r.user == nil {
return nil, errors.New("acme: cannot register a nil client or user")
}
accMsg := acme.Account{
TermsOfServiceAgreed: options.TermsOfServiceAgreed,
Contact: []string{},
}
if r.user.GetEmail() != "" {
log.Infof("acme: Registering account for %s", r.user.GetEmail())
accMsg.Contact = []string{"mailto:" + r.user.GetEmail()}
}
account, err := r.core.Accounts.New(accMsg)
if err != nil {
// seems impossible
var errorDetails acme.ProblemDetails
if !errors.As(err, &errorDetails) || errorDetails.HTTPStatus != http.StatusConflict {
return nil, err
}
}
return &Resource{URI: account.Location, Body: account.Account}, nil
}
// RegisterWithExternalAccountBinding Register the current account to the ACME server.
func (r *Registrar) RegisterWithExternalAccountBinding(options RegisterEABOptions) (*Resource, error) {
accMsg := acme.Account{
TermsOfServiceAgreed: options.TermsOfServiceAgreed,
Contact: []string{},
}
if r.user.GetEmail() != "" {
log.Infof("acme: Registering account for %s", r.user.GetEmail())
accMsg.Contact = []string{"mailto:" + r.user.GetEmail()}
}
account, err := r.core.Accounts.NewEAB(accMsg, options.Kid, options.HmacEncoded)
if err != nil {
// seems impossible
var errorDetails acme.ProblemDetails
if !errors.As(err, &errorDetails) || errorDetails.HTTPStatus != http.StatusConflict {
return nil, err
}
}
return &Resource{URI: account.Location, Body: account.Account}, nil
}
// QueryRegistration runs a POST request on the client's registration and returns the result.
//
// This is similar to the Register function,
// but acting on an existing registration link and resource.
func (r *Registrar) QueryRegistration() (*Resource, error) {
if r == nil || r.user == nil || r.user.GetRegistration() == nil {
return nil, errors.New("acme: cannot query the registration of a nil client or user")
}
// Log the URL here instead of the email as the email may not be set
log.Infof("acme: Querying account for %s", r.user.GetRegistration().URI)
account, err := r.core.Accounts.Get(r.user.GetRegistration().URI)
if err != nil {
return nil, err
}
return &Resource{
Body: account,
// Location: header is not returned so this needs to be populated off of existing URI
URI: r.user.GetRegistration().URI,
}, nil
}
// UpdateRegistration update the user registration on the ACME server.
func (r *Registrar) UpdateRegistration(options RegisterOptions) (*Resource, error) {
if r == nil || r.user == nil {
return nil, errors.New("acme: cannot update a nil client or user")
}
accMsg := acme.Account{
TermsOfServiceAgreed: options.TermsOfServiceAgreed,
Contact: []string{},
}
if r.user.GetEmail() != "" {
log.Infof("acme: Registering account for %s", r.user.GetEmail())
accMsg.Contact = []string{"mailto:" + r.user.GetEmail()}
}
accountURL := r.user.GetRegistration().URI
account, err := r.core.Accounts.Update(accountURL, accMsg)
if err != nil {
return nil, err
}
return &Resource{URI: accountURL, Body: account}, nil
}
// DeleteRegistration deletes the client's user registration from the ACME server.
func (r *Registrar) DeleteRegistration() error {
if r == nil || r.user == nil {
return errors.New("acme: cannot unregister a nil client or user")
}
log.Infof("acme: Deleting account for %s", r.user.GetEmail())
return r.core.Accounts.Deactivate(r.user.GetRegistration().URI)
}
// ResolveAccountByKey will attempt to look up an account using the given account key
// and return its registration resource.
func (r *Registrar) ResolveAccountByKey() (*Resource, error) {
log.Infof("acme: Trying to resolve account by key")
accMsg := acme.Account{OnlyReturnExisting: true}
account, err := r.core.Accounts.New(accMsg)
if err != nil {
return nil, err
}
return &Resource{URI: account.Location, Body: account.Account}, nil
}