Commit 7668b6b6 authored by Alex Kalderimis's avatar Alex Kalderimis

Support mixed old-new deployments

The following changes are made:

- when setting the session, we set both the old and new formats
- when loading sessions, we skip looking for old formats if we have
  found the new ones.
parent 3ef98122
...@@ -70,6 +70,7 @@ class ActiveSession ...@@ -70,6 +70,7 @@ class ActiveSession
session_private_id = request.session.id.private_id session_private_id = request.session.id.private_id
client = DeviceDetector.new(request.user_agent) client = DeviceDetector.new(request.user_agent)
timestamp = Time.current timestamp = Time.current
expiry = Settings.gitlab['session_expire_delay'] * 60
active_user_session = new( active_user_session = new(
ip_address: request.remote_ip, ip_address: request.remote_ip,
...@@ -86,10 +87,17 @@ class ActiveSession ...@@ -86,10 +87,17 @@ class ActiveSession
redis.pipelined do redis.pipelined do
redis.setex( redis.setex(
key_name(user.id, session_private_id), key_name(user.id, session_private_id),
Settings.gitlab['session_expire_delay'] * 60, expiry,
active_user_session.dump active_user_session.dump
) )
# Deprecated legacy format - temporary to support mixed deployments
redis.setex(
key_name_v1(user.id, session_private_id),
expiry,
Marshal.dump(active_user_session)
)
redis.sadd( redis.sadd(
lookup_key_name(user.id), lookup_key_name(user.id),
session_private_id session_private_id
...@@ -238,9 +246,13 @@ class ActiveSession ...@@ -238,9 +246,13 @@ class ActiveSession
session_ids.zip(redis.mget(entry_keys)).to_h session_ids.zip(redis.mget(entry_keys)).to_h
end end
found.compact!
missing = session_ids - found.keys
return found if missing.empty?
fallbacks = Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do fallbacks = Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
entry_keys = session_ids.map { |session_id| key_name_v1(user_id, session_id) } entry_keys = missing.map { |session_id| key_name_v1(user_id, session_id) }
session_ids.zip(redis.mget(entry_keys)).to_h missing.zip(redis.mget(entry_keys)).to_h
end end
fallbacks.merge(found.compact) fallbacks.merge(found.compact)
......
...@@ -190,7 +190,8 @@ RSpec.describe ActiveSession, :clean_gitlab_redis_sessions do ...@@ -190,7 +190,8 @@ RSpec.describe ActiveSession, :clean_gitlab_redis_sessions do
Gitlab::Redis::Sessions.with do |redis| Gitlab::Redis::Sessions.with do |redis|
expect(redis.scan_each.to_a).to include( expect(redis.scan_each.to_a).to include(
described_class.key_name(user.id, session_id), described_class.key_name(user.id, session_id), # current session
described_class.key_name_v1(user.id, session_id), # support for mixed deployment
lookup_key lookup_key
) )
end end
...@@ -216,6 +217,19 @@ RSpec.describe ActiveSession, :clean_gitlab_redis_sessions do ...@@ -216,6 +217,19 @@ RSpec.describe ActiveSession, :clean_gitlab_redis_sessions do
end end
end end
it 'is possible to log in only using the old session key' do
session_id = "2::418729c72310bbf349a032f0bb6e3fce9f5a69df8f000d8ae0ac5d159d8f21ae"
ActiveSession.set(user, request)
Gitlab::Redis::SharedState.with do |redis|
redis.del(described_class.key_name(user.id, session_id))
end
sessions = ActiveSession.list(user)
expect(sessions).to be_present
end
it 'keeps the created_at from the login on consecutive requests' do it 'keeps the created_at from the login on consecutive requests' do
created_at = Time.zone.parse('2018-03-12 09:06') created_at = Time.zone.parse('2018-03-12 09:06')
updated_at = created_at + 1.minute updated_at = created_at + 1.minute
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment