feat: replace registration.Resource

This commit is contained in:
Fernandez Ludovic 2026-02-26 17:05:39 +01:00
commit bbc6a174d9
21 changed files with 130 additions and 120 deletions

View file

@ -86,7 +86,7 @@ type ExtendedAccount struct {
Account
// Contains the value of the response header `Location`
Location string `json:"-"`
Location string `json:"accountURL,omitempty"`
}
// Account the ACME account Object.

View file

@ -100,9 +100,9 @@ func readAccounts(cmd *cli.Command) ([]ListAccount, error) {
var server string
uri, err := url.Parse(account.Registration.URI)
uri, err := url.Parse(account.Registration.Location)
if err != nil {
log.Error("Parsing account registration URI.", log.ErrorAttr(err))
log.Error("Parsing account registration Location.", log.ErrorAttr(err))
} else {
server = fmt.Sprintf("%s://%s", uri.Scheme, uri.Host)
}

View file

@ -8,6 +8,7 @@ import (
"os"
"strings"
"github.com/go-acme/lego/v5/acme"
"github.com/go-acme/lego/v5/certcrypto"
"github.com/go-acme/lego/v5/cmd/internal/storage"
"github.com/go-acme/lego/v5/lego"
@ -77,7 +78,7 @@ func register(ctx context.Context, cmd *cli.Command) error {
return nil
}
func registerAccount(ctx context.Context, cmd *cli.Command, client *lego.Client) (*registration.Resource, error) {
func registerAccount(ctx context.Context, cmd *cli.Command, client *lego.Client) (*acme.ExtendedAccount, error) {
accepted := handleTOS(cmd, client)
if !accepted {
log.Fatal("You did not accept the TOS. Unable to proceed.")

View file

@ -90,7 +90,7 @@ func renew(ctx context.Context, cmd *cli.Command) error {
return nil, fmt.Errorf("new client: %w", err)
}
setupChallenges(cmd, client, account)
setupChallenges(cmd, client, account.GetRegistration())
return client, nil
})

View file

@ -4,13 +4,13 @@ import (
"context"
"fmt"
"github.com/go-acme/lego/v5/acme"
"github.com/go-acme/lego/v5/certcrypto"
"github.com/go-acme/lego/v5/certificate"
"github.com/go-acme/lego/v5/cmd/internal/hook"
"github.com/go-acme/lego/v5/cmd/internal/storage"
"github.com/go-acme/lego/v5/lego"
"github.com/go-acme/lego/v5/log"
"github.com/go-acme/lego/v5/registration"
"github.com/urfave/cli/v3"
)
@ -60,7 +60,7 @@ func run(ctx context.Context, cmd *cli.Command) error {
}
if account.Registration == nil {
var reg *registration.Resource
var reg *acme.ExtendedAccount
reg, err = registerAccount(ctx, cmd, client)
if err != nil {
@ -75,7 +75,7 @@ func run(ctx context.Context, cmd *cli.Command) error {
fmt.Printf(rootPathWarningMessage, accountsStorage.GetRootPath())
}
setupChallenges(cmd, client, account)
setupChallenges(cmd, client, account.GetRegistration())
certRes, err := obtainCertificate(ctx, cmd, client)
if err != nil {

View file

@ -10,12 +10,23 @@ import (
"os"
"path/filepath"
"github.com/go-acme/lego/v5/acme"
"github.com/go-acme/lego/v5/certcrypto"
"github.com/go-acme/lego/v5/cmd/internal/storage"
"github.com/go-acme/lego/v5/log"
"github.com/mattn/go-zglob"
)
type OldAccount struct {
Email string `json:"email"`
Registration *OldResource `json:"registration"`
}
type OldResource struct {
Body acme.Account `json:"body"`
URI string `json:"uri,omitempty"`
}
// Accounts migrates the old accounts directory structure to the new one.
func Accounts(root string) error {
matches, err := zglob.Glob(filepath.Join(root, "**", "account.json"))
@ -31,25 +42,32 @@ func Accounts(root string) error {
return fmt.Errorf("could not read the account file %q: %w", srcAccountFilePath, err)
}
var account storage.Account
var oldAccount OldAccount
err = json.Unmarshal(data, &account)
err = json.Unmarshal(data, &oldAccount)
if err != nil {
return fmt.Errorf("could not parse the account file %q: %w", srcAccountFilePath, err)
}
account.ID = account.GetID()
account := storage.Account{
ID: oldAccount.Email,
Email: oldAccount.Email,
Registration: &acme.ExtendedAccount{
Account: oldAccount.Registration.Body,
Location: oldAccount.Registration.URI,
},
}
accountsDir := filepath.Dir(srcAccountFilePath)
srcKeyPath := filepath.Join(accountsDir, "keys", account.ID+storage.ExtKey)
srcKeyPath := filepath.Join(accountsDir, "keys", account.GetID()+storage.ExtKey)
account.KeyType, err = getKeyType(srcKeyPath)
if err != nil {
return fmt.Errorf("could not guess the account key type: %w", err)
}
newAccountDir := filepath.Join(accountsDir, string(account.KeyType))
newAccountDir := filepath.Join(accountsDir, string(account.GetKeyType()))
err = os.MkdirAll(newAccountDir, 0o700)
if err != nil {
@ -58,7 +76,7 @@ func Accounts(root string) error {
// Rename the private key file.
dstKeyPath := filepath.Join(newAccountDir, account.ID+storage.ExtKey)
dstKeyPath := filepath.Join(newAccountDir, account.GetID()+storage.ExtKey)
err = os.Rename(srcKeyPath, dstKeyPath)
if err != nil {

View file

@ -3,18 +3,18 @@ package storage
import (
"crypto"
"github.com/go-acme/lego/v5/acme"
"github.com/go-acme/lego/v5/certcrypto"
"github.com/go-acme/lego/v5/registration"
)
const AccountIDPlaceholder = "noemail@example.com"
// Account represents a users local saved credentials.
type Account struct {
ID string `json:"id"`
Email string `json:"email"`
KeyType certcrypto.KeyType `json:"keyType"`
Registration *registration.Resource `json:"registration"`
ID string `json:"id"`
Email string `json:"email"`
KeyType certcrypto.KeyType `json:"keyType"`
Registration *acme.ExtendedAccount `json:"registration"`
key crypto.PrivateKey
}
@ -46,7 +46,7 @@ func (a *Account) GetPrivateKey() crypto.PrivateKey {
}
// GetRegistration returns the server registration.
func (a *Account) GetRegistration() *registration.Resource {
func (a *Account) GetRegistration() *acme.ExtendedAccount {
return a.Registration
}

View file

@ -13,10 +13,10 @@ import (
"path/filepath"
"strings"
"github.com/go-acme/lego/v5/acme"
"github.com/go-acme/lego/v5/certcrypto"
"github.com/go-acme/lego/v5/lego"
"github.com/go-acme/lego/v5/log"
"github.com/go-acme/lego/v5/registration"
)
const (
@ -166,7 +166,7 @@ func (s *AccountsStorage) getAccount(ctx context.Context, keyType certcrypto.Key
account.key, err = s.readPrivateKey(keyType, effectiveAccountID)
if err == nil {
if account.Registration != nil && account.Registration.Body.Status != "" {
if account.Registration != nil && account.Registration.Status != "" {
return account, nil
}
@ -293,7 +293,7 @@ func (s *AccountsStorage) getRootUserPath(effectiveAccountID string) string {
}
// tryRecoverRegistration tries to recover the registration from the private key.
func (s *AccountsStorage) tryRecoverRegistration(ctx context.Context, privateKey crypto.PrivateKey) (*registration.Resource, error) {
func (s *AccountsStorage) tryRecoverRegistration(ctx context.Context, privateKey crypto.PrivateKey) (*acme.ExtendedAccount, error) {
// couldn't load account but got a key. Try to look the account up.
config := lego.NewConfig(&Account{key: privateKey})
config.CADirURL = s.server.String()

View file

@ -9,7 +9,6 @@ import (
"github.com/go-acme/lego/v5/acme"
"github.com/go-acme/lego/v5/certcrypto"
"github.com/go-acme/lego/v5/registration"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -46,8 +45,8 @@ func TestAccountsStorage_Save(t *testing.T) {
Email: "account@example.com",
ID: accountID,
KeyType: keyType,
Registration: &registration.Resource{
Body: acme.Account{
Registration: &acme.ExtendedAccount{
Account: acme.Account{
Status: "valid",
Contact: []string{"contact@example.com"},
TermsOfServiceAgreed: true,
@ -55,7 +54,7 @@ func TestAccountsStorage_Save(t *testing.T) {
OnlyReturnExisting: true,
ExternalAccountBinding: []byte(`"EAB"`),
},
URI: "https://ame.example.com",
Location: "https://ame.example.com",
},
key: crypto.PrivateKey(""),
}
@ -116,11 +115,11 @@ func TestAccountsStorage_Get_existingAccount(t *testing.T) {
assert.Equal(t, "test@example.com", account.GetID())
assert.Equal(t, certcrypto.RSA4096, account.KeyType)
expectedRegistration := &registration.Resource{
Body: acme.Account{
expectedRegistration := &acme.ExtendedAccount{
Account: acme.Account{
Status: "valid",
},
URI: "https://example.org/acme/acct/123456",
Location: "https://example.org/acme/acct/123456",
}
assert.Equal(t, expectedRegistration, account.GetRegistration())

View file

@ -3,16 +3,14 @@
"email": "account@example.com",
"keyType": "RSA4096",
"registration": {
"body": {
"status": "valid",
"contact": [
"contact@example.com"
],
"termsOfServiceAgreed": true,
"orders": "https://ame.example.com/orders/123456",
"onlyReturnExisting": true,
"externalAccountBinding": "EAB"
},
"uri": "https://ame.example.com"
"status": "valid",
"contact": [
"contact@example.com"
],
"termsOfServiceAgreed": true,
"orders": "https://ame.example.com/orders/123456",
"onlyReturnExisting": true,
"externalAccountBinding": "EAB",
"accountURL": "https://ame.example.com"
}
}

View file

@ -3,9 +3,7 @@
"email": "account@example.com",
"keyType": "RSA4096",
"registration": {
"body": {
"status": "valid"
},
"uri": "https://example.org/acme/acct/123456"
"status": "valid",
"accountURL": "https://example.org/acme/acct/123456"
}
}

View file

@ -1,13 +1,13 @@
package cmd
import (
"errors"
"fmt"
"log/slog"
"net"
"strings"
"time"
"github.com/go-acme/lego/v5/acme"
"github.com/go-acme/lego/v5/challenge"
"github.com/go-acme/lego/v5/challenge/dns01"
"github.com/go-acme/lego/v5/challenge/dnspersist01"
@ -19,12 +19,11 @@ import (
"github.com/go-acme/lego/v5/providers/http/memcached"
"github.com/go-acme/lego/v5/providers/http/s3"
"github.com/go-acme/lego/v5/providers/http/webroot"
"github.com/go-acme/lego/v5/registration"
"github.com/urfave/cli/v3"
)
//nolint:gocyclo // challenge setup dispatch is expected to branch by enabled challenge type.
func setupChallenges(cmd *cli.Command, client *lego.Client, account registration.User) {
func setupChallenges(cmd *cli.Command, client *lego.Client, account *acme.ExtendedAccount) {
if !cmd.Bool(flgHTTP) && !cmd.Bool(flgTLS) && !cmd.IsSet(flgDNS) && !cmd.Bool(flgDNSPersist) {
log.Fatal(fmt.Sprintf("No challenge selected. You must specify at least one challenge: `--%s`, `--%s`, `--%s`, `--%s`.",
flgHTTP, flgTLS, flgDNS, flgDNSPersist))
@ -213,11 +212,7 @@ func setupDNS(cmd *cli.Command, client *lego.Client) error {
return err
}
func setupDNSPersist(cmd *cli.Command, client *lego.Client, account registration.User) error {
if account == nil || account.GetRegistration() == nil || account.GetRegistration().URI == "" {
return errors.New("dns-persist-01 requires a registered account with an account URI")
}
func setupDNSPersist(cmd *cli.Command, client *lego.Client, account *acme.ExtendedAccount) error {
err := validatePropagationExclusiveOptions(cmd, flgDNSPersistPropagationWait, flgDNSPersistPropagationDisableANS, flgDNSPersistIssuerDomainName)
if err != nil {
return err
@ -236,7 +231,7 @@ func setupDNSPersist(cmd *cli.Command, client *lego.Client, account registration
shouldWait := cmd.IsSet(flgDNSPersistPropagationWait)
return client.Challenge.SetDNSPersist01(
dnspersist01.WithAccountURI(account.GetRegistration().URI),
dnspersist01.WithAccountURI(account.Location),
dnspersist01.WithIssuerDomainName(cmd.String(flgDNSPersistIssuerDomainName)),
dnspersist01.CondOptions(cmd.IsSet(flgDNSPersistPersistUntil),
dnspersist01.WithPersistUntil(cmd.Timestamp(flgDNSPersistPersistUntil)),

View file

@ -13,6 +13,7 @@ import (
"testing"
"time"
"github.com/go-acme/lego/v5/acme"
"github.com/go-acme/lego/v5/certcrypto"
"github.com/go-acme/lego/v5/certificate"
"github.com/go-acme/lego/v5/challenge/http01"
@ -420,9 +421,9 @@ func TestChallengeHTTP_Client_Registration_QueryRegistration(t *testing.T) {
require.NotNil(t, resource)
assert.Equal(t, "valid", resource.Body.Status)
assert.Regexp(t, `https://localhost:14000/list-orderz/[\w\d]+`, resource.Body.Orders)
assert.Regexp(t, `https://localhost:14000/my-account/[\w\d]+`, resource.URI)
assert.Equal(t, "valid", resource.Status)
assert.Regexp(t, `https://localhost:14000/list-orderz/[\w\d]+`, resource.Orders)
assert.Regexp(t, `https://localhost:14000/my-account/[\w\d]+`, resource.Location)
}
func TestChallengeTLS_Client_Obtain(t *testing.T) {
@ -588,25 +589,25 @@ func TestRegistrar_UpdateAccount(t *testing.T) {
regOptions := registration.RegisterOptions{TermsOfServiceAgreed: true}
reg, err := client.Registration.Register(ctx, regOptions)
require.NoError(t, err)
require.Equal(t, []string{"mailto:" + testEmail1}, reg.Body.Contact)
require.Equal(t, []string{"mailto:" + testEmail1}, reg.Contact)
user.registration = reg
user.email = testEmail2
resource, err := client.Registration.UpdateRegistration(ctx, regOptions)
require.NoError(t, err)
require.Equal(t, []string{"mailto:" + testEmail2}, resource.Body.Contact)
require.Equal(t, reg.URI, resource.URI)
require.Equal(t, []string{"mailto:" + testEmail2}, resource.Contact)
require.Equal(t, reg.Location, resource.Location)
}
type fakeUser struct {
email string
privateKey crypto.PrivateKey
registration *registration.Resource
registration *acme.ExtendedAccount
}
func (f *fakeUser) GetEmail() string { return f.email }
func (f *fakeUser) GetRegistration() *registration.Resource { return f.registration }
func (f *fakeUser) GetPrivateKey() crypto.PrivateKey { return f.privateKey }
func (f *fakeUser) GetEmail() string { return f.email }
func (f *fakeUser) GetRegistration() *acme.ExtendedAccount { return f.registration }
func (f *fakeUser) GetPrivateKey() crypto.PrivateKey { return f.privateKey }
func createTestCSRFile(t *testing.T, raw bool) string {
t.Helper()

View file

@ -9,6 +9,7 @@ import (
"os"
"testing"
"github.com/go-acme/lego/v5/acme"
"github.com/go-acme/lego/v5/certificate"
"github.com/go-acme/lego/v5/challenge/dns01"
"github.com/go-acme/lego/v5/e2e/loader"
@ -193,12 +194,12 @@ func TestChallengeDNS_Client_Obtain_profile(t *testing.T) {
type fakeUser struct {
email string
privateKey crypto.PrivateKey
registration *registration.Resource
registration *acme.ExtendedAccount
}
func (f *fakeUser) GetEmail() string { return f.email }
func (f *fakeUser) GetRegistration() *registration.Resource { return f.registration }
func (f *fakeUser) GetPrivateKey() crypto.PrivateKey { return f.privateKey }
func (f *fakeUser) GetEmail() string { return f.email }
func (f *fakeUser) GetRegistration() *acme.ExtendedAccount { return f.registration }
func (f *fakeUser) GetPrivateKey() crypto.PrivateKey { return f.privateKey }
func mockDefault(t *testing.T) {
t.Helper()

View file

@ -55,16 +55,16 @@ func TestChallengeDNSPersist_Client_Obtain(t *testing.T) {
reg, err := client.Registration.Register(context.Background(), registration.RegisterOptions{TermsOfServiceAgreed: true})
require.NoError(t, err)
require.NotEmpty(t, reg.URI)
require.NotEmpty(t, reg.Location)
user.registration = reg
updateDNS(t, reg.URI, testPersistBaseDomain)
updateDNS(t, reg.Location, testPersistBaseDomain)
mockDefaultPersist(t)
err = client.Challenge.SetDNSPersist01(
dnspersist01.WithAccountURI(reg.URI),
dnspersist01.WithAccountURI(reg.Location),
dnspersist01.DisableAuthoritativeNssPropagationRequirement(),
)
require.NoError(t, err)
@ -246,7 +246,7 @@ func createCLIAccountState(t *testing.T, email string) string {
reg, err := client.Registration.Register(context.Background(), registration.RegisterOptions{TermsOfServiceAgreed: true})
require.NoError(t, err)
require.NotEmpty(t, reg.URI)
require.NotEmpty(t, reg.Location)
keyType := certcrypto.EC256
@ -261,10 +261,10 @@ func createCLIAccountState(t *testing.T, email string) string {
accountPath := filepath.Join(accountPathRoot, "account.json")
content, err := json.MarshalIndent(struct {
ID string `json:"id"`
Email string `json:"email"`
KeyType certcrypto.KeyType `json:"keyType"`
Registration *registration.Resource `json:"registration"`
ID string `json:"id"`
Email string `json:"email"`
KeyType certcrypto.KeyType `json:"keyType"`
Registration *acme.ExtendedAccount `json:"registration"`
}{
ID: email,
Email: email,
@ -276,14 +276,14 @@ func createCLIAccountState(t *testing.T, email string) string {
err = os.WriteFile(accountPath, content, 0o600)
require.NoError(t, err)
return reg.URI
return reg.Location
}
func waitForAccountFile(ctx context.Context, email string) (string, error) {
accountPath := filepath.Join(getAccountPath(email, certcrypto.EC256), "account.json")
type accountFile struct {
Registration *registration.Resource `json:"registration"`
Registration *acme.ExtendedAccount `json:"registration"`
}
return backoff.Retry(ctx,
@ -304,8 +304,8 @@ func waitForAccountFile(ctx context.Context, email string) (string, error) {
return "", err
}
if account.Registration != nil && account.Registration.URI != "" {
return account.Registration.URI, nil
if account.Registration != nil && account.Registration.Location != "" {
return account.Registration.Location, nil
}
return "", errors.New("account URI not found")

View file

@ -42,7 +42,7 @@ func NewClient(config *Config) (*Client, error) {
var kid string
if reg := config.User.GetRegistration(); reg != nil {
kid = reg.URI
kid = reg.Location
}
core, err := api.New(config.HTTPClient, config.UserAgent, config.CADirURL, kid, privateKey)

View file

@ -6,8 +6,8 @@ import (
"crypto/rsa"
"testing"
"github.com/go-acme/lego/v5/acme"
"github.com/go-acme/lego/v5/internal/tester"
"github.com/go-acme/lego/v5/registration"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -20,7 +20,7 @@ func TestNewClient(t *testing.T) {
user := mockUser{
email: "test@test.com",
regres: new(registration.Resource),
regres: new(acme.ExtendedAccount),
privatekey: key,
}
@ -36,10 +36,10 @@ func TestNewClient(t *testing.T) {
type mockUser struct {
email string
regres *registration.Resource
regres *acme.ExtendedAccount
privatekey *rsa.PrivateKey
}
func (u mockUser) GetEmail() string { return u.email }
func (u mockUser) GetRegistration() *registration.Resource { return u.regres }
func (u mockUser) GetPrivateKey() crypto.PrivateKey { return u.privatekey }
func (u mockUser) GetEmail() string { return u.email }
func (u mockUser) GetRegistration() *acme.ExtendedAccount { return u.regres }
func (u mockUser) GetPrivateKey() crypto.PrivateKey { return u.privatekey }

View file

@ -16,14 +16,6 @@ import (
const mailTo = "mailto:"
// 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"`
URI string `json:"uri,omitempty"`
}
type RegisterOptions struct {
TermsOfServiceAgreed bool
}
@ -47,7 +39,7 @@ func NewRegistrar(core *api.Core, user User) *Registrar {
}
// Register the current account to the ACME server.
func (r *Registrar) Register(ctx context.Context, options RegisterOptions) (*Resource, error) {
func (r *Registrar) Register(ctx context.Context, options RegisterOptions) (*acme.ExtendedAccount, error) {
if r == nil || r.user == nil {
return nil, errors.New("acme: cannot register a nil client or user")
}
@ -59,6 +51,7 @@ func (r *Registrar) Register(ctx context.Context, options RegisterOptions) (*Res
if r.user.GetEmail() != "" {
log.Info("acme: Registering the account.", slog.String("email", r.user.GetEmail()))
accMsg.Contact = []string{mailTo + r.user.GetEmail()}
}
@ -71,11 +64,11 @@ func (r *Registrar) Register(ctx context.Context, options RegisterOptions) (*Res
}
}
return &Resource{URI: account.Location, Body: account.Account}, nil
return &account, nil
}
// RegisterWithExternalAccountBinding Register the current account to the ACME server.
func (r *Registrar) RegisterWithExternalAccountBinding(ctx context.Context, options RegisterEABOptions) (*Resource, error) {
func (r *Registrar) RegisterWithExternalAccountBinding(ctx context.Context, options RegisterEABOptions) (*acme.ExtendedAccount, error) {
accMsg := acme.Account{
TermsOfServiceAgreed: options.TermsOfServiceAgreed,
Contact: []string{},
@ -83,6 +76,7 @@ func (r *Registrar) RegisterWithExternalAccountBinding(ctx context.Context, opti
if r.user.GetEmail() != "" {
log.Info("acme: Registering the account.", slog.String("email", r.user.GetEmail()))
accMsg.Contact = []string{mailTo + r.user.GetEmail()}
}
@ -95,35 +89,36 @@ func (r *Registrar) RegisterWithExternalAccountBinding(ctx context.Context, opti
}
}
return &Resource{URI: account.Location, Body: account.Account}, nil
return &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(ctx context.Context) (*Resource, error) {
func (r *Registrar) QueryRegistration(ctx context.Context) (*acme.ExtendedAccount, 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.Info("acme: Querying the account.", slog.String("registrationURI", r.user.GetRegistration().URI))
log.Info("acme: Querying the account.", slog.String("registrationURI", r.user.GetRegistration().Location))
account, err := r.core.Accounts.Get(ctx, r.user.GetRegistration().URI)
account, err := r.core.Accounts.Get(ctx, r.user.GetRegistration().Location)
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,
return &acme.ExtendedAccount{
Account: account,
// Location: header is not returned, so this needs to be populated off of the existing URI
Location: r.user.GetRegistration().Location,
}, nil
}
// UpdateRegistration update the user registration on the ACME server.
func (r *Registrar) UpdateRegistration(ctx context.Context, options RegisterOptions) (*Resource, error) {
func (r *Registrar) UpdateRegistration(ctx context.Context, options RegisterOptions) (*acme.ExtendedAccount, error) {
if r == nil || r.user == nil {
return nil, errors.New("acme: cannot update a nil client or user")
}
@ -138,14 +133,14 @@ func (r *Registrar) UpdateRegistration(ctx context.Context, options RegisterOpti
accMsg.Contact = []string{mailTo + r.user.GetEmail()}
}
accountURL := r.user.GetRegistration().URI
accountURL := r.user.GetRegistration().Location
account, err := r.core.Accounts.Update(ctx, accountURL, accMsg)
if err != nil {
return nil, err
}
return &Resource{URI: accountURL, Body: account}, nil
return &acme.ExtendedAccount{Account: account, Location: accountURL}, nil
}
// DeleteRegistration deletes the client's user registration from the ACME server.
@ -156,12 +151,12 @@ func (r *Registrar) DeleteRegistration(ctx context.Context) error {
log.Info("acme: Deleting the account.", slog.String("email", r.user.GetEmail()))
return r.core.Accounts.Deactivate(ctx, r.user.GetRegistration().URI)
return r.core.Accounts.Deactivate(ctx, r.user.GetRegistration().Location)
}
// ResolveAccountByKey will attempt to look up an account using the given account key
// and return its registration resource.
func (r *Registrar) ResolveAccountByKey(ctx context.Context) (*Resource, error) {
func (r *Registrar) ResolveAccountByKey(ctx context.Context) (*acme.ExtendedAccount, error) {
log.Info("acme: Trying to resolve the account by key")
accMsg := acme.Account{OnlyReturnExisting: true}
@ -171,12 +166,12 @@ func (r *Registrar) ResolveAccountByKey(ctx context.Context) (*Resource, error)
return nil, err
}
return &Resource{URI: account.Location, Body: account.Account}, nil
return &account, nil
}
// RegisterWithZeroSSL registers the current account to the ZeroSSL.
// It uses either an access key or an email to generate an EAB.
func RegisterWithZeroSSL(ctx context.Context, r *Registrar, email string) (*Resource, error) {
func RegisterWithZeroSSL(ctx context.Context, r *Registrar, email string) (*acme.ExtendedAccount, error) {
zc := zerossl.NewClient()
value, find := os.LookupEnv(zerossl.EnvZeroSSLAccessKey)

View file

@ -31,7 +31,7 @@ func TestRegistrar_ResolveAccountByKey(t *testing.T) {
user := mockUser{
email: "test@test.com",
regres: &Resource{},
regres: &acme.ExtendedAccount{},
privatekey: key,
}
@ -43,5 +43,5 @@ func TestRegistrar_ResolveAccountByKey(t *testing.T) {
res, err := registrar.ResolveAccountByKey(t.Context())
require.NoError(t, err, "Unexpected error resolving account by key")
assert.Equal(t, "valid", res.Body.Status, "Unexpected account status")
assert.Equal(t, "valid", res.Status, "Unexpected account status")
}

View file

@ -2,12 +2,14 @@ package registration
import (
"crypto"
"github.com/go-acme/lego/v5/acme"
)
// User interface is to be implemented by users of this library.
// It is used by the client type to get user specific information.
type User interface {
GetEmail() string
GetRegistration() *Resource
GetRegistration() *acme.ExtendedAccount
GetPrivateKey() crypto.PrivateKey
}

View file

@ -3,14 +3,16 @@ package registration
import (
"crypto"
"crypto/rsa"
"github.com/go-acme/lego/v5/acme"
)
type mockUser struct {
email string
regres *Resource
regres *acme.ExtendedAccount
privatekey *rsa.PrivateKey
}
func (u mockUser) GetEmail() string { return u.email }
func (u mockUser) GetRegistration() *Resource { return u.regres }
func (u mockUser) GetPrivateKey() crypto.PrivateKey { return u.privatekey }
func (u mockUser) GetEmail() string { return u.email }
func (u mockUser) GetRegistration() *acme.ExtendedAccount { return u.regres }
func (u mockUser) GetPrivateKey() crypto.PrivateKey { return u.privatekey }