diff options
Diffstat (limited to 'lib/gitlab/auth/current_user_mode.rb')
-rw-r--r-- | lib/gitlab/auth/current_user_mode.rb | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/lib/gitlab/auth/current_user_mode.rb b/lib/gitlab/auth/current_user_mode.rb index df5039f50c1..cb39baaa6cc 100644 --- a/lib/gitlab/auth/current_user_mode.rb +++ b/lib/gitlab/auth/current_user_mode.rb @@ -8,9 +8,13 @@ module Gitlab # an administrator must have explicitly enabled admin-mode # e.g. on web access require re-authentication class CurrentUserMode + NotRequestedError = Class.new(StandardError) + SESSION_STORE_KEY = :current_user_mode ADMIN_MODE_START_TIME_KEY = 'admin_mode' + ADMIN_MODE_REQUESTED_TIME_KEY = 'admin_mode_requested' MAX_ADMIN_MODE_TIME = 6.hours + ADMIN_MODE_REQUESTED_GRACE_PERIOD = 5.minutes def initialize(user) @user = user @@ -19,8 +23,16 @@ module Gitlab def admin_mode? return false unless user - Gitlab::SafeRequestStore.fetch(request_store_key) do - user&.admin? && any_session_with_admin_mode? + Gitlab::SafeRequestStore.fetch(admin_mode_rs_key) do + user.admin? && any_session_with_admin_mode? + end + end + + def admin_mode_requested? + return false unless user + + Gitlab::SafeRequestStore.fetch(admin_mode_requested_rs_key) do + user.admin? && admin_mode_requested_in_grace_period? end end @@ -28,20 +40,45 @@ module Gitlab return unless user&.admin? return unless skip_password_validation || user&.valid_password?(password) + raise NotRequestedError unless admin_mode_requested? + + reset_request_store + + current_session_data[ADMIN_MODE_REQUESTED_TIME_KEY] = nil current_session_data[ADMIN_MODE_START_TIME_KEY] = Time.now end + def enable_sessionless_admin_mode! + request_admin_mode! && enable_admin_mode!(skip_password_validation: true) + end + def disable_admin_mode! + return unless user&.admin? + + reset_request_store + + current_session_data[ADMIN_MODE_REQUESTED_TIME_KEY] = nil current_session_data[ADMIN_MODE_START_TIME_KEY] = nil - Gitlab::SafeRequestStore.delete(request_store_key) + end + + def request_admin_mode! + return unless user&.admin? + + reset_request_store + + current_session_data[ADMIN_MODE_REQUESTED_TIME_KEY] = Time.now end private attr_reader :user - def request_store_key - @request_store_key ||= { res: :current_user_mode, user: user.id } + def admin_mode_rs_key + @admin_mode_rs_key ||= { res: :current_user_mode, user: user.id, method: :admin_mode? } + end + + def admin_mode_requested_rs_key + @admin_mode_requested_rs_key ||= { res: :current_user_mode, user: user.id, method: :admin_mode_requested? } end def current_session_data @@ -61,6 +98,15 @@ module Gitlab Gitlab::NamespacedSessionStore.new(SESSION_STORE_KEY, session.with_indifferent_access ) end end + + def admin_mode_requested_in_grace_period? + current_session_data[ADMIN_MODE_REQUESTED_TIME_KEY].to_i > ADMIN_MODE_REQUESTED_GRACE_PERIOD.ago.to_i + end + + def reset_request_store + Gitlab::SafeRequestStore.delete(admin_mode_rs_key) + Gitlab::SafeRequestStore.delete(admin_mode_requested_rs_key) + end end end end |