73 lines
2.5 KiB
Ruby
73 lines
2.5 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? && ::Feature.enabled?(:kas_user_access)
|
|
end
|
|
|
|
def enabled_for?(agent)
|
|
enabled? && ::Feature.enabled?(:kas_user_access_project, agent.project)
|
|
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)
|
|
decrypted = encryptor.decrypt_and_verify(data, purpose: public_session_id_purpose)
|
|
::Gitlab::Json.parse(decrypted)
|
|
end
|
|
|
|
def valid_authenticity_token?(session, masked_authenticity_token)
|
|
# rubocop:disable GitlabSecurity/PublicSend
|
|
ActionController::Base.new.send(:valid_authenticity_token?, session, masked_authenticity_token)
|
|
# rubocop:enable GitlabSecurity/PublicSend
|
|
end
|
|
|
|
def cookie_data(public_session_id)
|
|
uri = URI(::Gitlab::Kas.tunnel_url)
|
|
|
|
cookie = {
|
|
value: encrypt_public_session_id(public_session_id),
|
|
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
|
|
end
|
|
end
|
|
end
|
|
end
|