summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaire <claire.github-309c@sitedethib.com>2024-02-22 14:39:42 +0100
committerGitHub <noreply@github.com>2024-02-22 14:39:42 +0100
commit28b666b0d522071e38a5a0a3376d4548c36ee3e9 (patch)
tree256f3fc5eb06044c49c2dfbebaa96f65605b6161
parentfbb07893b82002686a144699ded4401ccd5b8ea7 (diff)
Automatically switch from open to approved registrations in absence of moderators (#29337)
-rw-r--r--app/mailers/admin_mailer.rb6
-rw-r--r--app/views/admin_mailer/auto_close_registrations.text.erb3
-rw-r--r--app/workers/scheduler/auto_close_registrations_scheduler.rb33
-rw-r--r--config/locales/en.yml3
-rw-r--r--config/sidekiq.yml4
-rw-r--r--spec/workers/scheduler/auto_close_registrations_scheduler_spec.rb60
6 files changed, 109 insertions, 0 deletions
diff --git a/app/mailers/admin_mailer.rb b/app/mailers/admin_mailer.rb
index 990b92c3377..6b08aa8ccff 100644
--- a/app/mailers/admin_mailer.rb
+++ b/app/mailers/admin_mailer.rb
@@ -61,6 +61,12 @@ class AdminMailer < ApplicationMailer
end
end
+ def auto_close_registrations
+ locale_for_account(@me) do
+ mail subject: default_i18n_subject(instance: @instance)
+ end
+ end
+
private
def process_params
diff --git a/app/views/admin_mailer/auto_close_registrations.text.erb b/app/views/admin_mailer/auto_close_registrations.text.erb
new file mode 100644
index 00000000000..c0f84869296
--- /dev/null
+++ b/app/views/admin_mailer/auto_close_registrations.text.erb
@@ -0,0 +1,3 @@
+<%= raw t('admin_mailer.auto_close_registrations.body', instance: @instance) %>
+
+<%= raw t('application_mailer.view')%> <%= admin_settings_registrations_url %>
diff --git a/app/workers/scheduler/auto_close_registrations_scheduler.rb b/app/workers/scheduler/auto_close_registrations_scheduler.rb
new file mode 100644
index 00000000000..17516dd23fe
--- /dev/null
+++ b/app/workers/scheduler/auto_close_registrations_scheduler.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+class Scheduler::AutoCloseRegistrationsScheduler
+ include Sidekiq::Worker
+ include Redisable
+
+ sidekiq_options retry: 0
+
+ # Automatically switch away from open registrations if no
+ # moderator had any activity in that period of time
+ OPEN_REGISTRATIONS_MODERATOR_THRESHOLD = 1.week + UserTrackingConcern::SIGN_IN_UPDATE_FREQUENCY
+
+ def perform
+ return if Rails.configuration.x.email_domains_whitelist.present? || ENV['DISABLE_AUTOMATIC_SWITCHING_TO_APPROVED_REGISTRATIONS'] == 'true'
+ return unless Setting.registrations_mode == 'open'
+
+ switch_to_approval_mode! unless active_moderators?
+ end
+
+ private
+
+ def active_moderators?
+ User.those_who_can(:manage_reports).exists?(current_sign_in_at: OPEN_REGISTRATIONS_MODERATOR_THRESHOLD.ago...)
+ end
+
+ def switch_to_approval_mode!
+ Setting.registrations_mode = 'approved'
+
+ User.those_who_can(:view_devops).includes(:account).find_each do |user|
+ AdminMailer.with(recipient: user.account).auto_close_registrations.deliver_later
+ end
+ end
+end
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 2b3bfb4c71a..85a0a9ff945 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -963,6 +963,9 @@ en:
title: Webhooks
webhook: Webhook
admin_mailer:
+ auto_close_registrations:
+ body: Due to a lack of recent moderator activity, registrations on %{instance} have been automatically switched to requiring manual review, to prevent %{instance} from being used as a platform for potential bad actors. You can switch it back to open registrations at any time.
+ subject: Registrations for %{instance} have been automatically switched to requiring approval
new_appeal:
actions:
delete_statuses: to delete their posts
diff --git a/config/sidekiq.yml b/config/sidekiq.yml
index f1ba5651dd4..8c9481c0500 100644
--- a/config/sidekiq.yml
+++ b/config/sidekiq.yml
@@ -62,3 +62,7 @@
interval: 30 minutes
class: Scheduler::SoftwareUpdateCheckScheduler
queue: scheduler
+ auto_close_registrations_scheduler:
+ interval: 1 hour
+ class: Scheduler::AutoCloseRegistrationsScheduler
+ queue: scheduler
diff --git a/spec/workers/scheduler/auto_close_registrations_scheduler_spec.rb b/spec/workers/scheduler/auto_close_registrations_scheduler_spec.rb
new file mode 100644
index 00000000000..c0c50b128d8
--- /dev/null
+++ b/spec/workers/scheduler/auto_close_registrations_scheduler_spec.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe Scheduler::AutoCloseRegistrationsScheduler do
+ subject { described_class.new }
+
+ describe '#perform' do
+ let(:moderator_activity_date) { Time.now.utc }
+
+ before do
+ Fabricate(:user, role: UserRole.find_by(name: 'Owner'), current_sign_in_at: 10.years.ago)
+ Fabricate(:user, role: UserRole.find_by(name: 'Moderator'), current_sign_in_at: moderator_activity_date)
+ end
+
+ context 'when registrations are open' do
+ before do
+ Setting.registrations_mode = 'open'
+ end
+
+ context 'when a moderator has logged in recently' do
+ let(:moderator_activity_date) { Time.now.utc }
+
+ it 'does not change registrations mode' do
+ expect { subject.perform }.to_not change(Setting, :registrations_mode)
+ end
+ end
+
+ context 'when a moderator has not recently signed in' do
+ let(:moderator_activity_date) { 1.year.ago }
+
+ it 'changes registrations mode from open to approved' do
+ expect { subject.perform }.to change(Setting, :registrations_mode).from('open').to('approved')
+ end
+ end
+ end
+
+ context 'when registrations are closed' do
+ before do
+ Setting.registrations_mode = 'none'
+ end
+
+ context 'when a moderator has logged in recently' do
+ let(:moderator_activity_date) { Time.now.utc }
+
+ it 'does not change registrations mode' do
+ expect { subject.perform }.to_not change(Setting, :registrations_mode)
+ end
+ end
+
+ context 'when a moderator has not recently signed in' do
+ let(:moderator_activity_date) { 1.year.ago }
+
+ it 'does not change registrations mode' do
+ expect { subject.perform }.to_not change(Setting, :registrations_mode)
+ end
+ end
+ end
+ end
+end