oso-oso 0.20.1.pre.beta → 0.22.1

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: 7a6c6bd2d2fb38245a5103c0153f943f51060c90
4
- data.tar.gz: 33dcb41c1c6bd0aeeec56d88391e1e80a66b6061
3
+ metadata.gz: 654992655445b1208dd37d8346e2bc969c75a883
4
+ data.tar.gz: 67f729e79b4ea0912f23141134e0543b7cca023a
5
5
  SHA512:
6
- metadata.gz: 5c025329ad3a4eff57b2cf5e7d5ca8430ef825ee287111690f06439a7c6f623068048d27ea70358af8ffb8f9d935b926cdecf54baa848f95da9ebaa23b0c0e39
7
- data.tar.gz: 2c4a4114eafb5887805a7b92015f466296ae9eaaa4ffe19f1cc60d4f2ec59b6b580ff80ebe60143e639d7f606d79f343c89e3fdd7e7a52789939af9716b9b2c3
6
+ metadata.gz: 000e0208a70ac3bcb967a3ee7ad2ecf2d89bcdb03a36abfadf89fbf5ab8da3e5f20b5209d9061d4c0f8a0e8c9cb4eec0723696771824e4866f3e6ac4d07734f8
7
+ data.tar.gz: a73f3e21418f3a3445bdcff2e81a50a36cc6d57bec0e5467c9ae7d4e77220924f1a96bd818d52dc3bfebc9ffc780c5ab6463c18df0ff55774fd5325966472a5f
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.pre.beta)
4
+ oso-oso (0.22.1)
5
5
  ffi (~> 1.0)
6
6
 
7
7
  GEM
@@ -116,4 +116,4 @@ DEPENDENCIES
116
116
  yard (~> 0.9.25)
117
117
 
118
118
  BUNDLED WITH
119
- 2.2.15
119
+ 2.2.4
Binary file
Binary file
Binary file
data/lib/oso/oso.rb CHANGED
@@ -173,14 +173,14 @@ module Oso
173
173
  fields
174
174
  end
175
175
 
176
- # Returns a query for resources of type +cls+ that +actor+ is allowed
177
- # to perform +action+ on.
176
+ # Create a query for resources of type +cls+ that +actor+ is
177
+ # allowed to perform +action+ on.
178
178
  #
179
179
  # @param actor The actor whose permissions to check.
180
180
  # @param action The action being taken on the resource.
181
181
  # @param resource_cls The resource being accessed.
182
182
  #
183
- # @returns A query for resources accessible to the actor.
183
+ # @return A query for resources accessible to the actor.
184
184
  def authorized_query(actor, action, resource_cls) # rubocop:disable Metrics/MethodLength
185
185
  resource = Polar::Variable.new 'resource'
186
186
 
@@ -204,19 +204,29 @@ module Oso
204
204
  .build_query
205
205
  end
206
206
 
207
- # Returns the resources of type +resource_cls+ that +actor+ is allowed
208
- # to perform +action+ on.
207
+ # Determine the resources of type +resource_cls+ that +actor+
208
+ # is allowed to perform +action+ on.
209
209
  #
210
210
  # @param actor The actor whose permissions to check.
211
211
  # @param action The action being taken on the resource.
212
212
  # @param resource_cls The resource being accessed.
213
213
  #
214
- # @returns A list of resources accessible to the actor.
214
+ # @return A list of resources accessible to the actor.
215
215
  def authorized_resources(actor, action, resource_cls)
216
216
  q = authorized_query actor, action, resource_cls
217
217
  return [] if q.nil?
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
@@ -87,6 +112,11 @@ module Oso
87
112
  class Relation
88
113
  attr_reader :kind, :other_type, :my_field, :other_field
89
114
 
115
+ # Describe a Relation from one type to another.
116
+ # @param kind [String] The type of relation, either "one" or "many"
117
+ # @param other_type The name or class object of the related type
118
+ # @param my_field The field on this type that matches +other_type+
119
+ # @param other_field The field on +other_type+ that matches this type
90
120
  def initialize(kind:, other_type:, my_field:, other_field:)
