Commit 8ef23816 authored by o@immerda.ch's avatar o@immerda.ch
Browse files

support for bill management through admin api

* open api endpoints for creating and querying transactions
* allow creation of user transactions for other users
* remove deprecated bill import script
parent e81df208
Pipeline #7925 passed with stage
in 3 minutes and 24 seconds
......@@ -191,6 +191,7 @@ class Authenticator
'/resource/list',
'/resource/schema',
'/users_admin/reserved_identifiers',
'/global_transaction/get',
],
'post' => [
'/users_admin/update',
......@@ -214,7 +215,9 @@ class Authenticator
'/resource/add_owner',
'/resource/remove_owner',
'/users_admin/release_reserved_identifier',
'/global_transaction/get_fresh_key',
'/global_transaction/add',
'/user_transaction/add',
],
}
},
......
......@@ -12,6 +12,7 @@ class IApi < Sinatra::Base
namespace '/global_transaction' do
post '/add' do
scope = parsed_body['scope']
allow_update = !!parsed_body['allow_update']
unless (verify_acl(scope, [], ['bill']))
return client_error('invalid_scope')
end
......@@ -28,12 +29,12 @@ class IApi < Sinatra::Base
if res.empty?
# keys must be reserved first to prevent enumeration and races
client_error('failed')
elsif !res.first.value.present?
elsif !res.first.value.present? || allow_update
res = res.first
res.ttl = ttl
res.remove_at = Time.now + ttl.days
res.value = Base64.encode64(value)
res.created_at = Time.now
res.update!
res.save!
json result: 'success'
else
client_error('failed')
......@@ -48,10 +49,13 @@ class IApi < Sinatra::Base
key = params['key']
res = GlobalTransaction.where(scope: scope, key: key)
if res.empty? || !res.first.value.present?
return json result: 'success', notfound: true
if res.empty?
return json result: 'success', status: "invalid"
end
if !res.first.value.present?
return json result: 'success', status: "empty"
end
return json result: 'success', value: Base64.decode64(res.first.value).force_encoding("utf-8")
return json result: 'success', status: "present", value: Base64.decode64(res.first.value).force_encoding("utf-8")
end
post '/get_fresh_key' do
......@@ -115,17 +119,26 @@ class IApi < Sinatra::Base
unless (verify_acl(scope, ['bill']))
return client_error('invalid_scope')
end
user = authenticated_user
if IApiConf.acl.has_access_to_admin_api?(authenticated_user.email) &&
parsed_body['target_user'].present?
user = EmailUser.by_email(parsed_body['target_user'])
unless user
return client_error('invalid_target_user')
end
end
key = user.iapi_public_key
value = parsed_body['value']
ttl = parsed_body['ttl']
ttl = ttl.to_i if ttl.present?
data = {email_user: authenticated_user, scope: scope, value: value}
data = {email_user: user, scope: scope, value: value}
if ttl.present?
data[:remove_at] = Time.now + ttl.days
end
if api_user_public_key
if key
data[:value] = Sodium::Box.close(
api_user_public_key,
key,
IApiConf.transaction_log_key.sec, data[:value])
data[:encrypted] = true
end
......
#!/bin/env ruby
require 'nokogiri'
# Our IBAN
IBAN='CH7809000000602170959'
file = if ARGV[0]
File.read(ARGV[0])
else
STDIN.read
end
doc = Nokogiri::XML(file)
doc.remove_namespaces!
txs = []
doc.xpath('//Ntry').each do |e|
if e = e.at('NtryDtls')
to = e.xpath('TxDtls/RltdPties/CdtrAcct').first
if to.to_s =~ /#{IBAN}/
from = e.xpath('TxDtls/RltdPties/Dbtr/Nm').first.content
ref = e.search('Ref').map{|r| r.content if r.content =~ /^RF/}.compact.first
if ref
amt = e.xpath('TxDtls/Amt').first
ccy = amt['Ccy']
amt = amt.content.to_f
txs << [from, ref, ccy, amt]
end
end
end
end
$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
require 'iapi'
ActiveRecord::Base.establish_connection(IApiConf.user_db)
txs.each do |e|
_, ref, currency, amount = e
ref = ref[4..-1].upcase
t = GlobalTransaction.where(scope: 'bill', key: ref)
if t.empty?
puts "Could not find transaction #{e}"
next
end
t = t.last
if t.value
puts "Already recorded transaction for #{e}"
next
end
puts "."
t.value = Base64.encode64({
currency: currency,
amount: amount,
status: 'paid'}.to_yaml)
t.save!
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment