2022-07-24 00:13:56 +02:00
|
|
|
package env
|
|
|
|
|
|
|
|
import (
|
2022-07-24 22:02:55 +02:00
|
|
|
"fmt"
|
2022-07-24 00:13:56 +02:00
|
|
|
"os"
|
2022-07-24 22:02:55 +02:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"lbryio/lbry-id/auth"
|
2022-07-24 00:13:56 +02:00
|
|
|
)
|
|
|
|
|
2022-07-29 19:37:41 +02:00
|
|
|
// 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.
|
2022-07-24 22:02:55 +02:00
|
|
|
const whitelistKey = "ACCOUNT_WHITELIST"
|
|
|
|
const verificationModeKey = "ACCOUNT_VERIFICATION_MODE"
|
|
|
|
|
2022-07-25 23:46:41 +02:00
|
|
|
type AccountVerificationMode string
|
2022-07-24 22:02:55 +02:00
|
|
|
|
|
|
|
// Everyone can make an account. Only use for dev purposes.
|
2022-07-25 23:46:41 +02:00
|
|
|
const AccountVerificationModeAllowAll = AccountVerificationMode("AllowAll")
|
2022-07-24 22:02:55 +02:00
|
|
|
|
|
|
|
// Verify accounts via email. Good for big open servers.
|
2022-07-25 23:46:41 +02:00
|
|
|
const AccountVerificationModeEmailVerify = AccountVerificationMode("EmailVerify")
|
2022-07-24 22:02:55 +02:00
|
|
|
|
|
|
|
// Specific email accounts are automatically verified. Good for small
|
|
|
|
// self-hosting users.
|
2022-07-25 23:46:41 +02:00
|
|
|
const AccountVerificationModeWhitelist = AccountVerificationMode("Whitelist")
|
2022-07-24 22:02:55 +02:00
|
|
|
|
2022-07-24 00:13:56 +02:00
|
|
|
// For test stubs
|
|
|
|
type EnvInterface interface {
|
|
|
|
Getenv(key string) string
|
|
|
|
}
|
|
|
|
|
|
|
|
type Env struct{}
|
|
|
|
|
|
|
|
func (e *Env) Getenv(key string) string {
|
|
|
|
return os.Getenv(key)
|
|
|
|
}
|
2022-07-24 22:02:55 +02:00
|
|
|
|
2022-07-25 23:46:41 +02:00
|
|
|
func GetAccountVerificationMode(e EnvInterface) (AccountVerificationMode, error) {
|
2022-07-24 22:02:55 +02:00
|
|
|
return getAccountVerificationMode(e.Getenv(verificationModeKey))
|
|
|
|
}
|
|
|
|
|
2022-07-25 23:46:41 +02:00
|
|
|
func GetAccountWhitelist(e EnvInterface, mode AccountVerificationMode) (emails []auth.Email, err error) {
|
2022-07-24 22:02:55 +02:00
|
|
|
return getAccountWhitelist(e.Getenv(whitelistKey), mode)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Factor out the guts of the functions so we can test them by just passing in
|
|
|
|
// the env vars
|
|
|
|
|
2022-07-25 23:46:41 +02:00
|
|
|
func getAccountVerificationMode(modeStr string) (AccountVerificationMode, error) {
|
|
|
|
mode := AccountVerificationMode(modeStr)
|
2022-07-24 22:02:55 +02:00
|
|
|
switch mode {
|
|
|
|
case "":
|
|
|
|
// Whitelist is the least dangerous mode. If you forget to set any env
|
|
|
|
// vars, it effectively disables all account creation.
|
2022-07-25 23:46:41 +02:00
|
|
|
return AccountVerificationModeWhitelist, nil
|
|
|
|
case AccountVerificationModeAllowAll:
|
|
|
|
case AccountVerificationModeEmailVerify:
|
|
|
|
case AccountVerificationModeWhitelist:
|
2022-07-24 22:02:55 +02:00
|
|
|
default:
|
|
|
|
return "", fmt.Errorf("Invalid account verification mode in %s: %s", verificationModeKey, mode)
|
|
|
|
}
|
|
|
|
return mode, nil
|
|
|
|
}
|
|
|
|
|
2022-07-25 23:46:41 +02:00
|
|
|
func getAccountWhitelist(whitelist string, mode AccountVerificationMode) (emails []auth.Email, err error) {
|
2022-07-24 22:02:55 +02:00
|
|
|
if whitelist == "" {
|
|
|
|
return []auth.Email{}, nil
|
|
|
|
}
|
|
|
|
|
2022-07-25 23:46:41 +02:00
|
|
|
if mode != AccountVerificationModeWhitelist {
|
2022-07-24 22:02:55 +02:00
|
|
|
return nil, fmt.Errorf("Do not specify ACCOUNT_WHITELIST in env if ACCOUNT_VERIFICATION_MODE is not Whitelist")
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|