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 +4 -4
- data/.gitignore +1 -1
- data/.rubocop.yml +3 -0
- data/Gemfile.lock +2 -2
- data/ext/oso-oso/lib/libpolar.dylib +0 -0
- data/ext/oso-oso/lib/libpolar.so +0 -0
- data/ext/oso-oso/lib/polar.dll +0 -0
- data/lib/oso/oso.rb +16 -6
- data/lib/oso/polar/data_filtering.rb +45 -6
- data/lib/oso/polar/host.rb +11 -3
- data/lib/oso/polar/polar.rb +6 -2
- data/lib/oso/version.rb +1 -1
- data/lib/oso-oso.rb +3 -0
- data/lib/oso.rb +3 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 654992655445b1208dd37d8346e2bc969c75a883
|
4
|
+
data.tar.gz: 67f729e79b4ea0912f23141134e0543b7cca023a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 000e0208a70ac3bcb967a3ee7ad2ecf2d89bcdb03a36abfadf89fbf5ab8da3e5f20b5209d9061d4c0f8a0e8c9cb4eec0723696771824e4866f3e6ac4d07734f8
|
7
|
+
data.tar.gz: a73f3e21418f3a3445bdcff2e81a50a36cc6d57bec0e5467c9ae7d4e77220924f1a96bd818d52dc3bfebc9ffc780c5ab6463c18df0ff55774fd5325966472a5f
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
Binary file
|
data/ext/oso-oso/lib/libpolar.so
CHANGED
Binary file
|
data/ext/oso-oso/lib/polar.dll
CHANGED
Binary file
|
data/lib/oso/oso.rb
CHANGED
@@ -173,14 +173,14 @@ module Oso
|
|
173
173
|
fields
|
174
174
|
end
|
175
175
|
|
176
|
-
#
|
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
|
-
# @
|
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
|
-
#
|
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
|
-
# @
|
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.
|
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?
|
147
|
-
|
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
|
data/lib/oso/polar/host.rb
CHANGED
@@ -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/polar/polar.rb
CHANGED
@@ -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
|
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
|
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
data/lib/oso-oso.rb
ADDED
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.
|
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-
|
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:
|
203
|
+
version: '0'
|
203
204
|
requirements: []
|
204
205
|
rubyforge_project:
|
205
206
|
rubygems_version: 2.6.14.4
|