foobara 0.5.7 → 0.5.9
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 +4 -4
- data/CHANGELOG.md +8 -0
- data/projects/command_connectors/spec/allowed_rules_spec.rb +77 -0
- data/projects/command_connectors/src/authenticator_selector.rb +1 -1
- data/projects/command_connectors/src/command_connector.rb +24 -4
- data/projects/command_connectors/src/command_registry.rb +19 -4
- data/projects/command_connectors/src/transformed_command.rb +6 -1
- data/projects/command_connectors/src/transformers/auth_errors_transformer.rb +1 -1
- data/projects/entities/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/symbolize_private.rb +1 -1
- data/projects/typesystem/projects/common/src/error_collection.rb +6 -2
- data/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c97d7f81b121b86084fb6305b3327cdb82500828a1e4f87fc308c11390c46045
|
|
4
|
+
data.tar.gz: 7a48863a2c118156769df85217057309a680207af1af989d2465676c6cf012bc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 25ea5d0c8f87d7f77c0d6f8feecf93aac2940161eceebd3b8935013b7e06b617e12d8e003826f439f5685027b96121e795765a9b4376e2f08038f682f7860601
|
|
7
|
+
data.tar.gz: 8b7796124e4e7d553f895c46913a693aa3f42666712a8100404bf68bcdaf80f25ec201177894c72efc6d7b53aac1565be8fe4c795f3a762ab4127d0da9b344fa
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
# [0.5.9] - 2026-03-06
|
|
2
|
+
|
|
3
|
+
- Do not require an allowed rule for builtin-in commands when using requires_allowed_rule: true
|
|
4
|
+
|
|
5
|
+
# [0.5.8] - 2026-03-04
|
|
6
|
+
|
|
7
|
+
- Provide a way for allowed rules to be declared independently of connecting commands
|
|
8
|
+
|
|
1
9
|
# [0.5.7] - 2026-02-25
|
|
2
10
|
|
|
3
11
|
- Add a Manifest::Model.associations convenience method
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
RSpec.describe Foobara::CommandConnector do
|
|
2
|
+
after { Foobara.reset_alls }
|
|
3
|
+
|
|
4
|
+
let(:authenticator) { -> { :some_user } }
|
|
5
|
+
|
|
6
|
+
let(:response) { command_connector.run(full_command_name:, action:, inputs:) }
|
|
7
|
+
let(:parsed_response) { JSON.parse(response.body) }
|
|
8
|
+
|
|
9
|
+
let(:action) { "run" }
|
|
10
|
+
let(:full_command_name) { "ComputeExponent" }
|
|
11
|
+
let(:inputs) do
|
|
12
|
+
{ base:, exponent: }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
let(:command_class) do
|
|
16
|
+
stub_class(:ComputeExponent, Foobara::Command) do
|
|
17
|
+
inputs do
|
|
18
|
+
exponent :integer, :required
|
|
19
|
+
base :integer, :required
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
result :integer
|
|
23
|
+
|
|
24
|
+
attr_accessor :exponential
|
|
25
|
+
|
|
26
|
+
def execute
|
|
27
|
+
compute
|
|
28
|
+
|
|
29
|
+
exponential
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def compute
|
|
33
|
+
self.exponential = 1
|
|
34
|
+
|
|
35
|
+
exponent.times do
|
|
36
|
+
self.exponential *= base
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context "when independently setting the allowed rules" do
|
|
43
|
+
let(:command_connector) do
|
|
44
|
+
described_class.new(authenticator:,
|
|
45
|
+
allow: { command_class => -> { base.even? } })
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
before do
|
|
49
|
+
command_connector.connect(command_class)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context "when allowed rule is met" do
|
|
53
|
+
let(:base) { 2 }
|
|
54
|
+
let(:exponent) { 3 }
|
|
55
|
+
|
|
56
|
+
it "runs the command" do
|
|
57
|
+
expect(response.status).to be(0)
|
|
58
|
+
expect(response.error).to be_nil
|
|
59
|
+
expect(response.body).to eq(8)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "when allowed rule is not met" do
|
|
64
|
+
let(:base) { 3 }
|
|
65
|
+
let(:exponent) { 3 }
|
|
66
|
+
|
|
67
|
+
it "is not authorized" do
|
|
68
|
+
expect(response.status).to be(1)
|
|
69
|
+
|
|
70
|
+
errors = response.body
|
|
71
|
+
|
|
72
|
+
expect(errors.size).to eq(1)
|
|
73
|
+
expect(errors.first).to be_a(Foobara::CommandConnector::NotAllowedError)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -9,7 +9,7 @@ module Foobara
|
|
|
9
9
|
def initialize(authenticators:, symbol: nil, explanation: nil, &block)
|
|
10
10
|
self.authenticators = authenticators
|
|
11
11
|
|
|
12
|
-
symbol ||= authenticators.map(&:symbol).
|
|
12
|
+
symbol ||= authenticators.map(&:symbol).join("_or_").to_sym
|
|
13
13
|
explanation ||= authenticators.map(&:explanation).join(", or ")
|
|
14
14
|
|
|
15
15
|
super(symbol:, explanation:)
|
|
@@ -199,7 +199,10 @@ module Foobara
|
|
|
199
199
|
default_pre_commit_transformers: nil,
|
|
200
200
|
auth_map: nil,
|
|
201
201
|
current_user: nil,
|
|
202
|
+
# TODO: let's default this to true
|
|
202
203
|
requires_allowed_rule: false,
|
|
204
|
+
allowed_rules: nil,
|
|
205
|
+
allow: nil,
|
|
203
206
|
&block)
|
|
204
207
|
authenticator = self.class.to_authenticator(authenticator)
|
|
205
208
|
|
|
@@ -216,6 +219,8 @@ module Foobara
|
|
|
216
219
|
|
|
217
220
|
self.authenticator = authenticator
|
|
218
221
|
self.command_registry = CommandRegistry.new(authenticator:)
|
|
222
|
+
allowed_rules&.each_pair { |symbol, rule| register_allowed_rule(symbol, rule) }
|
|
223
|
+
self.allow allow if allow
|
|
219
224
|
|
|
220
225
|
self.capture_unknown_error = capture_unknown_error
|
|
221
226
|
self.name = name
|
|
@@ -242,6 +247,10 @@ module Foobara
|
|
|
242
247
|
end
|
|
243
248
|
end
|
|
244
249
|
|
|
250
|
+
def allow(rules)
|
|
251
|
+
command_registry.allow rules
|
|
252
|
+
end
|
|
253
|
+
|
|
245
254
|
def register_allowed_rule(*ruleish_args)
|
|
246
255
|
command_registry.allowed_rule(*ruleish_args)
|
|
247
256
|
end
|
|
@@ -404,8 +413,6 @@ module Foobara
|
|
|
404
413
|
raise NoCommandFoundError.new(message: "Could not find command registered for #{full_command_name}")
|
|
405
414
|
# :nocov:
|
|
406
415
|
end
|
|
407
|
-
|
|
408
|
-
transformed_command_class
|
|
409
416
|
else
|
|
410
417
|
action = case action
|
|
411
418
|
when "describe_type", "manifest", "describe_command"
|
|
@@ -424,8 +431,15 @@ module Foobara
|
|
|
424
431
|
command_class = find_builtin_command_class(command_name)
|
|
425
432
|
full_command_name = command_class.full_command_name
|
|
426
433
|
|
|
427
|
-
transformed_command_from_name(full_command_name) ||
|
|
434
|
+
transformed_command_class = transformed_command_from_name(full_command_name) ||
|
|
435
|
+
transform_command_class(command_class)
|
|
436
|
+
|
|
437
|
+
if transformed_command_class < TransformedCommand
|
|
438
|
+
transformed_command_class.builtin = true
|
|
439
|
+
end
|
|
428
440
|
end
|
|
441
|
+
|
|
442
|
+
transformed_command_class
|
|
429
443
|
end
|
|
430
444
|
|
|
431
445
|
def request_to_command_inputs(request)
|
|
@@ -631,8 +645,14 @@ module Foobara
|
|
|
631
645
|
|
|
632
646
|
def run_command(request)
|
|
633
647
|
command = request.command
|
|
648
|
+
command_class = request.command_class
|
|
634
649
|
|
|
635
|
-
if requires_allowed_rule
|
|
650
|
+
if requires_allowed_rule &&
|
|
651
|
+
command.is_a?(TransformedCommand) &&
|
|
652
|
+
# The != false looks odd and must be that we want to distinguish between the default (nil)
|
|
653
|
+
# and explicitly not requiring auth
|
|
654
|
+
command.class.requires_authentication != false &&
|
|
655
|
+
!command_class.builtin?
|
|
636
656
|
unless command.allowed_rule
|
|
637
657
|
raise NoAllowedRuleGivenError,
|
|
638
658
|
"Must connect #{command.full_command_name} with an `allowed_if:` " \
|
|
@@ -9,9 +9,10 @@ module Foobara
|
|
|
9
9
|
# Should we support different authenticators for different commands?
|
|
10
10
|
# Might be a smell of two domains co-habitating in one? Or maybe one is just
|
|
11
11
|
# passing another through and we should support that?
|
|
12
|
-
def initialize(authenticator: nil)
|
|
12
|
+
def initialize(authenticator: nil, allow: nil)
|
|
13
13
|
self.scoped_path = []
|
|
14
14
|
self.authenticator = authenticator
|
|
15
|
+
self.allow allow if allow
|
|
15
16
|
|
|
16
17
|
customized = [:command]
|
|
17
18
|
|
|
@@ -193,15 +194,29 @@ module Foobara
|
|
|
193
194
|
foobara_all_command.size
|
|
194
195
|
end
|
|
195
196
|
|
|
197
|
+
def allow(rules = (no_args = true))
|
|
198
|
+
@allow ||= {}
|
|
199
|
+
|
|
200
|
+
if no_args
|
|
201
|
+
@allow
|
|
202
|
+
else
|
|
203
|
+
@allow = @allow.merge(rules)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
196
207
|
private
|
|
197
208
|
|
|
198
|
-
def create_exposed_command(command_class, **)
|
|
209
|
+
def create_exposed_command(command_class, **opts)
|
|
199
210
|
full_domain_name = command_class.domain.scoped_full_name
|
|
200
211
|
exposed_domain = foobara_lookup_domain(full_domain_name,
|
|
201
212
|
mode: Namespace::LookupMode::ABSOLUTE_SINGLE_NAMESPACE) ||
|
|
202
213
|
build_and_register_exposed_domain(full_domain_name)
|
|
203
214
|
|
|
204
|
-
|
|
215
|
+
if !opts.key?(:allowed_rule) && allow&.key?(command_class)
|
|
216
|
+
opts = opts.merge(allowed_rule: allow[command_class])
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
exposed_command = create_exposed_command_without_domain(command_class, **opts)
|
|
205
220
|
|
|
206
221
|
exposed_domain.foobara_register(exposed_command)
|
|
207
222
|
|
|
@@ -292,7 +307,7 @@ module Foobara
|
|
|
292
307
|
errors_transformers: nil,
|
|
293
308
|
pre_commit_transformers: nil,
|
|
294
309
|
serializers: nil,
|
|
295
|
-
allowed_rule:
|
|
310
|
+
allowed_rule: nil,
|
|
296
311
|
authenticator: nil,
|
|
297
312
|
**opts
|
|
298
313
|
)
|
|
@@ -21,7 +21,8 @@ module Foobara
|
|
|
21
21
|
:requires_authentication,
|
|
22
22
|
:authenticator,
|
|
23
23
|
:subclassed_in_namespace,
|
|
24
|
-
:suffix
|
|
24
|
+
:suffix,
|
|
25
|
+
:builtin
|
|
25
26
|
|
|
26
27
|
def subclass(
|
|
27
28
|
command_class,
|
|
@@ -546,6 +547,10 @@ module Foobara
|
|
|
546
547
|
end
|
|
547
548
|
end
|
|
548
549
|
|
|
550
|
+
def builtin?
|
|
551
|
+
builtin
|
|
552
|
+
end
|
|
553
|
+
|
|
549
554
|
private
|
|
550
555
|
|
|
551
556
|
def processors_to_manifest_symbols(processors)
|
|
@@ -12,7 +12,7 @@ module Foobara
|
|
|
12
12
|
map = map.merge(possible_error.key.to_s => possible_error)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
if transformed_command.allowed_rule
|
|
15
|
+
if transformed_command.allowed_rule && transformed_command.allowed_rule.symbol != :always
|
|
16
16
|
possible_error = PossibleError.new(CommandConnector::NotAllowedError)
|
|
17
17
|
map = map.merge(possible_error.key.to_s => possible_error)
|
|
18
18
|
end
|
data/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foobara
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Miles Georgi
|
|
@@ -106,6 +106,7 @@ files:
|
|
|
106
106
|
- projects/command/src/state_machine.rb
|
|
107
107
|
- projects/command_connectors/Guardfile
|
|
108
108
|
- projects/command_connectors/lib/foobara/command_connectors.rb
|
|
109
|
+
- projects/command_connectors/spec/allowed_rules_spec.rb
|
|
109
110
|
- projects/command_connectors/spec/ambiguous_lookups_spec.rb
|
|
110
111
|
- projects/command_connectors/spec/auth_mappers_spec.rb
|
|
111
112
|
- projects/command_connectors/spec/command_connector_spec.rb
|