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
This commit is contained in:
tomuta 2019-11-16 15:01:45 -07:00
parent a19a6fb016
commit 64d6f72e6c
3 changed files with 21 additions and 1 deletions

View file

@ -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

View file

@ -90,7 +90,7 @@ fn register(data: JsonUpcase<RegisterData>, 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")

View file

@ -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)?;