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
|
||||
|
||||
around_action :set_locale
|
||||
around_action :set_session_storage
|
||||
|
||||
after_action :set_page_title_header, if: :json_request?
|
||||
after_action :limit_unauthenticated_session_times
|
||||
|
@ -434,6 +435,10 @@ class ApplicationController < ActionController::Base
|
|||
Gitlab::I18n.with_user_locale(current_user, &block)
|
||||
end
|
||||
|
||||
def set_session_storage(&block)
|
||||
Gitlab::Session.with_session(session, &block)
|
||||
end
|
||||
|
||||
def set_page_title_header
|
||||
# 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'))
|
||||
|
|
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