foobara 0.0.104 → 0.0.106

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: be41d74ce30f423271c0b160d955d9ea7422e5d4337ab1d3c17deb0dae395d53
4
- data.tar.gz: 51f8a06a9468870be7e2db0dd2116a8bca141852f27d462b4ce01b74df490710
3
+ metadata.gz: 980071302c992808e812a703ff9a203fca501336c00225dd8eeb045982975704
4
+ data.tar.gz: '04901d96e1717a09d736feccd2c21d31873ae32235362b0613476f508423373f'
5
5
  SHA512:
6
- metadata.gz: 49e75de0f35a1a1eb257efd6e1304ed39d340ee8531e1b768ca8fc58ab4a0bc8e4422e3c50c379565c899708ac7a0768aa87aca326240933771147c285212894
7
- data.tar.gz: 6d3234ee0c549fd91d21fe11e16968a5fe56da263eafa90474b20baa2b091ec33b57b439891eeeccf7149e4a9d1995ebab8a3ecc864e1eb796a1a8bef60f1d63
6
+ metadata.gz: cee4fbf405088f382583642aed0c40c55010249e346f6881608463ec37d8bd8fe378fe030adedc3c2c1534a89980ee475affa872e260e7e95dbad611411d84f8
7
+ data.tar.gz: 741ed3a774a1d92dacef4a640706b41764f10144d39b130eeaf032648a60d95b3d450830facd8334b346a1a2e07179b750899063e69ac3bb1e6862884a0bff64
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ # [0.0.106] - 2025-04-20
2
+
3
+ - Fix authenticator explanation that was coupled to pry
4
+
5
+ # [0.0.105] - 2025-04-20
6
+
7
+ - Support registering allowed_rule and authenticator on connectors and using them by symbol
8
+ - Automatically set requires_authentication if there's an authenticator+allowed_rule for convenience.
9
+
1
10
  # [0.0.104] - 2025-04-17
2
11
 
3
12
  - Fix manifest bug when command has no possible errors
@@ -566,17 +566,18 @@ module Foobara
566
566
  end
567
567
 
568
568
  if explanation.nil?
569
- source = begin
570
- allowed_rule.block.source
571
- rescue MethodSource::SourceNotFoundError
572
- # This path is hit if the way the source code is extracted
573
- # doesn't result in valid Ruby, for example, as part of a hash such as:
574
- # allowed_rule: -> () { whatever?(something) },
575
- # :nocov:
576
- allowed_rule.block.source_location.join(":")
577
- # :nocov:
578
- end
569
+ source = if allowed_rule.block.respond_to?("source") && defined?(MethodSource)
570
+ begin
571
+ # This only works when pry is loaded
572
+ allowed_rule.block.source
573
+ rescue MethodSource::SourceNotFoundError
574
+ # This path is hit if the way the source code is extracted
575
+ # doesn't result in valid Ruby, for example, as part of a hash such as:
576
+ # allowed_rule: -> () { whatever?(something) },
577
+ end
578
+ end
579
579
 
580
+ source ||= allowed_rule.block.source_location.join(":")
580
581
  explanation = source || "No explanation."
581
582
  end
582
583
 
@@ -0,0 +1,19 @@
1
+ module Foobara
2
+ class CommandConnector
3
+ class Authenticator
4
+ attr_accessor :block, :explanation, :symbol
5
+
6
+ def initialize(symbol: nil, explanation: nil, &block)
7
+ symbol ||= Util.non_full_name_underscore(self.class).to_sym
8
+
9
+ self.symbol = symbol
10
+ self.block = block
11
+ self.explanation = explanation || symbol
12
+ end
13
+
14
+ def to_proc
15
+ block
16
+ end
17
+ end
18
+ end
19
+ end
@@ -84,18 +84,116 @@ module Foobara
84
84
  def find_builtin_command_class(command_class_name)
85
85
  Util.find_constant_through_class_hierarchy(self, "Commands::#{command_class_name}")
86
86
  end
