foobara 0.5.7 → 0.5.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d1c5cb75a03670d17291e1d85de76a826b6fedfe4b0f099f235ca646253c165
4
- data.tar.gz: 7f852654ca70620a4dd544792d4518cfb7a5cd64214802517bdd9a3e1f435b19
3
+ metadata.gz: 7f3a7dee25a0ab1d7598ec72bbd71ec8807113d417cc758842cf4edd7b214d2a
4
+ data.tar.gz: f81bd84c70a9d41a8db414ee9424d5c2e2d9533887cfaa1ea0b436094873bc9a
5
5
  SHA512:
6
- metadata.gz: 83077d31d4ac8f03a044568550f97a79a1772f6ec27f3b839501625a400d9b40550df500ba70e8e3241cf9ea001a2a52821b4c2c2c1a76241d5eb8265d36cf43
7
- data.tar.gz: 9e41a5c335dab08647082b411e55ef4962ddf09a280cba9c8ee58b77533072349a0b271607a1f28ccd56eff82219182dd66e7e41177200abd979d855d9d53430
6
+ metadata.gz: 8819827dfdffb0ae2bef29f3bbbeb944cd3270cfd1a7938037d487373123ce50e2a8f832c5687c6b75ef8fd6e2ebd2016689e4b7208752a1f4a15bafa6eac10d
7
+ data.tar.gz: ba81595289f961c7c5f639d85fb16f7d05fe5b3d0aa3fcbeec1499030b7e56bbab75afc1cef58b6eafd5e6f115c3f2c4dbfb15ab29de8bc081095ccb4a8bd089
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # [0.5.8] - 2026-03-04
2
+
3
+ - Provide a way for allowed rules to be declared independently of connecting commands
4
+
1
5
  # [0.5.7] - 2026-02-25
2
6
 
3
7
  - 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).map(&:to_s).join("_or_").to_sym
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
@@ -632,7 +641,7 @@ module Foobara
632
641
  def run_command(request)
633
642
  command = request.command
634
643
 
635
- if requires_allowed_rule
644
+ if requires_allowed_rule && command.is_a?(TransformedCommand) && command.class.requires_authentication != false
636
645
  unless command.allowed_rule
637
646
  raise NoAllowedRuleGivenError,
638
647
  "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
- exposed_command = create_exposed_command_without_domain(command_class, **)
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: default_allowed_rule,
310
+ allowed_rule: nil,
296
311
  authenticator: nil,
297
312
  **opts
298
313
  )
@@ -18,7 +18,7 @@ module Foobara
18
18
  def desugarize(rawish_type_declaration)
19
19
  private = rawish_type_declaration[:private]
20
20
 
21
- if private.any? { |key| key.is_a?(::String) }
21
+ if private.any?(::String)
22
22
  rawish_type_declaration[:private] = private.map(&:to_sym)
23
23
  end
24
24
 
@@ -83,9 +83,13 @@ module Foobara
83
83
  end
84
84
 
85
85
  def errors_hash
86
- each_with_object({}) do |error, hash|
87
- hash[error.key] = error.to_h
86
+ h = {}
87
+
88
+ each do |error|
89
+ h[error.key] = error.to_h
88
90
  end
91
+
92
+ h
89
93
  end
90
94
 
91
95
  def to_sentence
data/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Foobara
2
2
  module Version
3
- VERSION = "0.5.7".freeze
3
+ VERSION = "0.5.8".freeze
4
4
  MINIMUM_RUBY_VERSION = ">= 3.4.0".freeze
5
5
  end
6
6
  end
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.7
4
+ version: 0.5.8
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