forest_admin_agent 1.41.0 → 1.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e206afe12d8b554e97e214bc27441b51ddf5252d3e4b1ee5800645bd27baa228
4
- data.tar.gz: cb1e6a7aa74f086fb70ebc7f30808db2b984660f6e375a49a5ee3467ebf0dbd2
3
+ metadata.gz: 2efec0ce2de78876bbab2962c838ee712dc576c6133e6b705f6f4c9d62ea998b
4
+ data.tar.gz: 557af82363e33d90b02952742832f4cdd3e2283610a4850ce3252eef12f6f3ca
5
5
  SHA512:
6
- metadata.gz: 681910cfb585cef1e368db4e0f464b8866d35615cd1b2daaee1f02a45da613a52ec0a5063620ea36d2b1f47061486922227cc67cfa2d314b38f97a47c06fb7c8
7
- data.tar.gz: 16763d62485a9bf7be6d253fb68352e8da2edc2d7679b606b4b535fce67d2e301e39f236c649d4cb27930fb6b3b9a7daec5643ca9a51fb30e9e34bf14095e20a
6
+ metadata.gz: 0dcfa322e26c5fb8c0e65865abf8d5f5ab4cd9a7f3c5e5abe6d86c5b8ffc6149f16ea609417fb3c9ce421b46f81157cb408078e18aced4b6336cb474d0a70a05
7
+ data.tar.gz: 350b111bf50db137f596d884d4fceab32fbab20ee9858846d0342b360b731d157a37a9ecd59878483672f9c1411a683302ccac3cf76428714786e2bede72b319
@@ -330,11 +330,16 @@ module ForestAdminAgent
330
330
  end
331
331
 
332
332
  def collect_search_usages(collection, search, search_extended, usages)
333
- return if search.nil? || !collection.respond_to?(:searched_fields)
333
+ # The stack discards a blank search instead of running it, so there is nothing to authorize.
334
+ return if search.nil? || search.strip.empty?
334
335
 
335
- searched = collection.searched_fields(search, search_extended)
336
+ searched = collection.searched_fields(search, search_extended) if collection.respond_to?(:searched_fields)
336
337
 
337
- return if searched.nil?
338
+ if searched.nil?
339
+ assert_extended_search_checkable(collection, search_extended)
340
+
341
+ return
342
+ end
338
343
 
339
344
  published = collection.datasource.collections
340
345
 
@@ -344,6 +349,25 @@ module ForestAdminAgent
344
349
  end
345
350
  end
346
351
 
352
+ # Only a callable `replace_search` is a footprint this stack could have described and did not; a
353
+ # native child search, or no search decorator at all, builds no condition here. A plain search is
354
+ # served in either case — the extended flag is the caller's own, so the exemption stops there.
355
+ def assert_extended_search_checkable(collection, search_extended)
356
+ return unless search_extended
357
+ return unless describes_own_search?(collection)
358
+ return unless permission_system?
359
+
360
+ raise ForbiddenError,
361
+ "You cannot run an extended search on the '#{collection.name}' collection: the fields " \
362
+ 'it reaches cannot be determined, so they cannot be checked against your permissions.'
363
+ end
364
+
365
+ # Reaches the search decorator only through `CollectionDecorator#search_handler?`: drop that
366
+ # delegation and this answers false for every collection.
367
+ def describes_own_search?(collection)
368
+ collection.respond_to?(:search_handler?) && collection.search_handler?
369
+ end
370
+
347
371
  # `searched_fields` answers below the publication layer — deliberately, so a field hidden by
348
372
  # renaming above it is still checked — so it can name a collection `remove_collection` took out
349
373
  # of the API. An extended search does reach through to it: the condition is built below
@@ -10,6 +10,7 @@ module ForestAdminAgent
10
10
  DEFAULT_ITEMS_PER_PAGE = '15'.freeze
11
11
  DEFAULT_PAGE_TO_SKIP = '1'.freeze
12
12
  POLYMORPHIC_TARGET_WILDCARD = '*'.freeze
13
+ FALSY_SEARCH_EXTENDED = [nil, false, 0, '0', 'false', ''].freeze
13
14
 
14
15
  def self.parse_condition_tree(collection, args)
15
16
  filters = begin
@@ -230,21 +231,43 @@ module ForestAdminAgent
230
231
  Page.new(offset: 0, limit: limit&.to_i)
231
232
  end
232
233
 
234
+ # Presence, not truth: with +||+ a +false+ in the select-all body would silently lose to the
235
+ # query string. An explicit +null+ or +''+ there is read as absent rather than as "no search",
236
+ # so neither can widen a result set by discarding the term the URL carried.
237
+ def self.subset_or_query(args, key)
238
+ subset = begin
239
+ args.dig(:params, :data, :attributes, :all_records_subset_query)
240
+ rescue StandardError
241
+ nil
242
+ end
243
+
244
+ return subset[key] if subset.is_a?(Hash) && !subset[key].nil? && subset[key] != ''
245
+
246
+ begin
247
+ args.dig(:params, key)
248
+ rescue StandardError
249
+ nil
250
+ end
251
+ end
252
+
233
253
  def self.parse_search(collection, args)
234
- search = args.dig(:params, :data, :attributes, :all_records_subset_query, :search) || args.dig(:params, :search)
254
+ search = subset_or_query(args, :search)
255
+
256
+ return nil if search.nil?
235
257
 
236
- raise BadRequestError, 'Collection is not searchable' if search && !collection.is_searchable?
258
+ raise BadRequestError, 'Collection is not searchable' unless collection.is_searchable?
237
259
 
238
- search
260
+ unless search.is_a?(String) || search.is_a?(Numeric)
261
+ raise BadRequestError, 'Search must be a string or a number'
262
+ end
263
+
264
+ search.to_s
239
265
  end
240
266
 
241
267
  def self.parse_search_extended(args)
242
- extended = args.dig(:params, :data, :attributes, :all_records_subset_query,
243
- :searchExtended) || args.dig(:params, :searchExtended)
244
-
245
- return false if extended.nil?
268
+ extended = subset_or_query(args, :searchExtended)
246
269
 
247
- extended != '0'
270
+ !FALSY_SEARCH_EXTENDED.include?(extended.is_a?(String) ? extended.downcase : extended)
248
271
  end
249
272
 
250
273
  def self.parse_sort(collection, args)
@@ -6,7 +6,7 @@ module ForestAdminAgent
6
6
  module Schema
7
7
  class SchemaEmitter
8
8
  LIANA_NAME = "agent-ruby"
9
- LIANA_VERSION = "1.41.0"
9
+ LIANA_VERSION = "1.42.0"
10
10
 
11
11
  def self.generate(datasource)
12
12
  datasource.collections
@@ -1,3 +1,3 @@
1
1
  module ForestAdminAgent
2
- VERSION = "1.41.0"
2
+ VERSION = "1.42.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forest_admin_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.41.0
4
+ version: 1.42.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthieu
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2026-09-01 00:00:00.000000000 Z
12
+ date: 2026-09-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport