Extract LoginState and LogoutState classes

parent e6159431
......@@ -8,42 +8,20 @@ module Gitlab
attr_accessor :return_to
def oauth_state_valid?
return false unless state
salt, hmac, return_to = state.split(':', 3)
return false unless return_to
hmac == generate_oauth_hmac(salt, return_to)
salt, hmac, return_to = state.to_s.split(':', 3)
LoginState.new(salt, return_to).valid?(hmac)
end
def generate_oauth_state
return unless return_to
hmac = generate_oauth_hmac(oauth_salt, return_to)
self.state = "#{oauth_salt}:#{hmac}:#{return_to}"
self.state = LoginState.new(oauth_salt, return_to).encode
end
def generate_logout_state
return unless access_token
cipher = logout_token_cipher(oauth_salt, :encrypt)
encrypted = cipher.update(access_token) + cipher.final
full_path = ReturnToLocation.new(return_to).full_path
self.state = "#{oauth_salt}:#{Base64.urlsafe_encode64(encrypted)}:#{full_path}"
rescue OpenSSL::OpenSSLError
false
self.state = LogoutState.new(oauth_salt, access_token, return_to).encode
end
def extract_logout_token
return unless state.present?
salt, encrypted, _ = state.split(':', 3)
decipher = logout_token_cipher(salt, :decrypt)
decipher.update(Base64.urlsafe_decode64(encrypted)) + decipher.final
rescue OpenSSL::OpenSSLError
false
LogoutState.new(*state.to_s.split(':', 3)).decode
end
def get_oauth_state_return_to
......@@ -71,6 +49,65 @@ module Gitlab
private
class LoginState < Struct.new(:salt, :return_to)
def valid?(hmac)
return false unless salt && return_to
hmac == generate_hmac
end
def encode
return unless salt && return_to
"#{salt}:#{generate_hmac}:#{return_to}"
end
private
def generate_hmac
digest = OpenSSL::Digest.new('sha256')
key = Gitlab::Application.secrets.secret_key_base + salt
OpenSSL::HMAC.hexdigest(digest, key, return_to)
end
end
class LogoutState < Struct.new(:salt, :token, :return_to)
def decode
return unless salt && token
decrypt = cipher(salt, :decrypt)
decrypt.update(Base64.urlsafe_decode64(token)) + decrypt.final
rescue OpenSSL::OpenSSLError
nil
end
def encode
return unless token
encrypt = cipher(salt, :encrypt)
encrypted = encrypt.update(token) + encrypt.final
encoded = Base64.urlsafe_encode64(encrypted)
"#{salt}:#{encoded}:#{full_path}"
rescue OpenSSL::OpenSSLError
nil
end
private
def cipher(salt, operation)
cipher = OpenSSL::Cipher::AES.new(128, :CBC)
cipher.__send__(operation) # rubocop:disable GitlabSecurity/PublicSend
cipher.iv = salt
cipher.key = Settings.attr_encrypted_db_key_base[0..15]
cipher
end
def full_path
ReturnToLocation.new(return_to).full_path
end
end
class ReturnToLocation < Struct.new(:location)
def full_path
uri = parse_uri(location)
......@@ -91,22 +128,6 @@ module Gitlab
end
end
def generate_oauth_hmac(salt, return_to)
return false unless return_to
digest = OpenSSL::Digest.new('sha256')
key = Gitlab::Application.secrets.secret_key_base + salt
OpenSSL::HMAC.hexdigest(digest, key, return_to)
end
def logout_token_cipher(salt, operation)
cipher = OpenSSL::Cipher::AES.new(128, :CBC)
cipher.__send__(operation) # rubocop:disable GitlabSecurity/PublicSend
cipher.iv = salt
cipher.key = Settings.attr_encrypted_db_key_base[0..15]
cipher
end
def oauth_salt
@salt ||= SecureRandom.hex(8)
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