Gemfile 🔗
@@ -9,6 +9,7 @@ gem 'em-http-request'
gem 'em_promise.rb'
gem 'eventmachine'
gem 'goliath'
+gem 'lazy_object'
gem 'log4r'
gem 'rack', '< 2'
gem 'redis'
Stephen Paul Weber created
Keeps all knowledge about redis key structure, etc, in one place.
Gemfile | 1
lib/registration_repo.rb | 54 ++++++++++++++++++++++++++++++++
sgx-bwmsgsv2.rb | 69 +++++++++++------------------------------
3 files changed, 74 insertions(+), 50 deletions(-)
@@ -9,6 +9,7 @@ gem 'em-http-request'
gem 'em_promise.rb'
gem 'eventmachine'
gem 'goliath'
+gem 'lazy_object'
gem 'log4r'
gem 'rack', '< 2'
gem 'redis'
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require 'lazy_object'
+
+class RegistrationRepo
+ class Conflict < StandardError; end
+
+ def initialize(redis: LazyObject.new { REDIS })
+ @redis = redis
+ end
+
+ def find(jid)
+ REDIS.lrange(cred_key(jid), 0, 3)
+ end
+
+ def find_jid(tel)
+ REDIS.get(jid_key(tel))
+ end
+
+ def put(jid, *creds)
+ tel = creds.last
+
+ EMPromise.all([
+ find(jid),
+ REDIS.set(
+ jid_key(tel),
+ Blather::JID.new(jid).stripped.to_s,
+ "NX", "GET"
+ )
+ ]).then { |(oldcreds, oldjid)|
+ if oldjid && oldjid != jid.stripped.to_s
+ raise Conflict, "Another user exists for #{tel}"
+ end
+
+ if !oldcreds.empty? && oldcreds != creds
+ REDIS.set(jid_key(tel), oldjid).then do
+ raise Conflict, "Another user exists for #{jid}"
+ end
+ end
+ }.then {
+ REDIS.rpush(cred_key(jid), *creds)
+ }
+ end
+
+protected
+
+ def cred_key(jid)
+ "catapult_cred-#{Blather::JID.new(jid).stripped}"
+ end
+
+ def jid_key(tel)
+ "catapult_jid-#{tel}"
+ end
+end
@@ -34,6 +34,8 @@ require 'log4r'
require 'em_promise'
+require_relative 'lib/registration_repo'
+
def panic(e)
puts "Shutting down gateway due to exception: #{e.message}"
puts e.backtrace
@@ -84,6 +86,7 @@ end
module SGXbwmsgsv2
extend Blather::DSL
+ @registration_repo = RegistrationRepo.new
@client = SGXClient.new
@gateway_features = [
"http://jabber.org/protocol/disco#info",
@@ -385,8 +388,7 @@ module SGXbwmsgsv2
end
def self.fetch_catapult_cred_for(jid)
- cred_key = "catapult_cred-#{jid.stripped}"
- REDIS.lrange(cred_key, 0, 3).then { |creds|
+ @registration_repo.find(jid).then { |creds|
if creds.length < 4
# TODO: add text re credentials not registered
EMPromise.reject(
@@ -408,15 +410,13 @@ module SGXbwmsgsv2
validate_num(m),
fetch_catapult_cred_for(m.from)
]).then { |(num_dest, creds)|
- jid_key = "catapult_jid-#{num_dest}"
- REDIS.get(jid_key).then { |jid|
+ @registration_repo.find_jid(num_dest).then { |jid|
[jid, num_dest] + creds
}
}.then { |(jid, num_dest, *creds)|
if jid
- cred_key = "catapult_cred-#{jid}"
- REDIS.lrange(cred_key, 0, 0).then { |other_user|
- [jid, num_dest] + creds + other_user
+ @registration_repo.find(jid).then { |other_user|
+ [jid, num_dest] + creds + other_user.first
}
else
[jid, num_dest] + creds + [nil]
@@ -542,44 +542,13 @@ module SGXbwmsgsv2
end
def self.check_then_register(i, *creds)
- jid_key = "catapult_jid-#{creds.last}"
- bare_jid = i.from.stripped
- cred_key = "catapult_cred-#{bare_jid}"
-
- REDIS.get(jid_key).then { |existing_jid|
- if existing_jid && existing_jid != bare_jid
- # TODO: add/log text: credentials exist already
- EMPromise.reject([:cancel, 'conflict'])
- end
- }.then {
- REDIS.lrange(cred_key, 0, 3)
- }.then { |existing_creds|
- # TODO: add/log text: credentials exist already
- if existing_creds.length == 4 && creds != existing_creds
- EMPromise.reject([:cancel, 'conflict'])
- elsif existing_creds.length < 4
- REDIS.rpush(cred_key, *creds).then { |length|
- if length != 4
- EMPromise.reject([
- :cancel,
- 'internal-server-error'
- ])
- end
- }
- end
- }.then {
- # not necessary if existing_jid non-nil, easier this way
- REDIS.set(jid_key, bare_jid)
- }.then { |result|
- if result != 'OK'
- # TODO: add txt re push failure
- EMPromise.reject(
- [:cancel, 'internal-server-error']
- )
- end
- }.then {
- write_to_stream i.reply
- }
+ registration_repo
+ .put(i.from, *creds)
+ .catch_only(RegistrationRepo::Conflict) { |e|
+ EMPromise.reject([:cancel, 'conflict', e.message])
+ }.then {
+ write_to_stream i.reply
+ }
end
def self.creds_from_registration_query(qn)
@@ -756,9 +725,8 @@ module SGXbwmsgsv2
process_registration(i, qn)
when :get
bare_jid = i.from.stripped
- cred_key = "catapult_cred-#{bare_jid}"
- REDIS.lindex(cred_key, 3).then { |existing_number|
- reply = registration_form(i.reply, existing_number)
+ @registration_repo.find(bare_jid).then { |creds|
+ reply = registration_form(i.reply, creds.last)
puts "RESPONSE2: #{reply.inspect}"
write_to_stream reply
}
@@ -794,6 +762,8 @@ end
class WebhookHandler < Goliath::API
use Goliath::Rack::Params
+ @registration_repo = RegistrationRepo.new
+
def response(env)
# TODO: add timestamp grab here, and MUST include ./tai version
@@ -858,8 +828,7 @@ class WebhookHandler < Goliath::API
';phone-context=ca-us.phone-context.soprani.ca'
end
- jid_key = "catapult_jid-#{users_num}"
- bare_jid = REDIS.get(jid_key).promise.sync
+ bare_jid = @registration_repo.find_jid(users_num).sync
if !bare_jid
puts "jid_key (#{jid_key}) DNE; BW API misconfigured?"