oso-oso 0.6.0 → 0.7.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: 70321ccb3dc8e6468b89109aa7d9bbb97868d1be
4
- data.tar.gz: 8b7c1873eba4dae6d1150f8f91a74a3d5a72e51c
3
+ metadata.gz: 73b2001f3721fd450aaebcdf348ac8d05f1452f1
4
+ data.tar.gz: bf829788c21e9eb8b91ce05504800df3b13fd4fe
5
5
  SHA512:
6
- metadata.gz: 639ea45ef8a86ebf97ae20ee1977499e18f04827b05d869369c7ec01792eb7a7747c6bae9f7d7789af4993a4b04edef5b375c9caa504c6e09afe701ed931874f
7
- data.tar.gz: 7dc68ed639125472e808ff375059ceb6d70837fad20c05672a183452bef78eeee56dcc0dc58579d21536749bc8e2fbc2628baa349473984c824d23b38d1270f4
6
+ metadata.gz: 1590f8019ec1a5e13f8bb5b5f39a65a6e304d427312ea6996e41d6dfb56c0632a31d780dc55a9815734c7e3b6861d823a36878f46b26441d39c51296114b3086
7
+ data.tar.gz: 5dbcc691578bdcf01864895ab305aa9a97f7924e0f77a7ce33193dc047c99253f48f1ddfdfba65e290580ca6558132c6473911e5a54a5a64542e6f701f67796d
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oso-oso (0.6.0)
4
+ oso-oso (0.7.0)
5
5
  ffi (~> 1.0)
6
6
 
7
7
  GEM
Binary file
Binary file
@@ -32,7 +32,6 @@ module Oso
32
32
  # Errors originating from this side of the FFI boundary.
33
33
 
34
34
  class UnregisteredClassError < PolarRuntimeError; end
35
- class MissingConstructorError < PolarRuntimeError; end
36
35
  class UnregisteredInstanceError < PolarRuntimeError; end
37
36
  class DuplicateInstanceRegistrationError < PolarRuntimeError; end
38
37
 
@@ -68,6 +67,12 @@ module Oso
68
67
  end
69
68
  end
70
69
 
70
+ class UnimplementedOperationError < PolarRuntimeError # rubocop:disable Style/Documentation
71
+ def initialize(operation)
72
+ super("#{operation} are unimplemented in the oso Ruby library")
73
+ end
74
+ end
75
+
71
76
  # Generic operational exception.
72
77
  class OperationalError < Error; end
73
78
  class UnknownError < OperationalError; end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
4
+
3
5
  module Oso
4
6
  module Polar
5
7
  module FFI
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
4
+
3
5
  module Oso
4
6
  module Polar
5
7
  module FFI
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
4
+
3
5
  module Oso
4
6
  module Polar
5
7
  module FFI
@@ -11,6 +13,7 @@ module Oso
11
13
 
12
14
  attach_function :new, :polar_new, [], FFI::Polar
13
15
  attach_function :load, :polar_load, [FFI::Polar, :string, :string], :int32
16
+ attach_function :clear_rules, :polar_clear_rules, [FFI::Polar], :int32
14
17
  attach_function :next_inline_query, :polar_next_inline_query, [FFI::Polar, :uint32], FFI::Query
15
18
  attach_function :new_id, :polar_get_external_id, [FFI::Polar], :uint64
16
19
  attach_function :new_query_from_str, :polar_new_query, [FFI::Polar, :string, :uint32], FFI::Query
@@ -39,6 +42,13 @@ module Oso
39
42
  raise FFI::Error.get if loaded.zero?
40
43
  end
41
44
 
45
+ # @raise [FFI::Error] if the FFI call returns an error.
46
+ def clear_rules
47
+ cleared = Rust.clear_rules(self)
48
+ process_messages
49
+ raise FFI::Error.get if cleared.zero?
50
+ end
51
+
42
52
  # @return [FFI::Query] if there are remaining inline queries.
43
53
  # @return [nil] if there are no remaining inline queries.
44
54
  # @raise [FFI::Error] if the FFI call returns an error.
@@ -84,7 +94,7 @@ module Oso
84
94
  # @param name [String]
85
95
  # @param value [Hash<String, Object>]
86
96
  # @raise [FFI::Error] if the FFI call returns an error.
87
- def register_constant(name, value:)
97
+ def register_constant(value, name:)
88
98
  registered = Rust.register_constant(self, name, JSON.dump(value))
89
99
  raise FFI::Error.get if registered.zero?
90
100
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
4
+
3
5
  module Oso
4
6
  module Polar
5
7
  module FFI
@@ -10,8 +10,6 @@ module Oso
10
10
  attr_reader :ffi_polar
11
11
  # @return [Hash<String, Class>]
12
12
  attr_reader :classes
13
- # @return [Hash<String, Object>]
14
- attr_reader :constructors
15
13
  # @return [Hash<Integer, Object>]
