mirror of
https://github.com/Blockstream/satellite-api.git
synced 2025-02-22 05:41:37 +01:00
add error codes for other errors #3
This commit is contained in:
parent
980683fd65
commit
b4799ae80e
5 changed files with 100 additions and 26 deletions
|
@ -39,7 +39,22 @@ class ERROR
|
|||
BID_INCREASE_MISSING: 105,
|
||||
BID_INCREASE_TOO_SMALL: 106,
|
||||
LID_MISSING: 107,
|
||||
CHARGED_AUTH_TOKEN_MISSING: 108
|
||||
CHARGED_AUTH_TOKEN_MISSING: 108,
|
||||
INVALID_AUTH_TOKEN: 109,
|
||||
LIGHTNING_CHARGE_INVOICE_ERROR: 110,
|
||||
LIGHTNING_CHARGE_WEBHOOK_REGISTRATION_ERROR: 111,
|
||||
INVOICE_ID_NOT_FOUND_ERROR: 112,
|
||||
INVALID_DATE: 113,
|
||||
SEQUENCE_NUMBER_NOT_FOUND: 114,
|
||||
MESSAGE_FILE_MISSING: 115,
|
||||
MESSAGE_FILENAME_MISSING: 116,
|
||||
MESSAGE_FILE_TOO_SMALL: 117,
|
||||
MESSAGE_FILE_TOO_LARGE: 118,
|
||||
ORDER_BUMP_ERROR: 119,
|
||||
ORDER_CANCELLATION_ERROR: 120,
|
||||
INVOICE_NOT_FOUND: 121,
|
||||
ORPHANED_INVOICE: 122,
|
||||
ORDER_ALREADY_PAID: 123
|
||||
}
|
||||
|
||||
def self.code(p, e)
|
||||
|
|
|
@ -4,12 +4,13 @@ module Sinatra
|
|||
module InvoiceHelpers
|
||||
|
||||
def fetch_invoice_by_lid
|
||||
Invoice.where(lid: params[:lid]).first || halt(404, {:message => "Not found", :errors => ["Invalid invoice id"]}.to_json)
|
||||
Invoice.where(lid: params[:lid]).first ||
|
||||
error_object("Not found", "Invoice id #{params[:lib]} not found", ERROR::CODES[:INVOICE_ID_NOT_FOUND_ERROR])
|
||||
end
|
||||
|
||||
def authorize_invoice!(invoice)
|
||||
if invoice.charged_auth_token != params[:charged_auth_token]
|
||||
halt 401, {:message => "Unauthorized", :errors => ["Invalid authentication token"]}.to_json
|
||||
halt 401, error_object("Unauthorized", "Invalid authentication token", ERROR::CODES[:INVALID_AUTH_TOKEN])
|
||||
else
|
||||
invoice
|
||||
end
|
||||
|
@ -29,7 +30,7 @@ module Sinatra
|
|||
metadata: {uuid: order.uuid, sha256_message_digest: order.message_digest}
|
||||
}
|
||||
unless charged_response.status == 201
|
||||
halt 400, {:message => "Lightning Charge invoice creation error", :errors => ["received #{response.status} from charged"]}.to_json
|
||||
halt 400, error_object("Lightning Charge invoice creation error", "received #{response.status} from charged", ERROR::CODES[:LIGHTNING_CHARGE_INVOICE_ERROR])
|
||||
end
|
||||
|
||||
lightning_invoice = JSON.parse(charged_response.body)
|
||||
|
@ -40,10 +41,22 @@ module Sinatra
|
|||
url: invoice.callback_url
|
||||
}
|
||||
unless webhook_registration_response.status == 201
|
||||
halt 400, {:message => "Lightning Charge webhook registration error", :errors => ["received #{response.status} from charged"]}.to_json
|
||||
halt 400, error_object("Lightning Charge webhook registration error", "received #{response.status} from charged", ERROR::CODES[:LIGHTNING_CHARGE_WEBHOOK_REGISTRATION_ERROR])
|
||||
end
|
||||
invoice
|
||||
end
|
||||
|
||||
def invoice_not_found_error
|
||||
halt 404, error_object("Payment problem", "Invoice not found", ERROR::CODES[:INVOICE_NOT_FOUND])
|
||||
end
|
||||
|
||||
def orphaned_invoice_error
|
||||
halt 404, error_object("Payment problem", "Orphaned invoice", ERROR::CODES[:ORPHANED_INVOICE])
|
||||
end
|
||||
|
||||
def order_already_paid_error
|
||||
halt 400, error_object("Payment problem", "Order already paid", ERROR::CODES[:ORDER_ALREADY_PAID])
|
||||
end
|
||||
|
||||
end
|
||||
helpers InvoiceHelpers
|
||||
|
|
|
@ -2,12 +2,12 @@ module Sinatra
|
|||
module OrderHelpers
|
||||
|
||||
def fetch_order_by_uuid
|
||||
Order.where(uuid: params[:uuid]).first || halt(404, {:message => "Not found", :errors => ["Invalid order id"]}.to_json)
|
||||
Order.where(uuid: params[:uuid]).first || uuid_not_found_error
|
||||
end
|
||||
|
||||
def authorize_order!(order)
|
||||
if order.user_auth_token != params[:auth_token]
|
||||
halt 401, {:message => "Unauthorized", :errors => ["Invalid authentication token"]}.to_json
|
||||
halt 401, error_object("Unauthorized", "Invalid authentication token", ERROR::CODES[:INVALID_AUTH_TOKEN])
|
||||
else
|
||||
order
|
||||
end
|
||||
|
@ -16,6 +16,46 @@ module Sinatra
|
|||
def get_and_authenticate_order
|
||||
authorize_order!(fetch_order_by_uuid)
|
||||
end
|
||||
|
||||
def invalid_date_error
|
||||
halt 400, error_object("Invalid date", "Couldn't parse date given by before param", ERROR::CODES[:INVALID_DATE])
|
||||
end
|
||||
|
||||
def sequence_number_not_found_error
|
||||
halt 404, error_object("Sequence number not found", "Sent order with that tx sequence number not found", ERROR::CODES[:SEQUENCE_NUMBER_NOT_FOUND])
|
||||
end
|
||||
|
||||
def uuid_not_found_error
|
||||
halt 404, error_object("UUID not found", "UUID #{params[:uuid]} not found", ERROR::CODES[:UUID_MISSING])
|
||||
end
|
||||
|
||||
def message_file_missing_error
|
||||
halt 400, error_object("Message upload problem", "No tempfile received", ERROR::CODES[:MESSAGE_FILE_MISSING])
|
||||
end
|
||||
|
||||
def message_filename_missing_error
|
||||
halt 400, error_object("Message upload problem", "Filename missing", ERROR::CODES[:MESSAGE_FILENAME_MISSING])
|
||||
end
|
||||
|
||||
def message_file_too_large_error
|
||||
halt 413, error_object("Message upload problem", "Message size exceeds max size #{MAX_MESSAGE_SIZE}", ERROR::CODES[:MESSAGE_FILE_TOO_LARGE])
|
||||
end
|
||||
|
||||
def message_file_too_small_error
|
||||
halt 400, error_object("Message upload problem", "Message too small. Minimum message size is #{MIN_MESSAGE_SIZE} byte", ERROR::CODES[:MESSAGE_FILE_TOO_SMALL])
|
||||
end
|
||||
|
||||
def bid_too_small_error(min_bid)
|
||||
halt 413, error_object("Bid too low", "Per byte bid cannot be below #{MIN_PER_BYTE_BID} millisatoshis per byte. The minimum bid for this message is #{min_bid} millisatoshis.", ERROR::CODES[:BID_TOO_SMALL])
|
||||
end
|
||||
|
||||
def order_bump_error
|
||||
halt 400, error_object("Cannot bump order", "Order already #{order.status}", ERROR::CODES[:ORDER_BUMP_ERROR])
|
||||
end
|
||||
|
||||
def order_cancellation_error
|
||||
halt 400, error_object("Cannot cancel order", "Order already #{order.status}", ERROR::CODES[:ORDER_CANCELLATION_ERROR])
|
||||
end
|
||||
|
||||
end
|
||||
helpers OrderHelpers
|
||||
|
|
28
main.rb
28
main.rb
|
@ -24,7 +24,7 @@ end
|
|||
|
||||
configure :test, :development do
|
||||
get '/order/:uuid/sent_message' do
|
||||
(order = Order.find_by(uuid: params[:uuid], status: [:sent, :transmitting])) || halt(404, {:message => "Not found", :errors => ["Sent order with that id not found"]}.to_json)
|
||||
(order = Order.find_by(uuid: params[:uuid], status: [:sent, :transmitting])) || uuid_not_found_error
|
||||
send_file order.message_path, :disposition => 'attachment'
|
||||
end
|
||||
end
|
||||
|
@ -63,7 +63,7 @@ get '/orders/sent' do
|
|||
begin
|
||||
before = DateTime.iso8601(params[:before])
|
||||
rescue
|
||||
halt 400, {:message => "Invalid date", :errors => ["Couldn't parse date given by before param"]}.to_json
|
||||
invalid_date_error
|
||||
end
|
||||
Order.where(status: :sent).where("created_at < ?", before)
|
||||
.select(Order::PUBLIC_FIELDS)
|
||||
|
@ -81,7 +81,7 @@ get '/orders/pending' do
|
|||
begin
|
||||
before = DateTime.iso8601(params[:before])
|
||||
rescue
|
||||
halt 400, {:message => "Invalid date", :errors => ["Couldn't parse date given by before param"]}.to_json
|
||||
invalid_date_error
|
||||
end
|
||||
Order.where(status: :pending).where("created_at < ?", before)
|
||||
.select(Order::PUBLIC_FIELDS)
|
||||
|
@ -90,7 +90,7 @@ get '/orders/pending' do
|
|||
end
|
||||
|
||||
get '/message/:tx_seq_num' do
|
||||
(order = Order.find_by(tx_seq_num: params[:tx_seq_num], status: [:sent, :transmitting])) || halt(404, {:message => "Not found", :errors => ["Sent order with that tx sequence number not found"]}.to_json)
|
||||
(order = Order.find_by(tx_seq_num: params[:tx_seq_num], status: [:sent, :transmitting])) || sequence_number_not_found_error
|
||||
send_file order.message_path, :disposition => 'attachment'
|
||||
end
|
||||
|
||||
|
@ -105,10 +105,10 @@ post '/order' do
|
|||
|
||||
# process the upload
|
||||
unless tmpfile = params[:file][:tempfile]
|
||||
halt 400, {:message => "Message upload problem", :errors => ["No tempfile received"]}.to_json
|
||||
message_file_missing_error
|
||||
end
|
||||
unless name = params[:file][:filename]
|
||||
halt 400, {:message => "Message upload problem", :errors => ["Filename missing"]}.to_json
|
||||
message_filename_missing_error
|
||||
end
|
||||
|
||||
order = Order.new(uuid: SecureRandom.uuid)
|
||||
|
@ -118,7 +118,7 @@ post '/order' do
|
|||
while block = tmpfile.read(65536)
|
||||
message_size += block.size
|
||||
if message_size > MAX_MESSAGE_SIZE
|
||||
halt 413, {:message => "Message upload problem", :errors => ["Message size exceeds max size #{MAX_MESSAGE_SIZE}"]}.to_json
|
||||
message_file_too_large_error
|
||||
end
|
||||
sha256 << block
|
||||
message_file.write(block)
|
||||
|
@ -126,7 +126,7 @@ post '/order' do
|
|||
message_file.close()
|
||||
if message_size < MIN_MESSAGE_SIZE
|
||||
FileUtils.rm(message_file)
|
||||
halt 400, {:message => "Message upload problem", :errors => ["Message too small. Minimum message size is #{MIN_MESSAGE_SIZE} byte"]}.to_json
|
||||
message_file_too_small_error
|
||||
end
|
||||
|
||||
order.message_size = message_size
|
||||
|
@ -135,7 +135,7 @@ post '/order' do
|
|||
message_size_with_overhead = message_size + FRAMING_OVERHEAD_PER_FRAGMENT * (message_size / FRAGMENT_SIZE).ceil
|
||||
|
||||
if bid.to_f / message_size_with_overhead.to_f < MIN_PER_BYTE_BID
|
||||
halt 413, {:message => "Bid too low", :errors => ["Per byte bid cannot be below #{MIN_PER_BYTE_BID} millisatoshis per byte. The minimum bid for this message is #{message_size_with_overhead * MIN_PER_BYTE_BID} millisatoshis." ]}.to_json
|
||||
bid_too_small_error(message_size_with_overhead * MIN_PER_BYTE_BID)
|
||||
end
|
||||
|
||||
invoice = new_invoice(order, bid)
|
||||
|
@ -154,7 +154,7 @@ post '/order/:uuid/bump' do
|
|||
|
||||
order = get_and_authenticate_order
|
||||
unless order.bump
|
||||
halt 400, {:message => "Cannot bump order", :errors => ["Order already #{order.status}"]}.to_json
|
||||
order_bump_error
|
||||
end
|
||||
|
||||
invoice = new_invoice(order, bid_increase)
|
||||
|
@ -178,7 +178,7 @@ delete '/order/:uuid' do
|
|||
|
||||
order = get_and_authenticate_order
|
||||
unless order.cancel!
|
||||
halt 400, {:message => "Cannot cancel order", :errors => ["Order already #{order.status}"]}.to_json
|
||||
order_cancellation_error
|
||||
end
|
||||
|
||||
{:message => "order cancelled"}.to_json
|
||||
|
@ -191,15 +191,15 @@ post '/callback/:lid/:charged_auth_token' do
|
|||
|
||||
invoice = get_and_authenticate_invoice
|
||||
if invoice.nil?
|
||||
halt 404, {:message => "Payment problem", :errors => ["Invoice not found"]}.to_json
|
||||
invoice_not_found_error
|
||||
end
|
||||
|
||||
unless invoice.order
|
||||
halt 404, {:message => "Payment problem", :errors => ["Orphaned invoice"]}.to_json
|
||||
orphaned_invoice_error
|
||||
end
|
||||
|
||||
if invoice.paid?
|
||||
halt 400, {:message => "Payment problem", :errors => ["Order already paid"]}.to_json
|
||||
order_already_paid_error
|
||||
end
|
||||
|
||||
invoice.pay!
|
||||
|
|
|
@ -114,9 +114,7 @@ class MainAppTest < Minitest::Test
|
|||
def test_bid_too_low
|
||||
post '/order', params={"bid" => 1, "file" => Rack::Test::UploadedFile.new(TEST_FILE, "image/png")}
|
||||
refute last_response.ok?
|
||||
r = JSON.parse(last_response.body)
|
||||
assert_equal r['message'], 'Bid too low'
|
||||
refute_nil r['errors']
|
||||
assert_equal ERROR::CODES[:BID_TOO_SMALL], last_response_error_code
|
||||
end
|
||||
|
||||
def test_no_file_uploaded
|
||||
|
@ -132,8 +130,7 @@ class MainAppTest < Minitest::Test
|
|||
def test_uploaded_file_too_small
|
||||
post '/order', params={"bid" => DEFAULT_BID, "file" => Rack::Test::UploadedFile.new(TINY_TEST_FILE, "text/plain")}
|
||||
refute last_response.ok?
|
||||
r = JSON.parse(last_response.body)
|
||||
assert_match "too small", r["errors"][0]
|
||||
assert_equal ERROR::CODES[:MESSAGE_FILE_TOO_SMALL], last_response_error_code
|
||||
end
|
||||
|
||||
def test_bid_increase_missing_error
|
||||
|
@ -149,6 +146,13 @@ class MainAppTest < Minitest::Test
|
|||
assert_equal ERROR::CODES[:BID_INCREASE_TOO_SMALL], last_response_error_code
|
||||
end
|
||||
|
||||
def test_invalid_auth_token_error
|
||||
header 'X-Auth-Token', "not an auth token"
|
||||
post "/order/#{@order.uuid}/bump", params={"bid_increase" => DEFAULT_BID / 2}
|
||||
refute last_response.ok?
|
||||
assert_equal ERROR::CODES[:INVALID_AUTH_TOKEN], last_response_error_code
|
||||
end
|
||||
|
||||
def test_bump
|
||||
# place an order
|
||||
@order = place_order
|
||||
|
@ -212,6 +216,7 @@ class MainAppTest < Minitest::Test
|
|||
def test_that_bumping_down_fails
|
||||
bump_order(@order, -1)
|
||||
refute last_response.ok?
|
||||
assert_equal ERROR::CODES[:BID_INCREASE_TOO_SMALL], last_response_error_code
|
||||
end
|
||||
|
||||
def test_order_deletion
|
||||
|
@ -232,6 +237,7 @@ class MainAppTest < Minitest::Test
|
|||
@order = place_order
|
||||
get "/order/#{@order.uuid}/sent_message"
|
||||
refute last_response.ok?
|
||||
assert_equal ERROR::CODES[:UUID_MISSING], last_response_error_code
|
||||
|
||||
pay_invoice(@order.invoices.last)
|
||||
@order.reload
|
||||
|
|
Loading…
Add table
Reference in a new issue