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
session_private_id = request.session.id.private_id
client = DeviceDetector.new(request.user_agent)
timestamp = Time.current
expiry = Settings.gitlab['session_expire_delay'] * 60
active_user_session = new(
ip_address: request.remote_ip,
......@@ -86,10 +87,17 @@ class ActiveSession
redis.pipelined do
redis.setex(
key_name(user.id, session_private_id),
Settings.gitlab['session_expire_delay'] * 60,
expiry,
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(
lookup_key_name(user.id),
session_private_id
......@@ -238,9 +246,13 @@ class ActiveSession
session_ids.zip(redis.mget(entry_keys)).to_h
end
found.compact!
missing = session_ids - found.keys
return found if missing.empty?
fallbacks = Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
entry_keys = session_ids.map { |session_id| key_name_v1(user_id, session_id) }
session_ids.zip(redis.mget(entry_keys)).to_h
entry_keys = missing.map { |session_id| key_name_v1(user_id, session_id) }
missing.zip(redis.mget(entry_keys)).to_h
end
fallbacks.merge(found.compact)
......
......@@ -190,7 +190,8 @@ RSpec.describe ActiveSession, :clean_gitlab_redis_sessions do
Gitlab::Redis::Sessions.with do |redis|
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
)
end
......@@ -216,6 +217,19 @@ RSpec.describe ActiveSession, :clean_gitlab_redis_sessions do
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
created_at = Time.zone.parse('2018-03-12 09:06')
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