From bebd047775d5a7cf1349fd749411bdeb7d9ece6a Mon Sep 17 00:00:00 2001 From: Geoffrey Wilson Date: Mon, 9 Sep 2024 13:22:18 -0400 Subject: [PATCH] Add better auth error propogation from interactor to controller; plus unit test (#23) * Add better auth error propogation from interactor to controller; added interactor unit test * Use a concern to make interactors fail on error --- app/controllers/certificates_controller.rb | 4 +-- app/interactors/authenticate_identity.rb | 1 + app/interactors/authorize_request.rb | 1 + app/interactors/check_policy.rb | 6 ---- app/interactors/fail_on_error.rb | 11 ++++++++ app/interactors/obtain_cert.rb | 1 + test/interactors/authorize_request_test.rb | 33 ++++++++++++++++++++++ 7 files changed, 49 insertions(+), 8 deletions(-) delete mode 100644 app/interactors/check_policy.rb create mode 100644 app/interactors/fail_on_error.rb create mode 100644 test/interactors/authorize_request_test.rb diff --git a/app/controllers/certificates_controller.rb b/app/controllers/certificates_controller.rb index 5355f80..f4f204a 100644 --- a/app/controllers/certificates_controller.rb +++ b/app/controllers/certificates_controller.rb @@ -6,9 +6,9 @@ def create if !req.valid? raise BadRequestError.new req.errors.full_messages end - result = IssueCert.call(request: req, identity: @identity) + result = IssueCert.call(request: req, identity: identity) if result.failure? - raise StandardError.new result.message + raise (result.error || StandardError.new(result.message)) end @cert = result.cert end diff --git a/app/interactors/authenticate_identity.rb b/app/interactors/authenticate_identity.rb index 0ddcae8..8626708 100644 --- a/app/interactors/authenticate_identity.rb +++ b/app/interactors/authenticate_identity.rb @@ -1,5 +1,6 @@ class AuthenticateIdentity include Interactor + include FailOnError before do token = context.request.headers["Authorization"] diff --git a/app/interactors/authorize_request.rb b/app/interactors/authorize_request.rb index 8f033c5..bbcef74 100644 --- a/app/interactors/authorize_request.rb +++ b/app/interactors/authorize_request.rb @@ -1,5 +1,6 @@ class AuthorizeRequest include Interactor + include FailOnError def call Services::DomainOwnershipService.new.authorize!(context.identity, context.request) diff --git a/app/interactors/check_policy.rb b/app/interactors/check_policy.rb deleted file mode 100644 index 5aaa656..0000000 --- a/app/interactors/check_policy.rb +++ /dev/null @@ -1,6 +0,0 @@ -class CheckPolicy - include Interactor - - def call - end -end diff --git a/app/interactors/fail_on_error.rb b/app/interactors/fail_on_error.rb new file mode 100644 index 0000000..76d5723 --- /dev/null +++ b/app/interactors/fail_on_error.rb @@ -0,0 +1,11 @@ +module FailOnError + extend ActiveSupport::Concern + + included do + around do |interactor| + interactor.call + rescue => e + context.fail!(error: e) + end + end +end diff --git a/app/interactors/obtain_cert.rb b/app/interactors/obtain_cert.rb index d32e72c..8cd9b87 100644 --- a/app/interactors/obtain_cert.rb +++ b/app/interactors/obtain_cert.rb @@ -1,5 +1,6 @@ class ObtainCert include Interactor + include FailOnError def call if cert = Services::CertificateService.new.issue_cert(context.request) diff --git a/test/interactors/authorize_request_test.rb b/test/interactors/authorize_request_test.rb new file mode 100644 index 0000000..30cd3e6 --- /dev/null +++ b/test/interactors/authorize_request_test.rb @@ -0,0 +1,33 @@ +require "test_helper" + +class AuthorizeRequestTest < ActiveSupport::TestCase + def setup + @domain = domains(:group_match) + @identity = Identity.new(subject: @domain.owner) + @cr = CertIssueRequest.new(common_name: @domain.fqdn) + @interactor = AuthorizeRequest + end + + test "successful call" do + request = CertIssueRequest.new(common_name: @domain.fqdn) + srv = Minitest::Mock.new + srv.expect :authorize!, nil, [ @identity, @cr ] + Services::DomainOwnershipService.stub :new, srv do + context = @interactor.call(identity: @identity, request: @cr) + assert context.success? + end + end + + test "unsuccessful call" do + request = CertIssueRequest.new(common_name: @domain.fqdn) + srv = Services::DomainOwnershipService.new + Services::DomainOwnershipService.stub :new, srv do + err = ->(_, _) { raise AuthError.new "no can do" } + srv.stub :authorize!, err do + context = @interactor.call(identity: @identity, request: @cr) + assert_not context.success? + assert_kind_of AuthError, context.error + end + end + end +end