oso-oso 0.20.1 → 0.23.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: da642b9fbbfcad2d836a8db8c6ac83cbc8f1127a
4
- data.tar.gz: 1012ef61aa0a1791a1c759ba9f62e108918898b6
3
+ metadata.gz: 1e323fdc380d0763cb3b4d84618fb81c3b6957a8
4
+ data.tar.gz: 8571c1594862ec12dd1ed9bbbc49dec49a71567b
5
5
  SHA512:
6
- metadata.gz: 48d52111b817769f31086b4adbd7252bcab4355792ba85e378ab4a27c68272e8d2af55f8d2a258e0a3bb3b2cea30b6d0c98f6e20eec7ed9d1b127011a506cab7
7
- data.tar.gz: f40a6c5565655ee508ebc0c20b7f571616b42d4a76f986b51ad4349c1fe05200d8165990c98a00e2a7388ac41eb96182095b52a9f08ad022cc0880801ad87997
6
+ metadata.gz: 451a25cd51d463002223839c152a96aed018b958b0619103c8a7ad2e7e31fe4bab05ffded087ecde46036849b07d5f7ab34b5e8a5b2f6d761a741fe255c817a6
7
+ data.tar.gz: 2ccbcd09c12aeeedc86ce473b8f76439bc576016fb087dbbf9b8279c7a14128847130492698c37bdc76be2da5792fc674ee2be384e12f6f787c738fa5539cc6e
data/.gitignore CHANGED
@@ -7,7 +7,7 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  vendor
10
- active_record_test.db
10
+ *test.db
11
11
 
12
12
  # rspec failure tracking
13
13
  .rspec_status
data/.rubocop.yml CHANGED
@@ -5,3 +5,6 @@ AllCops:
5
5
  - "bin/oso"
6
6
  - "vendor/**/*"
7
7
  NewCops: enable
8
+ Naming/FileName:
9
+ Exclude:
10
+ - "lib/oso-oso.rb"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oso-oso (0.20.1)
4
+ oso-oso (0.23.0)
5
5
  ffi (~> 1.0)
6
6
 
7
7
  GEM
Binary file
Binary file
Binary file
data/lib/oso/oso.rb CHANGED
@@ -218,5 +218,15 @@ module Oso
218
218
 
219
219
  host.types[get_class_name resource_cls].exec_query[q]
220
220
  end
221
+
222
+ # Register default values for data filtering query functions.
223
+ # These can be overridden by passing specific implementations to
224
+ # `register_class` or by defining `build_query`, `exec_query` and
225
+ # `combine_query` methods on the class object.
226
+ def set_data_filtering_query_defaults(build_query: nil, exec_query: nil, combine_query: nil)
227
+ host.build_query = build_query if build_query
228
+ host.exec_query = exec_query if exec_query
229
+ host.combine_query = combine_query if combine_query
230
+ end
221
231
  end
222
232
  end
@@ -4,6 +4,7 @@ module Oso
4
4
  module Polar
5
5
  # Data filtering interface for Ruby
6
6
  module DataFiltering
7
+ GETATTR = ->(x, attr) { attr.nil? ? x : x.send(attr) }
7
8
  # Represents a set of filter sequences that should allow the host
8
9
  # to obtain the records satisfying a query.
9
10
  class FilterPlan
@@ -29,7 +30,7 @@ module Oso
29
30
  result_sets.each_with_object([]) do |rs, qb|
30
31
  rs.resolve_order.each_with_object({}) do |i, set_results|
31
32
  req = rs.requests[i]
32
- cs = req.constraints.each { |c| c.ground set_results }
33
+ cs = req.ground(set_results)
33
34
  typ = @polar.host.types[req.class_tag]
34
35
  q = typ.build_query[cs]
35
36
  if i != rs.result_id
@@ -68,6 +69,7 @@ module Oso
68
69
  attr_reader :constraints, :class_tag
69
70
 
70
71
  def self.parse(polar, parsed_json)
72
+ @polar = polar
71
73
  constraints = parsed_json['constraints'].map do |con|
72
74
  Filter.parse polar, con
73
75
  end