87
+
88
+ def allowed_rules_to_register
89
+ return @allowed_rules_to_register if defined?(@allowed_rules_to_register)
90
+
91
+ @allowed_rules_to_register = if superclass == Object
92
+ []
93
+ else
94
+ superclass.allowed_rules_to_register.dup
95
+ end
96
+ end
97
+
98
+ def register_allowed_rule(*rule_args)
99
+ allowed_rules_to_register << rule_args
100
+ end
101
+
102
+ def authenticator_registry
103
+ return @authenticator_registry if defined?(@authenticator_registry)
104
+
105
+ @authenticator_registry = if superclass == Object
106
+ {}
107
+ else
108
+ superclass.authenticator_registry.dup
109
+ end
110
+ end
111
+
112
+ def register_authenticator(*authenticatorish_args)
113
+ authenticator = to_authenticator(*authenticatorish_args)
114
+
115
+ unless authenticator.symbol
116
+ # :nocov:
117
+ raise ArgumentError, "Expected an authenticator to have a symbol"
118
+ # :nocov:
119
+ end
120
+
121
+ authenticator_registry[authenticator.symbol] = authenticator
122
+ end
123
+
124
+ def to_authenticator(*args)
125
+ symbol, object = case args.size
126
+ when 1
127
+ [nil, args.first]
128
+ when 2
129
+ args
130
+ else
131
+ # :nocov:
132
+ raise ArgumentError, "Expected 1 or 2 arguments, got #{args.size}"
133
+ # :nocov:
134
+ end
135
+
136
+ case object
137
+ when Class
138
+ if object < Authenticator
139
+ object.new
140
+ else
141
+ # :nocov:
142
+ raise ArgumentError, "Expected a class that inherits from Authenticator"
143
+ # :nocov:
144
+ end
145
+ when Authenticator, nil
146
+ object
147
+ when ::String
148
+ if symbol
149
+ # :nocov:
150
+ raise ArgumentError, "Was not expecting a symbol and a string"
151
+ # :nocov:
152
+ end
153
+
154
+ to_authenticator(object.to_sym)
155
+ when ::Symbol
156
+ authenticator = authenticator_registry[object]
157
+
158
+ unless authenticator
159
+ # :nocov:
160
+ raise "No authenticator found for #{object}"
161
+ # :nocov:
162
+ end
163
+
164
+ authenticator
165
+ else
166
+ if object.respond_to?(:call)
167
+ Authenticator.new(symbol:, &object)
168
+ else
169
+ # :nocov:
170
+ raise "Not sure how to convert #{object} into an AllowedRule object"
171
+ # :nocov:
172
+ end
173
+ end.tap do |resolved_authenticator|
174
+ if resolved_authenticator
175
+ resolved_authenticator.symbol ||= symbol
176
+ end
177
+ end
178
+ end
87
179
  end
88
180
 
89
181
  attr_accessor :command_registry, :authenticator, :capture_unknown_error
90
182
 
91
183
  def initialize(authenticator: nil, capture_unknown_error: nil, default_serializers: nil)
92
- self.command_registry = CommandRegistry.new(authenticator:)
184
+ authenticator = self.class.to_authenticator(authenticator)
185
+
93
186
  self.authenticator = authenticator
187
+ self.command_registry = CommandRegistry.new(authenticator:)
94
188
  self.capture_unknown_error = capture_unknown_error
95
189
 
96
190
  Util.array(default_serializers).each do |serializer|
97
191
  add_default_serializer(serializer)
98
192
  end
193
+
194
+ self.class.allowed_rules_to_register.each do |ruleish_args|
195
+ command_registry.allowed_rule(*ruleish_args)
196
+ end
99
197
  end
100
198
 
101
199
  def find_builtin_command_class(command_class_name)
@@ -293,7 +391,11 @@ module Foobara
293
391
  delayed_connections.clear
294
392
  end
295
393
 
296
- def connect(registerable, *, **)
394
+ def connect(registerable, *, authenticator: nil, **)
395
+ if authenticator
396
+ authenticator = self.class.to_authenticator(authenticator)
397
+ end
398
+
297
399
  case registerable
298
400
  when Class
299
401
  unless registerable < Command
@@ -302,15 +404,15 @@ module Foobara
302
404
  # :nocov:
303
405
  end
304
406
 
305
- command_registry.register(registerable, *, **)
407
+ command_registry.register(registerable, *, authenticator:, **)
306
408
  when Module
307
409
  if registerable.foobara_organization?
308
410
  registerable.foobara_domains.map do |domain|
309
- connect(domain, *, **)
411
+ connect(domain, *, authenticator:, **)
310
412
  end.flatten
311
413
  elsif registerable.foobara_domain?
312
414
  registerable.foobara_all_command(mode: Namespace::LookupMode::DIRECT).map do |command_class|
313
- Util.array(connect(command_class, *, **))
415
+ Util.array(connect(command_class, *, authenticator:, **))
314
416
  end.flatten
315
417
  else
316
418
  # :nocov:
@@ -318,7 +420,7 @@ module Foobara
318
420
  # :nocov:
319
421
  end
320
422
  when Symbol, String
321
- connect_delayed(registerable, *, **)
423
+ connect_delayed(registerable, *, authenticator:, **)
322
424
  else
323
425
  # :nocov:
324
426
  raise "Don't know how to register #{registerable} (#{registerable.class})"