16
14
  attr_reader :instances
17
15
 
@@ -20,14 +18,12 @@ module Oso
20
18
  def initialize(ffi_polar)
21
19
  @ffi_polar = ffi_polar
22
20
  @classes = {}
23
- @constructors = {}
24
21
  @instances = {}
25
22
  end
26
23
 
27
24
  def initialize_copy(other)
28
25
  @ffi_polar = other.ffi_polar
29
26
  @classes = other.classes.dup
30
- @constructors = other.constructors.dup
31
27
  @instances = other.instances.dup
32
28
  end
33
29
 
@@ -44,38 +40,18 @@ module Oso
44
40
 
45
41
  # Store a Ruby class in the {#classes} cache.
46
42
  #
47
- # @param cls [Class] the class to cache
48
- # @param name [String] the name to cache the class as. Defaults to the name of the class.
49
- # @param constructor [Proc] optional custom constructor function. Defaults to the :new method.
43
+ # @param cls [Class] the class to cache.
44
+ # @param name [String] the name to cache the class as.
50
45
  # @return [String] the name the class is cached as.
51
- # @raise [UnregisteredClassError] if the class has not been registered.
52
- def cache_class(cls, name:, constructor:) # rubocop:disable Metrics/MethodLength
53
- name = cls.name if name.nil?
46
+ # @raise [DuplicateClassAliasError] if attempting to register a class
47
+ # under a previously-registered name.
48
+ def cache_class(cls, name:)
54
49
  raise DuplicateClassAliasError, name: name, old: get_class(name), new: cls if classes.key? name
55
50
 
56
51
  classes[name] = cls
57
- if constructor.nil?
58
- constructors[name] = :new
59
- elsif constructor.respond_to? :call
60
- constructors[name] = constructor
61
- else
62
- raise InvalidConstructorError
63
- end
64
52
  name
65
53
  end
66
54
 
67
- # Fetch a constructor from the {#constructors} cache.
68
- #
69
- # @param name [String]
70
- # @return [Symbol] if constructor is the default of `:new`.
71
- # @return [Proc] if a custom constructor was registered.
72
- # @raise [MissingConstructorError] if the constructor has not been registered.
73
- def get_constructor(name)
74
- raise MissingConstructorError, name unless constructors.key? name
75
-
76
- constructors[name]
77
- end
78
-
79
55
  # Check if an instance exists in the {#instances} cache.
80
56
  #
81
57
  # @param id [Integer]
@@ -100,12 +76,12 @@ module Oso
100
76
  instances[id]
101
77
  end
102
78
 
103
- # Cache a Ruby instance in the {#instances} cache, fetching a {#new_id}
104
- # if one isn't provided.
79
+ # Cache a Ruby instance in the {#instances} cache, fetching a new id if
80
+ # one isn't provided.
105
81
  #
106
82
  # @param instance [Object]
107
- # @param id [Integer]
108
- # @return [Integer]
83
+ # @param id [Integer] the instance ID. Generated via FFI if not provided.
84
+ # @return [Integer] the instance ID.
109
85
  def cache_instance(instance, id: nil)
110
86
  id = ffi_polar.new_id if id.nil?
111
87
  instances[id] = instance
@@ -114,24 +90,17 @@ module Oso
114
90
 
115
91
  # Construct and cache a Ruby instance.
116
92
  #
117
- # @param cls_name [String]
118
- # @param args [Array<Object>]
119
- # @param kwargs [Hash<String, Object>]
120
- # @param id [Integer]
93
+ # @param cls_name [String] name of the instance's class.
94
+ # @param args [Array<Object>] positional args to the constructor.
95
+ # @param kwargs [Hash<String, Object>] keyword args to the constructor.
96
+ # @param id [Integer] the instance ID.
121
97
  # @raise [PolarRuntimeError] if instance construction fails.
122
- def make_instance(cls_name, args:, kwargs:, id:) # rubocop:disable Metrics/MethodLength
123
- constructor = get_constructor(cls_name)
124
- # The kwargs.empty? checks are for Ruby < 2.7.
125
- instance = if constructor == :new
126
- if kwargs.empty?
127
- get_class(cls_name).__send__(:new, *args)
128
- else
129
- get_class(cls_name).__send__(:new, *args, **kwargs)
130
- end
131
- elsif kwargs.empty?
132
- constructor.call(*args)
98
+ # @return [Integer] the instance ID.
99
+ def make_instance(cls_name, args:, kwargs:, id:)
100
+ instance = if kwargs.empty? # This check is for Ruby < 2.7.
101
+ get_class(cls_name).__send__(:new, *args)
133
102
  else
134
- constructor.call(*args, **kwargs)
103
+ get_class(cls_name).__send__(:new, *args, **kwargs)
135
104
  end
136
105
  cache_instance(instance, id: id)
