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

138 lines
3.1 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-05-18 00:54:41 +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
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
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
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,
shell_id,
2017-09-10 17:25:29 +05:30
key
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
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
2018-03-17 18:26:18 +05:30
self.fingerprint = public_key.fingerprint
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
allowed_types =
Gitlab::CurrentSettings
.allowed_key_types
.map(&:upcase)
.to_sentence(last_word_connector: ', or ', two_words_connector: ' or ')
"type is forbidden. Must be #{allowed_types}"
2017-08-17 22:00:37 +05:30
end
2014-09-02 18:07:02 +05:30
end