class StraightServer::GatewayOnDB

Uses database to load and save attributes

Attributes

update_secret[RW]

This virtual attribute is important because it's difficult to detect whether secret was actually updated or not. Sequel's changed_columns may mistakenly say :secret attr was changed, while it hasn't. Thus we provide a manual way of ensuring this. It's also better and works as safety switch: we don't want somebody accidentally updating a secret.

Public Class Methods

find_by_hashed_id(s) click to toggle source
# File lib/straight-server/gateway.rb, line 366
def self.find_by_hashed_id(s)
  self.where(hashed_id: s).first
end
find_by_id(id) click to toggle source
# File lib/straight-server/gateway.rb, line 421
def self.find_by_id(id)
  self[id]
end

Public Instance Methods

address_provider() click to toggle source
# File lib/straight-server/gateway.rb, line 450
def address_provider
  Kernel.const_get("Straight::AddressProvider::#{address_provider_type}").new(self)
end
address_provider_type() click to toggle source
# File lib/straight-server/gateway.rb, line 446
def address_provider_type
  self[:address_provider] ? self[:address_provider].to_sym : :Bip32
end
after_create() click to toggle source
# File lib/straight-server/gateway.rb, line 389
def after_create
  @@websockets[self.id] = {}
  update(hashed_id: OpenSSL::HMAC.digest('sha256', Config.server_secret, self.id.to_s).unpack("H*").first)
end
after_initialize() click to toggle source
# File lib/straight-server/gateway.rb, line 394
def after_initialize
  @status_check_schedule = Straight::GatewayModule::DEFAULT_STATUS_CHECK_SCHEDULE
  @@websockets[self.id] ||= {} if self.id
  initialize_callbacks
  initialize_exchange_rate_adapters
  initialize_blockchain_adapters
  initialize_status_check_schedule
  initialize_network
end
before_create() click to toggle source
Calls superclass method
# File lib/straight-server/gateway.rb, line 376
def before_create
  super
  encrypt_secret
  self.test_mode ||= false
  self.test_last_keychain_id ||= 0
end
before_update() click to toggle source
Calls superclass method
# File lib/straight-server/gateway.rb, line 383
def before_update
  encrypt_secret if @update_secret
  @update_secret = false
  super
end
disable_test_mode!() click to toggle source
# File lib/straight-server/gateway.rb, line 454
def disable_test_mode!
  self[:test_mode] = false
  save(columns: 'test_mode')
end
enable_test_mode!() click to toggle source
# File lib/straight-server/gateway.rb, line 459
def enable_test_mode!
  self[:test_mode] = true
  save(columns: 'test_mode')
end
encrypt_secret() click to toggle source
# File lib/straight-server/gateway.rb, line 425
def encrypt_secret
  cipher           = OpenSSL::Cipher::AES.new(128, :CBC)
  cipher.encrypt
  cipher.key       = OpenSSL::HMAC.digest('sha256', 'nonce', Config.server_secret).unpack("H*").first[0,16]

  cipher.iv        = iv = OpenSSL::HMAC.digest('sha256', 'nonce', "#{self.class.max(:id)}#{Config.server_secret}").unpack("H*").first[0,16]
  raise "cipher.iv cannot be nil" unless iv

  encrypted        = cipher.update(self[:secret]) << cipher.final()
  base64_encrypted = Base64.strict_encode64(encrypted).encode('utf-8')
  result           = "#{iv}:#{base64_encrypted}"

  # Check whether we can decrypt. It should not be possible to encrypt the
  # gateway secret unless we are sure we can decrypt it.
  if decrypt_secret(result) == self[:secret]
    self.secret = result
  else
    raise "Decrypted and original secrets don't match! Cannot proceed with writing the encrypted gateway secret."
  end
end
secret() click to toggle source

We cannot allow to store gateway secret in a DB plaintext, this would be completetly unsecure. Althougth we use symmetrical encryption here and store the encryption key in the server's in a special file (~/.straight/server_secret), which in turn can also be stolen, this is still marginally better than doing nothing.

Also, server admnistrators now have the freedom of developing their own strategy of storing that secret - it doesn't have to be stored on the same machine.

# File lib/straight-server/gateway.rb, line 417
def secret
  decrypt_secret
end
validate() click to toggle source
Calls superclass method
# File lib/straight-server/gateway.rb, line 404
def validate
  super
  errors.add(:pubkey, "Please provide public key") if pubkey_missing?
  errors.add(:test_pubkey, "Please provide test public key if you activate test mode") if test_pubkey_missing?
end

Private Instance Methods

decrypt_secret(encrypted_field=self[:secret]) click to toggle source
# File lib/straight-server/gateway.rb, line 466
def decrypt_secret(encrypted_field=self[:secret])
  decipher      = OpenSSL::Cipher::AES.new(128, :CBC)
  iv, encrypted = encrypted_field.split(':')
  decipher.decrypt
  decipher.key  = OpenSSL::HMAC.digest('sha256', 'nonce', Config.server_secret).unpack("H*").first[0,16]
  decipher.iv   = iv
  decipher.update(Base64.decode64(encrypted)) + decipher.final
end