oso-cloud 1.10.0 → 1.11.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: 6dac67a8075972556f7ae65a0536ec256633cb2262e09bc846c0d9abd5d076b7
4
- data.tar.gz: 5f99588ce46c6aa63eec48ba8c157f493a86f6341f7c3983ebaaef82712d424d
3
+ metadata.gz: c6dfcfe3d534a83d8c96e9fe04ae500921a483507c386baa4133143677fbac17
4
+ data.tar.gz: e61cb97030c944f5038e5214bc7573145c22f1d8674884a3c46fd57bc334d490
5
5
  SHA512:
6
- metadata.gz: e208dbfa5c8d680d6887369deb5acaf157ab3d06ed408b9fa375823a00c39a9c7a2bf397d1fb14d0716d71b9518bd1f7124900d7dc0ae586a2b12f964ff23315
7
- data.tar.gz: c4485eaf638f9e262c8b035c5b6606b0162fea19babe548f1ffd14cbee977e1ee0408f3679bc2f87eb984debeef86f176c4e0dcbed5c3164dea3acd7066fc515
6
+ metadata.gz: e3492c5a64c6a57aa72800736b096993fef0420c0719cfd86b0a98ed08c4ef30ca4a50a3802c01e4d8be5879078123820672119c6c9178d751124e20a8013ee8
7
+ data.tar.gz: 16e736b6a0e8fed24aa24f449be5065b83f88b8eb9de4908299d2069b6fc02d165479d04354d0011e7ad451e8a80498ef24f46191e9370a20f3674942328464f
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oso-cloud (1.10.0)
4
+ oso-cloud (1.11.0)
5
5
  faraday (~> 2.5.2)
6
6
  faraday-net_http_persistent (~> 2.0)
7
7
  faraday-retry (~> 2.0.0)
data/lib/oso/api.rb CHANGED
@@ -22,7 +22,10 @@ module OsoCloud
22
22
 
23
23
  # @!visibility private
24
24
  class ApiError < StandardError
25
- def initialize(message:)
25
+ attr_reader :status_code, :retry_after
26
+ def initialize(message:, status_code: nil, retry_after: nil)
27
+ @status_code = status_code
28
+ @retry_after = retry_after
26
29
  super(message)
27
30
  end
28
31
  end
@@ -164,23 +167,26 @@ module OsoCloud
164
167
 
165
168
  # @!visibility private
166
169
  class ListResult
167
- attr_reader :results
170
+ attr_reader :results, :next_page_token
168
171
 
169
- def initialize(results:)
172
+ def initialize(results:, next_page_token: nil)
170
173
  @results = results
174
+ @next_page_token = next_page_token
171
175
  end
172
176
  end
173
177
 
174
178
  # @!visibility private
175
179
  class ListQuery
176
- attr_reader :actor_type, :actor_id, :action, :resource_type, :context_facts
180
+ attr_reader :actor_type, :actor_id, :action, :resource_type, :context_facts, :page_size, :page_token
177
181
 
178
- def initialize(actor_type:, actor_id:, action:, resource_type:, context_facts:)
182
+ def initialize(actor_type:, actor_id:, action:, resource_type:, context_facts:, page_size: nil, page_token: nil)
179
183
  @actor_type = actor_type
180
184
  @actor_id = actor_id
181
185
  @action = action
182
186
  @resource_type = resource_type
183
187
  @context_facts = context_facts.map { |v| (v.is_a? Fact) ? v : Fact.new(**v) }
188
+ @page_size = page_size
189
+ @page_token = page_token
184
190
  end
185
191
  end
186
192
 
@@ -229,17 +235,6 @@ module OsoCloud
229
235
  end
230
236
  end
231
237
 
232
- # @!visibility private
233
- class StatsResult
234
- attr_reader :num_roles, :num_relations, :num_facts
235
-
236
- def initialize(num_roles:, num_relations:, num_facts:)
237
- @num_roles = num_roles
238
- @num_relations = num_relations
239
- @num_facts = num_facts
240
- end
241
- end
242
-
243
238
  # @!visibility private
244
239
  class LocalAuthQuery
245
240
  attr_reader :query, :data_bindings
@@ -298,6 +293,9 @@ module OsoCloud
298
293
  interval_randomness: 0.005,
299
294
  max_interval: 1,
300
295
  backoff_factor: 2,
296
+ # 409 (Conflict) is intentionally not retried here. The server uses 409
297
+ # with Retry-After for paginated results not yet ready, which needs
298
+ # longer delays than HTTP-level backoff. Handled by per-page retry in list().
301
299
  retry_statuses: [429, 500, 502, 503, 504],
302
300
  # This is the default set of methods plus POST.
303
301
  # ref: https://github.com/lostisland/faraday-retry#specify-which-methods-will-be-retried
