Commit 3db96117 authored by James Edwards-Jones's avatar James Edwards-Jones

SSO Enforcement requires sign in within 7 days

Adds SSO session timeout of 7 days using existing timestamp stored when
signing in via group level SAML.

Uses a feature flag, :enforced_sso_expiry, to allow us to gradually roll
out the change.
parent a9a54b29
---
title: SSO Enforcement requires sign in within 7 days
merge_request: 29786
author:
type: changed
...@@ -4,6 +4,8 @@ module Gitlab ...@@ -4,6 +4,8 @@ module Gitlab
module Auth module Auth
module GroupSaml module GroupSaml
class SsoEnforcer class SsoEnforcer
DEFAULT_SESSION_TIMEOUT = 7.days
attr_reader :saml_provider attr_reader :saml_provider
def initialize(saml_provider) def initialize(saml_provider)
...@@ -15,8 +17,12 @@ module Gitlab ...@@ -15,8 +17,12 @@ module Gitlab
end end
def active_session? def active_session?
if ::Feature.enabled?(:enforced_sso_expiry, group)
SsoState.new(saml_provider.id).active_since?(DEFAULT_SESSION_TIMEOUT.ago)
else
SsoState.new(saml_provider.id).active? SsoState.new(saml_provider.id).active?
end end
end
def access_restricted? def access_restricted?
saml_enforced? && !active_session? && ::Feature.enabled?(:enforced_sso_requires_session, group) saml_enforced? && !active_session? && ::Feature.enabled?(:enforced_sso_requires_session, group)
......
...@@ -13,7 +13,15 @@ module Gitlab ...@@ -13,7 +13,15 @@ module Gitlab
end end
def active? def active?
!session_available? || active_session_data[saml_provider_id] sessionless? || latest_sign_in
end
def active_since?(cutoff)
return active? unless cutoff
return true if sessionless?
return false unless latest_sign_in
latest_sign_in > cutoff
end end
def update_active(value) def update_active(value)
...@@ -26,8 +34,12 @@ module Gitlab ...@@ -26,8 +34,12 @@ module Gitlab
Gitlab::NamespacedSessionStore.new(SESSION_STORE_KEY) Gitlab::NamespacedSessionStore.new(SESSION_STORE_KEY)
end end
def session_available? def sessionless?
active_session_data.initiated? !active_session_data.initiated?
end
def latest_sign_in
active_session_data[saml_provider_id]
end end
end end
end end
......
...@@ -42,6 +42,27 @@ describe Gitlab::Auth::GroupSaml::SsoEnforcer do ...@@ -42,6 +42,27 @@ describe Gitlab::Auth::GroupSaml::SsoEnforcer do
expect(subject).to be_active_session expect(subject).to be_active_session
end end
describe 'enforced sso expiry' do
before do
stub_feature_flags(enforced_sso_requires_session: { enabled: true, thing: saml_provider.group })
end
it 'returns true if a sign in is recently recorded' do
subject.update_session
expect(subject).to be_active_session
end
it 'returns false if the sign in predates the session timeout' do
subject.update_session
days_after_timeout = Gitlab::Auth::GroupSaml::SsoEnforcer::DEFAULT_SESSION_TIMEOUT + 2.days
Timecop.freeze(days_after_timeout) do
expect(subject).not_to be_active_session
end
end
end
end end
describe '#allows_access?' do describe '#allows_access?' do
......
...@@ -27,4 +27,34 @@ describe Gitlab::Auth::GroupSaml::SsoState do ...@@ -27,4 +27,34 @@ describe Gitlab::Auth::GroupSaml::SsoState do
end end
end end
end end
describe '#active_since?' do
let(:cutoff) { 1.week.ago }
it 'is always active in a sessionless request' do
is_expected.to be_active_since(cutoff)
end
it 'is inactive if never signed in' do
Gitlab::Session.with_session({}) do
is_expected.not_to be_active_since(cutoff)
end
end
it 'is active if signed in since the cut off' do
time_after_cut_off = cutoff + 2.days
Gitlab::Session.with_session(active_group_sso_sign_ins: { saml_provider_id => time_after_cut_off }) do
is_expected.to be_active_since(cutoff)
end
end
it 'is inactive if signed in before the cut off' do
time_before_cut_off = cutoff - 2.days
Gitlab::Session.with_session(active_group_sso_sign_ins: { saml_provider_id => time_before_cut_off }) do
is_expected.not_to be_active_since(cutoff)
end
end
end
end end
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