diff --git a/cmd/accounts_storage.go b/cmd/accounts_storage.go index b3e4986dd9..95da37c9d2 100644 --- a/cmd/accounts_storage.go +++ b/cmd/accounts_storage.go @@ -58,6 +58,7 @@ const ( // │ └── root accounts directory // └── "path" option type AccountsStorage struct { + noEmail bool userID string rootPath string rootUserPath string @@ -68,8 +69,14 @@ type AccountsStorage struct { // NewAccountsStorage Creates a new AccountsStorage. func NewAccountsStorage(ctx *cli.Context) *AccountsStorage { - // TODO: move to account struct? Currently MUST pass email. - email := getEmail(ctx) + var userID string + noEmail := ctx.IsSet(flgNoEmail) + if noEmail { + userID = "default" + } else { + // TODO: move to account struct? + userID = getEmail(ctx) + } serverURL, err := url.Parse(ctx.String(flgServer)) if err != nil { @@ -79,10 +86,11 @@ func NewAccountsStorage(ctx *cli.Context) *AccountsStorage { rootPath := filepath.Join(ctx.String(flgPath), baseAccountsRootFolderName) serverPath := strings.NewReplacer(":", "_", "/", string(os.PathSeparator)).Replace(serverURL.Host) accountsPath := filepath.Join(rootPath, serverPath) - rootUserPath := filepath.Join(accountsPath, email) + rootUserPath := filepath.Join(accountsPath, userID) return &AccountsStorage{ - userID: email, + noEmail: noEmail, + userID: userID, rootPath: rootPath, rootUserPath: rootUserPath, keysPath: filepath.Join(rootUserPath, baseKeysFolderName), @@ -110,6 +118,9 @@ func (s *AccountsStorage) GetRootUserPath() string { } func (s *AccountsStorage) GetUserID() string { + if s.noEmail { + return "" + } return s.userID } diff --git a/cmd/flags.go b/cmd/flags.go index 0a8024dffc..13eb879a5e 100644 --- a/cmd/flags.go +++ b/cmd/flags.go @@ -16,6 +16,7 @@ const ( flgServer = "server" flgAcceptTOS = "accept-tos" flgEmail = "email" + flgNoEmail = "no-email" flgCSR = "csr" flgEAB = "eab" flgKID = "kid" @@ -73,6 +74,12 @@ func CreateFlags(defaultPath string) []cli.Flag { Aliases: []string{"m"}, Usage: "Email used for registration and recovery contact.", }, + &cli.BoolFlag{ + Name: flgNoEmail, + Aliases: []string{"M"}, + EnvVars: []string{"LEGO_NO_EMAIL"}, + Usage: "Create an ACME request without including an email address.", + }, &cli.StringFlag{ Name: flgCSR, Aliases: []string{"c"}, diff --git a/cmd/setup.go b/cmd/setup.go index 4a802ba132..8f94bbbcd0 100644 --- a/cmd/setup.go +++ b/cmd/setup.go @@ -93,7 +93,7 @@ func getKeyType(ctx *cli.Context) certcrypto.KeyType { func getEmail(ctx *cli.Context) string { email := ctx.String(flgEmail) if email == "" { - log.Fatalf("You have to pass an account (email address) to the program using --%s or -m", flgEmail) + log.Fatalf("You have to pass an account (email address) to the program using --%s or -m, or use --%s or -M to disable including an email in the ACME request.", flgEmail, flgNoEmail) } return email } diff --git a/docs/data/zz_cli_help.toml b/docs/data/zz_cli_help.toml index b6eec239b9..81c4845a3a 100644 --- a/docs/data/zz_cli_help.toml +++ b/docs/data/zz_cli_help.toml @@ -23,6 +23,7 @@ GLOBAL OPTIONS: --server value, -s value CA hostname (and optionally :port). The server certificate must be trusted in order to avoid further modifications to the client. (default: "https://acme-v02.api.letsencrypt.org/directory") [$LEGO_SERVER] --accept-tos, -a By setting this flag to true you indicate that you accept the current Let's Encrypt terms of service. (default: false) --email value, -m value Email used for registration and recovery contact. + --no-email, -M Create an ACME request without including an email address. (default: false) [$LEGO_NO_EMAIL] --csr value, -c value Certificate signing request filename, if an external CSR is to be used. --eab Use External Account Binding for account registration. Requires --kid and --hmac. (default: false) [$LEGO_EAB] --kid value Key identifier from External CA. Used for External Account Binding. [$LEGO_EAB_KID] diff --git a/providers/dns/westcn/westcn_test.go b/providers/dns/westcn/westcn_test.go index 71632d99f6..ac779253a4 100644 --- a/providers/dns/westcn/westcn_test.go +++ b/providers/dns/westcn/westcn_test.go @@ -1,4 +1,8 @@ +<<<<<<<< HEAD:providers/dns/westcn/westcn_test.go package westcn +======== +package technitium +>>>>>>>> master:providers/dns/technitium/technitium_test.go import ( "testing" @@ -9,7 +13,11 @@ import ( const envDomain = envNamespace + "DOMAIN" +<<<<<<<< HEAD:providers/dns/westcn/westcn_test.go var envTest = tester.NewEnvTest(EnvUsername, EnvPassword).WithDomain(envDomain) +======== +var envTest = tester.NewEnvTest(EnvServerBaseURL, EnvAPIToken).WithDomain(envDomain) +>>>>>>>> master:providers/dns/technitium/technitium_test.go func TestNewDNSProvider(t *testing.T) { testCases := []struct { @@ -20,6 +28,7 @@ func TestNewDNSProvider(t *testing.T) { { desc: "success", envVars: map[string]string{ +<<<<<<<< HEAD:providers/dns/westcn/westcn_test.go EnvUsername: "user", EnvPassword: "secret", }, @@ -39,11 +48,36 @@ func TestNewDNSProvider(t *testing.T) { EnvPassword: "", }, expected: "westcn: some credentials information are missing: WESTCN_PASSWORD", +======== + EnvServerBaseURL: "https://localhost:5380", + EnvAPIToken: "secret", + }, + }, + { + desc: "missing server base URL", + envVars: map[string]string{ + EnvServerBaseURL: "", + EnvAPIToken: "secret", + }, + expected: "technitium: some credentials information are missing: TECHNITIUM_SERVER_BASE_URL", + }, + { + desc: "missing token", + envVars: map[string]string{ + EnvServerBaseURL: "https://localhost:5380", + EnvAPIToken: "", + }, + expected: "technitium: some credentials information are missing: TECHNITIUM_API_TOKEN", +>>>>>>>> master:providers/dns/technitium/technitium_test.go }, { desc: "missing credentials", envVars: map[string]string{}, +<<<<<<<< HEAD:providers/dns/westcn/westcn_test.go expected: "westcn: some credentials information are missing: WESTCN_USERNAME,WESTCN_PASSWORD", +======== + expected: "technitium: some credentials information are missing: TECHNITIUM_SERVER_BASE_URL,TECHNITIUM_API_TOKEN", +>>>>>>>> master:providers/dns/technitium/technitium_test.go }, } @@ -71,6 +105,7 @@ func TestNewDNSProvider(t *testing.T) { func TestNewDNSProviderConfig(t *testing.T) { testCases := []struct { desc string +<<<<<<<< HEAD:providers/dns/westcn/westcn_test.go username string password string expected string @@ -93,14 +128,43 @@ func TestNewDNSProviderConfig(t *testing.T) { { desc: "missing credentials", expected: "westcn: credentials missing", +======== + baseURL string + token string + expected string + }{ + { + desc: "success", + baseURL: "https://localhost:5380", + token: "secret", + }, + { + desc: "missing server base URL", + token: "secret", + expected: "technitium: missing server URL", + }, + { + desc: "missing token", + baseURL: "https://localhost:5380", + expected: "technitium: missing credentials", + }, + { + desc: "missing credentials", + expected: "technitium: missing credentials", +>>>>>>>> master:providers/dns/technitium/technitium_test.go }, } for _, test := range testCases { t.Run(test.desc, func(t *testing.T) { config := NewDefaultConfig() +<<<<<<<< HEAD:providers/dns/westcn/westcn_test.go config.Username = test.username config.Password = test.password +======== + config.BaseURL = test.baseURL + config.APIToken = test.token +>>>>>>>> master:providers/dns/technitium/technitium_test.go p, err := NewDNSProviderConfig(config)