From 451024eb3d350cfe2ac9b48f73f940a592b1374f Mon Sep 17 00:00:00 2001 From: Lee Quarella Date: Wed, 9 Jun 2021 12:25:59 -0400 Subject: [PATCH 01/20] Bump gem major version to 5 --- README.md | 2 +- lib/chatops/controller/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4190613..8575013 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ which will be accepted. This is helpful when rolling keys. ## Rails compatibility -This gem is intended to work with rails 4.x and 5.x. If you find a version +This gem is intended to work with rails 6.x and 7.x. If you find a version with a problem, please report it in an issue. ## Development diff --git a/lib/chatops/controller/version.rb b/lib/chatops/controller/version.rb index e990348..5c4995c 100644 --- a/lib/chatops/controller/version.rb +++ b/lib/chatops/controller/version.rb @@ -1,3 +1,3 @@ module ChatopsController - VERSION = "4.1.0" + VERSION = "5.0.0" end From fe0fa0472ca4b3fe33504f92b1bdee7c2d4de504 Mon Sep 17 00:00:00 2001 From: Parker Moore <237985+parkr@users.noreply.github.com> Date: Tue, 22 Jun 2021 12:10:59 -0400 Subject: [PATCH 02/20] Define Chatops::THREAD_STYLES ChatopsRPC has been updated to support thread styles, which allows a Chatops RPC call to reply either in the channel, in a thread of the original message, or both. --- lib/chatops.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/chatops.rb b/lib/chatops.rb index 949bc77..b95e747 100644 --- a/lib/chatops.rb +++ b/lib/chatops.rb @@ -1,4 +1,16 @@ module Chatops + # THREAD_STYLES defines the various thread styles available to Hubot Chatops RPC. + # https://github.com/github/hubot-classic/blob/master/docs/rpc_chatops_protocol.md#executing-commands + THREAD_STYLES = { + # Channel thread style is a standard in-channel reply. + channel: 0, + # Threaded thread style will send the reply to a thread from the original message. + threaded: 1, + # Threaded and channel thread style will send the reply to a thread from the original message, + # and post an update into the channel as well (helpful when the original message in the thread is old). + threaded_and_channel: 2, + }.freeze + def self.public_key ENV[public_key_env_var_name] end From 4e37bf87873ccc78779f6a91e8bba31621583b17 Mon Sep 17 00:00:00 2001 From: Max Wagner Date: Thu, 20 Oct 2022 08:54:25 -0600 Subject: [PATCH 03/20] Permit raw_command This is to allow implementation of another feature that sends the raw_command, in addition to the parsed command, to the chatops server so the server can parse the command itself. --- lib/chatops/controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/chatops/controller.rb b/lib/chatops/controller.rb index 4af2ee1..72aa8fe 100644 --- a/lib/chatops/controller.rb +++ b/lib/chatops/controller.rb @@ -57,7 +57,7 @@ def setup_params! @jsonrpc_params = params.delete(:params) if params.has_key? :params - self.params = params.permit(:action, :chatop, :controller, :id, :mention_slug, :message_id, :method, :room_id, :user) + self.params = params.permit(:action, :chatop, :controller, :id, :mention_slug, :message_id, :method, :room_id, :user, :raw_command) end def jsonrpc_params From 07d4dc8e5c51396f13ae384aa367ea8972c0f034 Mon Sep 17 00:00:00 2001 From: Max Wagner Date: Thu, 20 Oct 2022 11:10:44 -0600 Subject: [PATCH 04/20] Create 5.1.0 release This release includes a new permitted parameter `raw_command`. See #59 --- lib/chatops/controller/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/chatops/controller/version.rb b/lib/chatops/controller/version.rb index 5c4995c..6e8f6d1 100644 --- a/lib/chatops/controller/version.rb +++ b/lib/chatops/controller/version.rb @@ -1,3 +1,3 @@ module ChatopsController - VERSION = "5.0.0" + VERSION = "5.1.0" end From 3e42ea0397cd5064240294043850c3385f917a55 Mon Sep 17 00:00:00 2001 From: Artem Egorov Date: Fri, 5 Jan 2024 14:45:08 +0000 Subject: [PATCH 05/20] Allows to set multiple base auth urls --- README.md | 5 +++-- lib/chatops.rb | 4 ++-- lib/chatops/controller.rb | 28 ++++++++++++++++------------ spec/lib/chatops/controller_spec.rb | 6 +++--- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 8575013..724cb4e 100644 --- a/README.md +++ b/README.md @@ -114,11 +114,12 @@ two environment variables to use this protocol: format. This environment variable will be the contents of a `.pub` file, newlines and all. -`CHATOPS_AUTH_BASE_URL` is the base URL of your server as the chatops client +`CHATOPS_AUTH_BASE_URL` is the base URLs of your servers as the chatops client sees it. This is specified as an environment variable since rails will trust client headers about a forwarded hostname. For example, if your chatops client has added the url `https://example.com/_chatops`, you'd set this to -`https://example.com`. +`https://example.com`. You can specify more than one base url divided by comma, +e.g. `https://example.com,https://example2.com` You can also optionally set `CHATOPS_AUTH_ALT_PUBLIC_KEY` to a second public key which will be accepted. This is helpful when rolling keys. diff --git a/lib/chatops.rb b/lib/chatops.rb index b95e747..fa7d90c 100644 --- a/lib/chatops.rb +++ b/lib/chatops.rb @@ -23,8 +23,8 @@ def self.alt_public_key ENV["CHATOPS_AUTH_ALT_PUBLIC_KEY"] end - def self.auth_base_url - ENV[auth_base_url_env_var_name] + def self.auth_base_urls + ENV.fetch(auth_base_url_env_var_name, "").split(",").map(&:strip) end def self.auth_base_url_env_var_name diff --git a/lib/chatops/controller.rb b/lib/chatops/controller.rb index 72aa8fe..8f95150 100644 --- a/lib/chatops/controller.rb +++ b/lib/chatops/controller.rb @@ -118,26 +118,30 @@ def ensure_user_given end def ensure_chatops_authenticated - body = request.raw_post || "" - signature_string = [@chatops_url, @chatops_nonce, @chatops_timestamp, body].join("\n") - # We return this just to aid client debugging. - response.headers["Chatops-Signature-String"] = Base64.strict_encode64(signature_string) raise ConfigurationError.new("You need to add a client's public key in .pem format via #{Chatops.public_key_env_var_name}") unless Chatops.public_key.present? - if signature_valid?(Chatops.public_key, @chatops_signature, signature_string) || - signature_valid?(Chatops.alt_public_key, @chatops_signature, signature_string) - return true + + body = request.raw_post || "" + + valid = @chatops_urls.any? do |url| + signature_string = [url, @chatops_nonce, @chatops_timestamp, body].join("\n") + # We return this just to aid client debugging. + response.headers["Chatops-Signature-String"] = Base64.strict_encode64(signature_string) + if signature_valid?(Chatops.public_key, @chatops_signature, signature_string) || + signature_valid?(Chatops.alt_public_key, @chatops_signature, signature_string) + return true + end end + + return true if valid return jsonrpc_error(-32800, 403, "Not authorized") end def ensure_valid_chatops_url - unless Chatops.auth_base_url.present? + unless Chatops.auth_base_urls.present? raise ConfigurationError.new("You need to set the server's base URL to authenticate chatops RPC via #{Chatops.auth_base_url_env_var_name}") end - if Chatops.auth_base_url[-1] == "/" - raise ConfigurationError.new("Don't include a trailing slash in #{Chatops.auth_base_url_env_var_name}; the rails path will be appended and it must match exactly.") - end - @chatops_url = Chatops.auth_base_url + request.path + + @chatops_urls = Chatops.auth_base_urls.map { |url| url.chomp("/") + request.path } end def ensure_valid_chatops_nonce diff --git a/spec/lib/chatops/controller_spec.rb b/spec/lib/chatops/controller_spec.rb index 6225af3..591c6fc 100644 --- a/spec/lib/chatops/controller_spec.rb +++ b/spec/lib/chatops/controller_spec.rb @@ -56,7 +56,7 @@ def ensure_app_given @private_key = OpenSSL::PKey::RSA.new(2048) ENV["CHATOPS_AUTH_PUBLIC_KEY"] = @private_key.public_key.to_pem - ENV["CHATOPS_AUTH_BASE_URL"] = "http://test.host" + ENV["CHATOPS_AUTH_BASE_URL"] = "http://old.host,http://test.host/" end def rails_flexible_post(path, outer_params, jsonrpc_params = nil) @@ -315,7 +315,7 @@ def rails_flexible_post(path, outer_params, jsonrpc_params = nil) :room_id => "#someroom", :unknown_key => "few" # This should get ignored }, { - "app" => "foo" + "app" => "foo" } expect(json_response).to eq({ "jsonrpc" => "2.0", @@ -323,7 +323,7 @@ def rails_flexible_post(path, outer_params, jsonrpc_params = nil) "result" => "{\"params\":{\"action\":\"proxy_parameters\",\"chatop\":\"proxy_parameters\",\"controller\":\"anonymous\",\"mention_slug\":\"mention_slug_here\",\"message_id\":\"message_id_here\",\"room_id\":\"#someroom\",\"user\":\"foo\"},\"jsonrpc_params\":{\"app\":\"foo\"}}" }) expect(response.status).to eq 200 - end + end it "uses typical controller fun like before_action" do From 9c1c630eb0229dc27b3588b972c502c6b0501505 Mon Sep 17 00:00:00 2001 From: Artem Egorov Date: Fri, 5 Jan 2024 16:52:53 +0000 Subject: [PATCH 06/20] stick rails version for tests --- Gemfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index eefd680..9d9ce9c 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ -source 'https://rubygems.org' +source "https://rubygems.org" -gem 'rails' +gem "rails", "~> 6" group :development, :test do gem "rspec-rails", "~> 3" From f7cd321515cfa51a37d0a365946e13d95759d63a Mon Sep 17 00:00:00 2001 From: Artem Egorov Date: Fri, 5 Jan 2024 16:57:04 +0000 Subject: [PATCH 07/20] can't stick rails actually --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 9d9ce9c..a9f7234 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source "https://rubygems.org" -gem "rails", "~> 6" +gem "rails" group :development, :test do gem "rspec-rails", "~> 3" From 1c937719f84a8602cf5a5d217e69fdd615b28a36 Mon Sep 17 00:00:00 2001 From: Artem Egorov Date: Fri, 5 Jan 2024 16:59:15 +0000 Subject: [PATCH 08/20] install rails 6 for tests only --- .github/workflows/ruby.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 16a50a7..0da8023 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -15,5 +15,6 @@ jobs: ruby-version: 2.7.2 - name: Build and test run: | + gem install rails -v "~> 6" bundle install --binstubs bin/rspec From 508fbb0fe2034cd2addf9111153885133c1c3e88 Mon Sep 17 00:00:00 2001 From: Artem Egorov Date: Fri, 5 Jan 2024 17:40:48 +0000 Subject: [PATCH 09/20] revert --- .github/workflows/ruby.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 0da8023..16a50a7 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -15,6 +15,5 @@ jobs: ruby-version: 2.7.2 - name: Build and test run: | - gem install rails -v "~> 6" bundle install --binstubs bin/rspec From eabf05f9726d5238db11d6d56eef6765112f8f5d Mon Sep 17 00:00:00 2001 From: Artem Egorov Date: Mon, 8 Jan 2024 11:58:38 +0000 Subject: [PATCH 10/20] fix tests --- Gemfile | 3 +-- chatops-controller.gemspec | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index a9f7234..d86ba4a 100644 --- a/Gemfile +++ b/Gemfile @@ -1,8 +1,7 @@ source "https://rubygems.org" -gem "rails" - group :development, :test do + gem "rails", "~> 6" gem "rspec-rails", "~> 3" gem "pry", "~> 0" end diff --git a/chatops-controller.gemspec b/chatops-controller.gemspec index fda8ee0..ce5e50c 100644 --- a/chatops-controller.gemspec +++ b/chatops-controller.gemspec @@ -17,6 +17,7 @@ Gem::Specification.new do |s| s.files = Dir["{app,config,db,lib}/**/*", "README.md"] s.test_files = Dir["spec/**/*"] + s.add_dependency "rails" s.add_dependency "actionpack", ">= 6.0" s.add_dependency "activesupport", ">= 6.0" From e60af165bac95da42c8fe392d19d2445d13dd38f Mon Sep 17 00:00:00 2001 From: Artem Egorov Date: Mon, 8 Jan 2024 13:01:54 +0000 Subject: [PATCH 11/20] fix ensure_chatops_authenticated return --- lib/chatops/controller.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/chatops/controller.rb b/lib/chatops/controller.rb index 8f95150..8280eed 100644 --- a/lib/chatops/controller.rb +++ b/lib/chatops/controller.rb @@ -122,17 +122,16 @@ def ensure_chatops_authenticated body = request.raw_post || "" - valid = @chatops_urls.any? do |url| + @chatops_urls.each do |url| signature_string = [url, @chatops_nonce, @chatops_timestamp, body].join("\n") # We return this just to aid client debugging. response.headers["Chatops-Signature-String"] = Base64.strict_encode64(signature_string) if signature_valid?(Chatops.public_key, @chatops_signature, signature_string) || signature_valid?(Chatops.alt_public_key, @chatops_signature, signature_string) - return true + return true end end - return true if valid return jsonrpc_error(-32800, 403, "Not authorized") end From 03ea3fef1159876cf192ab9bb9829bdc494910e1 Mon Sep 17 00:00:00 2001 From: Artem Egorov Date: Wed, 10 Jan 2024 12:43:14 +0000 Subject: [PATCH 12/20] Create 5.2.0 release --- lib/chatops/controller/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/chatops/controller/version.rb b/lib/chatops/controller/version.rb index 6e8f6d1..a2fe68f 100644 --- a/lib/chatops/controller/version.rb +++ b/lib/chatops/controller/version.rb @@ -1,3 +1,3 @@ module ChatopsController - VERSION = "5.1.0" + VERSION = "5.2.0" end From 1975bd1461541a9933f94b694980f5cea510a1a9 Mon Sep 17 00:00:00 2001 From: Roye Tadmor <48676534+royetadmor@users.noreply.github.com> Date: Tue, 19 Mar 2024 17:01:56 +0200 Subject: [PATCH 13/20] Update docs --- docs/why.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/why.md b/docs/why.md index 8875770..3624358 100644 --- a/docs/why.md +++ b/docs/why.md @@ -47,7 +47,7 @@ bridge, and we find this maps well to the asymmetric crypto authentication. ### Keyword Arguments -We pair this system with , which +We pair this system with , which provides generic argument support for long arguments, like `--argument foo`. While regexes create much more natural commands, rarely used options tend to create ugly regexes that are hard to test. If a command can potentially take 10 From 46ca18d8017fcea8b1efbc16ee3bff5bdae81d05 Mon Sep 17 00:00:00 2001 From: Roye Tadmor <48676534+royetadmor@users.noreply.github.com> Date: Tue, 19 Mar 2024 17:03:52 +0200 Subject: [PATCH 14/20] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 724cb4e..40603b3 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ You're all done. Try `.echo foo`, and you should see your client respond with `Echoing back to you: foo`. A hubot client implementation is available at - + ## Usage From 76f2338360371fa87b79a5ce8b7992cf21ca81ba Mon Sep 17 00:00:00 2001 From: Aleksey Levenstein Date: Tue, 2 Jul 2024 11:12:44 +0300 Subject: [PATCH 15/20] fix: allow 5 mins time skew --- lib/chatops.rb | 2 ++ lib/chatops/controller.rb | 4 ++-- lib/chatops/controller/version.rb | 2 +- spec/lib/chatops/controller_spec.rb | 12 ++++++------ 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/chatops.rb b/lib/chatops.rb index fa7d90c..5b67b6e 100644 --- a/lib/chatops.rb +++ b/lib/chatops.rb @@ -11,6 +11,8 @@ module Chatops threaded_and_channel: 2, }.freeze + ALLOWED_TIME_SKEW_MINS = 5 + def self.public_key ENV[public_key_env_var_name] end diff --git a/lib/chatops/controller.rb b/lib/chatops/controller.rb index 8280eed..750f971 100644 --- a/lib/chatops/controller.rb +++ b/lib/chatops/controller.rb @@ -168,8 +168,8 @@ def ensure_valid_chatops_signature def ensure_valid_chatops_timestamp @chatops_timestamp = request.headers["Chatops-Timestamp"] time = Time.iso8601(@chatops_timestamp) - if !(time > 1.minute.ago && time < 1.minute.from_now) - return jsonrpc_error(-32803, 403, "Chatops timestamp not within 1 minute of server time: #{@chatops_timestamp} vs #{Time.now.utc.iso8601}") + if !(time > Chatops::ALLOWED_TIME_SKEW_MINS.minute.ago && time < Chatops::ALLOWED_TIME_SKEW_MINS.minute.from_now) + return jsonrpc_error(-32803, 403, "Chatops timestamp not within #{Chatops::ALLOWED_TIME_SKEW_MINS} minutes of server time: #{@chatops_timestamp} vs #{Time.now.utc.iso8601}") end rescue ArgumentError, TypeError # time parsing or missing can raise these diff --git a/lib/chatops/controller/version.rb b/lib/chatops/controller/version.rb index a2fe68f..be86876 100644 --- a/lib/chatops/controller/version.rb +++ b/lib/chatops/controller/version.rb @@ -1,3 +1,3 @@ module ChatopsController - VERSION = "5.2.0" + VERSION = "5.3.0" end diff --git a/spec/lib/chatops/controller_spec.rb b/spec/lib/chatops/controller_spec.rb index 591c6fc..e88cf5f 100644 --- a/spec/lib/chatops/controller_spec.rb +++ b/spec/lib/chatops/controller_spec.rb @@ -177,9 +177,9 @@ def rails_flexible_post(path, outer_params, jsonrpc_params = nil) expect(response.status).to eq 403 end - it "doesn't allow requests more than 1 minute old" do + it "doesn't allow requests more than 5 minute old" do nonce = SecureRandom.hex(20) - timestamp = 2.minutes.ago.utc.iso8601 + timestamp = 6.minutes.ago.utc.iso8601 request.headers["Chatops-Nonce"] = nonce request.headers["Chatops-Timestamp"] = timestamp digest = OpenSSL::Digest::SHA256.new @@ -188,12 +188,12 @@ def rails_flexible_post(path, outer_params, jsonrpc_params = nil) request.headers["Chatops-Signature"] = "Signature keyid=foo,signature=#{signature}" get :list expect(response.status).to eq 403 - expect(response.body).to include "Chatops timestamp not within 1 minute" + expect(response.body).to include "Chatops timestamp not within 5 minutes" end - it "doesn't allow requests more than 1 minute in the future" do + it "doesn't allow requests more than 5 minute in the future" do nonce = SecureRandom.hex(20) - timestamp = 2.minutes.from_now.utc.iso8601 + timestamp = 6.minutes.from_now.utc.iso8601 request.headers["Chatops-Nonce"] = nonce request.headers["Chatops-Timestamp"] = timestamp digest = OpenSSL::Digest::SHA256.new @@ -202,7 +202,7 @@ def rails_flexible_post(path, outer_params, jsonrpc_params = nil) request.headers["Chatops-Signature"] = "Signature keyid=foo,signature=#{signature}" get :list expect(response.status).to eq 403 - expect(response.body).to include "Chatops timestamp not within 1 minute" + expect(response.body).to include "Chatops timestamp not within 5 minutes" end it "does not add authentication to non-chatops routes" do From cbbba2e64bac83d6f76b26359f251e8bf48fb306 Mon Sep 17 00:00:00 2001 From: Joseph Felix <98041255+panthervfs@users.noreply.github.com> Date: Mon, 14 Oct 2024 09:15:15 -0700 Subject: [PATCH 16/20] pvfs-failure-context-update This commit adds more context to the chatop tests failures by checking for keys in the json_response and raising if they do not exist. This should give users a better idea of why their expectations fail. --- lib/chatops/controller/test_case_helpers.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/chatops/controller/test_case_helpers.rb b/lib/chatops/controller/test_case_helpers.rb index f6c4313..34d4933 100644 --- a/lib/chatops/controller/test_case_helpers.rb +++ b/lib/chatops/controller/test_case_helpers.rb @@ -42,6 +42,7 @@ def chatop(method, params = {}) def chat(message, user, room_id = "123", message_id = "456") get :list json_response = JSON.load(response.body) + raise "Invalid Chatop response - BODY: #{json_response}" unless json_response.key?("methods") matchers = json_response["methods"].map { |name, metadata| metadata = metadata.dup metadata["name"] = name @@ -75,6 +76,7 @@ def chatop_response def chatop_error json_response = JSON.load(response.body) + raise "There is no chatop error - BODY: #{json_response}" unless json_response.key?("error") json_response["error"]["message"] end From f6f1557f476de2bf53fb2f3ee8817c6cc7d72417 Mon Sep 17 00:00:00 2001 From: Joseph Felix <98041255+panthervfs@users.noreply.github.com> Date: Mon, 14 Oct 2024 09:18:57 -0700 Subject: [PATCH 17/20] Removing changes so I can submit a PR --- lib/chatops/controller/test_case_helpers.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/chatops/controller/test_case_helpers.rb b/lib/chatops/controller/test_case_helpers.rb index 34d4933..f6c4313 100644 --- a/lib/chatops/controller/test_case_helpers.rb +++ b/lib/chatops/controller/test_case_helpers.rb @@ -42,7 +42,6 @@ def chatop(method, params = {}) def chat(message, user, room_id = "123", message_id = "456") get :list json_response = JSON.load(response.body) - raise "Invalid Chatop response - BODY: #{json_response}" unless json_response.key?("methods") matchers = json_response["methods"].map { |name, metadata| metadata = metadata.dup metadata["name"] = name @@ -76,7 +75,6 @@ def chatop_response def chatop_error json_response = JSON.load(response.body) - raise "There is no chatop error - BODY: #{json_response}" unless json_response.key?("error") json_response["error"]["message"] end From 78b3a765b3f43e009f910405d283404bda75626d Mon Sep 17 00:00:00 2001 From: Joseph Felix <98041255+panthervfs@users.noreply.github.com> Date: Mon, 14 Oct 2024 09:19:47 -0700 Subject: [PATCH 18/20] Check for fields and provide error desc This commit adds more context to the chatop tests failures by checking for keys in the json_response and raising if they do not exist. This should give users a better idea of why their expectations fail. --- lib/chatops/controller/test_case_helpers.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/chatops/controller/test_case_helpers.rb b/lib/chatops/controller/test_case_helpers.rb index f6c4313..34d4933 100644 --- a/lib/chatops/controller/test_case_helpers.rb +++ b/lib/chatops/controller/test_case_helpers.rb @@ -42,6 +42,7 @@ def chatop(method, params = {}) def chat(message, user, room_id = "123", message_id = "456") get :list json_response = JSON.load(response.body) + raise "Invalid Chatop response - BODY: #{json_response}" unless json_response.key?("methods") matchers = json_response["methods"].map { |name, metadata| metadata = metadata.dup metadata["name"] = name @@ -75,6 +76,7 @@ def chatop_response def chatop_error json_response = JSON.load(response.body) + raise "There is no chatop error - BODY: #{json_response}" unless json_response.key?("error") json_response["error"]["message"] end From 9e0ea4d5248b282515932dd6e833ee7435cc4149 Mon Sep 17 00:00:00 2001 From: Aleksey Levenstein Date: Sun, 25 Jan 2026 12:02:02 +0200 Subject: [PATCH 19/20] Permit thread_id --- lib/chatops/controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/chatops/controller.rb b/lib/chatops/controller.rb index 750f971..e51a7ec 100644 --- a/lib/chatops/controller.rb +++ b/lib/chatops/controller.rb @@ -57,7 +57,7 @@ def setup_params! @jsonrpc_params = params.delete(:params) if params.has_key? :params - self.params = params.permit(:action, :chatop, :controller, :id, :mention_slug, :message_id, :method, :room_id, :user, :raw_command) + self.params = params.permit(:action, :chatop, :controller, :id, :mention_slug, :message_id, :method, :room_id, :user, :raw_command, :thread_id) end def jsonrpc_params From 8baa25b796e24bb1acd36d08ed162a54c14fa4c3 Mon Sep 17 00:00:00 2001 From: Aleksey Levenstein Date: Sun, 25 Jan 2026 16:45:00 +0200 Subject: [PATCH 20/20] bump version to 5.4.0 --- lib/chatops/controller/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/chatops/controller/version.rb b/lib/chatops/controller/version.rb index be86876..f27c53f 100644 --- a/lib/chatops/controller/version.rb +++ b/lib/chatops/controller/version.rb @@ -1,3 +1,3 @@ module ChatopsController - VERSION = "5.3.0" + VERSION = "5.4.0" end