1#!/usr/bin/env ruby
2#
3# Copyright (C) 2017 Denver Gingerich <denver@ossguy.com>
4#
5# This file is part of sgx-catapult.
6#
7# sgx-catapult is free software: you can redistribute it and/or modify it under
8# the terms of the GNU Affero General Public License as published by the Free
9# Software Foundation, either version 3 of the License, or (at your option) any
10# later version.
11#
12# sgx-catapult is distributed in the hope that it will be useful, but WITHOUT
13# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
15# details.
16#
17# You should have received a copy of the GNU Affero General Public License along
18# with sgx-catapult. If not, see <http://www.gnu.org/licenses/>.
19
20puts "Soprani.ca/MMS Proxy for XMPP - Catapult v0.001"
21
22require 'goliath'
23require 'net/http'
24require 'redis/connection/hiredis'
25require 'uri'
26
27if ARGV.size != 3 then
28 puts "Usage: mpx-catapult.rb <http_listen_port> " +
29 "<redis_hostname> <redis_port>"
30 exit 0
31end
32
33class WebhookHandler < Goliath::API
34 def response(env)
35 puts 'ENV: ' + env.to_s
36 puts 'path: ' + env['REQUEST_PATH']
37 puts 'method: ' + env['REQUEST_METHOD']
38 puts 'BODY: ' + Rack::Request.new(env).body.read
39
40 cred_key = "catapult_cred-"+env['REQUEST_PATH'].split('/', 3)[1]
41
42 # TODO: connect at start of program instead
43 conn = Hiredis::Connection.new
44 begin
45 conn.connect(ARGV[1], ARGV[2].to_i)
46 rescue => e
47 puts 'ERROR: Redis connection failed: ' + e.inspect
48 return [500, {'Content-Type' => 'text/plain'},
49 e.inspect]
50 end
51
52 conn.write ["EXISTS", cred_key]
53 if conn.read == 0
54 conn.disconnect
55
56 puts 'ERROR: invalid path rqst: ' + env['REQUEST_PATH']
57 return [404, {'Content-Type' => 'text/plain'},
58 'not found']
59 end
60
61 conn.write ["LRANGE", cred_key, 0, 3]
62 # we don't actually use users_num, but easier to read so left in
63 user_id, api_token, api_secret, users_num = conn.read
64 conn.disconnect
65
66 uri = URI.parse('https://api.catapult.inetwork.com')
67 http = Net::HTTP.new(uri.host, uri.port)
68 http.use_ssl = true
69 request = Net::HTTP::Get.new('/v1/users/' + user_id +
70 '/media/' + env['REQUEST_PATH'].split('/', 3)[2])
71 request.basic_auth api_token, api_secret
72 response = http.request(request)
73
74 puts 'API response to send: ' + response.to_s + ' with code ' +
75 response.code + ', body <omitted_due_to_length>'
76
77 if response.code != '200'
78 puts 'ERROR: unexpected return code ' + response.code
79
80 if response.code == '404'
81 return [404, {'Content-Type' => 'text/plain'},
82 'not found']
83 end
84
85 return [response.code, {'Content-Type' => 'text/plain'},
86 'unexpected error']
87 end
88
89 # TODO: maybe need to reflect more headers (multi-part?)
90 [200, {}, response.body]
91 end
92end
93
94EM.run do
95 server = Goliath::Server.new('0.0.0.0', ARGV[0].to_i)
96 server.api = WebhookHandler.new
97 server.app = Goliath::Rack::Builder.build(server.api.class, server.api)
98 server.logger = Log4r::Logger.new('goliath')
99 server.logger.add(Log4r::StdoutOutputter.new('console'))
100 server.logger.level = Log4r::INFO
101 server.start
102end