136 lines
4.8 KiB
Go
136 lines
4.8 KiB
Go
package env
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"lbryio/wallet-sync-server/auth"
|
|
)
|
|
|
|
// NOTE for users: If you have weird characters in your email address, please
|
|
// remember to properly escape it as necessary when putting it in an
|
|
// environmental variable, lest you run commands you didn't mean to run.
|
|
//
|
|
// We'll replace this with a config file later.
|
|
const whitelistKey = "ACCOUNT_WHITELIST"
|
|
const verificationModeKey = "ACCOUNT_VERIFICATION_MODE"
|
|
const mailgunIsDomainEUKey = "MAILGUN_SENDING_DOMAIN_IS_EU"
|
|
const mailgunPrivateAPIKeyKey = "MAILGUN_PRIVATE_API_KEY"
|
|
|
|
// for the "from" address
|
|
const mailgunSendingDomainKey = "MAILGUN_SENDING_DOMAIN"
|
|
|
|
// for links in the emails
|
|
const mailgunServerDomainKey = "MAILGUN_SERVER_DOMAIN"
|
|
|
|
type AccountVerificationMode string
|
|
|
|
// Everyone can make an account. Only use for dev purposes.
|
|
const AccountVerificationModeAllowAll = AccountVerificationMode("AllowAll")
|
|
|
|
// Verify accounts via email. Good for big open servers.
|
|
const AccountVerificationModeEmailVerify = AccountVerificationMode("EmailVerify")
|
|
|
|
// Specific email accounts are automatically verified. Good for small
|
|
// self-hosting users.
|
|
const AccountVerificationModeWhitelist = AccountVerificationMode("Whitelist")
|
|
|
|
// For test stubs
|
|
type EnvInterface interface {
|
|
Getenv(key string) string
|
|
}
|
|
|
|
type Env struct{}
|
|
|
|
func (e *Env) Getenv(key string) string {
|
|
return os.Getenv(key)
|
|
}
|
|
|
|
func GetAccountVerificationMode(e EnvInterface) (AccountVerificationMode, error) {
|
|
return getAccountVerificationMode(e.Getenv(verificationModeKey))
|
|
}
|
|
|
|
func GetAccountWhitelist(e EnvInterface, mode AccountVerificationMode) (emails []auth.Email, err error) {
|
|
return getAccountWhitelist(e.Getenv(whitelistKey), mode)
|
|
}
|
|
|
|
func GetMailgunConfigs(e EnvInterface, mode AccountVerificationMode) (sendingDomain string, serverDomain string, isDomainEU bool, privateAPIKey string, err error) {
|
|
return getMailgunConfigs(e.Getenv(mailgunSendingDomainKey), e.Getenv(mailgunServerDomainKey), e.Getenv(mailgunIsDomainEUKey), e.Getenv(mailgunPrivateAPIKeyKey), mode)
|
|
}
|
|
|
|
// Factor out the guts of the functions so we can test them by just passing in
|
|
// the env vars
|
|
|
|
func getAccountVerificationMode(modeStr string) (AccountVerificationMode, error) {
|
|
mode := AccountVerificationMode(modeStr)
|
|
switch mode {
|
|
case "":
|
|
// Whitelist is the least dangerous mode. If you forget to set any env
|
|
// vars, it effectively disables all account creation.
|
|
return AccountVerificationModeWhitelist, nil
|
|
case AccountVerificationModeAllowAll:
|
|
case AccountVerificationModeEmailVerify:
|
|
case AccountVerificationModeWhitelist:
|
|
default:
|
|
return "", fmt.Errorf("Invalid account verification mode in %s: %s", verificationModeKey, mode)
|
|
}
|
|
return mode, nil
|
|
}
|
|
|
|
func getAccountWhitelist(whitelist string, mode AccountVerificationMode) (emails []auth.Email, err error) {
|
|
if whitelist == "" {
|
|
return []auth.Email{}, nil
|
|
}
|
|
|
|
if mode != AccountVerificationModeWhitelist {
|
|
return nil, fmt.Errorf("Do not specify %s in env if %s is not %s",
|
|
whitelistKey,
|
|
verificationModeKey,
|
|
AccountVerificationModeWhitelist,
|
|
)
|
|
}
|
|
|
|
rawEmails := strings.Split(whitelist, ",")
|
|
for _, rawEmail := range rawEmails {
|
|
// Give them a specific error here to let them know not to add spaces. It
|
|
// could be confusing otherwise to figure out what's invalid.
|
|
if strings.TrimSpace(rawEmail) != rawEmail {
|
|
return nil, fmt.Errorf("Emails in %s should be comma separated with no spaces.", whitelistKey)
|
|
}
|
|
email := auth.Email(rawEmail)
|
|
if !email.Validate() {
|
|
return nil, fmt.Errorf("Invalid email in %s: %s", whitelistKey, email)
|
|
}
|
|
emails = append(emails, email)
|
|
}
|
|
return emails, nil
|
|
}
|
|
|
|
func getMailgunConfigs(sendingDomain string, serverDomain string, isDomainEUStr string, privateAPIKey string, mode AccountVerificationMode) (string, string, bool, string, error) {
|
|
if mode != AccountVerificationModeEmailVerify && (sendingDomain != "" || serverDomain != "" || isDomainEUStr != "" || privateAPIKey != "") {
|
|
return "", "", false, "", fmt.Errorf("Do not specify %s, %s, %s or %s in env if %s is not %s",
|
|
mailgunSendingDomainKey,
|
|
mailgunServerDomainKey,
|
|
mailgunIsDomainEUKey,
|
|
mailgunPrivateAPIKeyKey,
|
|
verificationModeKey,
|
|
AccountVerificationModeEmailVerify,
|
|
)
|
|
}
|
|
if mode == AccountVerificationModeEmailVerify && (sendingDomain == "" || serverDomain == "" || privateAPIKey == "") {
|
|
return "", "", false, "", fmt.Errorf("Specify %s, %s and %s in env if %s is %s",
|
|
mailgunSendingDomainKey,
|
|
mailgunServerDomainKey,
|
|
mailgunPrivateAPIKeyKey,
|
|
verificationModeKey,
|
|
AccountVerificationModeEmailVerify,
|
|
)
|
|
}
|
|
|
|
if isDomainEUStr != "true" && isDomainEUStr != "false" && isDomainEUStr != "" {
|
|
return "", "", false, "", fmt.Errorf("%s must be 'true' or 'false'", mailgunIsDomainEUKey)
|
|
}
|
|
|
|
return sendingDomain, serverDomain, isDomainEUStr == "true", privateAPIKey, nil
|
|
}
|