137
106
  rescue StandardError => e
@@ -1,10 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
- require 'pp'
5
- require 'set'
6
- require 'digest/md5'
7
-
8
3
  # Missing Ruby type.
9
4
  module PolarBoolean; end
10
5
  # Monkey-patch Ruby true type.
@@ -52,9 +47,12 @@ module Oso
52
47
  register_class String
53
48
  end
54
49
 
55
- # Replace the current Polar instance but retain all registered classes and constructors.
56
- def clear
57
- @ffi_polar = FFI::Polar.create
50
+ # Clear all rules and rule sources from the current Polar instance
51
+ #
52
+ # @return [self] for chaining.
53
+ def clear_rules
54
+ ffi_polar.clear_rules
55
+ self
58
56
  end
59
57
 
60
58
  # Load a Polar policy file.
@@ -62,6 +60,7 @@ module Oso
62
60
  # @param name [String]
63
61
  # @raise [PolarFileExtensionError] if provided filename has invalid extension.
64
62
  # @raise [PolarFileNotFoundError] if provided filename does not exist.
63
+ # @return [self] for chaining.
65
64
  def load_file(name)
66
65
  raise PolarFileExtensionError, name unless File.extname(name) == '.polar'
67
66
 
@@ -78,6 +77,7 @@ module Oso
78
77
  # @raise [NullByteInPolarFileError] if str includes a non-terminating null byte.
79
78
  # @raise [InlineQueryFailedError] on the first failed inline query.
80
79
  # @raise [Error] if any of the FFI calls raise one.
80
+ # @return [self] for chaining.
81
81
  def load_str(str, filename: nil) # rubocop:disable Metrics/MethodLength
82
82
  raise NullByteInPolarFileError if str.chomp("\0").include?("\0")
83
83
 
@@ -92,6 +92,7 @@ module Oso
92
92
  raise InlineQueryFailedError, next_query.source
93
93
  end
94
94
  end
95
+ self
95
96
  end
96
97
 
97
98
  # Query for a Polar predicate or string.
@@ -129,18 +130,26 @@ module Oso
129
130
 
130
131
  # Register a Ruby class with Polar.
131
132
  #
132
- # @param cls [Class]
133
- # @param name [String]
134
- # @param from_polar [Proc]
135
- # @raise [InvalidConstructorError] if provided an invalid 'from_polar' constructor.
136
- def register_class(cls, name: nil, from_polar: nil)
137
- from_polar = Proc.new if block_given?
138
- name = host.cache_class(cls, name: name, constructor: from_polar)
139
- register_constant(name, value: cls)
133
+ # @param cls [Class] the class to register.
134
+ # @param name [String] the name to register the class as. Defaults to the name of the class.
135
+ # @raise [DuplicateClassAliasError] if attempting to register a class
136
+ # under a previously-registered name.
137
+ # @raise [FFI::Error] if the FFI call returns an error.
138
+ # @return [self] for chaining.
139
+ def register_class(cls, name: nil)
140
+ name = host.cache_class(cls, name: name || cls.name)
141
+ register_constant(cls, name: name)
140
142
  end
141
143
 
142
- def register_constant(name, value:)
143
- ffi_polar.register_constant(name, value: host.to_polar(value))
144
+ # Register a Ruby object with Polar.
145
+ #
146
+ # @param value [Object] the object to register.
147
+ # @param name [String] the name to register the object as.
148
+ # @return [self] for chaining.
149
+ # @raise [FFI::Error] if the FFI call returns an error.
150
+ def register_constant(value, name:)
151
+ ffi_polar.register_constant(host.to_polar(value), name: name)
152
+ self
144
153
  end
145
154
 
146
155
  # Start a REPL session.
@@ -162,10 +171,6 @@ module Oso
162
171
 
163
172
  # @return [FFI::Polar]
164
173
  attr_reader :ffi_polar
165
- # @return [Hash<String, String>]
166
- attr_reader :loaded_names
167
- # @return [Hash<String, String>]
168
- attr_reader :loaded_contents
169
174
 
170
175
  # The R and L in REPL for systems where readline is available.
171
176
  def repl_readline(prompt)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
4
+
3
5
  module Oso
4
6
  module Polar
5
7
  # A single Polar query.
@@ -169,6 +171,8 @@ module Oso
169
171
  end
170
172
  command = JSON.dump(host.to_polar(input))
171
173
  ffi_query.debug_command(command)
174
+ when 'ExternalOp'
175
+ raise UnimplementedOperationError, 'comparison operators'
172
176
  else
173
177
  raise "Unhandled event: #{JSON.dump(event.inspect)}"
174
178
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Oso
4
- VERSION = '0.6.0'
4
+ VERSION = '0.7.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.6.0
4
+ version: 0.7.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-09-22 00:00:00.000000000 Z
11
+ date: 2020-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi