Files
gitlab-foss/lib/gitlab/kas/user_access.rb
2025-05-21 21:12:42 +00:00

78 lines
2.7 KiB
Ruby

# frozen_string_literal: true
module Gitlab
module Kas
# The name of the cookie that will be used for the KAS cookie
COOKIE_KEY = '_gitlab_kas'
DEFAULT_ENCRYPTED_COOKIE_CIPHER = 'aes-256-gcm'
class UserAccess
class << self
def enabled?
::Gitlab::Kas.enabled?
end
def encrypt_public_session_id(data)
encryptor.encrypt_and_sign(data.to_json, purpose: public_session_id_purpose)
end
def decrypt_public_session_id(data)
encrypted_data = data.delete_prefix(session_cookie_token_prefix)
decrypted = encryptor.decrypt_and_verify(encrypted_data, purpose: public_session_id_purpose)
::Gitlab::Json.parse(decrypted)
end
def valid_authenticity_token?(session, masked_authenticity_token)
# rubocop:disable GitlabSecurity/PublicSend
controller = ActionController::Base.new
controller.set_request!(ActionDispatch::Request.new('rack.session' => session))
controller.send(:valid_authenticity_token?, nil, masked_authenticity_token)
# rubocop:enable GitlabSecurity/PublicSend
end
def cookie_data(public_session_id)
uri = URI(::Gitlab::Kas.tunnel_url)
value = session_cookie_token_prefix + encrypt_public_session_id(public_session_id)
cookie = {
value: value,
expires: 1.day,
httponly: true,
path: uri.path.presence || '/',
secure: Gitlab.config.gitlab.https
}
# Only set domain attribute if KAS is on a subdomain.
# When on the same domain, we can omit the attribute.
gitlab_host = Gitlab.config.gitlab.host
cookie[:domain] = gitlab_host if uri.host.end_with?(".#{gitlab_host}")
cookie
end
private
def encryptor
action_dispatch_config = Gitlab::Application.config.action_dispatch
serializer = ActiveSupport::MessageEncryptor::NullSerializer
key_generator = ::Gitlab::Application.key_generator
cipher = action_dispatch_config.encrypted_cookie_cipher || DEFAULT_ENCRYPTED_COOKIE_CIPHER
salt = action_dispatch_config.authenticated_encrypted_cookie_salt
key_len = ActiveSupport::MessageEncryptor.key_len(cipher)
secret = key_generator.generate_key(salt, key_len)
ActiveSupport::MessageEncryptor.new(secret, cipher: cipher, serializer: serializer)
end
def public_session_id_purpose
"kas.user_public_session_id"
end
def session_cookie_token_prefix
Rails.application.config.session_options[:session_cookie_token_prefix] || ''
end
end
end
end
end