From 4217dbfc54ed340ada97d28605a8995ba58917ef Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Tue, 10 May 2022 15:07:12 -0500 Subject: [PATCH] Refactor knowledge of registration persistance to RegistrationRepo 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(-) create mode 100644 lib/registration_repo.rb diff --git a/Gemfile b/Gemfile index fd4bb1bbaddecf438c8eba1a847ed5e55eb02f29..ae87ae096743ba19e0bf0e9bd831d00c63c62d85 100644 --- a/Gemfile +++ b/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' diff --git a/lib/registration_repo.rb b/lib/registration_repo.rb new file mode 100644 index 0000000000000000000000000000000000000000..2e25c361574782c192ee0b5be9d13e71fc8ceab3 --- /dev/null +++ b/lib/registration_repo.rb @@ -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 diff --git a/sgx-bwmsgsv2.rb b/sgx-bwmsgsv2.rb index b600afb12d20fa64186e1943d36b4cf6a90ea8a1..f1329b01705e639479db1cde9554ca36ccbf49e1 100755 --- a/sgx-bwmsgsv2.rb +++ b/sgx-bwmsgsv2.rb @@ -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?"