oso-oso 0.7.0 → 0.9.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: 73b2001f3721fd450aaebcdf348ac8d05f1452f1
4
- data.tar.gz: bf829788c21e9eb8b91ce05504800df3b13fd4fe
3
+ metadata.gz: c567d76126dbe08f29eb4f7c3bec635a17224718
4
+ data.tar.gz: a9632184c981bcd2501d21da0dbe8850c6b53446
5
5
  SHA512:
6
- metadata.gz: 1590f8019ec1a5e13f8bb5b5f39a65a6e304d427312ea6996e41d6dfb56c0632a31d780dc55a9815734c7e3b6861d823a36878f46b26441d39c51296114b3086
7
- data.tar.gz: 5dbcc691578bdcf01864895ab305aa9a97f7924e0f77a7ce33193dc047c99253f48f1ddfdfba65e290580ca6558132c6473911e5a54a5a64542e6f701f67796d
6
+ metadata.gz: 12d72946b6e4af9d109757b6fcc0f983e2bf2f53df5dbd6f02d13ec4e0ff46c3a42adceaec2cc5c8433481dc48d5742290ce7ea469bcad55120f70feb21a7460
7
+ data.tar.gz: a0914390d8667609a6d908c50212899111cc2324f9283383d9e17e6863cafa31bf6752ca4b975760e8c3c20714d3bed6defc4df26e95b05765336e00d8c99688
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oso-oso (0.7.0)
4
+ oso-oso (0.9.0)
5
5
  ffi (~> 1.0)
6
6
 
7
7
  GEM
Binary file
Binary file
data/lib/oso.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'oso/http'
4
3
  require 'oso/oso'
5
- require 'oso/path_mapper'
6
4
  require 'oso/polar'
7
5
  require 'oso/version'
8
6
 
@@ -7,8 +7,6 @@ module Oso
7
7
  class Oso < Polar::Polar
8
8
  def initialize
9
9
  super
10
- register_class(Http, name: 'Http')
11
- register_class(PathMapper, name: 'PathMapper')
12
10
  end
13
11
 
14
12
  # Query the knowledge base to determine whether an actor is allowed to
@@ -38,6 +38,7 @@ module Oso
38
38
  # TODO: I think this should probably have some arguments to say what the call is
39
39
  class InvalidCallError < PolarRuntimeError; end
40
40
  class InvalidConstructorError < PolarRuntimeError; end
41
+ class InvalidIteratorError < PolarRuntimeError; end
41
42
  class InvalidQueryTypeError < PolarRuntimeError; end
42
43
  class NullByteInPolarFileError < PolarRuntimeError; end
43
44
  class UnexpectedPolarTypeError < PolarRuntimeError; end
@@ -38,6 +38,9 @@ module Oso
38
38
  @ffi_polar = FFI::Polar.create
39
39
  @host = Host.new(ffi_polar)
40
40
 
41
+ # Register global constants.
42
+ register_constant nil, name: 'nil'
43
+
41
44
  # Register built-in classes.
42
45
  register_class PolarBoolean, name: 'Boolean'
43
46
  register_class Integer
@@ -36,33 +36,6 @@ module Oso
36
36
  ffi_query.question_result(result, call_id: call_id)
37
37
  end
38
38
 
