-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaccount.go
131 lines (114 loc) · 2.7 KB
/
account.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
package hatchcert
import (
"crypto"
"log"
"path/filepath"
"github.com/go-acme/lego/v4/lego"
"github.com/go-acme/lego/v4/registration"
)
var (
// LEDirectoryProduction URL to the Let's Encrypt production
LEDirectoryProduction = "https://acme-v02.api.letsencrypt.org/directory"
// LEDirectoryStaging URL to the Let's Encrypt staging
LEDirectoryStaging = "https://acme-staging-v02.api.letsencrypt.org/directory"
)
type SavedAccount struct {
Email string `json:"email"`
Registration *registration.Resource `json:"registration"`
AccountKey string `json:"account_key"`
}
type AccountMeta struct {
Path string
AccountFile string
Key crypto.PrivateKey
SavedAccount
Client *lego.Client
Config *lego.Config
}
func Account(path string) *AccountMeta {
ac := &AccountMeta{
Path: path,
AccountFile: filepath.Join(path, "account"),
}
if exists(ac.AccountFile) {
if err := unmarshal(ac.AccountFile, &ac.SavedAccount); err != nil {
panic(err)
}
k, err := parseKey(ac.SavedAccount.AccountKey)
if err != nil {
panic(err)
}
ac.Key = k
}
return ac
}
func Setup(acct *AccountMeta, acme, email string) error {
if acme == "" {
acme = LEDirectoryProduction
}
store := false
if acct.Key == nil {
pk, pv, err := generatePrivateKey(DefaultKeyType)
if err != nil {
return err
}
store = true
acct.SavedAccount.AccountKey = pv
acct.Key = pk
} else if acct.SavedAccount.Email != email {
// ...
}
acct.SavedAccount.Email = email
o := InterceptOutput()
defer o.Restore()
var err error
acct.Config = lego.NewConfig(acct)
acct.Config.CADirURL = acme
acct.Config.UserAgent = "hatchcert+lego/0.2"
acct.Client, err = lego.NewClient(acct.Config)
if err != nil {
o.Emit()
panic(err)
}
if acct.Registration == nil {
reg, err := acct.Client.Registration.ResolveAccountByKey()
if err != nil {
// If the error is something like
// `urn:ietf:params:acme:error:accountDoesNotExist` we want to
// just register a new account
log.Printf("%T: %v", err, err)
} else {
acct.Registration = reg
store = true
}
}
if acct.Registration == nil {
reg, err := acct.Client.Registration.Register(registration.RegisterOptions{
TermsOfServiceAgreed: true,
})
if err != nil {
o.Emit()
return err
}
acct.Registration = reg
store = true
}
if store {
if err := marshal(acct.AccountFile, acct.SavedAccount); err != nil {
return err
}
}
return nil
}
//
// Lego integration
//
func (am *AccountMeta) GetRegistration() *registration.Resource {
return am.Registration
}
func (am *AccountMeta) GetEmail() string {
return am.Email
}
func (am *AccountMeta) GetPrivateKey() crypto.PrivateKey {
return am.Key
}