diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 4c285e63f..48da47153 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -22,17 +22,17 @@ class RegistrationsController < Devise::RegistrationsController build_devise_resource if resource.persisted? - update_first_user_permissions(resource) + resource.set_initial_roles! - if ForemInstance.smtp_enabled? + if resource.creator? + prepare_new_forem_instance + sign_in(resource) + redirect_to new_admin_creator_setting_path + elsif ForemInstance.smtp_enabled? redirect_to confirm_email_path(email: resource.email) else sign_in(resource) - if resource.roles.includes(:creator).any? - redirect_to new_admin_creator_setting_path - else - redirect_to root_path - end + redirect_to root_path end else render action: "by_email" @@ -41,13 +41,7 @@ class RegistrationsController < Devise::RegistrationsController private - def update_first_user_permissions(resource) - return unless Settings::General.waiting_on_first_user - - resource.add_role(:creator) - resource.add_role(:super_admin) - resource.add_role(:trusted) - resource.skip_confirmation! + def prepare_new_forem_instance Settings::General.waiting_on_first_user = false Users::CreateMascotAccount.call Discover::RegisterWorker.perform_async # Register Forem instance on https://discover.forem.com diff --git a/app/helpers/admin/settings_helper.rb b/app/helpers/admin/settings_helper.rb index 1149f6bdf..3ebc4090f 100644 --- a/app/helpers/admin/settings_helper.rb +++ b/app/helpers/admin/settings_helper.rb @@ -7,5 +7,11 @@ module Admin def billboard_all_countries_for_editing ISO3166::Country.all.to_h { |country| [country.alpha2, country.common_name] } end + + def new_user_status_options + ::Settings::Authentication::NEW_USER_STATUSES.map do |status| + [status.humanize, status] + end + end end end diff --git a/app/lib/constants/settings/authentication.rb b/app/lib/constants/settings/authentication.rb index fec2411fd..f1b0608f5 100644 --- a/app/lib/constants/settings/authentication.rb +++ b/app/lib/constants/settings/authentication.rb @@ -66,6 +66,10 @@ module Constants description: I18n.t("lib.constants.settings.authentication.invite_only.description"), placeholder: "" }, + new_user_status: { + description: I18n.t("lib.constants.settings.authentication.new_user_status.description"), + placeholder: I18n.t("lib.constants.settings.authentication.new_user_status.placeholder") + }, recaptcha_site_key: { description: I18n.t("lib.constants.settings.authentication.recaptcha_site.description"), placeholder: I18n.t("lib.constants.settings.authentication.recaptcha_site.placeholder") diff --git a/app/models/settings/authentication.rb b/app/models/settings/authentication.rb index 46d5eff17..25dccb7e2 100644 --- a/app/models/settings/authentication.rb +++ b/app/models/settings/authentication.rb @@ -2,6 +2,8 @@ module Settings class Authentication < Base self.table_name = :settings_authentications + NEW_USER_STATUSES = %w[good_standing limited].freeze + setting :allow_email_password_login, type: :boolean, default: true setting :allow_email_password_registration, type: :boolean, default: false setting :allowed_registration_email_domains, type: :array, default: %w[], validates: { @@ -24,6 +26,9 @@ module Settings setting :google_oauth2_key, type: :string setting :google_oauth2_secret, type: :string setting :invite_only_mode, type: :boolean, default: false + setting :new_user_status, type: :string, default: "good_standing", validates: { + inclusion: { in: NEW_USER_STATUSES } + } setting :providers, type: :array, default: %w[] setting :require_captcha_for_email_password_registration, type: :boolean, default: false setting :twitter_key, type: :string, default: ApplicationConfig["TWITTER_KEY"] @@ -57,5 +62,9 @@ module Settings false end + + def self.limit_new_users? + new_user_status == "limited" + end end end diff --git a/app/models/user.rb b/app/models/user.rb index e983708aa..773ab837e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -277,6 +277,21 @@ class User < ApplicationRecord self.remember_created_at ||= Time.now.utc end + def set_initial_roles! + # Avoid overwriting roles for users who already exist but are e.g. logging in + # through a new identity provider + return unless valid? && previously_new_record? + + if Settings::General.waiting_on_first_user + add_role(:creator) + add_role(:super_admin) + add_role(:trusted) + elsif Settings::Authentication.limit_new_users? + add_role(:limited) + # Otherwise just leave the new user in good standing + end + end + def calculate_score # User score is used to mitigate spam by reducing visibility of flagged users # It can generally be used as a baseline for affecting certain functionality which diff --git a/app/services/authentication/authenticator.rb b/app/services/authentication/authenticator.rb index f35fa171f..6ebd60206 100644 --- a/app/services/authentication/authenticator.rb +++ b/app/services/authentication/authenticator.rb @@ -51,6 +51,7 @@ module Authentication else update_user(user) end + user.set_initial_roles! identity.user = user if identity.user_id.blank? new_identity = identity.new_record? diff --git a/app/views/admin/settings/forms/_authentication.html.erb b/app/views/admin/settings/forms/_authentication.html.erb index 71fa84bad..e3ec4ae30 100644 --- a/app/views/admin/settings/forms/_authentication.html.erb +++ b/app/views/admin/settings/forms/_authentication.html.erb @@ -207,6 +207,15 @@