oso-oso 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.solargraph.yml +17 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +95 -0
- data/Makefile +10 -0
- data/README.md +30 -0
- data/Rakefile +9 -0
- data/bin/console +33 -0
- data/bin/setup +6 -0
- 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.rb +14 -0
- data/lib/oso/http.rb +16 -0
- data/lib/oso/oso.rb +47 -0
- data/lib/oso/path_mapper.rb +29 -0
- data/lib/oso/polar.rb +18 -0
- data/lib/oso/polar/errors.rb +84 -0
- data/lib/oso/polar/ffi.rb +49 -0
- data/lib/oso/polar/ffi/error.rb +123 -0
- data/lib/oso/polar/ffi/polar.rb +97 -0
- data/lib/oso/polar/ffi/query.rb +55 -0
- data/lib/oso/polar/ffi/query_event.rb +23 -0
- data/lib/oso/polar/polar.rb +381 -0
- data/lib/oso/polar/predicate.rb +26 -0
- data/lib/oso/polar/query.rb +117 -0
- data/lib/oso/polar/query_event.rb +22 -0
- data/lib/oso/polar/variable.rb +20 -0
- data/lib/oso/version.rb +5 -0
- data/oso-oso.gemspec +37 -0
- metadata +159 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 9e511f86c5a330c1bb071824398085362def8ba7
|
|
4
|
+
data.tar.gz: da3baaad23fb6e28c8ef0558bbf1deb659c03700
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 9d55c689e8ffc0e3f7b533f54d3e622f77bd7f563182fc7b9dfc047a7a9b1554ed02711fbb8326f55fed76529dde2040d6f829bd4439a63773c9bb58ffb8c8a3
|
|
7
|
+
data.tar.gz: 60b1c8f83803656373a108a64159636292bc91c1840292e7c01ea0c74961533d076ceaa6576010ecdf9dc062bc60c6b112e9900b726db227a322aa52c41f40e0
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.solargraph.yml
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
include:
|
|
3
|
+
- "lib/**/*.rb"
|
|
4
|
+
exclude:
|
|
5
|
+
- spec/**/*
|
|
6
|
+
- test/**/*
|
|
7
|
+
- vendor/**/*
|
|
8
|
+
- ".bundle/**/*"
|
|
9
|
+
require: []
|
|
10
|
+
domains: []
|
|
11
|
+
reporters:
|
|
12
|
+
- rubocop
|
|
13
|
+
- require_not_found
|
|
14
|
+
- typecheck
|
|
15
|
+
require_paths: []
|
|
16
|
+
plugins: []
|
|
17
|
+
max_files: 5000
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
oso-oso (0.2.5)
|
|
5
|
+
ffi (~> 1.0)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
ast (2.4.1)
|
|
11
|
+
backport (1.1.2)
|
|
12
|
+
benchmark (0.1.0)
|
|
13
|
+
byebug (11.1.3)
|
|
14
|
+
coderay (1.1.3)
|
|
15
|
+
diff-lcs (1.3)
|
|
16
|
+
e2mmap (0.1.0)
|
|
17
|
+
ffi (1.13.1)
|
|
18
|
+
jaro_winkler (1.5.4)
|
|
19
|
+
maruku (0.7.3)
|
|
20
|
+
method_source (1.0.0)
|
|
21
|
+
mini_portile2 (2.4.0)
|
|
22
|
+
nokogiri (1.10.9)
|
|
23
|
+
mini_portile2 (~> 2.4.0)
|
|
24
|
+
parallel (1.19.1)
|
|
25
|
+
parser (2.7.1.3)
|
|
26
|
+
ast (~> 2.4.0)
|
|
27
|
+
pry (0.13.1)
|
|
28
|
+
coderay (~> 1.1)
|
|
29
|
+
method_source (~> 1.0)
|
|
30
|
+
pry-byebug (3.9.0)
|
|
31
|
+
byebug (~> 11.0)
|
|
32
|
+
pry (~> 0.13.0)
|
|
33
|
+
rainbow (3.0.0)
|
|
34
|
+
rake (12.3.3)
|
|
35
|
+
regexp_parser (1.7.1)
|
|
36
|
+
reverse_markdown (2.0.0)
|
|
37
|
+
nokogiri
|
|
38
|
+
rexml (3.2.4)
|
|
39
|
+
rspec (3.9.0)
|
|
40
|
+
rspec-core (~> 3.9.0)
|
|
41
|
+
rspec-expectations (~> 3.9.0)
|
|
42
|
+
rspec-mocks (~> 3.9.0)
|
|
43
|
+
rspec-core (3.9.2)
|
|
44
|
+
rspec-support (~> 3.9.3)
|
|
45
|
+
rspec-expectations (3.9.2)
|
|
46
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
47
|
+
rspec-support (~> 3.9.0)
|
|
48
|
+
rspec-mocks (3.9.1)
|
|
49
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
50
|
+
rspec-support (~> 3.9.0)
|
|
51
|
+
rspec-support (3.9.3)
|
|
52
|
+
rubocop (0.85.1)
|
|
53
|
+
parallel (~> 1.10)
|
|
54
|
+
parser (>= 2.7.0.1)
|
|
55
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
56
|
+
regexp_parser (>= 1.7)
|
|
57
|
+
rexml
|
|
58
|
+
rubocop-ast (>= 0.0.3)
|
|
59
|
+
ruby-progressbar (~> 1.7)
|
|
60
|
+
unicode-display_width (>= 1.4.0, < 2.0)
|
|
61
|
+
rubocop-ast (0.0.3)
|
|
62
|
+
parser (>= 2.7.0.1)
|
|
63
|
+
ruby-progressbar (1.10.1)
|
|
64
|
+
solargraph (0.39.8)
|
|
65
|
+
backport (~> 1.1)
|
|
66
|
+
benchmark
|
|
67
|
+
bundler (>= 1.17.2)
|
|
68
|
+
e2mmap
|
|
69
|
+
jaro_winkler (~> 1.5)
|
|
70
|
+
maruku (~> 0.7, >= 0.7.3)
|
|
71
|
+
nokogiri (~> 1.9, >= 1.9.1)
|
|
72
|
+
parser (~> 2.3)
|
|
73
|
+
reverse_markdown (>= 1.0.5, < 3)
|
|
74
|
+
rubocop (~> 0.52)
|
|
75
|
+
thor (~> 1.0)
|
|
76
|
+
tilt (~> 2.0)
|
|
77
|
+
yard (~> 0.9, >= 0.9.24)
|
|
78
|
+
thor (1.0.1)
|
|
79
|
+
tilt (2.0.10)
|
|
80
|
+
unicode-display_width (1.7.0)
|
|
81
|
+
yard (0.9.25)
|
|
82
|
+
|
|
83
|
+
PLATFORMS
|
|
84
|
+
ruby
|
|
85
|
+
|
|
86
|
+
DEPENDENCIES
|
|
87
|
+
oso-oso!
|
|
88
|
+
pry-byebug (~> 3.9.0)
|
|
89
|
+
rake (~> 12.0)
|
|
90
|
+
rspec (~> 3.0)
|
|
91
|
+
solargraph (~> 0.39.8)
|
|
92
|
+
yard (~> 0.9.25)
|
|
93
|
+
|
|
94
|
+
BUNDLED WITH
|
|
95
|
+
2.1.4
|
data/Makefile
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Oso::Oso
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
Add this line to your application's Gemfile:
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
gem 'oso-oso'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
And then execute:
|
|
12
|
+
|
|
13
|
+
$ bundle install
|
|
14
|
+
|
|
15
|
+
Or install it yourself as:
|
|
16
|
+
|
|
17
|
+
$ gem install oso-oso
|
|
18
|
+
|
|
19
|
+
## Development
|
|
20
|
+
|
|
21
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
22
|
+
`rake spec` to run the tests. You can also run `bin/console` for an interactive
|
|
23
|
+
prompt that will allow you to experiment.
|
|
24
|
+
|
|
25
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
26
|
+
release a new version, update the version number in `version.rb`, and then run
|
|
27
|
+
`bundle exec rake release`, which will create a git tag for the version, push
|
|
28
|
+
git commits and tags, and push the `.gem` file to
|
|
29
|
+
[rubygems.org](https://rubygems.org).
|
|
30
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'oso'
|
|
6
|
+
|
|
7
|
+
polar = Oso::Polar.new.tap do |p| # rubocop:disable Lint/UselessAssignment
|
|
8
|
+
p.load_str('f(1); f(2); g(1); g(2); h(2); k(x) := f(x), h(x), g(x);')
|
|
9
|
+
puts 'f(x)', p.send(:query_str, 'f(x)').to_a
|
|
10
|
+
puts 'k(x)', p.send(:query_str, 'k(x)').to_a
|
|
11
|
+
|
|
12
|
+
p.load_str('foo(1, 2); foo(3, 4); foo(5, 6);')
|
|
13
|
+
expected = [{ 'x' => 1, 'y' => 2 }, { 'x' => 3, 'y' => 4 }, { 'x' => 5, 'y' => 6 }]
|
|
14
|
+
raise 'AssertionError' if p.send(:query_str, 'foo(x, y)').to_a != expected
|
|
15
|
+
|
|
16
|
+
class TestClass # rubocop:disable Style/Documentation
|
|
17
|
+
def my_method
|
|
18
|
+
1
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
p.register_class(TestClass)
|
|
23
|
+
|
|
24
|
+
p.load_str('external(x, 3) := x = new TestClass{}.my_method;')
|
|
25
|
+
results = p.send(:query_str, 'external(1, x)')
|
|
26
|
+
p results.next
|
|
27
|
+
|
|
28
|
+
# p.load_str('testDebug() := debug(), foo(x, y), k(y);')
|
|
29
|
+
# p.send(:query_str, 'testDebug()').next
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
require 'pry'
|
|
33
|
+
Pry.start
|
data/bin/setup
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/lib/oso.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'oso/http'
|
|
4
|
+
require 'oso/oso'
|
|
5
|
+
require 'oso/path_mapper'
|
|
6
|
+
require 'oso/polar'
|
|
7
|
+
require 'oso/version'
|
|
8
|
+
|
|
9
|
+
# Top-level namespace for oso authorization library.
|
|
10
|
+
module Oso
|
|
11
|
+
def self.new
|
|
12
|
+
::Oso::Oso.new
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/oso/http.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Oso
|
|
4
|
+
# An HTTP resource.
|
|
5
|
+
class Http
|
|
6
|
+
def initialize(hostname: nil, path: nil, query: nil)
|
|
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
|
data/lib/oso/oso.rb
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Oso
|
|
4
|
+
# Oso authorization API.
|
|
5
|
+
class Oso
|
|
6
|
+
def initialize
|
|
7
|
+
@polar = ::Oso::Polar.new
|
|
8
|
+
register_class(Http, name: 'Http')
|
|
9
|
+
register_class(PathMapper, name: 'PathMapper')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def load_file(file)
|
|
13
|
+
polar.load_file(file)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def load_str(str)
|
|
17
|
+
polar.load_str(str)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def register_class(cls, name: nil) # rubocop:disable Naming/MethodParameterName
|
|
21
|
+
if block_given?
|
|
22
|
+
polar.register_class(cls, name: name, from_polar: Proc.new)
|
|
23
|
+
else
|
|
24
|
+
polar.register_class(cls, name: name)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def allow(actor:, action:, resource:)
|
|
29
|
+
polar.query_pred('allow', args: [actor, action, resource]).next
|
|
30
|
+
true
|
|
31
|
+
rescue StopIteration
|
|
32
|
+
false
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def query_predicate(name, *args)
|
|
36
|
+
polar.query_pred(name, args: args)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def load_queued_files
|
|
40
|
+
polar.load_queued_files
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
attr_reader :polar
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
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
|
data/lib/oso/polar.rb
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'oso/polar/errors'
|
|
4
|
+
require 'oso/polar/ffi'
|
|
5
|
+
require 'oso/polar/polar'
|
|
6
|
+
require 'oso/polar/predicate'
|
|
7
|
+
require 'oso/polar/query'
|
|
8
|
+
require 'oso/polar/query_event'
|
|
9
|
+
require 'oso/polar/variable'
|
|
10
|
+
|
|
11
|
+
module Oso
|
|
12
|
+
# Top-level namespace for Polar language library.
|
|
13
|
+
module Polar
|
|
14
|
+
def self.new
|
|
15
|
+
::Oso::Polar::Polar.new
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Oso
|
|
4
|
+
module Polar
|
|
5
|
+
# Base error type for Oso::Polar.
|
|
6
|
+
class Error < ::RuntimeError
|
|
7
|
+
attr_reader :stack_trace
|
|
8
|
+
|
|
9
|
+
# @param message [String]
|
|
10
|
+
# @param details [Hash]
|
|
11
|
+
def initialize(message = nil, details: nil)
|
|
12
|
+
@details = details
|
|
13
|
+
if details and details.key?("stack_trace")
|
|
14
|
+
@stack_trace = details['stack_trace']
|
|
15
|
+
else
|
|
16
|
+
@stack_trace = nil
|
|
17
|
+
end
|
|
18
|
+
super(message)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Expected to find an FFI error to convert into a Ruby exception but found none.
|
|
23
|
+
class FFIErrorNotFound < Error; end
|
|
24
|
+
|
|
25
|
+
# Generic runtime exception.
|
|
26
|
+
class PolarRuntimeError < Error; end
|
|
27
|
+
|
|
28
|
+
# Errors from across the FFI boundary.
|
|
29
|
+
|
|
30
|
+
class SerializationError < PolarRuntimeError; end
|
|
31
|
+
class UnsupportedError < PolarRuntimeError; end
|
|
32
|
+
class PolarTypeError < PolarRuntimeError; end
|
|
33
|
+
class StackOverflowError < PolarRuntimeError; end
|
|
34
|
+
|
|
35
|
+
# Errors originating from this side of the FFI boundary.
|
|
36
|
+
|
|
37
|
+
class UnregisteredClassError < PolarRuntimeError; end
|
|
38
|
+
class MissingConstructorError < PolarRuntimeError; end
|
|
39
|
+
class UnregisteredInstanceError < PolarRuntimeError; end
|
|
40
|
+
class DuplicateInstanceRegistrationError < PolarRuntimeError; end
|
|
41
|
+
class InvalidCallError < PolarRuntimeError; end
|
|
42
|
+
class InvalidConstructorError < PolarRuntimeError; end
|
|
43
|
+
class InlineQueryFailedError < PolarRuntimeError; end
|
|
44
|
+
class NullByteInPolarFileError < PolarRuntimeError; end
|
|
45
|
+
class UnexpectedPolarTypeError < PolarRuntimeError; end
|
|
46
|
+
class PolarFileExtensionError < PolarRuntimeError # rubocop:disable Style/Documentation
|
|
47
|
+
def initialize
|
|
48
|
+
super('Polar files must have .pol or .polar extension.')
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
class PolarFileNotFoundError < PolarRuntimeError # rubocop:disable Style/Documentation
|
|
52
|
+
# @param file [String]
|
|
53
|
+
def initialize(file)
|
|
54
|
+
super("Could not find file: #{file}")
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
class DuplicateClassAliasError < PolarRuntimeError # rubocop:disable Style/Documentation
|
|
58
|
+
# @param as [String]
|
|
59
|
+
# @param old [Class]
|
|
60
|
+
# @param new [Class]
|
|
61
|
+
def initialize(name:, old:, new:) # rubocop:disable Naming/MethodParameterName
|
|
62
|
+
super("Attempted to alias #{new} as '#{name}', but #{old} already has that alias.")
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Generic operational exception.
|
|
67
|
+
class OperationalError < Error; end
|
|
68
|
+
class UnknownError < OperationalError; end
|
|
69
|
+
|
|
70
|
+
# Catch-all for a parsing error that doesn't match any of the more specific types.
|
|
71
|
+
class ParseError < Error
|
|
72
|
+
class ExtraToken < ParseError; end
|
|
73
|
+
class IntegerOverflow < ParseError; end
|
|
74
|
+
class InvalidTokenCharacter < ParseError; end
|
|
75
|
+
class InvalidToken < ParseError; end
|
|
76
|
+
class UnrecognizedEOF < ParseError; end
|
|
77
|
+
class UnrecognizedToken < ParseError; end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Generic Polar API exception.
|
|
81
|
+
class ApiError < Error; end
|
|
82
|
+
class ParameterError < ApiError; end
|
|
83
|
+
end
|
|
84
|
+
end
|