DEV: New readonly mode. Only applies to non-staff (#16243)

This commit is contained in:
Daniel Waterworth
2022-05-17 13:06:08 -05:00
committed by GitHub
parent 985afe1092
commit 6e53f4d913
14 changed files with 228 additions and 27 deletions

View File

@@ -15,6 +15,13 @@ RSpec.describe ForumsController do
expect(response.status).to eq(200)
expect(response.headers['Discourse-Readonly']).to eq('true')
end
it "returns a readonly header if the site is in staff-writes-only mode" do
Discourse.stubs(:staff_writes_only_mode?).returns(true)
get "/srv/status"
expect(response.status).to eq(200)
expect(response.headers['Discourse-Readonly']).to eq('true')
end
end
describe "cluster parameter" do

View File

@@ -168,6 +168,33 @@ RSpec.describe Users::OmniauthCallbacksController do
end
end
context "in staff writes only mode" do
use_redis_snapshotting
before do
Discourse.enable_readonly_mode(Discourse::STAFF_WRITES_ONLY_MODE_KEY)
end
it "returns a 503 for non-staff" do
mock_auth(user.email, user.username, user.name)
get "/auth/google_oauth2/callback.json"
expect(response.status).to eq(503)
logged_on_user = Discourse.current_user_provider.new(request.env).current_user
expect(logged_on_user).to eq(nil)
end
it "completes for staff" do
user.update!(admin: true)
mock_auth(user.email, user.username, user.name)
get "/auth/google_oauth2/callback.json"
expect(response.status).to eq(302)
logged_on_user = Discourse.current_user_provider.new(request.env).current_user
expect(logged_on_user).not_to eq(nil)
end
end
context "without an `omniauth.auth` env" do
it "should return a 404" do
get "/auth/eviltrout/callback"

View File

@@ -6,6 +6,9 @@ describe SessionController do
let(:user) { Fabricate(:user) }
let(:email_token) { Fabricate(:email_token, user: user) }
fab!(:admin) { Fabricate(:admin) }
let(:admin_email_token) { Fabricate(:email_token, user: admin) }
shared_examples 'failed to continue local login' do
it 'should return the right response' do
expect(response).not_to be_successful
@@ -549,6 +552,41 @@ describe SessionController do
sso
end
context 'in staff writes only mode' do
use_redis_snapshotting
before do
Discourse.enable_readonly_mode(Discourse::STAFF_WRITES_ONLY_MODE_KEY)
end
it 'allows staff to login' do
sso = get_sso('/a/')
sso.external_id = '666'
sso.email = 'bob@bob.com'
sso.name = 'Bob Bobson'
sso.username = 'bob'
sso.admin = true
get "/session/sso_login", params: Rack::Utils.parse_query(sso.payload), headers: headers
logged_on_user = Discourse.current_user_provider.new(request.env).current_user
expect(logged_on_user).not_to eq(nil)
end
it 'doesn\'t allow non-staff to login' do
sso = get_sso('/a/')
sso.external_id = '666'
sso.email = 'bob@bob.com'
sso.name = 'Bob Bobson'
sso.username = 'bob'
get "/session/sso_login", params: Rack::Utils.parse_query(sso.payload), headers: headers
logged_on_user = Discourse.current_user_provider.new(request.env).current_user
expect(logged_on_user).to eq(nil)
end
end
it 'does not create superfluous auth tokens when already logged in' do
user = Fabricate(:user)
sign_in(user)
@@ -1494,6 +1532,55 @@ describe SessionController do
end
describe '#create' do
context 'read only mode' do
use_redis_snapshotting
before do
Discourse.enable_readonly_mode
EmailToken.confirm(email_token.token)
EmailToken.confirm(admin_email_token.token)
end
it 'prevents login by regular users' do
post "/session.json", params: {
login: user.username, password: 'myawesomepassword'
}
expect(response.status).not_to eq(200)
end
it 'prevents login by admins' do
post "/session.json", params: {
login: user.username, password: 'myawesomepassword'
}
expect(response.status).not_to eq(200)
end
end
context 'staff writes only mode' do
use_redis_snapshotting
before do
Discourse.enable_readonly_mode(Discourse::STAFF_WRITES_ONLY_MODE_KEY)
EmailToken.confirm(email_token.token)
EmailToken.confirm(admin_email_token.token)
end
it 'allows admin login' do
post "/session.json", params: {
login: admin.username, password: 'myawesomepassword'
}
expect(response.status).to eq(200)
expect(response.parsed_body['error']).not_to be_present
end
it 'prevents login by regular users' do
post "/session.json", params: {
login: user.username, password: 'myawesomepassword'
}
expect(response.status).not_to eq(200)
end
end
context 'local login is disabled' do
before do
SiteSetting.enable_local_logins = false