Class: Gitlab::Auth::CurrentUserMode
- Inherits:
-
Object
- Object
- Gitlab::Auth::CurrentUserMode
- Defined in:
- lib/gitlab/auth/current_user_mode.rb
Overview
Keeps track of the current session user mode
In order to perform administrative tasks over some interfaces, an administrator must have explicitly enabled admin-mode e.g. on web access require re-authentication
Constant Summary collapse
- NotRequestedError =
Class.new(StandardError)
- CURRENT_REQUEST_BYPASS_SESSION_ADMIN_ID_RS_KEY =
RequestStore entries
{ res: :current_user_mode, data: :bypass_session_admin_id }.freeze
- CURRENT_REQUEST_ADMIN_MODE_USER_RS_KEY =
{ res: :current_user_mode, data: :current_admin }.freeze
- SESSION_STORE_KEY =
SessionStore entries
: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
Class Method Summary collapse
-
.bypass_session!(admin_id) ⇒ Object
Admin mode activation requires storing a flag in the user session.
- .bypass_session_admin_id ⇒ Object
- .current_admin ⇒ Object
- .reset_bypass_session!(admin_id = nil) ⇒ Object
- .uncache_admin_mode_state(admin_id = nil) ⇒ Object
-
.with_current_admin(admin) ⇒ Object
Store in the current request the provided user model (only if in admin mode) and yield.
Instance Method Summary collapse
- #admin_mode? ⇒ Boolean
- #admin_mode_requested? ⇒ Boolean
- #disable_admin_mode! ⇒ Object
- #enable_admin_mode!(password: nil, skip_password_validation: false) ⇒ Object
-
#initialize(user) ⇒ CurrentUserMode
constructor
A new instance of CurrentUserMode.
- #request_admin_mode! ⇒ Object
Constructor Details
#initialize(user) ⇒ CurrentUserMode
Returns a new instance of CurrentUserMode.
88 89 90 |
# File 'lib/gitlab/auth/current_user_mode.rb', line 88 def initialize(user) @user = user end |
Class Method Details
.bypass_session!(admin_id) ⇒ Object
Admin mode activation requires storing a flag in the user session. Using this method when scheduling jobs in sessionless environments (e.g. Sidekiq, API) will bypass the session check for a user that was already in admin mode
If passed a block, it will surround the block execution and reset the session bypass at the end; otherwise you must remember to call ‘.reset_bypass_session!’
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/gitlab/auth/current_user_mode.rb', line 31 def bypass_session!(admin_id) Gitlab::SafeRequestStore[CURRENT_REQUEST_BYPASS_SESSION_ADMIN_ID_RS_KEY] = admin_id # Bypassing the session invalidates the cached value of admin_mode? # Any new calls need to be re-computed. uncache_admin_mode_state(admin_id) Gitlab::AppLogger.debug("Bypassing session in admin mode for: #{admin_id}") return unless block_given? begin yield ensure reset_bypass_session!(admin_id) end end |
.bypass_session_admin_id ⇒ Object
54 55 56 |
# File 'lib/gitlab/auth/current_user_mode.rb', line 54 def bypass_session_admin_id Gitlab::SafeRequestStore[CURRENT_REQUEST_BYPASS_SESSION_ADMIN_ID_RS_KEY] end |
.current_admin ⇒ Object
83 84 85 |
# File 'lib/gitlab/auth/current_user_mode.rb', line 83 def current_admin Gitlab::SafeRequestStore[CURRENT_REQUEST_ADMIN_MODE_USER_RS_KEY] end |
.reset_bypass_session!(admin_id = nil) ⇒ Object
48 49 50 51 52 |
# File 'lib/gitlab/auth/current_user_mode.rb', line 48 def reset_bypass_session!(admin_id = nil) # Restoring the session bypass invalidates the cached value of admin_mode? uncache_admin_mode_state(admin_id) Gitlab::SafeRequestStore.delete(CURRENT_REQUEST_BYPASS_SESSION_ADMIN_ID_RS_KEY) end |
.uncache_admin_mode_state(admin_id = nil) ⇒ Object
58 59 60 61 62 63 64 65 66 67 |
# File 'lib/gitlab/auth/current_user_mode.rb', line 58 def uncache_admin_mode_state(admin_id = nil) if admin_id key = { res: :current_user_mode, user: admin_id, method: :admin_mode? } Gitlab::SafeRequestStore.delete(key) else Gitlab::SafeRequestStore.delete_if do |key| key.is_a?(Hash) && key[:res] == :current_user_mode && key[:method] == :admin_mode? end end end |
.with_current_admin(admin) ⇒ Object
Store in the current request the provided user model (only if in admin mode) and yield
71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/gitlab/auth/current_user_mode.rb', line 71 def with_current_admin(admin) return yield unless new(admin).admin_mode? Gitlab::SafeRequestStore[CURRENT_REQUEST_ADMIN_MODE_USER_RS_KEY] = admin Gitlab::AppLogger.debug("Admin mode active for: #{admin.username}") yield ensure Gitlab::SafeRequestStore.delete(CURRENT_REQUEST_ADMIN_MODE_USER_RS_KEY) end |
Instance Method Details
#admin_mode? ⇒ Boolean
92 93 94 95 96 97 98 |
# File 'lib/gitlab/auth/current_user_mode.rb', line 92 def admin_mode? return false unless user Gitlab::SafeRequestStore.fetch(admin_mode_rs_key) do user.admin? && (privileged_runtime? || session_with_admin_mode?) end end |
#admin_mode_requested? ⇒ Boolean
100 101 102 103 104 105 106 |
# File 'lib/gitlab/auth/current_user_mode.rb', line 100 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 |
#disable_admin_mode! ⇒ Object
124 125 126 127 128 129 130 131 |
# File 'lib/gitlab/auth/current_user_mode.rb', line 124 def disable_admin_mode! return unless user&.admin? reset_request_store_cache_entries current_session_data[ADMIN_MODE_REQUESTED_TIME_KEY] = nil current_session_data[ADMIN_MODE_START_TIME_KEY] = nil end |
#enable_admin_mode!(password: nil, skip_password_validation: false) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/gitlab/auth/current_user_mode.rb', line 108 def enable_admin_mode!(password: nil, skip_password_validation: false) return false unless user&.admin? return false unless skip_password_validation || user&.valid_password?(password) raise NotRequestedError unless admin_mode_requested? reset_request_store_cache_entries current_session_data[ADMIN_MODE_REQUESTED_TIME_KEY] = nil current_session_data[ADMIN_MODE_START_TIME_KEY] = Time.now audit_user_enable_admin_mode true end |
#request_admin_mode! ⇒ Object
133 134 135 136 137 138 139 |
# File 'lib/gitlab/auth/current_user_mode.rb', line 133 def request_admin_mode! return unless user&.admin? reset_request_store_cache_entries current_session_data[ADMIN_MODE_REQUESTED_TIME_KEY] = Time.now end |