debian-mirror-gitlab/app/models/key.rb

151 lines
3.5 KiB
Ruby
Raw Normal View History

2018-11-18 11:00:15 +05:30
# frozen_string_literal: true
2014-09-02 18:07:02 +05:30
require 'digest/md5'
2019-07-07 11:18:12 +05:30
class Key < ApplicationRecord
2018-03-17 18:26:18 +05:30
include AfterCommitQueue
2015-04-26 12:48:37 +05:30
include Sortable
2020-01-01 13:55:28 +05:30
include Sha256Attribute
sha256_attribute :fingerprint_sha256
2014-09-02 18:07:02 +05:30
2017-08-17 22:00:37 +05:30
belongs_to :user
2014-09-02 18:07:02 +05:30
2017-08-17 22:00:37 +05:30
before_validation :generate_fingerprint
validates :title,
presence: true,
length: { maximum: 255 }
2018-03-17 18:26:18 +05:30
2017-08-17 22:00:37 +05:30
validates :key,
presence: true,
length: { maximum: 5000 },
format: { with: /\A(ssh|ecdsa)-.*\Z/ }
2018-03-17 18:26:18 +05:30
2017-08-17 22:00:37 +05:30
validates :fingerprint,
uniqueness: true,
presence: { message: 'cannot be generated' }
2014-09-02 18:07:02 +05:30
2018-03-17 18:26:18 +05:30
validate :key_meets_restrictions
2014-09-02 18:07:02 +05:30
delegate :name, :email, to: :user, prefix: true
2017-09-10 17:25:29 +05:30
after_commit :add_to_shell, on: :create
2015-04-26 12:48:37 +05:30
after_create :post_create_hook
2018-03-17 18:26:18 +05:30
after_create :refresh_user_cache
2017-09-10 17:25:29 +05:30
after_commit :remove_from_shell, on: :destroy
2015-04-26 12:48:37 +05:30
after_destroy :post_destroy_hook
2018-03-17 18:26:18 +05:30
after_destroy :refresh_user_cache
2014-09-02 18:07:02 +05:30
2020-01-01 13:55:28 +05:30
alias_attribute :fingerprint_md5, :fingerprint
scope :preload_users, -> { preload(:user) }
scope :for_user, -> (user) { where(user: user) }
scope :order_last_used_at_desc, -> { reorder(::Gitlab::Database.nulls_last_order('last_used_at', 'DESC')) }
2018-12-13 13:39:08 +05:30
def self.regular_keys
where(type: ['Key', nil])
end
2017-08-17 22:00:37 +05:30
def key=(value)
2018-03-27 19:54:05 +05:30
write_attribute(:key, value.present? ? Gitlab::SSHPublicKey.sanitize(value) : nil)
2018-03-17 18:26:18 +05:30
@public_key = nil
2014-09-02 18:07:02 +05:30
end
2015-09-11 14:41:01 +05:30
def publishable_key
2016-09-13 17:45:13 +05:30
# Strip out the keys comment so we don't leak email addresses
# Replace with simple ident of user_name (hostname)
self.key.split[0..1].push("#{self.user_name} (#{Gitlab.config.gitlab.host})").join(' ')
2015-09-11 14:41:01 +05:30
end
2014-09-02 18:07:02 +05:30
# projects that has this key
def projects
user.authorized_projects
end
def shell_id
"key-#{id}"
end
2019-09-04 21:01:54 +05:30
# EE overrides this
def can_delete?
true
end
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ServiceClass
2017-08-17 22:00:37 +05:30
def update_last_used_at
2018-03-17 18:26:18 +05:30
Keys::LastUsedService.new(self).execute
2017-08-17 22:00:37 +05:30
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ServiceClass
2017-08-17 22:00:37 +05:30
2014-09-02 18:07:02 +05:30
def add_to_shell
GitlabShellWorker.perform_async(
:add_key,
shell_id,
key
)
end
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ServiceClass
2015-04-26 12:48:37 +05:30
def post_create_hook
SystemHooksService.new.execute_hooks_for(self, :create)
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ServiceClass
2015-04-26 12:48:37 +05:30
2014-09-02 18:07:02 +05:30
def remove_from_shell
GitlabShellWorker.perform_async(
:remove_key,
2020-03-09 13:42:32 +05:30
shell_id
2014-09-02 18:07:02 +05:30
)
end
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ServiceClass
2018-03-17 18:26:18 +05:30
def refresh_user_cache
return unless user
Users::KeysCountService.new(user).refresh_cache
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ServiceClass
2018-03-17 18:26:18 +05:30
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ServiceClass
2015-04-26 12:48:37 +05:30
def post_destroy_hook
SystemHooksService.new.execute_hooks_for(self, :destroy)
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ServiceClass
2015-04-26 12:48:37 +05:30
2018-03-17 18:26:18 +05:30
def public_key
@public_key ||= Gitlab::SSHPublicKey.new(key)
end
2014-09-02 18:07:02 +05:30
private
2015-04-26 12:48:37 +05:30
def generate_fingerprint
2014-09-02 18:07:02 +05:30
self.fingerprint = nil
2020-01-01 13:55:28 +05:30
self.fingerprint_sha256 = nil
2015-04-26 12:48:37 +05:30
2018-03-27 19:54:05 +05:30
return unless public_key.valid?
2015-04-26 12:48:37 +05:30
2020-01-01 13:55:28 +05:30
self.fingerprint_md5 = public_key.fingerprint
self.fingerprint_sha256 = public_key.fingerprint("SHA256").gsub("SHA256:", "")
2014-09-02 18:07:02 +05:30
end
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
def key_meets_restrictions
restriction = Gitlab::CurrentSettings.key_restriction_for(public_key.type)
if restriction == ApplicationSetting::FORBIDDEN_KEY_VALUE
errors.add(:key, forbidden_key_type_message)
elsif public_key.bits < restriction
errors.add(:key, "must be at least #{restriction} bits")
end
end
def forbidden_key_type_message
2020-03-09 13:42:32 +05:30
allowed_types = Gitlab::CurrentSettings.allowed_key_types.map(&:upcase)
2018-03-17 18:26:18 +05:30
2020-03-09 13:42:32 +05:30
"type is forbidden. Must be #{Gitlab::Utils.to_exclusive_sentence(allowed_types)}"
2017-08-17 22:00:37 +05:30
end
2014-09-02 18:07:02 +05:30
end
2019-12-04 20:38:33 +05:30
Key.prepend_if_ee('EE::Key')