Skip to content

Commit 4db058b

Browse files
committed
fix: code
1 parent a6edcad commit 4db058b

8 files changed

Lines changed: 32 additions & 71 deletions

File tree

packages/forest_admin_agent/lib/forest_admin_agent/builder/agent_factory.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ def initialize
2222

2323
def setup(options)
2424
@options = options
25-
Services::Permissions.skip_relation_read_permissions =
26-
options.to_h[:skip_relation_read_permissions] == true
2725
@has_env_secret = !options.to_h[:env_secret].nil?
2826
@customizer = ForestAdminDatasourceCustomizer::DatasourceCustomizer.new
2927
build_container
@@ -345,8 +343,10 @@ def should_skip_schema_update?
345343
end
346344

347345
# An auditor reading the boot log should see the weakened posture without reading the config.
346+
# Read from the options `setup` was handed: `Facades::Container` resolves against
347+
# `AgentFactory.instance`, which a host subclassing this factory has not populated.
348348
def warn_relation_read_permissions_skipped
349-
return unless Services::Permissions.skip_relation_read_permissions?
349+
return unless @options.to_h[:skip_relation_read_permissions] == true
350350

351351
@logger.log(
352352
'Warn',

packages/forest_admin_agent/lib/forest_admin_agent/routes/capabilities/collections.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def handle_request(args = {})
6969
canUseProjectionViaHeaderOnList: true,
7070
canUseMultipleFieldsProjectionOnRelation: true,
7171
canUseAuditTrail: audit_trail_enabled?,
72-
checksRelationReadPermissions: !Services::Permissions.skip_relation_read_permissions?
72+
checksRelationReadPermissions: !skip_relation_read_permissions?
7373
}
7474
},
7575
status: 200
@@ -81,6 +81,10 @@ def handle_request(args = {})
8181
# True only where the store the record-history route reads from exists — the same lookup that route
8282
# mounts itself on, so the capability cannot drift from what the routes actually serve. The front gates
8383
# its History tab on this.
84+
def skip_relation_read_permissions?
85+
ForestAdminAgent::Facades::Container.config_from_cache[:skip_relation_read_permissions] == true
86+
end
87+
8488
def audit_trail_enabled?
8589
!::ForestAdminAgent::AuditTrail.store.nil?
8690
end

packages/forest_admin_agent/lib/forest_admin_agent/routes/charts/charts.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ def aggregate_field_name(args)
5555
field.nil? || field.to_s.empty? ? nil : field
5656
end
5757

58+
def skip_relation_read_permissions?
59+
ForestAdminAgent::Facades::Container.config_from_cache[:skip_relation_read_permissions] == true
60+
end
61+
5862
def validate_and_get_type(type)
5963
chart_types = %w[Value Objective Pie Line Leaderboard]
6064
unless chart_types.include?(type)
@@ -204,7 +208,7 @@ def make_leaderboard(context, filter, args)
204208
# A count exposes the cardinality of the relation, which `/relationships/<name>/count`
205209
# puts behind `browse`. No path names it, so nothing above sees it. It arrived with the
206210
# related-read checks, so it goes away with them.
207-
if aggregation.field.nil? && !Services::Permissions.skip_relation_read_permissions?
211+
if aggregation.field.nil? && !skip_relation_read_permissions?
208212
context.permissions.can?(:browse, context.datasource.get_collection(field.foreign_collection))
209213
end
210214

packages/forest_admin_agent/lib/forest_admin_agent/services/permissions.rb

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,6 @@ def self.invalidate_cache(id_cache = nil)
3535
ForestAdminAgent::Facades::Container.logger.log('Info', "Invalidating #{id_cache} cache..")
3636
end
3737

38-
# Set once from the options `AgentFactory#setup` was handed, rather than resolved from
39-
# `Facades::Container`: that answers from `AgentFactory.instance`, so a host subclassing the
40-
# factory — `ForestAdminRpcAgent::Agent` has its own singleton — would leave the option
41-
# ignored and the checks silently on. A class method so the chart and capabilities routes can
42-
# ask without an instance, and so the route specs faking this service with an
43-
# `instance_double` do not each have to stub one more message.
44-
class << self
45-
attr_writer :skip_relation_read_permissions
46-
end
47-
48-
def self.skip_relation_read_permissions?
49-
@skip_relation_read_permissions == true
50-
end
51-
5238
def can?(action, collection, allow_fetch: false)
5339
return true unless permission_system?
5440

@@ -81,7 +67,7 @@ def read_permissions(root_collection_name, collection_names)
8167
# An absent permission system is not a denial: `can?` allows everything there, and answering
8268
# anything else would redact every relation on a deployment that granted nothing to check.
8369
# `skip_relation_read_permissions` is the operator asking for that same answer on purpose.
84-
if self.class.skip_relation_read_permissions? || !permission_system?
70+
if skip_relation_read_permissions? || !permission_system?
8571
return allowed.merge(to_check.to_h { |name| [name, true] })
8672
end
8773

@@ -290,6 +276,10 @@ def readable_leaves?(names, allowed)
290276
names.any? && names.all? { |name| allowed[name] }
291277
end
292278

279+
def skip_relation_read_permissions?
280+
Facades::Container.config_from_cache[:skip_relation_read_permissions] == true
281+
end
282+
293283
def leaf_label(names)
294284
names.empty? ? 'an unresolved polymorphic relation' : "the '#{names.join("' or '")}' collection"
295285
end
@@ -374,7 +364,7 @@ def assert_extended_search_checkable(collection, search_extended)
374364
return unless describes_own_search?(collection)
375365
return unless permission_system?
376366
# Refused ahead of `read_permissions`, so the skip has to be read here as well.
377-
return if self.class.skip_relation_read_permissions?
367+
return if skip_relation_read_permissions?
378368

