Skip to content

Commit 347783b

Browse files
committed
Fix authorize_show_related_resource
1 parent 1e4d611 commit 347783b

File tree

5 files changed

+30
-13
lines changed

5 files changed

+30
-13
lines changed

lib/jsonapi/authorization/authorizing_processor.rb

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def authorize_show_relationship
7575
related_resource =
7676
case relationship
7777
when JSONAPI::Relationship::ToOne
78-
parent_resource.public_send(params[:relationship_type].to_sym)
78+
resources_from_relationship(source_klass, source_id, relationship.type, context).first
7979
when JSONAPI::Relationship::ToMany
8080
# Do nothing — already covered by policy scopes
8181
else
@@ -94,10 +94,13 @@ def authorize_show_related_resource
9494

9595
source_resource = source_klass.find_by_key(source_id, context: context)
9696

97-
related_resource = source_resource.public_send(relationship_type)
97+
related_resource = resources_from_relationship(
98+
source_klass, source_id, relationship_type, context
99+
)&.first
98100

99101
source_record = source_resource._model
100102
related_record = related_resource._model unless related_resource.nil?
103+
101104
authorizer.show_related_resource(
102105
source_record: source_record, related_record: related_record
103106
)
@@ -285,6 +288,18 @@ def authorizer
285288
@authorizer ||= ::JSONAPI::Authorization.configuration.authorizer.new(context: context)
286289
end
287290

291+
def resources_from_relationship(source_klass, source_id, relationship_type, context)
292+
rid = source_klass.find_related_fragments(
293+
[JSONAPI::ResourceIdentity.new(source_klass, source_id)],
294+
relationship_type,
295+
context: context
296+
).keys.first
297+
298+
return nil if rid.nil?
299+
300+
rid.resource_klass.find_to_populate_by_keys(rid.id)
301+
end
302+
288303
# TODO: Communicate with upstream to fix this nasty hack
289304
def operation_resource_id
290305
case operation_type

lib/jsonapi/authorization/pundit_scoped_resource.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ module PunditScopedResource
1010
module ClassMethods
1111
def records(options = {})
1212
user_context = JSONAPI::Authorization.configuration.user_context(options[:context])
13-
::Pundit.policy_scope!(user_context, _model_class)
13+
::Pundit.policy_scope!(user_context, super)
1414
end
1515
end
1616

spec/requests/custom_name_relationship_operations_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
require 'spec_helper'
44

5-
RSpec.describe 'including custom name relationships', type: :request, pending: 'compatibility with JR 0.10' do
5+
RSpec.describe 'including custom name relationships', type: :request do
66
include AuthorizationStubs
77
fixtures :all
88

spec/requests/included_resources_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@
533533
include_examples :scope_limited_directive_tests
534534
end
535535

536-
describe 'GET /articles/:id/article', pending: true do
536+
describe 'GET /articles/:id/article' do
537537
let(:article) do
538538
Article.create(
539539
external_id: "indifferent_external_id",

spec/requests/related_resources_operations_spec.rb

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,29 +65,31 @@
6565
subject(:last_response) { get("/articles/#{article.external_id}/author") }
6666
let(:article) { articles(:article_with_author) }
6767
let(:policy_scope) { Article.all }
68+
let(:user_policy_scope) { User.all }
6869

69-
context 'unauthorized for show_related_resource', pending: 'Compatibility with JR 0.10' do
70+
before do
71+
allow_any_instance_of(UserPolicy::Scope).to receive(:resolve).and_return(user_policy_scope)
72+
end
73+
74+
context 'unauthorized for show_related_resource' do
7075
before { disallow_operation('show_related_resource', source_record: article, related_record: article.author) }
7176
it { is_expected.to be_forbidden }
7277
end
7378

74-
context 'authorized for show_related_resource', pending: 'Compatibility with JR 0.10' do
79+
context 'authorized for show_related_resource' do
7580
before { allow_operation('show_related_resource', source_record: article, related_record: article.author) }
7681
it { is_expected.to be_ok }
7782

7883
# If this happens in real life, it's mostly a bug. We want to document the
7984
# behaviour in that case anyway, as it might be surprising.
80-
context 'limited by policy scope', pending: false do
85+
context 'limited by policy scope' do
8186
let(:policy_scope) { Article.where.not(id: article.id) }
8287
it { is_expected.to be_not_found }
8388
end
8489
end
8590

86-
context 'authorized for show_related_resource while related resource is limited by policy scope', pending: 'Compatibility with JR 0.10' do
87-
# It might be surprising that with jsonapi-authorization that supports JR 0.9, the `related_record`
88-
# is indeed a real record here and not `nil`. If the policy scope was used, then the `related_record`
89-
# should be `nil` but alas, that is not the case.
90-
before { allow_operation('show_related_resource', source_record: article, related_record: article.author) }
91+
context 'authorized for show_related_resource while related resource is limited by policy scope' do
92+
before { allow_operation('show_related_resource', source_record: article, related_record: nil) }
9193

9294
let(:user_policy_scope) { User.where.not(id: article.author.id) }
9395

0 commit comments

Comments
 (0)