mirror of
https://github.com/go-acme/lego
synced 2026-03-14 14:35:48 +01:00
feat: replace registration.Resource
This commit is contained in:
parent
c8a455c506
commit
bbc6a174d9
21 changed files with 130 additions and 120 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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: ®istration.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 := ®istration.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())
|
||||
|
|
|
|||
20
cmd/internal/storage/testdata/account.json
vendored
20
cmd/internal/storage/testdata/account.json
vendored
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)),
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue