JID Switch

Christopher Vollick created

This allows a customer to change their JID, but it's a bit raw.
In practice I don't expect anyone to actually run this directly, instead
cheogram covers with with a friendlier and safer version.

This is just the business.

Change summary

forms/jid_switch.rb  |  8 ++++++++
lib/customer_repo.rb | 23 +++++++++++++++++++++++
sgx_jmp.rb           | 29 +++++++++++++++++++++++++++++
3 files changed, 60 insertions(+)

Detailed changes

forms/jid_switch.rb 🔗

@@ -0,0 +1,8 @@
+form!
+title "JID Switch"
+
+field(
+	var: "jid",
+	type: "jid-single",
+	label: "JID to Switch To"
+)

lib/customer_repo.rb 🔗

@@ -125,6 +125,29 @@ class CustomerRepo
 		@redis.set(k, limit)
 	end
 
+	def change_jid(customer, new_jid)
+		@redis.set("jmp_customer_id-#{new_jid}", customer.customer_id).then {
+			@redis.set("jmp_customer_jid-#{customer.customer_id}", new_jid)
+		}.then {
+			SwapDefaultFwd.new.do(self, customer, new_jid)
+		}.then do
+			@redis.del("jmp_customer_id-#{customer.jid}")
+		end
+	end
+
+	# I've put this here to hide the lines from rubocop
+	# After we sort out where call routing should live, this whole process will
+	# no longer be necessary
+	class SwapDefaultFwd
+		def do(repo, customer, new_jid)
+			unless customer.fwd.uri == "xmpp:#{customer.jid}"
+				return EMPromise.resolve(nil)
+			end
+
+			repo.put_fwd(customer, customer.fwd.with(uri: "xmpp:#{new_jid}"))
+		end
+	end
+
 protected
 
 	def new_sgx(customer_id)

sgx_jmp.rb 🔗

@@ -760,6 +760,35 @@ def reply_with_note(iq, text, type: :info)
 	self << reply
 end
 
+Command.new(
+	"https://ns.cheogram.com/sgx/jid-switch",
+	"Change JID",
+	list_for: ->(customer: nil, **) { customer },
+	customer_repo: CustomerRepo.new(sgx_repo: Bwmsgsv2Repo.new)
+) {
+	Command.customer.then { |customer|
+		Command.reply { |reply|
+			reply.command << FormTemplate.render("jid_switch")
+		}.then { |response|
+			new_jid = response.form.field("jid").value
+			repo = Command.execution.customer_repo
+			repo.find_by_jid(new_jid)
+				.catch_only(CustomerRepo::NotFound) { nil }
+				.then { |cust|
+					next EMPromise.reject("Customer Already Exists") if cust
+
+					repo.change_jid(customer, new_jid)
+				}
+		}.then {
+			StatsD.increment("changejid.completed")
+			Command.finish { |reply|
+				reply.note_type = :info
+				reply.note_text = "Customer JID Changed"
+			}
+		}
+	}
+}.register(self).then(&CommandList.method(:register))
+
 Command.new(
 	"web-register",
 	"Initiate Register from Web",