From: Julien Lancelot Date: Thu, 21 Jul 2016 08:01:28 +0000 (+0200) Subject: SONAR-7758 Rails flash feature should not use HTTP session X-Git-Tag: 6.1-RC1~159 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=33e007102cd99490694f44f070d3319005621943;p=sonarqube.git SONAR-7758 Rails flash feature should not use HTTP session --- diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/application_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/application_controller.rb index 0f19befb9b9..dc1cba4fc8b 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/application_controller.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/application_controller.rb @@ -21,6 +21,7 @@ class ApplicationController < ActionController::Base include AuthenticatedSystem include NeedAuthorization::Helper + include CookieFlash before_filter :check_database_version, :set_i18n, :check_authentication diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/sessions_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/sessions_controller.rb index 51e8fda5ae0..f688c3551db 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/sessions_controller.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/sessions_controller.rb @@ -32,8 +32,8 @@ class SessionsController < ApplicationController if logged_in? self.current_user.on_logout end - flash[:notice]=message('session.flash_notice.logged_out') - reset_session + cookies.delete 'JWT-SESSION' + cookies.delete 'XSRF-TOKEN' redirect_to(home_path) end diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_footer.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_footer.html.erb index c5dbab53411..cccfd95447c 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_footer.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_footer.html.erb @@ -8,13 +8,21 @@ -<% if flash[:notice] || flash[:warning] || flash[:error] %> +<% if cookies['flash'] %> <% end %> +<% cookies.delete 'flash' %> <%= yield :extra_script -%> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/sessions/_form.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/sessions/_form.html.erb index 3cb6a3187e0..9a5399f6e98 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/sessions/_form.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/sessions/_form.html.erb @@ -23,12 +23,14 @@ - <% if flash[:loginerror] %> -
<%= flash[:loginerror] %>
- <% end %> - <% if flash[:notice] %> -
<%= flash[:notice] %>
- <% end %> +
@@ -76,5 +78,18 @@ 401: null } }); + + <% if cookies['flash'] %> + var data = JSON.parse(unescape('<%= escape_javascript(cookies['flash']) -%>')); + if (data['loginerror']) { + error(data['loginerror'].toString().replace(/\+/g, ' ')); + } + if (data['info']) { + info(data['info'].toString().replace(/\+/g, ' ')); + } + <% cookies.delete 'flash' %> + <% end %> + })(window.jQuery); + diff --git a/server/sonar-web/src/main/webapp/WEB-INF/gems/gems/actionpack-2.3.15/lib/action_controller/base.rb b/server/sonar-web/src/main/webapp/WEB-INF/gems/gems/actionpack-2.3.15/lib/action_controller/base.rb index 3cc1d061939..41a8a64ad26 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/gems/gems/actionpack-2.3.15/lib/action_controller/base.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/gems/gems/actionpack-2.3.15/lib/action_controller/base.rb @@ -1241,9 +1241,6 @@ module ActionController #:nodoc: # Resets the session by clearing out all the objects stored within and initializing a new session object. def reset_session #:doc: - cookies.delete 'JWT-SESSION' - cookies.delete 'XSRF-TOKEN' - request.reset_session @_session = request.session end diff --git a/server/sonar-web/src/main/webapp/WEB-INF/gems/gems/actionpack-2.3.15/lib/action_controller/flash.rb b/server/sonar-web/src/main/webapp/WEB-INF/gems/gems/actionpack-2.3.15/lib/action_controller/flash.rb index e15d0d80e76..a47b8b5476e 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/gems/gems/actionpack-2.3.15/lib/action_controller/flash.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/gems/gems/actionpack-2.3.15/lib/action_controller/flash.rb @@ -127,7 +127,7 @@ module ActionController #:nodoc: def store(session, key = "flash") return if self.empty? - session[key] = self + raise "Session are disabled" end private @@ -181,7 +181,7 @@ module ActionController #:nodoc: # to put a new one. def flash #:doc: if !defined?(@_flash) - @_flash = session["flash"] || FlashHash.new + @_flash = FlashHash.new @_flash.sweep end diff --git a/server/sonar-web/src/main/webapp/WEB-INF/lib/authenticated_system.rb b/server/sonar-web/src/main/webapp/WEB-INF/lib/authenticated_system.rb index 83ac2b912c4..f60edd6088b 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/lib/authenticated_system.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/lib/authenticated_system.rb @@ -78,6 +78,7 @@ module AuthenticatedSystem if logged_in? flash[:loginerror]='You are not authorized to access this page. Please log in with more privileges and try again.' end + write_flash_to_cookie redirect_to url_for :controller => '/sessions', :action => 'new' end # format.any doesn't work in rails version < http://dev.rubyonrails.org/changeset/8987 diff --git a/server/sonar-web/src/main/webapp/WEB-INF/lib/cookie_flash.rb b/server/sonar-web/src/main/webapp/WEB-INF/lib/cookie_flash.rb new file mode 100644 index 00000000000..1a0c9289981 --- /dev/null +++ b/server/sonar-web/src/main/webapp/WEB-INF/lib/cookie_flash.rb @@ -0,0 +1,59 @@ +require 'json' + +module CookieFlash + + def self.included(base) + #base must define around_action or around_filter, as in Rails + + around_method = if base.respond_to?(:around_action) + :around_action + else + :around_filter + end + + base.send around_method, :write_flash_to_cookie + end + + def write_flash_to_cookie + yield if block_given? + + if !flash.empty? + cookies['flash'] = { :value => cookie_flash(flash, cookies)} + # because flashes are only removed from cookies when they are used. + flash.clear + end + end + + # @parameters + # cookies - + # There might be crusty flash from a previous request, or set elsewhere, already in the cookie. + # Pull it out and parse it so we can preserve it. + # flash - + # This is the fresh, super-stacked (by stackable_flash gem) FlashHash from the current request. + # Needs to be added to the cookie flash. + def cookie_flash(flash, cookies) + cflash = (JSON.parse(cookies['flash']) if cookies['flash']) || {} rescue {} + + flash.each do |key, value| # key like :notice, or :error, or :sticky + # When stacking we won't be escaping anything here, because will be array, not string + value = ERB::Util.html_escape(value) if value.kind_of?(String) && !value.html_safe? # Since v0.3.0 only escaping strings + skey = key.to_s + # This allows any data type to be stored in the cookie; important for using an array as the value with + # stackable_flash + # The cookie flash will generally be set to a value stacked according to the :stack_with_proc of stackable_flash + # But when there is already a value for the cookie when we get here, we need to join them somehow. + stacked_value = value.respond_to?(:stack) ? value.stack : value + if cflash[skey].kind_of?(Array) # Just because it could be an array + if stacked_value.kind_of?(Array) + cflash[skey] += stacked_value + else + cflash[skey] << stacked_value + end + else + cflash[skey] = stacked_value + end + end + # I have forgotten why the gsub + matters, so NOTE: to future self: document weird shit. + cflash.to_json.gsub("+", "%2B") + end +end