From b1dba4f23d357e1b96ff4a3e8295412b55d5c330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Lapeyre?= Date: Tue, 19 Nov 2019 01:07:46 +0100 Subject: [PATCH] Add support to update account (#1002) --- acme/api/account.go | 14 ++++++++++++++ e2e/challenges_test.go | 31 +++++++++++++++++++++++++++++++ registration/registar.go | 24 ++++++++++++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/acme/api/account.go b/acme/api/account.go index 195e5b5d..7b34ed0d 100644 --- a/acme/api/account.go +++ b/acme/api/account.go @@ -57,6 +57,20 @@ func (a *AccountService) Get(accountURL string) (acme.Account, error) { return account, nil } +// Update Updates an account. +func (a *AccountService) Update(accountURL string, req acme.Account) (acme.ExtendedAccount, error) { + if len(accountURL) == 0 { + return acme.ExtendedAccount{}, errors.New("account[update]: empty URL") + } + + var account acme.ExtendedAccount + _, err := a.core.post(accountURL, req, &account) + if err != nil { + return acme.ExtendedAccount{}, err + } + return account, nil +} + // Deactivate Deactivates an account. func (a *AccountService) Deactivate(accountURL string) error { if len(accountURL) == 0 { diff --git a/e2e/challenges_test.go b/e2e/challenges_test.go index 0cdabcaf..4c169067 100644 --- a/e2e/challenges_test.go +++ b/e2e/challenges_test.go @@ -319,6 +319,37 @@ func TestChallengeTLS_Client_ObtainForCSR(t *testing.T) { assert.NotEmpty(t, resource.CSR) } +func TestRegistrar_UpdateAccount(t *testing.T) { + err := os.Setenv("LEGO_CA_CERTIFICATES", "./fixtures/certs/pebble.minica.pem") + require.NoError(t, err) + defer func() { _ = os.Unsetenv("LEGO_CA_CERTIFICATES") }() + + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) + require.NoError(t, err, "Could not generate test key") + + user := &fakeUser{ + privateKey: privateKey, + email: "foo@example.com", + } + config := lego.NewConfig(user) + config.CADirURL = load.PebbleOptions.HealthCheckURL + + client, err := lego.NewClient(config) + require.NoError(t, err) + + regOptions := registration.RegisterOptions{TermsOfServiceAgreed: true} + reg, err := client.Registration.Register(regOptions) + require.NoError(t, err) + require.Equal(t, reg.Body.Contact, []string{"mailto:foo@example.com"}) + user.registration = reg + + user.email = "bar@example.com" + resource, err := client.Registration.UpdateRegistration(regOptions) + require.NoError(t, err) + require.Equal(t, resource.Body.Contact, []string{"mailto:bar@example.com"}) + require.Empty(t, resource.URI) +} + type fakeUser struct { email string privateKey crypto.PrivateKey diff --git a/registration/registar.go b/registration/registar.go index dbc109ee..77c390ee 100644 --- a/registration/registar.go +++ b/registration/registar.go @@ -115,6 +115,30 @@ func (r *Registrar) QueryRegistration() (*Resource, error) { }, 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()} + } + + account, err := r.core.Accounts.Update(r.user.GetRegistration().URI, accMsg) + if err != nil { + return nil, err + } + + return &Resource{URI: account.Location, Body: account.Account}, nil +} + // DeleteRegistration deletes the client's user registration from the ACME server. func (r *Registrar) DeleteRegistration() error { if r == nil || r.user == nil {