mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-23 22:27:38 -05:00
letsencrypt: Allow (but warn about) empty emails
This commit is contained in:
parent
e99b3af0a5
commit
3843cea959
4 changed files with 37 additions and 9 deletions
|
@ -156,10 +156,6 @@ func groupConfigsByEmail(configs []server.Config) (map[string][]*server.Config,
|
|||
continue
|
||||
}
|
||||
leEmail := getEmail(configs[i])
|
||||
if leEmail == "" {
|
||||
// TODO: This may not be an error; just a poor choice by the user
|
||||
return nil, errors.New("must have email address to serve HTTPS without existing certificate and key")
|
||||
}
|
||||
initMap[leEmail] = append(initMap[leEmail], &configs[i])
|
||||
}
|
||||
return initMap, nil
|
||||
|
|
|
@ -48,12 +48,18 @@ func (s Storage) Users() string {
|
|||
|
||||
// User gets the account folder for the user with email.
|
||||
func (s Storage) User(email string) string {
|
||||
if email == "" {
|
||||
email = emptyEmail
|
||||
}
|
||||
return filepath.Join(s.Users(), email)
|
||||
}
|
||||
|
||||
// UserRegFile gets the path to the registration file for
|
||||
// the user with the given email address.
|
||||
func (s Storage) UserRegFile(email string) string {
|
||||
if email == "" {
|
||||
email = emptyEmail
|
||||
}
|
||||
fileName := emailUsername(email)
|
||||
if fileName == "" {
|
||||
fileName = "registration"
|
||||
|
@ -64,7 +70,9 @@ func (s Storage) UserRegFile(email string) string {
|
|||
// UserKeyFile gets the path to the private key file for
|
||||
// the user with the given email address.
|
||||
func (s Storage) UserKeyFile(email string) string {
|
||||
// TODO: Read the KeyFile property in the registration file instead?
|
||||
if email == "" {
|
||||
email = emptyEmail
|
||||
}
|
||||
fileName := emailUsername(email)
|
||||
if fileName == "" {
|
||||
fileName = "private"
|
||||
|
|
|
@ -35,6 +35,17 @@ func TestStorage(t *testing.T) {
|
|||
if expected, actual := filepath.Join("letsencrypt", "users", "me@example.com", "me.key"), storage.UserKeyFile("me@example.com"); actual != expected {
|
||||
t.Errorf("Expected UserKeyFile() to return '%s' but got '%s'", expected, actual)
|
||||
}
|
||||
|
||||
// Test with empty emails
|
||||
if expected, actual := filepath.Join("letsencrypt", "users", emptyEmail), storage.User(emptyEmail); actual != expected {
|
||||
t.Errorf("Expected User(\"\") to return '%s' but got '%s'", expected, actual)
|
||||
}
|
||||
if expected, actual := filepath.Join("letsencrypt", "users", emptyEmail, emptyEmail+".json"), storage.UserRegFile(""); actual != expected {
|
||||
t.Errorf("Expected UserRegFile(\"\") to return '%s' but got '%s'", expected, actual)
|
||||
}
|
||||
if expected, actual := filepath.Join("letsencrypt", "users", emptyEmail, emptyEmail+".key"), storage.UserKeyFile(""); actual != expected {
|
||||
t.Errorf("Expected UserKeyFile(\"\") to return '%s' but got '%s'", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmailUsername(t *testing.T) {
|
||||
|
@ -61,6 +72,10 @@ func TestEmailUsername(t *testing.T) {
|
|||
input: "@foobar.com",
|
||||
expect: "foobar.com",
|
||||
},
|
||||
{
|
||||
input: emptyEmail,
|
||||
expect: emptyEmail,
|
||||
},
|
||||
} {
|
||||
if actual := emailUsername(test.input); actual != test.expect {
|
||||
t.Errorf("Test %d: Expected username to be '%s' but was '%s'", i, test.expect, actual)
|
||||
|
|
|
@ -115,6 +115,8 @@ func newUser(email string) (User, error) {
|
|||
// getEmail does everything it can to obtain an email
|
||||
// address from the user to use for TLS for cfg. If it
|
||||
// cannot get an email address, it returns empty string.
|
||||
// (It will warn the user of the consequences of an
|
||||
// empty email.)
|
||||
func getEmail(cfg server.Config) string {
|
||||
// First try the tls directive from the Caddyfile
|
||||
leEmail := cfg.TLS.LetsEncryptEmail
|
||||
|
@ -124,7 +126,6 @@ func getEmail(cfg server.Config) string {
|
|||
}
|
||||
if leEmail == "" {
|
||||
// Then try to get most recent user email ~/.caddy/users file
|
||||
// TODO: Probably better to open the user's json file and read the email out of there...
|
||||
userDirs, err := ioutil.ReadDir(storage.Users())
|
||||
if err == nil {
|
||||
var mostRecent os.FileInfo
|
||||
|
@ -143,9 +144,13 @@ func getEmail(cfg server.Config) string {
|
|||
}
|
||||
if leEmail == "" {
|
||||
// Alas, we must bother the user and ask for an email address
|
||||
// TODO/BUG: This doesn't work when Caddyfile is piped into caddy
|
||||
reader := bufio.NewReader(stdin)
|
||||
fmt.Print("Email address: ") // TODO: More explanation probably, and show ToS?
|
||||
fmt.Println("Your sites will be served over HTTPS automatically using Let's Encrypt.")
|
||||
fmt.Println("By continuing, you agree to the Let's Encrypt Subscriber Agreement at:")
|
||||
fmt.Println(" <TODO: link>")
|
||||
fmt.Println("Please enter your email address so you can recover your account if needed.")
|
||||
fmt.Println("You can leave it blank, but you lose the ability to recover your account.")
|
||||
fmt.Print("Email address: ")
|
||||
var err error
|
||||
leEmail, err = reader.ReadString('\n')
|
||||
if err != nil {
|
||||
|
@ -169,7 +174,7 @@ func promptUserAgreement(agreementURL string, changed bool) bool {
|
|||
fmt.Print("Do you agree to the terms? (y/n): ")
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(stdin) // TODO/BUG: This doesn't work when Caddyfile is piped into caddy
|
||||
reader := bufio.NewReader(stdin)
|
||||
answer, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return false
|
||||
|
@ -182,3 +187,7 @@ func promptUserAgreement(agreementURL string, changed bool) bool {
|
|||
// stdin is used to read the user's input if prompted;
|
||||
// this is changed by tests during tests.
|
||||
var stdin = io.ReadWriter(os.Stdin)
|
||||
|
||||
// The name of the folder for accounts where the email
|
||||
// address was not provided; default 'username' if you will.
|
||||
const emptyEmail = "default"
|
||||
|
|
Loading…
Reference in a new issue