account.go raw
1 package api
2
3 import (
4 "encoding/base64"
5 "errors"
6 "fmt"
7
8 "github.com/go-acme/lego/v4/acme"
9 )
10
11 type AccountService service
12
13 // New Creates a new account.
14 func (a *AccountService) New(req acme.Account) (acme.ExtendedAccount, error) {
15 var account acme.Account
16
17 resp, err := a.core.post(a.core.GetDirectory().NewAccountURL, req, &account)
18 location := getLocation(resp)
19
20 if location != "" {
21 a.core.jws.SetKid(location)
22 }
23
24 if err != nil {
25 return acme.ExtendedAccount{Location: location}, err
26 }
27
28 return acme.ExtendedAccount{Account: account, Location: location}, nil
29 }
30
31 // NewEAB Creates a new account with an External Account Binding.
32 func (a *AccountService) NewEAB(accMsg acme.Account, kid, hmacEncoded string) (acme.ExtendedAccount, error) {
33 hmac, err := decodeEABHmac(hmacEncoded)
34 if err != nil {
35 return acme.ExtendedAccount{}, err
36 }
37
38 eabJWS, err := a.core.signEABContent(a.core.GetDirectory().NewAccountURL, kid, hmac)
39 if err != nil {
40 return acme.ExtendedAccount{}, fmt.Errorf("acme: error signing eab content: %w", err)
41 }
42
43 accMsg.ExternalAccountBinding = eabJWS
44
45 return a.New(accMsg)
46 }
47
48 // Get Retrieves an account.
49 func (a *AccountService) Get(accountURL string) (acme.Account, error) {
50 if accountURL == "" {
51 return acme.Account{}, errors.New("account[get]: empty URL")
52 }
53
54 var account acme.Account
55
56 _, err := a.core.postAsGet(accountURL, &account)
57 if err != nil {
58 return acme.Account{}, err
59 }
60
61 return account, nil
62 }
63
64 // Update Updates an account.
65 func (a *AccountService) Update(accountURL string, req acme.Account) (acme.Account, error) {
66 if accountURL == "" {
67 return acme.Account{}, errors.New("account[update]: empty URL")
68 }
69
70 var account acme.Account
71
72 _, err := a.core.post(accountURL, req, &account)
73 if err != nil {
74 return acme.Account{}, err
75 }
76
77 return account, nil
78 }
79
80 // Deactivate Deactivates an account.
81 func (a *AccountService) Deactivate(accountURL string) error {
82 if accountURL == "" {
83 return errors.New("account[deactivate]: empty URL")
84 }
85
86 req := acme.Account{Status: acme.StatusDeactivated}
87 _, err := a.core.post(accountURL, req, nil)
88
89 return err
90 }
91
92 func decodeEABHmac(hmacEncoded string) ([]byte, error) {
93 hmac, errRaw := base64.RawURLEncoding.DecodeString(hmacEncoded)
94 if errRaw == nil {
95 return hmac, nil
96 }
97
98 hmac, err := base64.URLEncoding.DecodeString(hmacEncoded)
99 if err == nil {
100 return hmac, nil
101 }
102
103 return nil, fmt.Errorf("acme: could not decode hmac key: %w", errors.Join(errRaw, err))
104 }
105