diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 3c3328d7..76f75165 100755 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,6 +1,6 @@ # License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later class ApplicationController < ActionController::Base - before_filter :set_locale + before_filter :set_locale, :redirect_to_maintenance protect_from_forgery @@ -19,6 +19,15 @@ class ApplicationController < ActionController::Base end end + def redirect_to_maintenance + if (Settings&.maintenance&.maintenance_mode && !current_user) + unless (self.class == Users::SessionsController && + ((Settings.maintenance.maintenance_token && params[:maintenance_token] == Settings.maintenance.maintenance_token) || params[:format] == 'json')) + redirect_to Settings.maintenance.maintenance_page + end + end + end + protected def json_saved(model, msg=nil) diff --git a/config/environment.rb b/config/environment.rb index b8209deb..b036d1a3 100755 --- a/config/environment.rb +++ b/config/environment.rb @@ -268,6 +268,20 @@ Config.schema do end end + # the settings to get into maintenance_mode + optional(:maintenance).schema do + # true if you want to be in maintenance mode, otherwise false + required(:maintenance_mode).filled(:bool?) + + # the token you pass into /users/sign_in to actually get to + # a signin page during maintenance mode + optional(:maintenance_token).filled(:str?) + + # the url, absolute or relative, that visitors should be redirected to + optional(:maintenance_page).filled(:str?) + + end + end Settings.reload! diff --git a/config/initializers/config.rb b/config/initializers/config.rb index 897a47c5..b253585e 100644 --- a/config/initializers/config.rb +++ b/config/initializers/config.rb @@ -2,7 +2,7 @@ Config.setup do |config| # Name of the constant exposing loaded settings config.const_name = 'Settings' - + config.use_env = true # Ability to remove elements of the array set in earlier loaded settings file. For example value: '--'. # # config.knockout_prefix = nil diff --git a/public/maintenance.html b/public/maintenance.html index 1f46eb24..75e2d914 100644 --- a/public/maintenance.html +++ b/public/maintenance.html @@ -26,7 +26,6 @@

Houdini Project

We're down for maintenance.

-

All of our hamsters needed a break from running in their wheels all day.

We're sorry for the inconvenience. Please check back soon.

diff --git a/spec/requests/maintenance_spec.rb b/spec/requests/maintenance_spec.rb new file mode 100644 index 00000000..407558bc --- /dev/null +++ b/spec/requests/maintenance_spec.rb @@ -0,0 +1,113 @@ +# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later +require 'rails_helper' +require 'controllers/support/shared_user_context' + +describe 'Maintenance Mode' do + page = "http://commet" + token = "thoathioa" + include_context :shared_user_context + around(:each) do |example| + example.run + Settings.reload! + end + + describe OnboardController, type: :controller do + describe '(Onboard is just a basic example controller)' + it 'not in maintenance mode' do + get :index + assert_response 200 + end + + describe 'in maintenance' do + before(:each) do + Settings.merge!({maintenance: + {maintenance_mode: true, + maintenance_token: token, + maintenance_page: page}}) + end + + it 'redirects for onboard' do + get :index + assert_redirected_to page + end + + it 'allows access to non-sign_in pages if youre logged in' do + sign_in user_as_np_associate + get :index + assert_response 200 + end + end + end + + describe Users::SessionsController, type: :controller do + describe 'in maintenance' do + include_context :shared_user_context + around(:each) do |example| + example.run + Settings.reload! + end + + before(:each) do + @request.env["devise.mapping"] = Devise.mappings[:user] + end + + describe 'in maintenance' do + before(:each) do + Settings.merge!({maintenance: + {maintenance_mode: true, + maintenance_token: token, + maintenance_page: page}}) + end + + it 'redirects sign_in if the token is wrong' do + get(:new, {maintenance_token: "#{token}3"}) + expect(response.code).to eq "302" + expect(response.location).to eq page + end + + it 'redirects for login' do + get(:new) + expect(response.code).to eq "302" + expect(response.location).to eq page + end + + + it 'redirects sign_in if the token is passed in wrong param' do + get(:new, {maintnancerwrwer_token: "#{token}"}) + expect(response.code).to eq "302" + expect(response.location).to eq page + end + + it 'allows sign_in if the token is passed' do + get(:new, {maintenance_token: "#{token}"}) + expect(response.code).to eq '200' + end + + it 'allows sign_in.json' do + get(:new, {maintenance_token: "#{token}", format: 'json'}) + expect(response.code).to eq '406' + end + end + end + + describe 'in maintenance without maintenance_token set' do + before(:each) do + @request.env["devise.mapping"] = Devise.mappings[:user] + end + before(:each) do + Settings.merge!({maintenance: + {maintenance_mode: true, + maintenance_token: nil, + maintenance_page: page}}) + end + + it 'redirects sign_in if the token is nil' do + get(:new) + expect(response.code).to eq "302" + expect(response.location).to eq page + end + end + + end +end +