@@ -76,6 +78,29 @@ module Oso
76
78
  new(constraints: constraints, class_tag: class_tag)
77
79
  end
78
80
 
81
+ def ground(results) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
82
+ xrefs, rest = constraints.partition do |c|
83
+ c.value.is_a?(Ref) and !c.value.result_id.nil?
84
+ end
85
+
86
+ yrefs, nrefs = xrefs.partition { |r| %w[In Eq].include? r.kind }
87
+ [[yrefs, 'In'], [nrefs, 'Nin']].each do |refs, kind|
88
+ refs.group_by { |f| f.value.result_id }.each do |rid, fils|
89
+ if fils.length > 1
90
+ value = results[rid].map { |r| fils.map { |f| GETATTR[r, f.value.field] } }
91
+ field = fils.map(&:field)
92
+ rest.push(Filter.new(kind: kind, value: value, field: field))
93
+ else
94
+ fil = fils[0]
95
+ field = fil.value.field
96
+ value = results[rid].map { |r| field.nil? ? r : r.send(field) }
97
+ rest.push(Filter.new(kind: kind, field: fil.field, value: value))
98
+ end
99
+ end
100
+ end
101
+ rest
102
+ end
103
+
79
104
  def initialize(constraints:, class_tag:)
80
105
  @constraints = constraints
81
106
  @class_tag = class_tag
@@ -127,6 +152,7 @@ module Oso
127
152
  'Eq' => ->(a, b) { a == b },
128
153
  'In' => ->(a, b) { b.include? a },
129
154
  'Neq' => ->(a, b) { a != b },
155
+ 'Nin' => ->(a, b) { !b.include?(a) },
130
156
  'Contains' => ->(a, b) { a.include? b }
131
157
  }.freeze
132
158
 
@@ -138,8 +164,6 @@ module Oso
138
164
  @kind = kind
139
165
  @field = field
140
166
  @value = value
141
- @check = CHECKS[kind]
142
- raise "Unknown constraint kind `#{kind}`" if @check.nil?
143
167
  end
144
168
 
145
169
  def ground(results)
@@ -150,10 +174,16 @@ module Oso
150
174
  @value = value.map { |v| v.send ref.field } unless ref.field.nil?
151
175
  end
152
176
 
153
- def check(item)
177
+ def check(item) # rubocop:disable Metrics/AbcSize
154
178
  val = value.is_a?(Field) ? item.send(value.field) : value
155
- item = field.nil? ? item : item.send(field)
156
- @check[item, val]
179
+ item = if field.nil?
180
+ item
181
+ elsif field.is_a? Array
182
+ field.map { |f| GETATTR[item, f] }
183
+ else
184
+ item.send field
185
+ end
186
+ CHECKS[@kind][item, val]
157
187
  end
158
188
 
159
189
  def self.parse(polar, constraint) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
@@ -23,7 +23,6 @@ module Oso
23
23
 
24
24
  # Errors from across the FFI boundary.
25
25
 
26
- class SerializationError < PolarRuntimeError; end
27
26
  class UnsupportedError < PolarRuntimeError; end
28
27
  class PolarTypeError < PolarRuntimeError; end
29
28
  class StackOverflowError < PolarRuntimeError; end
@@ -96,10 +95,6 @@ module Oso
96
95
  class UnrecognizedToken < ParseError; end
97
96
  end
98
97
 
99
- # Generic Polar API exception.
100
- class ApiError < Error; end
101
- class ParameterError < ApiError; end
102
-
103
98
  class ValidationError < Error; end
104
99
 
105
100
  UNEXPECTED_EXPRESSION_MESSAGE = <<~MSG
@@ -54,8 +54,6 @@ module Oso
54
54
  runtime_error(subkind, msg: msg, details: details)
55
55
  when 'Operational'
56
56
  operational_error(subkind, msg: msg, details: details)
57
- when 'Parameter'
58
- api_error(subkind, msg: msg, details: details)
59
57
  when 'Validation'
60
58
  validation_error(msg, details: details)
61
59
  end
@@ -94,8 +92,6 @@ module Oso
94
92
  # @return [::Oso::Polar::PolarRuntimeError] the object converted into the expected format.