@@ -439,12 +437,6 @@ module OsoCloud
439
437
  QueryResult.new(**result)
440
438
  end
441
439
 
442
- def get_stats
443
- url = '/stats'
444
- result = GET(url, {})
445
- StatsResult.new(**result)
446
- end
447
-
448
440
  def post_authorize_query(query, parity_handle = nil)
449
441
  url = '/authorize_query'
450
442
  data = LocalAuthQuery.new(query: query, data_bindings: @data_bindings)
@@ -598,10 +590,13 @@ module OsoCloud
598
590
 
599
591
  def handle_faraday_error(error)
600
592
  resp = error.response
601
- create_api_error(resp, error.message)
593
+ status_code = resp && resp[:status]
594
+ retry_after = resp && resp[:headers] && resp[:headers]['Retry-After']
595
+ retry_after = retry_after.to_f if retry_after
596
+ create_api_error(resp, error.message, status_code: status_code, retry_after: retry_after)
602
597
  end
603
598
 
604
- def create_api_error(resp, message)
599
+ def create_api_error(resp, message, status_code: nil, retry_after: nil)
605
600
  formatted_request_id = if resp.nil? || resp[:headers].nil? || resp[:headers]['X-Request-ID'].nil?
606
601
  ''
607
602
  else
@@ -613,7 +608,11 @@ module OsoCloud
613
608
  else
614
609
  resp[:body][:message]
615
610
  end
616
- raise ApiError.new(message: err + formatted_request_id)
611
+
612
+ sc = status_code || (resp && resp[:status])
613
+ ra = retry_after || (resp && resp[:headers] && resp[:headers]['Retry-After'] ? resp[:headers]['Retry-After'].to_f : nil)
614
+
615
+ raise ApiError.new(message: err + formatted_request_id, status_code: sc, retry_after: ra)
617
616
  end
618
617
 
619
618
  def post_expected_result(expected_result)
data/lib/oso/oso.rb CHANGED
@@ -228,15 +228,50 @@ module OsoCloud
228
228
  # @return [Array<String>]
229
229
  # @see Oso for more information about facts
230
230
  def list(actor, action, resource_type, context_facts = [])
231
+ all_results = []
232
+ page_token = nil
233
+ loop do
234
+ page = list_paginated(actor, action, resource_type, 10000, page_token: page_token, context_facts: context_facts)
235
+ all_results.concat(page.results)
236
+ break if page.next_page_token.nil?
237
+ page_token = page.next_page_token
238
+ end
239
+ all_results
240
+ end
241
+
242
+ ##
243
+ # List authorized resources with pagination
244
+ #
245
+ # Fetches a page of resource ids on which an actor can perform a
246
+ # particular action. Returns a ListResult with `results` and `next_page_token`.
247
+ # Pass `next_page_token` to fetch subsequent pages.
248
+ #
249
+ # @param actor [OsoCloud::Value]
250
+ # @param action [String]
251
+ # @param resource_type [String]
252
+ # @param page_size [Integer]
253
+ # @param page_token [String, nil]
254
+ # @param context_facts [Array<fact>]
255
+ # @return [OsoCloud::Core::ListResult]
256
+ def list_paginated(actor, action, resource_type, page_size, page_token: nil, context_facts: [])
231
257
  actor_typed_id = actor.to_api_value
232
- result = @api.post_list(OsoCloud::Core::ListQuery.new(
233
- actor_type: actor_typed_id.type,
234
- actor_id: actor_typed_id.id,
235
- action: action,
236
- resource_type: resource_type,
237
- context_facts: OsoCloud::Helpers.params_to_facts(context_facts)
238
- ))
239
- result.results
258
+ 10.times do |attempt|
259
+ begin
260
+ return @api.post_list(OsoCloud::Core::ListQuery.new(
261
+ actor_type: actor_typed_id.type,
262
+ actor_id: actor_typed_id.id,
263
+ action: action,
264
+ resource_type: resource_type,
265
+ context_facts: OsoCloud::Helpers.params_to_facts(context_facts),
266
+ page_size: page_size,
267
+ page_token: page_token
268
+ ))
269
+ rescue OsoCloud::Core::ApiError => e
270
+ raise unless e.status_code == 409 && e.retry_after && attempt < 9
271
+ sleep(e.retry_after)
272
+ end
273
+ end
274
+ raise OsoCloud::Core::ApiError.new(message: 'Page not available after retries', status_code: 409)
240
275
  end
241
276
 
242
277
  ##
data/lib/oso/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  # !! IMPORTANT: Update the ruby docs to reflect the latest version !!
4
4
  module OsoCloud
5
- VERSION = '1.10.0'
5
+ VERSION = '1.11.0'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oso-cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.0
4
+ version: 1.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oso Security, Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-06-18 00:00:00.000000000 Z
11
+ date: 2026-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday