From 64d6f72e6c71dec7cbcb5992f31473c416d0678e Mon Sep 17 00:00:00 2001 From: tomuta Date: Sat, 16 Nov 2019 15:01:45 -0700 Subject: [PATCH] Add the ability to disable signups, but allow signups from a whitelist This feature can be enabled by setting SIGNUPS_ALLOWED=false and providing a comma-separated list of whitelisted domains in SIGNUPS_DOMAINS_WHITELIST. Fixes #727 --- .env.template | 8 ++++++++ src/api/core/accounts.rs | 2 +- src/config.rs | 12 ++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.env.template b/.env.template index 79b93f47..7c0200d0 100644 --- a/.env.template +++ b/.env.template @@ -95,6 +95,14 @@ ## Controls if new users can register # SIGNUPS_ALLOWED=true +## Controls if new users from a list of comma-separated domains can register +## even if SIGNUPS_ALLOWED is set to false +## +## WARNING: There is currently no validation that prevents anyone from +## signing up with any made-up email address from one of these +## whitelisted domains! +# SIGNUPS_DOMAINS_WHITELIST=example.com,example.net,example.org + ## Token for the admin interface, preferably use a long random string ## One option is to use 'openssl rand -base64 48' ## If not set, the admin panel is disabled diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs index 9c9e7da6..b91e724d 100644 --- a/src/api/core/accounts.rs +++ b/src/api/core/accounts.rs @@ -90,7 +90,7 @@ fn register(data: JsonUpcase, conn: DbConn) -> EmptyResult { } } None => { - if CONFIG.signups_allowed() || Invitation::take(&data.Email, &conn) { + if CONFIG.signups_allowed() || Invitation::take(&data.Email, &conn) || CONFIG.can_signup_user(&data.Email) { User::new(data.Email.clone()) } else { err!("Registration not allowed or user already exists") diff --git a/src/config.rs b/src/config.rs index 1f18549a..f75b9e64 100644 --- a/src/config.rs +++ b/src/config.rs @@ -243,6 +243,8 @@ make_config! { disable_icon_download: bool, true, def, false; /// Allow new signups |> Controls if new users can register. Note that while this is disabled, users could still be invited signups_allowed: bool, true, def, true; + /// Allow signups only from this list of comma-separated domains + signups_domains_whitelist: String, true, def, "".to_string(); /// Allow invitations |> Controls whether users can be invited by organization admins, even when signups are disabled invitations_allowed: bool, true, def, true; /// Password iterations |> Number of server-side passwords hashing iterations. @@ -491,6 +493,16 @@ impl Config { self.update_config(builder) } + pub fn can_signup_user(&self, email: &str) -> bool { + let e: Vec<&str> = email.rsplitn(2, "@").collect(); + if e.len() != 2 || e[0].is_empty() || e[1].is_empty() { + warn!("Failed to parse email address '{}'", email); + return false + } + + self.signups_domains_whitelist().split(",").any(|d| d == e[0]) + } + pub fn delete_user_config(&self) -> Result<(), Error> { crate::util::delete_file(&CONFIG_FILE)?;