Skip to content

Commit

Permalink
Update migration
Browse files Browse the repository at this point in the history
  • Loading branch information
dnfd committed Aug 9, 2019
1 parent 132f71f commit 31b5c73
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 22 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ gem 'peatio', '~> 0.6.1'
gem 'rack-cors', '~> 1.0.2', require: false
gem 'env-tweaks', '~> 1.0.0'
gem 'vault', '~> 0.12', require: false
gem 'vault-rails', '~> 0.5.0', git: 'http://github.com/dnfd/vault-rails'
gem 'vault-rails', '~> 0.5.0', git: 'http://github.com/rubykube/vault-rails'
gem 'bootsnap', '>= 1.1.0', require: false
gem 'net-http-persistent', '~> 3.0.1'

Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
GIT
remote: http://github.com/dnfd/vault-rails
revision: 1d191f32709a478675894c17c720cb5f7493e09a
remote: http://github.com/rubykube/vault-rails
revision: ef9b8626e4bf41dcea8696c4aec91e543ddd80a5
specs:
vault-rails (0.5.0)
rails (>= 4.1)
Expand Down
4 changes: 3 additions & 1 deletion app/models/payment_address.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class PaymentAddress < ApplicationRecord
include BelongsToCurrency
include BelongsToAccount

vault_lazy_decrypt!

after_commit :enqueue_address_generation

validates :address, uniqueness: { scope: :currency_id }, if: :address?
Expand Down Expand Up @@ -53,7 +55,7 @@ def to_cash_address
# account_id :integer not null
# address :string(95)
# secret_encrypted :string(255)
# details_encrypted :string(255)
# details_encrypted :string(1024)
# created_at :datetime not null
# updated_at :datetime not null
#
Expand Down
3 changes: 2 additions & 1 deletion app/models/wallet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class Wallet < ApplicationRecord
ENUMERIZED_KINDS = { deposit: 100, fee: 200, hot: 310, warm: 320, cold: 330 }.freeze
enumerize :kind, in: ENUMERIZED_KINDS, scope: true

