diff --git a/cmd/cmd.go b/cmd/cmd.go index d34e5e3f6..6ccd1c355 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -8,6 +8,7 @@ func CreateCommands() []*cli.Command { createRun(), createRevoke(), createRenew(), + createRegister(), createDNSHelp(), createList(), } diff --git a/cmd/cmd_register.go b/cmd/cmd_register.go index 395c5bbb5..8e64fe4a7 100644 --- a/cmd/cmd_register.go +++ b/cmd/cmd_register.go @@ -8,14 +8,13 @@ import ( "os" "strings" + "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" ) -// TODO(ldez): add register command. - const rootPathWarningMessage = `!!!! HEADS UP !!!! Your account credentials have been saved in your @@ -27,6 +26,55 @@ generated by lego and certificates obtained from the ACME server. Making regular backups of this folder is ideal. ` +func createRegister() *cli.Command { + return &cli.Command{ + Name: "register", + Usage: "Register an account.", + Action: register, + Flags: createRegisterFlags(), + } +} + +func register(ctx context.Context, cmd *cli.Command) error { + keyType, err := getKeyType(cmd.String(flgKeyType)) + if err != nil { + return fmt.Errorf("get the key type: %w", err) + } + + accountsStorage, err := storage.NewAccountsStorage(newAccountsStorageConfig(cmd)) + if err != nil { + return fmt.Errorf("accounts storage initialization: %w", err) + } + + account, err := accountsStorage.Get(ctx, keyType) + if err != nil { + return fmt.Errorf("set up account: %w", err) + } + + if account.Registration == nil { + client, err := newClient(cmd, account, keyType) + if err != nil { + return fmt.Errorf("new client: %w", err) + } + + reg, err := registerAccount(ctx, cmd, client) + if err != nil { + return fmt.Errorf("could not complete registration: %w", err) + } + + account.Registration = reg + if err = accountsStorage.Save(account); err != nil { + return fmt.Errorf("could not save the account file: %w", err) + } + + fmt.Printf(rootPathWarningMessage, accountsStorage.GetRootPath()) + } else { + log.Info("Account already registered, skipping.") + } + + return nil +} + func registerAccount(ctx context.Context, cmd *cli.Command, client *lego.Client) (*registration.Resource, error) { accepted := handleTOS(cmd, client) if !accepted { diff --git a/cmd/flags.go b/cmd/flags.go index 13a081d36..b8fa75ce4 100644 --- a/cmd/flags.go +++ b/cmd/flags.go @@ -512,6 +512,17 @@ func createListFlags() []cli.Flag { } } +func createRegisterFlags() []cli.Flag { + flags := []cli.Flag{ + CreatePathFlag(true), + } + + flags = append(flags, CreateACMEClientFlags()...) + flags = append(flags, CreateAccountFlags()...) + + return flags +} + func CreateDomainFlag() cli.Flag { return &cli.StringSliceFlag{ Name: flgDomains, diff --git a/docs/data/zz_cli_help.toml b/docs/data/zz_cli_help.toml index 629b05d6a..892651bbe 100644 --- a/docs/data/zz_cli_help.toml +++ b/docs/data/zz_cli_help.toml @@ -11,12 +11,13 @@ USAGE: lego [global options] [command [command options]] COMMANDS: - run Register an account, then create and install a certificate - revoke Revoke a certificate - renew Renew a certificate - dnshelp Shows additional help for the '--dns' global option - list Display certificates and accounts information. - help, h Shows a list of commands or help for one command + run Register an account, then create and install a certificate + revoke Revoke a certificate + renew Renew a certificate + register Register an account. + dnshelp Shows additional help for the '--dns' global option + list Display certificates and accounts information. + help, h Shows a list of commands or help for one command GLOBAL OPTIONS: --help, -h show help