#794: update KeyPair model, write migration
This commit is contained in:
parent
06f629fdd6
commit
334b078855
2
Gemfile
2
Gemfile
|
@ -56,6 +56,8 @@ gem 'rails-backbone', '~> 0.7.2'
|
||||||
gem 'rack-throttle'
|
gem 'rack-throttle'
|
||||||
gem 'rest-client', '~> 1.6.6'
|
gem 'rest-client', '~> 1.6.6'
|
||||||
|
|
||||||
|
gem 'attr_encrypted', '1.2.1'
|
||||||
|
|
||||||
group :assets do
|
group :assets do
|
||||||
gem 'sass-rails', '~> 3.2.5'
|
gem 'sass-rails', '~> 3.2.5'
|
||||||
gem 'coffee-rails', '~> 3.2.2'
|
gem 'coffee-rails', '~> 3.2.2'
|
||||||
|
|
|
@ -58,6 +58,8 @@ GEM
|
||||||
ancestry (1.3.0)
|
ancestry (1.3.0)
|
||||||
activerecord (>= 2.3.14)
|
activerecord (>= 2.3.14)
|
||||||
arel (3.0.2)
|
arel (3.0.2)
|
||||||
|
attr_encrypted (1.2.1)
|
||||||
|
encryptor (>= 1.1.1)
|
||||||
bcrypt-ruby (3.0.1)
|
bcrypt-ruby (3.0.1)
|
||||||
blankslate (2.1.2.4)
|
blankslate (2.1.2.4)
|
||||||
bluepill (0.0.60)
|
bluepill (0.0.60)
|
||||||
|
@ -102,6 +104,7 @@ GEM
|
||||||
diff-display (0.0.1)
|
diff-display (0.0.1)
|
||||||
diff-lcs (1.1.3)
|
diff-lcs (1.1.3)
|
||||||
ejs (1.0.0)
|
ejs (1.0.0)
|
||||||
|
encryptor (1.1.3)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
escape_utils (0.2.4)
|
escape_utils (0.2.4)
|
||||||
eventmachine (0.12.10)
|
eventmachine (0.12.10)
|
||||||
|
@ -364,6 +367,7 @@ DEPENDENCIES
|
||||||
RedCloth
|
RedCloth
|
||||||
airbrake (~> 3.1.2)
|
airbrake (~> 3.1.2)
|
||||||
ancestry (~> 1.3.0)
|
ancestry (~> 1.3.0)
|
||||||
|
attr_encrypted (= 1.2.1)
|
||||||
bluepill (~> 0.0.60)
|
bluepill (~> 0.0.60)
|
||||||
cancan (= 1.6.7)
|
cancan (= 1.6.7)
|
||||||
cape
|
cape
|
||||||
|
|
|
@ -2,34 +2,59 @@ class KeyPair < ActiveRecord::Base
|
||||||
belongs_to :repository
|
belongs_to :repository
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
|
||||||
attr_accessor :secret
|
attr_accessor :fingerprint
|
||||||
attr_accessible :public, :secret, :repository_id
|
attr_accessible :public, :secret, :repository_id
|
||||||
|
attr_encrypted :secret, :key => APP_CONFIG['secret_key']
|
||||||
|
|
||||||
validates :repository_id, :public, :user_id, :presence => true
|
validates :repository_id, :public, :user_id, :presence => true
|
||||||
validates :secret, :presence => true, :on => :create
|
validates :secret, :presence => true, :on => :create
|
||||||
|
|
||||||
validates :repository_id, :uniqueness => {:message => I18n.t("activerecord.errors.key_pair.repo_key_exists")}
|
validates :repository_id, :uniqueness => {:message => I18n.t("activerecord.errors.key_pair.repo_key_exists")}
|
||||||
|
validate :check_keys
|
||||||
|
|
||||||
before_create :key_create_call
|
before_create :set_key_id
|
||||||
before_destroy :rm_key_call
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def key_create_call
|
def set_key_id
|
||||||
result, self.key_id = BuildServer.import_gpg_key_pair(public, secret)
|
self.key_id = @fingerprint
|
||||||
raise "Failed to create key_pairs for repository #{repository_id} with code #{result}." if result == 4
|
|
||||||
if result != 0 || self.key_id.nil?
|
|
||||||
errors.add(:public, I18n.t("activerecord.errors.key_pair.rpc_error_#{result}"))
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
result = BuildServer.set_repository_key(repository.platform.name, repository.name, self.key_id)
|
|
||||||
raise "Failed to sign repository #{repository.name} in platform #{repository.platform.name}
|
|
||||||
using key_id #{self.key_id} with code #{result}." unless result.zero?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def rm_key_call
|
def check_keys
|
||||||
result = BuildServer.rm_repository_key(repository.platform.name, repository.name)
|
p_key_fingerprint = fingerprint_of_key(:public)
|
||||||
raise "Failed to desroy repository key #{repository.name} in platform
|
s_key_fingerprint = fingerprint_of_key(:secret)
|
||||||
#{repository.platform.name} with code #{result}." unless result.zero?
|
if p_key_fingerprint && s_key_fingerprint
|
||||||
|
if p_key_fingerprint != s_key_fingerprint
|
||||||
|
errors.add :secret, I18n.t('activerecord.errors.key_pair.rpc_error_3')
|
||||||
|
else
|
||||||
|
@fingerprint = p_key_fingerprint
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fingerprint_of_key(field)
|
||||||
|
key = self.send(field)
|
||||||
|
tmp_file = "key-#{repository_id}-#{user_id}"
|
||||||
|
file = Tempfile.new tmp_file
|
||||||
|
file.write key
|
||||||
|
file.close
|
||||||
|
str = %x[ gpg --with-fingerprint #{file.path} | sed -n 1,2p]
|
||||||
|
info = str.strip.split("\n")
|
||||||
|
if info.size != 2 || (fingerprint = info[1].gsub(/.*\=/, '').strip.gsub(/\s/, ':') && fingerprint.present?)
|
||||||
|
errors.add field, I18n.t('activerecord.errors.key_pair.wrong_key')
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
prefix = field == :public ? 'pub' : 'sec'
|
||||||
|
if info[0] !~ /^#{prefix}/
|
||||||
|
errors.add field, I18n.t("activerecord.errors.key_pair.contains_#{field}_key")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
return fingerprint
|
||||||
|
ensure
|
||||||
|
if file
|
||||||
|
file.close
|
||||||
|
file.unlink # deletes the temp file
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,6 +21,9 @@ en:
|
||||||
rpc_error_1: could not import public key
|
rpc_error_1: could not import public key
|
||||||
rpc_error_2: could not import secret key
|
rpc_error_2: could not import secret key
|
||||||
rpc_error_3: keys are imported, but it is not a key pair (ids differ)
|
rpc_error_3: keys are imported, but it is not a key pair (ids differ)
|
||||||
|
wrong_key: wrong
|
||||||
|
contains_public_key: contains secret key
|
||||||
|
contains_secret_key: contains public key
|
||||||
models:
|
models:
|
||||||
key_pair: Key Pair
|
key_pair: Key Pair
|
||||||
attributes:
|
attributes:
|
||||||
|
|
|
@ -21,6 +21,9 @@ ru:
|
||||||
rpc_error_1: Проблемы с импортром публичного ключа
|
rpc_error_1: Проблемы с импортром публичного ключа
|
||||||
rpc_error_2: Проблемы с импортром секретного ключа
|
rpc_error_2: Проблемы с импортром секретного ключа
|
||||||
rpc_error_3: Ключи импортированы, но не являются парой (идентификаторы не совпадают)
|
rpc_error_3: Ключи импортированы, но не являются парой (идентификаторы не совпадают)
|
||||||
|
wrong_key: неправильный
|
||||||
|
contains_public_key: содержит секретный ключ
|
||||||
|
contains_secret_key: содержит публичный ключ
|
||||||
models:
|
models:
|
||||||
key_pair: Подпись
|
key_pair: Подпись
|
||||||
attributes:
|
attributes:
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
class AddEncryptedSecretToKeyPairs < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
rename_table :key_pairs, :key_pairs_backup
|
||||||
|
rename_index :key_pairs_backup, 'index_key_pairs_on_repository_id', 'index_key_pairs_backup_on_repository_id'
|
||||||
|
|
||||||
|
create_table :key_pairs do |t|
|
||||||
|
t.text :public, :null => false
|
||||||
|
t.text :encrypted_secret, :null => false
|
||||||
|
t.string :key_id, :null => false
|
||||||
|
t.references :user, :null => false
|
||||||
|
t.references :repository, :null => false
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
add_index :key_pairs, :repository_id, :unique => true
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
drop_table :key_pairs
|
||||||
|
rename_table :key_pairs_backup, :key_pairs
|
||||||
|
rename_index :key_pairs, 'index_key_pairs_backup_on_repository_id', 'index_key_pairs_on_repository_id'
|
||||||
|
end
|
||||||
|
end
|
16
db/schema.rb
16
db/schema.rb
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20121214145009) do
|
ActiveRecord::Schema.define(:version => 20121219122905) do
|
||||||
|
|
||||||
create_table "activity_feeds", :force => true do |t|
|
create_table "activity_feeds", :force => true do |t|
|
||||||
t.integer "user_id", :null => false
|
t.integer "user_id", :null => false
|
||||||
|
@ -207,6 +207,18 @@ ActiveRecord::Schema.define(:version => 20121214145009) do
|
||||||
add_index "issues", ["project_id", "serial_id"], :name => "index_issues_on_project_id_and_serial_id", :unique => true
|
add_index "issues", ["project_id", "serial_id"], :name => "index_issues_on_project_id_and_serial_id", :unique => true
|
||||||
|
|
||||||
create_table "key_pairs", :force => true do |t|
|
create_table "key_pairs", :force => true do |t|
|
||||||
|
t.text "public", :null => false
|
||||||
|
t.text "encrypted_secret", :null => false
|
||||||
|
t.string "key_id", :null => false
|
||||||
|
t.integer "user_id", :null => false
|
||||||
|
t.integer "repository_id", :null => false
|
||||||
|
t.datetime "created_at", :null => false
|
||||||
|
t.datetime "updated_at", :null => false
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "key_pairs", ["repository_id"], :name => "index_key_pairs_on_repository_id", :unique => true
|
||||||
|
|
||||||
|
create_table "key_pairs_backup", :force => true do |t|
|
||||||
t.integer "repository_id", :null => false
|
t.integer "repository_id", :null => false
|
||||||
t.integer "user_id", :null => false
|
t.integer "user_id", :null => false
|
||||||
t.string "key_id", :null => false
|
t.string "key_id", :null => false
|
||||||
|
@ -215,7 +227,7 @@ ActiveRecord::Schema.define(:version => 20121214145009) do
|
||||||
t.datetime "updated_at", :null => false
|
t.datetime "updated_at", :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "key_pairs", ["repository_id"], :name => "index_key_pairs_on_repository_id", :unique => true
|
add_index "key_pairs_backup", ["repository_id"], :name => "index_key_pairs_backup_on_repository_id", :unique => true
|
||||||
|
|
||||||
create_table "labelings", :force => true do |t|
|
create_table "labelings", :force => true do |t|
|
||||||
t.integer "label_id", :null => false
|
t.integer "label_id", :null => false
|
||||||
|
|
Loading…
Reference in New Issue