# Remove after admin panel deletion.
SETTING_ATTRIBUTES = %i[ uri
secret
bitgo_test_net
Expand Down Expand Up @@ -123,10 +124,10 @@ def wallet_url
# kind :integer not null
# nsig :integer
# gateway :string(20) default(""), not null
# settings_encrypted :string(1024)
# max_balance :decimal(32, 16) default(0.0), not null
# parent :integer
# status :string(32)
# settings_encrypted :string(255)
# created_at :datetime not null
# updated_at :datetime not null
#
Expand Down
4 changes: 2 additions & 2 deletions config/initializers/vault.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
# frozen_string_literal: true

require 'vault/totp'
require "vault/rails"
require 'vault/rails'

Vault.configure do |config|
config.address = ENV.fetch('VAULT_URL', 'http://127.0.0.1:8200')
config.token = ENV.fetch('VAULT_TOKEN')
config.ssl_verify = false
config.timeout = 60
config.application = 'peatio'
config.application = ENV.fetch('VAULT_APP_NAME', 'peatio')
end
Original file line number Diff line number Diff line change
@@ -1,26 +1,67 @@
class AddEncryptedSecretToPaymentAddress < ActiveRecord::Migration[5.2]
def up
secrets = PaymentAddress.pluck(:id, :secret)
# details = PaymentAddress.pluck(:id, :details)
# settings = Wallet.pluck(:id, :settings)
details = PaymentAddress.pluck(:id, :details)
settings = Wallet.pluck(:id, :settings)

remove_column :payment_addresses, :secret
add_column :payment_addresses, :secret_encrypted , :string, after: :address

remove_column :payment_addresses, :details
add_column :payment_addresses, :details_encrypted , :string, after: :secret_encrypted
add_column :payment_addresses, :details_encrypted , :string, limit: 1024, after: :secret_encrypted

remove_column :wallets, :settings
add_column :wallets, :settings_encrypted , :string, after: :status
add_column :wallets, :settings_encrypted , :string, limit: 1024, after: :gateway

secrets.each do |s|
atr = PaymentAddress.__vault_attributes[:secret]
enc = Vault::Rails.encrypt(atr[:path], atr[:key], s[1])
# PaymentAddress.find(s[0]).update!(secret: s[1])
execute "UPDATE payment_addresses SET secret_encrypted = #{enc} WHERE id = #{s[0]}"
execute "UPDATE payment_addresses SET #{atr[:encrypted_column]} = '#{enc}' WHERE id = #{s[0]}"
end

details.each do |d|
atr = PaymentAddress.__vault_attributes[:details]
enc = Vault::Rails.encrypt(atr[:path], atr[:key], d[1])
execute "UPDATE payment_addresses SET #{atr[:encrypted_column]} = '#{enc}' WHERE id = #{d[0]}"
end

settings.each do |s|
atr = Wallet.__vault_attributes[:settings]
enc = Vault::Rails.encrypt(atr[:path], atr[:key], s[1])
execute "UPDATE wallets SET #{atr[:encrypted_column]} = '#{enc}' WHERE id = #{s[0]}"
end
# details.each { |s| PaymentAddress.find(s[0]).update(details_encrypted: s[1]) }
# settings.each { |s| Wallet.find(s[0]).update(settings_encrypted: s[1]) }
end

def down
secrets = PaymentAddress.pluck(:id, :secret_encrypted)
details = PaymentAddress.pluck(:id, :details_encrypted)
settings = Wallet.pluck(:id, :settings_encrypted)

add_column :payment_addresses, :secret, :string, limit: 128, after: :address
remove_column :payment_addresses, :secret_encrypted , :string, after: :address

add_column :payment_addresses, :details, :string, limit: 1.kilobyte, null: false, default: '{}', after: :secret
remove_column :payment_addresses, :details_encrypted , :string, limit: 1024, after: :secret_encrypted

add_column :wallets, :settings, :string, limit: 1000, default: '{}', null: false, after: :gateway
remove_column :wallets, :settings_encrypted , :string, limit: 1024, after: :gateway

secrets.each do |s|
atr = PaymentAddress.__vault_attributes[:secret]
dec = Vault::Rails.decrypt(atr[:path], atr[:key], s[1])
execute "UPDATE payment_addresses SET secret = '#{dec}' WHERE id = #{s[0]}"
end

details.each do |d|
atr = PaymentAddress.__vault_attributes[:details]
dec = Vault::Rails.decrypt(atr[:path], atr[:key], d[1])
execute "UPDATE payment_addresses SET details = '#{dec}' WHERE id = #{d[0]}"
end

settings.each do |s|
atr = Wallet.__vault_attributes[:settings]
dec = Vault::Rails.decrypt(atr[:path], atr[:key], s[1])
execute "UPDATE wallets SET settings = '#{dec}' WHERE id = #{s[0]}"
end
end
end
4 changes: 2 additions & 2 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@
t.integer "account_id", null: false
t.string "address", limit: 95
t.string "secret_encrypted"
t.string "details_encrypted"
t.string "details_encrypted", limit: 1024
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["currency_id", "address"], name: "index_payment_addresses_on_currency_id_and_address", unique: true
Expand Down Expand Up @@ -278,10 +278,10 @@
t.integer "kind", null: false
t.integer "nsig"
t.string "gateway", limit: 20, default: "", null: false
t.string "settings_encrypted", limit: 1024
t.decimal "max_balance", precision: 32, scale: 16, default: "0.0", null: false
t.integer "parent"
t.string "status", limit: 32
t.string "settings_encrypted"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["currency_id"], name: "index_wallets_on_currency_id"
Expand Down
33 changes: 28 additions & 5 deletions spec/models/payment_address_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,38 @@
context '.create' do
let(:member) { create(:member, :level_3) }
let!(:account) { member.get_account(:btc) }
let(:secret) { 's3cr3t' }
let(:details) { { 'a' => 'b', 'b' => 'c' } }
let!(:addr) { create(:payment_address, :btc_address, secret: secret) }

after do
DatabaseCleaner.strategy = :truncation
end

it 'generate address after commit', clean_database_with_truncation: true do
it 'generate address after commit' do
AMQPQueue.expects(:enqueue)
.with(:deposit_coin_address, { account_id: account.id }, { persistent: true })
account.payment_address
end

it 'updates secret' do
expect {
addr.update(secret: 'new_secret')
}.to change { addr.reload.secret_encrypted }.and change { addr.reload.secret }.to 'new_secret'
end

it 'updates details' do
expect {
addr.update(details: details)
}.to change { addr.reload.details_encrypted }.and change { addr.reload.details }.to details
end

it 'long secret' do
expect {
addr.update(secret: Faker::String.random(1024))
}.to raise_error ActiveRecord::ValueTooLong
end

it 'long details' do
expect {
addr.update(details: { test: Faker::String.random(1024) })
}.to raise_error ActiveRecord::ValueTooLong
end
end
end
27 changes: 27 additions & 0 deletions spec/models/wallet_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,32 @@
expect(subject).to_not be_valid
expect(subject.errors.full_messages).to eq ['Name has already been taken']
end

it 'saves settings in encrypted column' do
subject.save
expect {
subject.uri = 'http://geth:8545/'
subject.save
}.to change { subject.settings_encrypted }
end

it 'does not update settings_encrypted before model is saved' do
subject.save
expect {
subject.uri = 'http://geth:8545/'
}.not_to change { subject.settings_encrypted }
end

it 'updates setting fields' do
expect {
subject.uri = 'http://geth:8545/'
}.to change { subject.settings['uri'] }.to 'http://geth:8545/'
end

it 'long encrypted secret' do
expect {
subject.secret = Faker::String.random(1024)
}.to raise_error ActiveRecord::ValueTooLong
end
end
end

0 comments on commit 31b5c73

Please sign in to comment.