Open ErikDeBruijn opened 4 years ago
The issue with your script is that the server_public_key
references the public key portion of the generated SSL certificate instead of the server_public_key
that is returned when an installation is created.
I created the following helper class that I use for my own testing
# frozen_string_literal: true
require 'openssl'
class BunqInstaller
def initialize(api_key: ENV['api_key'])
@configuration = OpenStruct.new api_key: api_key
end
def generate_configuration
configuration = with_installation_token(
with_ssl_certificate(@configuration)
)
create_device_server(configuration)
yield configuration
end
def with_ssl_certificate(configuration)
openssl_key = OpenSSL::PKey::RSA.new(2048)
new_configuration = OpenStruct.new(configuration)
new_configuration.private_key = openssl_key.to_pem
new_configuration.public_key = openssl_key.public_key.to_pem
new_configuration
end
def with_installation_token(configuration)
Bunq.configure do |config|
config.api_key = configuration.api_key
config.private_key = configuration.private_key
config.server_public_key = nil # you don't have this yet
config.installation_token = nil # this MUST be nil for installations
end
response = Bunq.client.installations.create(configuration.public_key)
# NOTE: we won't need this field anymore after this step
configuration.delete_field('public_key')
new_configuration = OpenStruct.new(configuration)
new_configuration.installation_token = response[1]['Token']['token']
new_configuration.server_public_key = response[2]['ServerPublicKey']['server_public_key']
new_configuration
end
def create_device_server(configuration)
Bunq.configure do |config|
config.api_key = configuration.api_key
config.private_key = configuration.private_key
config.server_public_key = configuration.server_public_key
config.installation_token = configuration.installation_token
end
Bunq.client.device_servers.create(Socket.gethostname.to_s)
end
end
This allows me to create a new configuration and consume the resulting configuration. For local testing I simply write the result to a .env
file.
installer = BunqInstaller.new api_key: <api_key>
installer.genererate_configuration do |config|
File.open('.env', 'a') do |f|
f.puts "api_key=\"#{config.api_key}\"" unless ENV['api_key']
f.puts "private_key=\"#{config.private_key}\""
f.puts "server_public_key=\"#{config.server_public_key}\""
f.puts "installation_token=\"#{config.installation_token}\""
end
end
that way I can consume it in an initializer using dot-env-rails
gem:
# frozen_string_literal: true
Bunq.configure do |config|
config.api_key = ENV['api_key']
config.private_key = ENV['private_key']
config.server_public_key = ENV['server_public_key']
config.installation_token = ENV['installation_token']
end
You could also write the configuration to a database if you want to support multiple users, and have a BunqClient wrapper that configures the BunqClient to use the configuration of the current_user.
To make it easier for people to register I created this registration script:
Obviously it could use some refinement. Also, I never got a good response from
Bunq.client.device_servers.create
, but this should probably not be worked around with a rescue block.The error I'm now catching is the following:
Since I am abandoning this attempt to automate payments for now, maybe someone likes to take it from here?