39
- # Register a Ruby method call, wrapping the call result in a generator if
40
- # it isn't already one.
41
- #
42
- # @param method [#to_sym]
43
- # @param call_id [Integer]
44
- # @param instance [Hash<String, Object>]
45
- # @param args [Array<Hash>]
46
- # @raise [InvalidCallError] if the method doesn't exist on the instance or
47
- # the args passed to the method are invalid.
48
- def register_call(attribute, call_id:, instance:, args:, kwargs:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
49
- return if calls.key?(call_id)
50
-
51
- instance = host.to_ruby(instance)
52
- args = args.map { |a| host.to_ruby(a) }
53
- kwargs = Hash[kwargs.map { |k, v| [k.to_sym, host.to_ruby(v)] }]
54
- # The kwargs.empty? check is for Ruby < 2.7.
55
- result = if kwargs.empty?
56
- instance.__send__(attribute, *args)
57
- else
58
- instance.__send__(attribute, *args, **kwargs)
59
- end
60
- result = [result].to_enum unless result.is_a? Enumerator # Call must be a generator.
61
- calls[call_id] = result.lazy
62
- rescue ArgumentError, NoMethodError
63
- raise InvalidCallError
64
- end
65
-
66
39
  # Send next result of Ruby method call across FFI boundary.
67
40
  #
68
41
  # @param result [String]
@@ -97,13 +70,33 @@ module Oso
97
70
  # @param call_id [Integer]
98
71
  # @param instance [Hash<String, Object>]
99
72
  # @raise [Error] if the FFI call raises one.
100
- def handle_call(attribute, call_id:, instance:, args:, kwargs:)
101
- register_call(attribute, call_id: call_id, instance: instance, args: args, kwargs: kwargs)
102
- result = JSON.dump(next_call_result(call_id))
73
+ def handle_call(attribute, call_id:, instance:, args:, kwargs:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
74
+ instance = host.to_ruby(instance)
75
+ args = args.map { |a| host.to_ruby(a) }
76
+ kwargs = Hash[kwargs.map { |k, v| [k.to_sym, host.to_ruby(v)] }]
77
+ # The kwargs.empty? check is for Ruby < 2.7.
78
+ result = if kwargs.empty?
79
+ instance.__send__(attribute, *args)
80
+ else
81
+ instance.__send__(attribute, *args, **kwargs)
82
+ end
83
+ result = JSON.dump(host.to_polar(result))
103
84
  call_result(result, call_id: call_id)
104
- rescue InvalidCallError => e
85
+ rescue ArgumentError, NoMethodError => e
105
86
  application_error(e.message)
106
87
  call_result(nil, call_id: call_id)
88
+ end
89
+
90
+ def handle_next_external(call_id, iterable)
91
+ unless calls.key? call_id
92
+ value = host.to_ruby iterable
93
+ raise InvalidIteratorError unless value.is_a? Enumerable
94
+
95
+ calls[call_id] = value.lazy
96
+ end
97
+
98
+ result = JSON.dump(next_call_result(call_id))
99
+ call_result(result, call_id: call_id)
107
100
  rescue StopIteration
108
101
  call_result(nil, call_id: call_id)
109
102
  end
@@ -173,6 +166,10 @@ module Oso
173
166
  ffi_query.debug_command(command)
174
167
  when 'ExternalOp'
175
168
  raise UnimplementedOperationError, 'comparison operators'
169
+ when 'NextExternal'
170
+ call_id = event.data['call_id']
171
+ iterable = event.data['iterable']
172
+ handle_next_external(call_id, iterable)
176
173
  else
177
174
  raise "Unhandled event: #{JSON.dump(event.inspect)}"
178
175
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Oso
4
- VERSION = '0.7.0'
4
+ VERSION = '0.9.0'
5
5
  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.7.0
4
+ version: 0.9.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: 2020-10-13 00:00:00.000000000 Z
11
+ date: 2020-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -130,9 +130,7 @@ files:
130
130
  - ext/oso-oso/lib/libpolar.so
131
131
  - ext/oso-oso/lib/polar.dll
132
132
  - lib/oso.rb
133
- - lib/oso/http.rb
134
133
  - lib/oso/oso.rb
135
- - lib/oso/path_mapper.rb
136
134
  - lib/oso/polar.rb
137
135
  - lib/oso/polar/errors.rb
138
136
  - lib/oso/polar/ffi.rb
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Oso
4
- # An HTTP resource.
5
- class Http
6
- def initialize(hostname, path, query)
7
- @hostname = hostname
8
- @path = path
9
- @query = query
10
- end
11
-
12
- private
13
-
14
- attr_reader :hostname, :path, :query
15
- end
16
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Oso
4
- # Map from a template string with capture groups of the form
5
- # `{name}` to a dictionary of the form `{name: captured_value}`
6
- class PathMapper
7
- def initialize(template)
8
- capture_group = /({([^}]+)})/
9
-
10
- template = template.dup
11
- template.scan(capture_group).each do |outer, inner|
12
- template = if inner == '*'
13
- template.gsub! outer, '.*'
14
- else
15
- template.gsub! outer, "(?<#{inner}>[^/]+)"
16
- end
17
- end
18
- @pattern = /\A#{template}\Z/
19
- end
20
-
21
- def map(string)
22
- string.match(pattern)&.named_captures || {}
23
- end
24
-
25
- private
26
-
27
- attr_reader :pattern
28
- end
29
- end