379369
raise ForbiddenError,
380370
"You cannot run an extended search on the '#{collection.name}' collection: the fields " \

packages/forest_admin_agent/spec/lib/forest_admin_agent/builder/agent_factory_spec.rb

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -900,13 +900,12 @@ module Builder
900900
end
901901

902902
describe 'warning that the relation read checks are off' do
903-
after { Services::Permissions.skip_relation_read_permissions = false }
904-
903+
# `@options` is what `setup` holds when it calls this, so the spec hands over the same thing.
905904
def boot_with(skip)
906905
instance = described_class.instance
907906
logger = instance_spy(Services::LoggerService)
908907
instance.instance_variable_set(:@logger, logger)
909-
Services::Permissions.skip_relation_read_permissions = skip
908+
instance.instance_variable_set(:@options, { skip_relation_read_permissions: skip })
910909

911910
instance.send(:warn_relation_read_permissions_skipped)
912911

@@ -925,46 +924,6 @@ def boot_with(skip)
925924
expect(boot_with(false)).not_to have_received(:log)
926925
end
927926
end
928-
929-
# `Facades::Container` resolves against `AgentFactory.instance`, so a host that subclasses
930-
# this factory — `ForestAdminRpcAgent::Agent`, with its own singleton — has no container
931-
# there. Reading the option through the facade left it ignored on exactly those hosts, which
932-
# kept the checks on while the operator had asked for them off.
933-
describe 'carrying skip_relation_read_permissions out of the options' do
934-
let(:options) do
935-
{
936-
auth_secret: 'cba803d01a4d43b55010cab41fa1ea1f1f51a95e',
937-
env_secret: '89719c6d8e2e2de2694c2f220fe2dbf02d5289487364daf1e4c6b13733ed0cdb',
938-
is_production: false,
939-
schema_path: File.join('tmp', '.forestadmin-schema.json')
940-
}
941-
end
942-
943-
after { Services::Permissions.skip_relation_read_permissions = false }
944-
945-
it 'takes the value setup was handed' do
946-
described_class.instance.setup(options.merge(skip_relation_read_permissions: true))
947-
948-
expect(Services::Permissions.skip_relation_read_permissions?).to be true
949-
end
950-
951-
it 'defaults to keeping the checks on when the host declares nothing' do
952-
Services::Permissions.skip_relation_read_permissions = true
953-
954-
described_class.instance.setup(options)
955-
956-
expect(Services::Permissions.skip_relation_read_permissions?).to be false
957-
end
958-
959-
it 'answers without resolving the base facade container' do
960-
allow(Facades::Container).to receive(:config_from_cache).and_raise(
961-
NoMethodError, "undefined method `resolve' for nil"
962-
)
963-
Services::Permissions.skip_relation_read_permissions = true
964-
965-
expect(Services::Permissions.skip_relation_read_permissions?).to be true
966-
end
967-
end
968927
end
969928
end
970929
end

packages/forest_admin_agent/spec/lib/forest_admin_agent/routes/capabilities/collections_spec.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,12 @@ module Capabilities
9595
# The frontend prunes projections on this flag, so announcing it wrong either hides
9696
# columns the agent serves or lets the frontend ask for ones it refuses.
9797
it 'announces the relation read checks as off once the option turns them off' do
98-
ForestAdminAgent::Services::Permissions.skip_relation_read_permissions = true
98+
configured = ForestAdminAgent::Facades::Container.config_from_cache.merge(
99+
skip_relation_read_permissions: true
100+
)
101+
allow(ForestAdminAgent::Facades::Container).to receive(:config_from_cache).and_return(configured)
99102

100103
expect(result[:content][:agentCapabilities][:checksRelationReadPermissions]).to be false
101-
ensure
102-
ForestAdminAgent::Services::Permissions.skip_relation_read_permissions = false
103104
end
104105

105106
it 'returns agentCapabilities' do

packages/forest_admin_agent/spec/lib/forest_admin_agent/routes/charts/charts_spec.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -581,8 +581,10 @@ module Charts
581581
type: 'Leaderboard',
582582
timezone: 'Europe/Paris'
583583
})
584-
allow(ForestAdminAgent::Services::Permissions).to receive(:skip_relation_read_permissions?)
585-
.and_return(true)
584+
configured = ForestAdminAgent::Facades::Container.config_from_cache.merge(
585+
skip_relation_read_permissions: true
586+
)
587+
allow(ForestAdminAgent::Facades::Container).to receive(:config_from_cache).and_return(configured)
586588
allow(permissions).to receive(:can?)
587589
allow(@datasource.get_collection('book')).to receive(:datasource).and_return(@datasource)
588590
review = @datasource.get_collection('review')

packages/forest_admin_agent/spec/lib/forest_admin_agent/security/related_read_permissions_spec.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -619,9 +619,10 @@ def with_instant_cache_refresh(enabled)
619619
# asked by the route through `can?`, and still answered.
620620
describe 'with skip_relation_read_permissions' do
621621
def unchecked_permissions(readable = [])
622-
allow(described_class).to receive(:skip_relation_read_permissions?).and_return(true)
622+
permissions = build_permissions(readable)
623+
allow(permissions).to receive(:skip_relation_read_permissions?).and_return(true)
623624

624-
build_permissions(readable)
625+
permissions
625626
end
626627

627628
def searchable_cards(searched, search_handler: false)

0 commit comments

Comments
 (0)