2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-03-03 23:54:20 +08:00
discourse/spec/lib/read_only_mixin_spec.rb
Régis Hanol bccf4e0b53
FIX: improve "read only" modes (#33521)
The reasons for these changes is https://meta.discourse.org/t/-/89605
broke and admins were not able to log back in if they had previously
enabled the "read only" mode.

Thus ensued a deep dive into how all the "read only" modes worked, which
was made difficult due to the lack of tests.

The "cornerstone" of this PR is the `read_only_mixin.rb` file which was
improved to be able to differentiate between the "readonly" mode and the
"staff writes only" mode.

I then made use of the `allow_in_readonly_mode` and
`allow_in_staff_writes_only_mode` method to **explicitely** list all the
actions that should work in those modes.

I also added the "readonly" mixin to the `WebhooksController` since it
doesn't inherit from the `ApplicationController`.

I improved the security of the `/u/admin-login` endpoint by always
sending the same message no matter if we found or not an admin account
with the provided email address.

I added two system specs:

1. for ensuring that admins can log in via /u/admin-lgoin and then
clicking the link in the email they received while the site is in
readonly mode.
2. for ensuring the "staff writes only mode" is _actually_ tested by
ensuring a moderator can log in and create a topic while the site is in
that mode.

Plenty of specs were updated to ensure 100% converage of the various
"read only" modes.
2025-07-10 09:08:00 +02:00

59 lines
2.3 KiB
Ruby

# frozen_string_literal: true
describe ReadOnlyMixin do
before { Rails.application.eager_load! }
it "allows only these actions in readonly mode" do
controllers_with_readonly_actions = []
ApplicationController.descendants.each do |controller_class|
controller_class.actions_allowed_in_readonly_mode&.each do |action|
controllers_with_readonly_actions << [controller_class, action]
end
end
expect(controllers_with_readonly_actions).to contain_exactly(
# All the /admin/backups actions that modify data
[Admin::BackupsController, :readonly],
[Admin::BackupsController, :create],
[Admin::BackupsController, :cancel],
[Admin::BackupsController, :restore],
[Admin::BackupsController, :rollback],
[Admin::BackupsController, :destroy],
[Admin::BackupsController, :email],
[Admin::BackupsController, :upload_backup_chunk],
[Admin::BackupsController, :create_multipart],
[Admin::BackupsController, :abort_multipart],
[Admin::BackupsController, :complete_multipart],
[Admin::BackupsController, :batch_presign_multipart_parts],
# Search uses a POST request but doesn't modify any data
[CategoriesController, :search],
# Allows admins to log in (via email) when the site is in readonly mode (cf. https://meta.discourse.org/t/-/89605)
[SessionController, :email_login],
[UsersController, :admin_login],
)
end
it "allows only these actions in staff writes only mode" do
controllers_with_staff_writes_only_actions = []
ApplicationController.descendants.each do |controller_class|
controller_class.actions_allowed_in_staff_writes_only_mode&.each do |action|
controllers_with_staff_writes_only_actions << [controller_class, action]
end
end
expect(controllers_with_staff_writes_only_actions).to contain_exactly(
# Allows staff to log in using email/username and password
[SessionController, :create],
# Allows staff to reset their password (part 1/2)
[SessionController, :forgot_password],
# Allows staff to log in via OAuth
[Users::OmniauthCallbacksController, :complete],
# Allows staff to log in via email link
[UsersController, :email_login],
# Allows staff to reset their password (part 2/2)
[UsersController, :password_reset_update],
)
end
end