diff --git a/lib/jsonapi/authorization/authorizing_processor.rb b/lib/jsonapi/authorization/authorizing_processor.rb index dd5712d7..b7cc1613 100644 --- a/lib/jsonapi/authorization/authorizing_processor.rb +++ b/lib/jsonapi/authorization/authorizing_processor.rb @@ -101,12 +101,16 @@ def authorize_show_related_resource end def authorize_show_related_resources - source_record = params[:source_klass].find_by_key( + source_resource = params[:source_klass].find_by_key( params[:source_id], context: context - )._model + ) - authorizer.show_related_resources(source_record: source_record) + source_record = source_resource._model + + authorizer.show_related_resources( + source_record: source_record, related_record_class: @resource_klass._model_class + ) end def authorize_replace_fields diff --git a/lib/jsonapi/authorization/default_pundit_authorizer.rb b/lib/jsonapi/authorization/default_pundit_authorizer.rb index 9708a540..460f873f 100644 --- a/lib/jsonapi/authorization/default_pundit_authorizer.rb +++ b/lib/jsonapi/authorization/default_pundit_authorizer.rb @@ -77,8 +77,10 @@ def show_related_resource(source_record:, related_record:) # ==== Parameters # # * +source_record+ - The record whose relationship is queried - def show_related_resources(source_record:) + # * +related_record_class+ - The associated record class to show + def show_related_resources(source_record:, related_record_class:) ::Pundit.authorize(user, source_record, 'show?') + ::Pundit.authorize(user, related_record_class, 'index?') end # PATCH /resources/:id diff --git a/spec/jsonapi/authorization/default_pundit_authorizer_spec.rb b/spec/jsonapi/authorization/default_pundit_authorizer_spec.rb index 9f939edf..f010f385 100644 --- a/spec/jsonapi/authorization/default_pundit_authorizer_spec.rb +++ b/spec/jsonapi/authorization/default_pundit_authorizer_spec.rb @@ -185,18 +185,42 @@ end describe '#show_related_resources' do + let(:related_record) { Comment.new } + subject(:method_call) do - -> { authorizer.show_related_resources(source_record: source_record) } + lambda { + authorizer.show_related_resources(source_record: source_record, + related_record_class: related_record + ) + } end - context 'authorized for show? on record' do + context 'authorized for show? on source record' do before { allow_action(source_record, 'show?') } - it { is_expected.not_to raise_error } + + context 'authorized for index? on related record' do + before { allow_action(related_record, 'index?') } + it { is_expected.not_to raise_error } + end + + context 'unauthorized for index? on related record' do + before { disallow_action(related_record, 'index?') } + it { is_expected.to raise_error(::Pundit::NotAuthorizedError) } + end end context 'unauthorized for show? on record' do before { disallow_action(source_record, 'show?') } - it { is_expected.to raise_error(::Pundit::NotAuthorizedError) } + + context 'authorized for index? on related record' do + before { allow_action(related_record, 'index?') } + it { is_expected.to raise_error(::Pundit::NotAuthorizedError) } + end + + context 'unauthorized for index? on related record' do + before { disallow_action(related_record, 'index?') } + it { is_expected.to raise_error(::Pundit::NotAuthorizedError) } + end end end diff --git a/spec/requests/included_resources_spec.rb b/spec/requests/included_resources_spec.rb index 6a762e6f..1e117960 100644 --- a/spec/requests/included_resources_spec.rb +++ b/spec/requests/included_resources_spec.rb @@ -392,7 +392,7 @@ let(:article_policy_scope) { Article.where(id: article.id) } subject(:last_response) { get("/articles/#{article.external_id}/articles?include=#{include_query}") } - let!(:chained_authorizer) { allow_operation('show_related_resources', source_record: article) } + let!(:chained_authorizer) { allow_operation('show_related_resources', source_record: article, related_record_class: article.class) } include_examples :include_directive_tests end diff --git a/spec/requests/related_resources_operations_spec.rb b/spec/requests/related_resources_operations_spec.rb index 958c3dd0..d7e9c721 100644 --- a/spec/requests/related_resources_operations_spec.rb +++ b/spec/requests/related_resources_operations_spec.rb @@ -24,6 +24,7 @@ let(:policy_scope) { Article.all } let(:comments_on_article) { article.comments } + let(:comments_class) { comments_on_article.first.class } let(:comments_policy_scope) { comments_on_article.limit(1) } before do @@ -31,12 +32,12 @@ end context 'unauthorized for show_related_resources' do - before { disallow_operation('show_related_resources', source_record: article) } + before { disallow_operation('show_related_resources', source_record: article, related_record_class: comments_class) } it { is_expected.to be_forbidden } end context 'authorized for show_related_resources' do - before { allow_operation('show_related_resources', source_record: article) } + before { allow_operation('show_related_resources', source_record: article, related_record_class: comments_class) } it { is_expected.to be_ok } # If this happens in real life, it's mostly a bug. We want to document the