Session stored globally per request
- This can be accessed with Session.current and is restored after. - Data can be stored under a key with NamespacedSessionStore
This commit is contained in:
parent
0f863c68bb
commit
5faa98f481
5 changed files with 103 additions and 0 deletions
|
@ -27,6 +27,7 @@ class ApplicationController < ActionController::Base
|
||||||
before_action :check_impersonation_availability
|
before_action :check_impersonation_availability
|
||||||
|
|
||||||
around_action :set_locale
|
around_action :set_locale
|
||||||
|
around_action :set_session_storage
|
||||||
|
|
||||||
after_action :set_page_title_header, if: :json_request?
|
after_action :set_page_title_header, if: :json_request?
|
||||||
after_action :limit_unauthenticated_session_times
|
after_action :limit_unauthenticated_session_times
|
||||||
|
@ -434,6 +435,10 @@ class ApplicationController < ActionController::Base
|
||||||
Gitlab::I18n.with_user_locale(current_user, &block)
|
Gitlab::I18n.with_user_locale(current_user, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_session_storage(&block)
|
||||||
|
Gitlab::Session.with_session(session, &block)
|
||||||
|
end
|
||||||
|
|
||||||
def set_page_title_header
|
def set_page_title_header
|
||||||
# Per https://tools.ietf.org/html/rfc5987, headers need to be ISO-8859-1, not UTF-8
|
# Per https://tools.ietf.org/html/rfc5987, headers need to be ISO-8859-1, not UTF-8
|
||||||
response.headers['Page-Title'] = URI.escape(page_title('GitLab'))
|
response.headers['Page-Title'] = URI.escape(page_title('GitLab'))
|
||||||
|
|
22
lib/gitlab/namespaced_session_store.rb
Normal file
22
lib/gitlab/namespaced_session_store.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Gitlab
|
||||||
|
class NamespacedSessionStore
|
||||||
|
delegate :[], :[]=, to: :store
|
||||||
|
|
||||||
|
def initialize(key)
|
||||||
|
@key = key
|
||||||
|
end
|
||||||
|
|
||||||
|
def initiated?
|
||||||
|
!Session.current.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def store
|
||||||
|
return unless Session.current
|
||||||
|
|
||||||
|
Session.current[@key] ||= {}
|
||||||
|
Session.current[@key]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
27
lib/gitlab/session.rb
Normal file
27
lib/gitlab/session.rb
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Gitlab
|
||||||
|
class Session
|
||||||
|
STORE_KEY = :session_storage
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def with_session(session)
|
||||||
|
old = self.current
|
||||||
|
self.current = session
|
||||||
|
yield
|
||||||
|
ensure
|
||||||
|
self.current = old
|
||||||
|
end
|
||||||
|
|
||||||
|
def current
|
||||||
|
Thread.current[STORE_KEY]
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def current=(value)
|
||||||
|
Thread.current[STORE_KEY] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
22
spec/lib/gitlab/namespaced_session_store_spec.rb
Normal file
22
spec/lib/gitlab/namespaced_session_store_spec.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Gitlab::NamespacedSessionStore do
|
||||||
|
let(:key) { :some_key }
|
||||||
|
subject { described_class.new(key) }
|
||||||
|
|
||||||
|
it 'stores data under the specified key' do
|
||||||
|
Gitlab::Session.with_session({}) do
|
||||||
|
subject[:new_data] = 123
|
||||||
|
|
||||||
|
expect(Thread.current[:session_storage][key]).to eq(new_data: 123)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'retrieves data from the given key' do
|
||||||
|
Thread.current[:session_storage] = { key => { existing_data: 123 } }
|
||||||
|
|
||||||
|
expect(subject[:existing_data]).to eq 123
|
||||||
|
end
|
||||||
|
end
|
27
spec/lib/gitlab/session_spec.rb
Normal file
27
spec/lib/gitlab/session_spec.rb
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Gitlab::Session do
|
||||||
|
it 'uses the current thread as a data store' do
|
||||||
|
Thread.current[:session_storage] = { a: :b }
|
||||||
|
|
||||||
|
expect(described_class.current).to eq(a: :b)
|
||||||
|
ensure
|
||||||
|
Thread.current[:session_storage] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#with_session' do
|
||||||
|
it 'sets session hash' do
|
||||||
|
described_class.with_session(one: 1) do
|
||||||
|
expect(described_class.current).to eq(one: 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'restores current store after' do
|
||||||
|
described_class.with_session(two: 2) { }
|
||||||
|
|
||||||
|
expect(described_class.current).to eq nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue