hub_kernel-interface 0.10.0 → 0.11.0

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: a110bf3b15c7fbe91d280d688cadadb134e3e2ab7bbf2ef513d56b23ccbb94d6
4
- data.tar.gz: eed0d2ced815810fb69566fcf8d23782855a9034c5ff4e9d498c9b18c82ca165
3
+ metadata.gz: 9ec695e1e219b18dba2295e8220f822ac9794349257dd4b3cbf25eafc48c28f8
4
+ data.tar.gz: 98594b01c83ef1d32d8ae54d46ad1a09f735476d619beeb4e6a19f21e2e2bda6
5
5
  SHA512:
6
- metadata.gz: ce020e02f3fb14ac881793f935ddb4f2e25f5f9a848da3c15a7ebb8e64a285dcda66f235fe19bcda4fee37316e0d34bc00cbb191de458f08c890083644a6190c
7
- data.tar.gz: e3468ec19dc532b3a6092084f9e7bb07d20a78072679f86976a946be4dd2ad439d4934add1168d2338a28b450659910f6ccd8a06c425ce3f72214c326a72f316
6
+ metadata.gz: f3761790ed1527d238b1e28b74ed0d696a4bbe158d27fb4627a8e98258764278de133390ac4575705aec1bfdd89c684dd8241367709bde4ebf683e118fe05063
7
+ data.tar.gz: 638b9ae5eb1dd64ab0ec9383c80744b23e3a709bdbad9e4f2bdfd1b39fa65fb2150cf630f7271daece97694c3cb40575e0edb3fcd66a3027dfa58d3b2a28504e
data/README.md CHANGED
@@ -27,6 +27,19 @@ HubKernel::Authz.check = ->(person, action, account) { true }
27
27
  HubKernel::Context.scope = ->(account, &call) { call.call }
28
28
  ```
29
29
 
30
+ A scope that declares a `person:` keyword is given the calling person as well as the account:
31
+
32
+ ```ruby
33
+ HubKernel::Context.scope = ->(account, person:, &call) { call.call }
34
+ ```
35
+
36
+ A hub method called by name reads the person who made the call, and reading it outside a call
37
+ gives `nil`:
38
+
39
+ ```ruby
40
+ HubKernel::Context.person
41
+ ```
42
+
30
43
  An interface gem lists the methods a person may call on an account, and calls one by name:
31
44
 
32
45
  ```ruby
@@ -1,5 +1,15 @@
1
1
  module HubKernel
2
2
  module Context
3
3
  singleton_class.attr_accessor :scope
4
+
5
+ def self.person = Thread.current[:hub_kernel_person]
6
+
7
+ def self.with_person(person)
8
+ previous = self.person
9
+ Thread.current[:hub_kernel_person] = person
10
+ yield
11
+ ensure
12
+ Thread.current[:hub_kernel_person] = previous
13
+ end
4
14
  end
5
15
  end
@@ -46,7 +46,7 @@ module HubKernel
46
46
  exposure = exposed(name) || raise(UnexposedMethodError, "#{exposing_hub} does not expose #{name}")
47
47
  refuse_unless_allowed(exposure, person, account)
48
48
  refuse_missing_values(exposure, values)
49
- within_account(account) { public_send(exposure.name, **values.slice(*exposure.takes)) }
49
+ Context.with_person(person) { within_account(account, person) { public_send(exposure.name, **values.slice(*exposure.takes)) } }
50
50
  end
51
51
 
52
52
  def exposure_problems
@@ -83,12 +83,15 @@ module HubKernel
83
83
  answer
84
84
  end
85
85
 
86
- def within_account(account, &call)
86
+ def within_account(account, person, &call)
87
87
  raise UnwiredPortError, "hub_kernel's account scope is not filled" unless Context.scope
88
+ return Context.scope.call(account, person: person, &call) if scope_takes_person?
88
89
 
89
90
  Context.scope.call(account, &call)
90
91
  end
91
92
 
93
+ def scope_takes_person? = (Context.scope.respond_to?(:parameters) ? Context.scope : Context.scope.method(:call)).parameters.any? { |kind, name| %i[key keyreq].include?(kind) && name == :person }
94
+
92
95
  def refuse_missing_values(exposure, values)
93
96
  missing = keywords(exposure, :keyreq) - values.keys
94
97
  raise MissingArgumentError, "Give #{missing.join(", ")}" if missing.any?
@@ -1,5 +1,5 @@
1
1
  module HubKernel
2
2
  module Interface
3
- VERSION = "0.10.0"
3
+ VERSION = "0.11.0"
4
4
  end
5
5
  end
@@ -20,6 +20,7 @@ The contract between a hub and the interfaces that call it from outside the app.
20
20
  - `exposures_for` — returns the declarations the permission check lets a person call on an account.
21
21
  - `allows?` — asks the permission check whether a person may call one exposed method on an account, returning `true` or `false`.
22
22
  - `call_exposed` — calls an exposed method by name with a person, an account and its values, behind the permission check and inside the account scope, and returns the method's value.
23
+ - `HubKernel::Context.person` — returns the person making the call by name, readable from inside a hub method, and `nil` outside a call.
23
24
  - `exposure_problems` — returns one message per declaration the hub has no method for, or whose values do not match the method's keywords.
24
25
  - `HubKernel::Interface.find` — returns the hub served at a name, or `nil`.
25
26
  - `HubKernel::Interface.served` — returns a hash of every served name to its hub.
@@ -67,6 +67,7 @@ The contract between an app's hubs and the interfaces that call them from outsid
67
67
  - It must call the block exactly once, inside the scope.
68
68
  - It must return the block's value, since that value is what the call by name returns.
69
69
  - If the app has no account scoping, ask before using `->(account, &call) { call.call }`.
70
+ - A scope that also needs the calling person declares a `person:` keyword and is given both: `HubKernel::Context.scope = ->(account, person:, &call) { call.call }`. A scope taking only the account keeps working.
70
71
 
71
72
  6. Run `bin/rails runner 'p HubKernel::Interface.hubs, HubKernel::Authz.check, HubKernel::Context.scope'` and confirm it prints the hub list and two callables, none of them empty or `nil`.
72
73
 
@@ -15,6 +15,7 @@ develop:
15
15
  - allows?
16
16
  - call_exposed
17
17
  - exposure_problems
18
+ - HubKernel::Context.person
18
19
  - HubKernel::Interface.find
19
20
  - HubKernel::Interface.served
20
21
  - HubKernel::Interface.check!
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hub_kernel-interface
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tylercschneider