aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2016-07-21 10:01:28 +0200
committerJulien Lancelot <julien.lancelot@sonarsource.com>2016-09-09 10:10:51 +0200
commit33e007102cd99490694f44f070d3319005621943 (patch)
tree52146ef0e7057b7df9adbc49c12f0aec4c474303
parent79c3bfc01953b03cee1e0bf210cf11734ce9ef24 (diff)
downloadsonarqube-33e007102cd99490694f44f070d3319005621943.tar.gz
sonarqube-33e007102cd99490694f44f070d3319005621943.zip
SONAR-7758 Rails flash feature should not use HTTP session
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/controllers/application_controller.rb1
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/controllers/sessions_controller.rb4
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/layouts/_footer.html.erb16
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/sessions/_form.html.erb27
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/gems/gems/actionpack-2.3.15/lib/action_controller/base.rb3
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/gems/gems/actionpack-2.3.15/lib/action_controller/flash.rb4
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/lib/authenticated_system.rb1
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/lib/cookie_flash.rb59
8 files changed, 98 insertions, 17 deletions
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 @@
</div>
<!--<![endif]-->
-<% if flash[:notice] || flash[:warning] || flash[:error] %>
+<% if cookies['flash'] %>
<script>
- <% if flash[:notice] %>info('<%= escape_javascript(flash[:notice])-%>');<% end %>
- <% if flash[:warning] %>warning('<%= escape_javascript(flash[:warning])-%>');<% end %>
- <% if flash[:error] %>error('<%= escape_javascript(flash[:error])-%>');<% end %>
+ var data = JSON.parse(unescape('<%= escape_javascript(cookies['flash']) -%>'));
+ if (data['notice']) {
+ info(data['notice'].toString().replace(/\+/g, ' '));
+ }
+ if (data['warning']) {
+ warning(data['warning'].toString().replace(/\+/g, ' '));
+ }
+ if (data['error']) {
+ error(data['error'].toString().replace(/\+/g, ' '));
+ }
</script>
<% end %>
+<% cookies.delete 'flash' %>
<script src="<%= ApplicationController.root_context -%>/js/bundles/main.js?v=<%= sonar_version -%>"></script>
<%= 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 @@
<input type="hidden" name="return_to_anchor" value="<%= h @return_to_anchor %>">
<div class="alert alert-danger alert-authentication-failed hidden"><%= message('session.flash_notice.authentication_failed') %></div>
- <% if flash[:loginerror] %>
- <div class="alert alert-danger alert-flash"> <%= flash[:loginerror] %></div>
- <% end %>
- <% if flash[:notice] %>
- <div class="alert alert-info alert-flash"><%= flash[:notice] %></div>
- <% end %>
+ <div class="hidden" id="messages-panel">
+ <div class="alert alert-danger alert-flash hidden" id="error">
+ <span id="errormsg"></span>
+ </div>
+ <div class="alert alert-info alert-flash hidden" id="info">
+ <span id="infomsg"></span>
+ </div>
+ </div>
<div class="big-spacer-bottom">
<label for="login" class="login-label"><%= message('login') %></label>
@@ -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);
</script>
+
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