Repository navigation
Expand file tree
/
Copy pathapi_controller.rb
More file actions
76 lines (62 loc) · 2.54 KB
/
Copy pathapi_controller.rb
File metadata and controls
76 lines (62 loc) · 2.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# frozen_string_literal: true
module Api
module V1
class ApiController < ApplicationController
rescue_from ActiveRecord::RecordNotFound, with: :not_found
rescue_from ActiveRecord::RecordInvalid, with: :unprocessable
rescue_from RuntimeError, with: :bad_request
rescue_from Foaf::Trustline::Protocol::InsufficientCapacity, with: :insufficient_capacity
rescue_from Foaf::Trustline::Protocol::MaxFeeExceeded, with: :max_fee_exceeded
private
# Verify the request is signed by the claimed actor.
# Like blockchain nodes verifying transaction signatures.
# Returns true if valid, renders error and returns false if not.
def verify_signature!(address)
# Skip verification if signature enforcement is not active
return true unless signature_enforcement?
payload = request.raw_post
signature = request.headers["X-Signature"]
unless signature.present?
render json: { error: "Missing X-Signature header" }, status: :unauthorized
return false
end
unless SignatureVerifier.verify_by_address(payload: payload, signature: signature, address: address)
render json: { error: "Invalid signature for address #{address}" }, status: :unauthorized
return false
end
true
end
# Signature enforcement is controlled by protocol parameter.
# Phase 1: off by default. Flip to "true" to enable.
def signature_enforcement?
ProtocolParameter.get("signature_enforcement", default: "false") == "true"
end
def not_found(exception)
render json: { error: exception.message }, status: :not_found
end
def unprocessable(exception)
render json: { error: exception.record.errors.full_messages.join(", ") }, status: :unprocessable_entity
end
def bad_request(exception)
render json: { error: exception.message }, status: :bad_request
end
def insufficient_capacity(exception)
render json: {
error: exception.message,
requested: exception.requested.to_f,
available: exception.available.to_f
}, status: :bad_request
end
def max_fee_exceeded(exception)
render json: {
error: exception.message,
totalFees: exception.total_fees.to_f,
maxFee: exception.max_fee.to_f
}, status: :bad_request
end
def find_network!
@network = CurrencyNetwork.find_by!(address: params[:network_address] || params[:address])
end
end
end
end