From 070c451e7df1f23299b0c49827330c885a7f005a Mon Sep 17 00:00:00 2001 From: Martijn Versluis Date: Fri, 7 Jun 2024 09:45:17 +0200 Subject: [PATCH] Correctly handle Amazon GW forbidden errors The Amazon API gateway used by the Easee API seems to route some requests to a blackhole, possibly because we keep trying to login with outdated credentials. However, such responses should result in a Forbidden error to make sure they're dealt with correctly upstream. This PR adds a Faraday middleware that detects the Amazon Forbidden response header and changes the response status code to 403. --- lib/easee/amazon_gw_middleware.rb | 10 ++++++++++ lib/easee/client.rb | 1 + lib/stekker_easee.rb | 1 + spec/easee/client_spec.rb | 29 +++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 lib/easee/amazon_gw_middleware.rb diff --git a/lib/easee/amazon_gw_middleware.rb b/lib/easee/amazon_gw_middleware.rb new file mode 100644 index 0000000..8fcad0e --- /dev/null +++ b/lib/easee/amazon_gw_middleware.rb @@ -0,0 +1,10 @@ +module Easee + class AmazonGwMiddleware < Faraday::Middleware + def on_complete(env) + return unless env.response_headers["X-Amzn-Errortype"] == "ForbiddenException" + + response_values = Faraday::Response::RaiseError.new.response_values(env) + raise(Faraday::ForbiddenError, response_values) + end + end +end diff --git a/lib/easee/client.rb b/lib/easee/client.rb index 95b8d7e..9f5c1f5 100644 --- a/lib/easee/client.rb +++ b/lib/easee/client.rb @@ -91,6 +91,7 @@ def connection Faraday.new(url: BASE_URL) do |conn| conn.request :json conn.response :raise_error + conn.use AmazonGwMiddleware conn.response :json, content_type: /\bjson$/ end end diff --git a/lib/stekker_easee.rb b/lib/stekker_easee.rb index 2bd80b0..a912240 100644 --- a/lib/stekker_easee.rb +++ b/lib/stekker_easee.rb @@ -13,6 +13,7 @@ require_relative "easee/site" require_relative "easee/state" require_relative "easee/charger" +require_relative "easee/amazon_gw_middleware" module Easee end diff --git a/spec/easee/client_spec.rb b/spec/easee/client_spec.rb index 7462c2f..0ece8a8 100644 --- a/spec/easee/client_spec.rb +++ b/spec/easee/client_spec.rb @@ -232,6 +232,35 @@ expect { client.login } .to raise_error(Easee::Errors::InvalidCredentials) end + + it "raises Forbidden errors when the request is rerouted with X-Amzn-Errortype: ForbiddenException" do + user_name = "test" + password = "old" + + stub_request(:post, "https://api.easee.cloud/api/accounts/login") + .with( + body: { userName: user_name, password: }.to_json, + ) + .to_return( + status: 301, + headers: { + Date: "Fri, 07 Jun 2024 07:30:02 GMT", + "Content-Type": "application/json", + "Content-Length": "0", + Connection: "keep-alive", + "X-Amzn-Requestid": "aaa0a000-000a-0000-a0a0-00000a00aa00", + "X-Amzn-Errortype": "ForbiddenException", + "X-Amz-Apigw-Id": "A_AAAAa0aaAAAaa=", + "X-Easee-Key": "a00a0000-0a0a-0a0a-aa00-0a0000a0a0a0", + Location: "https://blackhole.easee.com", + }, + ) + + client = Easee::Client.new(user_name:, password:) + + expect { client.login } + .to raise_error(Easee::Errors::Forbidden) + end end describe "#pair" do