91
121
  @kind = kind
92
122
  @other_type = other_type
@@ -122,15 +152,18 @@ module Oso
122
152
  'Eq' => ->(a, b) { a == b },
123
153
  'In' => ->(a, b) { b.include? a },
124
154
  'Neq' => ->(a, b) { a != b },
155
+ 'Nin' => ->(a, b) { !b.include?(a) },
125
156
  'Contains' => ->(a, b) { a.include? b }
126
157
  }.freeze
127
158
 
159
+ # Create a new predicate for data filtering.
160
+ # @param kind [String] Represents a condition. One of "Eq", "Neq", "In", "Contains".
161
+ # @param field The field the condition applies to.
162
+ # @param value The value with which to compare the field according to the condition.
128
163
  def initialize(kind:, field:, value:)
129
164
  @kind = kind
130
165
  @field = field
131
166
  @value = value
132
- @check = CHECKS[kind]
133
- raise "Unknown constraint kind `#{kind}`" if @check.nil?
134
167
  end
135
168
 
136
169
  def ground(results)
@@ -141,10 +174,16 @@ module Oso
141
174
  @value = value.map { |v| v.send ref.field } unless ref.field.nil?
142
175
  end
143
176
 
144
- def check(item)
177
+ def check(item) # rubocop:disable Metrics/AbcSize
145
178
  val = value.is_a?(Field) ? item.send(value.field) : value
146
- item = field.nil? ? item : item.send(field)
147
- @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]
148
187
  end
149
188
 
150
189
  def self.parse(polar, constraint) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
@@ -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
@@ -136,12 +136,12 @@ module Oso
136
136
  # @return [self] for chaining.
137
137
  #
138
138
  # @deprecated {#load_file} has been deprecated in favor of {#load_files}
139
- # as of the 0.20.0 release. Please see changelog for migration
139
+ # as of the 0.20 release. Please see changelog for migration
140
140
  # instructions:
141
141
  # https://docs.osohq.com/project/changelogs/2021-09-15.html
142
142
  def load_file(filename)
143
143
  warn <<~WARNING
144
- `Oso#load_file` has been deprecated in favor of `Oso#load_files` as of the 0.20.0 release.
144
+ `Oso#load_file` has been deprecated in favor of `Oso#load_files` as of the 0.20 release.
145
145
 
146
146
  Please see changelog for migration instructions: https://docs.osohq.com/project/changelogs/2021-09-15.html
147
147
  WARNING
@@ -211,6 +211,10 @@ module Oso
211
211
  #
212
212
  # @param cls [Class] the class to register.
213
213
  # @param name [String] the name to register the class as. Defaults to the name of the class.
214
+ # @param fields [Hash] a map from field names on instances of +cls+ to types, or Relation objects.
215
+ # @param build_query [Proc] a method to produce a query for +cls+ objects, given a list of Filters.
216
+ # @param exec_query [Proc] a method to execute a query produced by +build_query+
217
+ # @param combine_query [Proc] a method to merge two queries produced by +build_query+
214
218
  # @raise [DuplicateClassAliasError] if attempting to register a class
215
219
  # under a previously-registered name.
216
220
  # @raise [FFI::Error] if the FFI call returns an error.
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-beta'
4
+ VERSION = '0.22.1'
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.pre.beta
4
+ version: 0.22.1
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-10 00:00:00.000000000 Z
11
+ date: 2021-11-01 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
@@ -197,9 +198,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
197
198
  version: 2.4.0
198
199
  required_rubygems_version: !ruby/object:Gem::Requirement
199
200
  requirements:
200
- - - ">"
201
+ - - ">="
201
202
  - !ruby/object:Gem::Version
202
- version: 1.3.1
203
+ version: '0'
203
204
  requirements: []
204
205
  rubyforge_project:
205
206
  rubygems_version: 2.6.14.4