diff options
Diffstat (limited to 'app/models/key.rb')
-rw-r--r-- | app/models/key.rb | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/app/models/key.rb b/app/models/key.rb index 49bc26122fa..27c91679ec9 100644 --- a/app/models/key.rb +++ b/app/models/key.rb @@ -1,6 +1,8 @@ require 'digest/md5' class Key < ActiveRecord::Base + include AfterCommitQueue + include Gitlab::CurrentSettings include Sortable LAST_USED_AT_REFRESH_TIME = 1.day.to_i @@ -12,14 +14,18 @@ class Key < ActiveRecord::Base validates :title, presence: true, length: { maximum: 255 } + validates :key, presence: true, length: { maximum: 5000 }, format: { with: /\A(ssh|ecdsa)-.*\Z/ } + validates :fingerprint, uniqueness: true, presence: { message: 'cannot be generated' } + validate :key_meets_minimum_bit_length, :key_type_is_allowed + delegate :name, :email, to: :user, prefix: true after_commit :add_to_shell, on: :create @@ -80,6 +86,10 @@ class Key < ActiveRecord::Base SystemHooksService.new.execute_hooks_for(self, :destroy) end + def public_key + @public_key ||= Gitlab::SSHPublicKey.new(key) + end + private def generate_fingerprint @@ -87,7 +97,40 @@ class Key < ActiveRecord::Base return unless self.key.present? - self.fingerprint = Gitlab::KeyFingerprint.new(self.key).fingerprint + self.fingerprint = public_key.fingerprint + end + + def key_meets_minimum_bit_length + case public_key.type + when :rsa + if public_key.bits < current_application_settings.minimum_rsa_bits + errors.add(:key, "length must be at least #{current_application_settings.minimum_rsa_bits} bits") + end + when :dsa + if public_key.bits < current_application_settings.minimum_dsa_bits + errors.add(:key, "length must be at least #{current_application_settings.minimum_dsa_bits} bits") + end + when :ecdsa + if public_key.bits < current_application_settings.minimum_ecdsa_bits + errors.add(:key, "elliptic curve size must be at least #{current_application_settings.minimum_ecdsa_bits} bits") + end + when :ed25519 + if public_key.bits < current_application_settings.minimum_ed25519_bits + errors.add(:key, "length must be at least #{current_application_settings.minimum_ed25519_bits} bits") + end + end + end + + def key_type_is_allowed + unless current_application_settings.allowed_key_types.include?(public_key.type.to_s) + allowed_types = + current_application_settings + .allowed_key_types + .map(&:upcase) + .to_sentence(last_word_connector: ', or ', two_words_connector: ' or ') + + errors.add(:key, "type is not allowed. Must be #{allowed_types}") + end end def notify_user |