app/models/key_pair.rb
require 'open3'class KeyPair < ActiveRecord::Base belongs_to :repository belongs_to :user attr_accessor :fingerprint attr_encrypted :secret, key: APP_CONFIG['keys']['key_pair_secret_key'] validates :repository, :user, presence: true validates :secret, :public, presence: true, length: { maximum: 10000 }, on: :create validates :repository_id, uniqueness: { message: I18n.t("activerecord.errors.key_pair.repo_key_exists") } validate :check_keys before_create { |record| record.key_id = @fingerprint } after_create { |record| record.repository.resign } protected Method `check_keys` has a Cognitive Complexity of 12 (exceeds 5 allowed). Consider refactoring. def check_keys dir = Dir.mktmpdir 'keys-', APP_CONFIG['tmpfs_path'] begin %w(pubring secring).each do |kind| filename = "#{dir}/#{kind}" open("#{filename}.txt", "w") { |f| f.write self.send(kind == 'pubring' ? :public : :secret) } system "gpg --homedir #{dir} --dearmor < #{filename}.txt > #{filename}.gpg" end public_key = get_info_of_key "#{dir}/pubring.txt" secret_key = get_info_of_key "#{dir}/secring.txt" if correct_key?(public_key, :public) & correct_key?(secret_key, :secret) if public_key[:fingerprint] != secret_key[:fingerprint] errors.add :secret, I18n.t('activerecord.errors.key_pair.wrong_keys') else stdin, stdout, stderr = Open3.popen3("echo '\n\n\n\n\nsave' | LC_ALL=en gpg --command-fd 0 --homedir #{dir} --edit-key #{secret_key[:keyid]} passwd") output = stderr.read if output =~ /Invalid\spassphrase/ errors.add :secret, I18n.t('activerecord.errors.key_pair.key_has_passphrase') else @fingerprint = secret_key[:fingerprint] end end end ensure # remove the directory. FileUtils.remove_entry_secure dir end end def correct_key?(info, field) if info.empty? || info[:type].blank? || info[:fingerprint].blank? || info[:keyid].blank? errors.add field, I18n.t('activerecord.errors.key_pair.wrong_key') return false else if info[:type] != field errors.add field, I18n.t("activerecord.errors.key_pair.wrong_#{field}_key") return false end end return true end Method `get_info_of_key` has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring. def get_info_of_key(file_path) results = {} str = %x[ cat #{file_path} | gpg --quiet --import-options import-show --dry-run --keyid-format LONG --import | sed -n 1,2p ] info = str.strip.split("\n") if info.size == 2 results[:fingerprint] = info[1].gsub(/.*\=/, '').strip.gsub(/\s/, ':') results[:type] = info[0] =~ /^pub\s/ ? :public : nil results[:type] ||= info[0] =~ /^sec#\s/ ? :secret : nil if keyid = info[0].match(/\/[\w]+\s/) results[:keyid] = keyid[0].strip[1..-1] end end return results end end