95
93
  private_class_method def self.runtime_error(kind, msg:, details:) # rubocop:disable Metrics/MethodLength
96
94
  case kind
97
- when 'Serialization'
98
- ::Oso::Polar::SerializationError.new(msg, details: details)
99
95
  when 'Unsupported'
100
96
  ::Oso::Polar::UnsupportedError.new(msg, details: details)
101
97
  when 'TypeError'
@@ -124,21 +120,6 @@ module Oso
124
120
  end
125
121
  end
126
122
 
127
- # Map FFI API errors into Ruby exceptions.
128
- #
129
- # @param kind [String]
130
- # @param msg [String]
131
- # @param details [Hash<String, Object>]
132
- # @return [::Oso::Polar::ApiError] the object converted into the expected format.
133
- private_class_method def self.api_error(kind, msg:, details:)
134
- case kind
135
- when 'Parameter'
136
- ::Oso::Polar::ParameterError.new(msg, details: details)
137
- else
138
- ::Oso::Polar::ApiError.new(msg, details: details)
139
- end
140
- end
141
-
142
123
  # Map FFI Validation errors into Ruby exceptions.
143
124
  #
144
125
  # @param msg [String]
@@ -67,12 +67,20 @@ module Oso
67
67
  public
68
68
 
69
69
  attr_writer :accept_expression
70
+ attr_accessor :build_query, :combine_query, :exec_query
71
+
72
+ DEFAULT_COMBINE_QUERY = proc { raise 'implement combine_query to use data filtering' }
73
+ DEFAULT_BUILD_QUERY = proc { raise 'implement build_query to use data filtering' }
74
+ DEFAULT_EXEC_QUERY = proc { raise 'implement exec_query to use data filtering' }
70
75
 
71
76
  def initialize(ffi_polar)
72
77
  @ffi_polar = ffi_polar
73
78
  @types = {}
74
79
  @instances = {}
75
80
  @accept_expression = false
81
+ @combine_query = DEFAULT_COMBINE_QUERY
82
+ @build_query = DEFAULT_BUILD_QUERY
83
+ @exec_query = DEFAULT_EXEC_QUERY
76
84
  end
77
85
 
78
86
  def initialize_copy(other)
@@ -107,9 +115,9 @@ module Oso
107
115
  klass: PolarClass.new(cls),
108
116
  id: cache_instance(cls),
109
117
  fields: fields || {},
110
- combine_query: combine_query,
111
- exec_query: exec_query,
112
- build_query: build_query
118
+ combine_query: combine_query || self.combine_query,
119
+ exec_query: exec_query || self.exec_query,
120
+ build_query: build_query || self.build_query
113
121
  )
114
122
  name
115
123
  end
data/lib/oso/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Oso
4
- VERSION = '0.20.1'
4
+ VERSION = '0.23.0'
5
5
  end
data/lib/oso-oso.rb ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './oso'
data/lib/oso.rb CHANGED
@@ -7,6 +7,9 @@ require 'oso/version'
7
7
 
8
8
  # Top-level namespace for Oso authorization library.
9
9
  module Oso
10
+ Relation = ::Oso::Polar::DataFiltering::Relation
11
+ Filter = ::Oso::Polar::DataFiltering::Filter
12
+
10
13
  def self.new(not_found_error: NotFoundError, forbidden_error: ForbiddenError, read_action: 'read')
11
14
  ::Oso::Oso.new(not_found_error: not_found_error, forbidden_error: forbidden_error, read_action: read_action)
12
15
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oso-oso
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.1
4
+ version: 0.23.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oso Security, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-14 00:00:00.000000000 Z
11
+ date: 2021-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -157,6 +157,7 @@ files:
157
157
  - ext/oso-oso/lib/libpolar.dylib
158
158
  - ext/oso-oso/lib/libpolar.so
159
159
  - ext/oso-oso/lib/polar.dll
160
+ - lib/oso-oso.rb
160
161
  - lib/oso.rb
161
162
  - lib/oso/errors.rb
162
163
  - lib/oso/oso.rb