diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 3b4cff1f18..ce300b5b85 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -89,7 +89,14 @@ class ApplicationController < ActionController::Base # is raised here, but is denied by disable_api. # # See http://stackoverflow.com/a/15350123 for more information on login CSRF. - render_error status: 422, message: 'Invalid form authenticity token.' unless api_request? + unless api_request? + + # Check whether user have cookies enabled, otherwise they'll only be + # greeted with the CSRF error upon login. + message = I18n.t(:error_token_authenticity) + message << ' ' + I18n.t(:error_cookie_missing) if openproject_cookie_missing? + render_error status: 422, message: message + end end rescue_from ActionController::ParameterMissing do |exception| @@ -193,6 +200,13 @@ class ApplicationController < ActionController::Base require_login if Setting.login_required? end + # Checks if the session cookie is missing. + # This is useful only on a second request + def openproject_cookie_missing? + request.cookies[OpenProject::Configuration['session_cookie_name']].nil? + end + helper_method :openproject_cookie_missing? + def log_requesting_user return unless Setting.log_requesting_user? login_and_mail = " (#{escape_for_logging(User.current.login)} ID: #{User.current.id} " \ diff --git a/config/configuration.yml.example b/config/configuration.yml.example index cff1a55428..25fa1a6159 100644 --- a/config/configuration.yml.example +++ b/config/configuration.yml.example @@ -194,6 +194,9 @@ default: # autologin_cookie_path: # autologin_cookie_secure: + # Configuration of the session cookie + # session_cookie_name: the name of the OpenProject cookie (default: _open_project_session) + # disable browser cache for security reasons # see: https://websecuritytool.codeplex.com/wikipage?title=Checks#http-cache-control-header-no-store # disable_browser_cache: true diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index adeccd2dbc..05045278cc 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -35,7 +35,7 @@ session_store = config['session_store'].to_sym relative_url_root = config['rails_relative_url_root'].presence session_options = { - key: '_open_project_session', + key: config['session_cookie_name'], path: relative_url_root } diff --git a/config/locales/en.yml b/config/locales/en.yml index a1cc84d8f5..a7e558a84b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -753,6 +753,8 @@ en: error_can_not_remove_role: "This role is in use and cannot be deleted." error_can_not_reopen_work_package_on_closed_version: "A work package assigned to a closed version cannot be reopened" error_check_user_and_role: "Please choose a user and a role." + error_cookie_missing: 'The OpenProject cookie is missing. Please ensure that cookies are enabled, as this application will not properly function without.' + error_token_authenticity: 'Unable to verify Cross-Site Request Forgery token.' error_work_package_done_ratios_not_updated: "Work package done ratios not updated." error_work_package_not_found_in_project: "The work package was not found or does not belong to this project" error_must_be_project_member: "must be project member" diff --git a/lib/open_project/configuration.rb b/lib/open_project/configuration.rb index 77c8eb0aed..fff9d1ccc6 100644 --- a/lib/open_project/configuration.rb +++ b/lib/open_project/configuration.rb @@ -54,6 +54,7 @@ module OpenProject 'cache_memcache_server' => nil, # where to store session data 'session_store' => :cache_store, + 'session_cookie_name' => '_open_project_session', # url-path prefix 'rails_relative_url_root' => '', 'rails_force_ssl' => false,