@@ -372,9 +474,10 @@ module Foobara
372
474
 
373
475
  def authenticate(request)
374
476
  request_command = request.command
477
+ auth_block = request_command.authenticator || authenticator
375
478
 
376
479
  request_command.after_load_records do |command:, **|
377
- authenticated_user = request.instance_exec(&authenticator)
480
+ authenticated_user = request.instance_exec(&auth_block)
378
481
 
379
482
  request_command.authenticated_user = authenticated_user
380
483
 
@@ -38,6 +38,10 @@ module Foobara
38
38
  aggregate_entities: nil,
39
39
  atomic_entities: nil
40
40
  )
41
+ if allowed_rule && authenticator && requires_authentication.nil?
42
+ requires_authentication = true
43
+ end
44
+
41
45
  if requires_authentication || allowed_rule
42
46
  errors_transformers = [
43
47
  *errors_transformers,
@@ -6,6 +6,9 @@ module Foobara
6
6
 
7
7
  attr_accessor :authenticator, :default_allowed_rule
8
8
 
9
+ # Should we support different authenticators for different commands?
10
+ # Might be a smell of two domains co-habitating in one? Or maybe one is just
11
+ # passing another through and we should support that?
9
12
  def initialize(authenticator: nil)
10
13
  self.scoped_path = []
11
14
  self.authenticator = authenticator
@@ -50,7 +53,7 @@ module Foobara
50
53
  pre_commit_transformers: nil,
51
54
  serializers: nil,
52
55
  allowed_rule: default_allowed_rule,
53
- authenticator: self.authenticator,
56
+ authenticator: nil,
54
57
  **opts
55
58
  )
56
59
  opts.merge(
@@ -60,7 +63,7 @@ module Foobara
60
63
  pre_commit_transformers: [*pre_commit_transformers, *default_pre_commit_transformers],
61
64
  serializers: [*serializers, *default_serializers],
62
65
  allowed_rule: allowed_rule && to_allowed_rule(allowed_rule),
63
- authenticator:
66
+ authenticator: authenticator || self.authenticator
64
67
  )
65
68
  end
66
69
 
@@ -140,8 +143,8 @@ module Foobara
140
143
  @allowed_rule_registry ||= {}
141
144
  end
142
145
 
143
- def allowed_rule(ruleish)
144
- allowed_rule = to_allowed_rule(ruleish)
146
+ def allowed_rule(*)
147
+ allowed_rule = to_allowed_rule(*)
145
148
 
146
149
  unless allowed_rule.symbol
147
150
  # :nocov:
@@ -201,11 +204,28 @@ module Foobara
201
204
  default_serializers << serializer
202
205
  end
203
206
 
204
- def to_allowed_rule(object)
207
+ def to_allowed_rule(*args)
208
+ symbol, object = case args.size
209
+ when 1
210
+ [nil, args.first]
211
+ when 2
212
+ args
213
+ else
214
+ # :nocov:
215
+ raise ArgumentError, "Expected 1 or 2 arguments, got #{args.size}"
216
+ # :nocov:
217
+ end
218
+
205
219
  case object
206
220
  when AllowedRule, nil
207
221
  object
208
222
  when ::String
223
+ if symbol
224
+ # :nocov:
225
+ raise ArgumentError, "Was not expecting a symbol and a string"
226
+ # :nocov:
227
+ end
228
+
209
229
  to_allowed_rule(object.to_sym)
210
230
  when ::Symbol
211
231
  allowed_rule = allowed_rule_registry[object]
@@ -251,12 +271,14 @@ module Foobara
251
271
  allowed_rule
252
272
  else
253
273
  if object.respond_to?(:call)
254
- AllowedRule.new(&object)
274
+ AllowedRule.new(symbol:, &object)
255
275
  else
256
276
  # :nocov:
257
277
  raise "Not sure how to convert #{object} into an AllowedRule object"
258
278
  # :nocov:
259
279
  end
280
+ end.tap do |rule|
281
+ rule.symbol ||= symbol
260
282
  end
261
283
  end
262
284
 
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.0.104
4
+ version: 0.0.106
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Georgi
@@ -181,6 +181,7 @@ files:
181
181
  - projects/command/src/state_machine.rb
182
182
  - projects/command/src/transformed_command.rb
183
183
  - projects/command_connectors/lib/foobara/command_connectors.rb
184
+ - projects/command_connectors/src/authenticator.rb
184
185
  - projects/command_connectors/src/command_connector.rb
185
186
  - projects/command_connectors/src/command_connector/commands/describe.rb
186
187
  - projects/command_connectors/src/command_connector/commands/list_commands.rb