yes-command-api 1.3.0 → 2.3.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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f5858eb1ab299af656214dea454421e4f12984c247f651c3c49d39dde342a3c2
|
|
4
|
+
data.tar.gz: 0ea41eff2118ef258f8c8d8cc2b53ec96b5a713aba7f8ad728aaa43f60909a4d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ca81f8a20dbf7bfa0660cf29d20ab5f1d819f2ac282d2ff8906e01fcaf5057a7bad723c165ed9e6a71025d5dd24b877789ef1489aff393076ccbaabaafcc476e
|
|
7
|
+
data.tar.gz: be67f2f36b7cbf9f1078dfcb3fa2f47e4606890eef3333e9a88d5ee95d3c39dccde6758ea6049f06cbc8c1f8c53d6546d8ff09aa3b43dc2bd4f057fafb1ffcc4
|
|
@@ -100,10 +100,21 @@ module Yes
|
|
|
100
100
|
render json: { error: }, status: :unprocessable_content
|
|
101
101
|
end
|
|
102
102
|
|
|
103
|
+
# Unwraps both legacy stateless `Yes::Core::Commands::Group` and
|
|
104
|
+
# the new aggregate-DSL `Yes::Core::Commands::CommandGroup` into
|
|
105
|
+
# their sub-commands for batch authorization + validation. This
|
|
106
|
+
# is used ONLY by `BatchAuthorizer`/`BatchValidator`; the wrapped
|
|
107
|
+
# originals are still passed to `command_bus.call` so the
|
|
108
|
+
# Processor dispatches groups as single atomic units.
|
|
103
109
|
def expand_commands(deserialize_commands)
|
|
104
|
-
deserialize_commands.
|
|
105
|
-
|
|
106
|
-
|
|
110
|
+
deserialize_commands.flat_map do |command|
|
|
111
|
+
case command
|
|
112
|
+
when Yes::Core::Commands::Group, Yes::Core::Commands::CommandGroup
|
|
113
|
+
command.commands
|
|
114
|
+
else
|
|
115
|
+
command
|
|
116
|
+
end
|
|
117
|
+
end
|
|
107
118
|
end
|
|
108
119
|
|
|
109
120
|
def add_metadata(commands)
|
|
@@ -20,11 +20,28 @@ module Yes
|
|
|
20
20
|
# @raise [CommandsNotAuthorized] if any command is not authorized
|
|
21
21
|
# @return [void]
|
|
22
22
|
def call(commands, auth_data)
|
|
23
|
-
unauthorized =
|
|
23
|
+
unauthorized = Yes::Core::Authorization::LookupCache.with_scope do
|
|
24
|
+
authorize_each(commands, auth_data)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
return unless unauthorized.any?
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
trace_error('Unauthorized', { unauthorized: unauthorized.to_json })
|
|
30
|
+
raise CommandsNotAuthorized.new(extra: unauthorized)
|
|
31
|
+
end
|
|
32
|
+
otl_trackable :call, Yes::Core::OpenTelemetry::OtlSpan::OtlData.new(span_name: 'Authorize Commands')
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
# Authorizes every command, collecting the ones that were rejected instead
|
|
37
|
+
# of failing on the first rejection, so the caller can report all of them.
|
|
38
|
+
#
|
|
39
|
+
# @param commands [Array<Yes::Core::Command>] commands to authorize
|
|
40
|
+
# @param auth_data [Hash] authorization data
|
|
41
|
+
# @return [Array<Hash>] unauthorized command data
|
|
42
|
+
def authorize_each(commands, auth_data)
|
|
43
|
+
commands.each_with_object([]) do |command, unauthorized|
|
|
44
|
+
authorizer_for(command).call(command, auth_data)
|
|
28
45
|
rescue CommandAuthorizerNotFound
|
|
29
46
|
unauthorized << unauthorized_data(command, 'Not allowed').tap do
|
|
30
47
|
trace_error('Command authorizer not found', { command: command.to_json })
|
|
@@ -34,15 +51,7 @@ module Yes
|
|
|
34
51
|
trace_error('Command not authorized', { command: })
|
|
35
52
|
end
|
|
36
53
|
end
|
|
37
|
-
|
|
38
|
-
return unless unauthorized.any?
|
|
39
|
-
|
|
40
|
-
trace_error('Unauthorized', { unauthorized: unauthorized.to_json })
|
|
41
|
-
raise CommandsNotAuthorized.new(extra: unauthorized)
|
|
42
54
|
end
|
|
43
|
-
otl_trackable :call, Yes::Core::OpenTelemetry::OtlSpan::OtlData.new(span_name: 'Authorize Commands')
|
|
44
|
-
|
|
45
|
-
private
|
|
46
55
|
|
|
47
56
|
# Returns the command authorizer for the given command.
|
|
48
57
|
#
|
|
@@ -47,12 +47,21 @@ module Yes
|
|
|
47
47
|
|
|
48
48
|
private
|
|
49
49
|
|
|
50
|
-
# Resolves the command class name, trying
|
|
50
|
+
# Resolves the command class name, trying (in order):
|
|
51
|
+
# 1. legacy top-level command group: `CommandGroups::<Name>::Command`
|
|
52
|
+
# 2. aggregate-DSL command group: `<Ctx>::<Subj>::CommandGroups::<Name>::Command`
|
|
53
|
+
# 3. V2 command: `<Ctx>::<Subj>::Commands::<Name>::Command`
|
|
54
|
+
# 4. V1 command: `<Ctx>::Commands::<Subj>::<Name>`
|
|
51
55
|
#
|
|
52
56
|
# @param command [Hash] command data
|
|
53
57
|
# @return [String] command class name
|
|
54
58
|
def command_class_name(command)
|
|
55
|
-
[
|
|
59
|
+
[
|
|
60
|
+
command_group_class(command),
|
|
61
|
+
command_group_v2_class(command),
|
|
62
|
+
command_v2_class(command),
|
|
63
|
+
command_class(command)
|
|
64
|
+
].each do |name|
|
|
56
65
|
Kernel.const_get(name)
|
|
57
66
|
return name
|
|
58
67
|
rescue NameError
|
|
@@ -78,13 +87,23 @@ module Yes
|
|
|
78
87
|
"#{command[:context]}::#{command[:subject]}::Commands::#{command[:command]}::Command"
|
|
79
88
|
end
|
|
80
89
|
|
|
81
|
-
# Returns the command group class name
|
|
90
|
+
# Returns the legacy top-level command group class name (used by
|
|
91
|
+
# stateless cross-aggregate groups).
|
|
82
92
|
#
|
|
83
93
|
# @param command [Hash] command data
|
|
84
94
|
# @return [String] command group class name
|
|
85
95
|
def command_group_class(command)
|
|
86
96
|
"CommandGroups::#{command[:command]}::Command"
|
|
87
97
|
end
|
|
98
|
+
|
|
99
|
+
# Returns the aggregate-DSL command group class name (generated
|
|
100
|
+
# by the `command_group` macro inside an aggregate body).
|
|
101
|
+
#
|
|
102
|
+
# @param command [Hash] command data
|
|
103
|
+
# @return [String] command group class name
|
|
104
|
+
def command_group_v2_class(command)
|
|
105
|
+
"#{command[:context]}::#{command[:subject]}::CommandGroups::#{command[:command]}::Command"
|
|
106
|
+
end
|
|
88
107
|
end
|
|
89
108
|
end
|
|
90
109
|
end
|