83 lines
1.6 KiB
Ruby
83 lines
1.6 KiB
Ruby
# frozen_string_literal: true
|
|
class KeysFinder
|
|
delegate :find, :find_by_id, to: :execute
|
|
|
|
InvalidFingerprint = Class.new(StandardError)
|
|
GitLabAccessDeniedError = Class.new(StandardError)
|
|
|
|
FINGERPRINT_ATTRIBUTES = {
|
|
'sha256' => 'fingerprint_sha256',
|
|
'md5' => 'fingerprint'
|
|
}.freeze
|
|
|
|
def initialize(params)
|
|
@params = params
|
|
end
|
|
|
|
def execute
|
|
keys = by_key_type
|
|
keys = by_users(keys)
|
|
keys = sort(keys)
|
|
|
|
by_fingerprint(keys)
|
|
end
|
|
|
|
private
|
|
|
|
attr_reader :params
|
|
|
|
def by_key_type
|
|
if params[:key_type] == 'ssh'
|
|
Key.regular_keys
|
|
else
|
|
Key.all
|
|
end
|
|
end
|
|
|
|
def sort(keys)
|
|
keys.order_last_used_at_desc
|
|
end
|
|
|
|
def by_users(keys)
|
|
return keys unless params[:users]
|
|
|
|
keys.for_user(params[:users])
|
|
end
|
|
|
|
def by_fingerprint(keys)
|
|
return keys unless params[:fingerprint].present?
|
|
raise InvalidFingerprint unless valid_fingerprint_param?
|
|
|
|
keys.find_by(fingerprint_query) # rubocop: disable CodeReuse/ActiveRecord
|
|
end
|
|
|
|
def valid_fingerprint_param?
|
|
return Base64.decode64(fingerprint).length == 32 if fingerprint_type == "sha256"
|
|
|
|
return false if Gitlab::FIPS.enabled?
|
|
|
|
fingerprint =~ /^(\h{2}:){15}\h{2}/
|
|
end
|
|
|
|
def fingerprint_query
|
|
fingerprint_attribute = FINGERPRINT_ATTRIBUTES[fingerprint_type]
|
|
|
|
Key.arel_table[fingerprint_attribute].eq(fingerprint)
|
|
end
|
|
|
|
def fingerprint_type
|
|
if params[:fingerprint].start_with?(/sha256:|SHA256:/)
|
|
"sha256"
|
|
else
|
|
"md5"
|
|
end
|
|
end
|
|
|
|
def fingerprint
|
|
if fingerprint_type == "sha256"
|
|
params[:fingerprint].gsub(/sha256:|SHA256:/, "")
|
|
else
|
|
params[:fingerprint]
|
|
end
|
|
end
|
|
end
|