trailblazer-endpoint 0.0.3 → 0.0.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 +4 -4
- data/.gitignore +16 -0
- data/Appraisals +5 -0
- data/CHANGES.md +27 -0
- data/README.md +40 -5
- data/Rakefile +7 -1
- data/gemfiles/rails_app.gemfile +12 -0
- data/lib/trailblazer/endpoint.rb +50 -14
- data/lib/trailblazer/endpoint/adapter.rb +30 -121
- data/lib/trailblazer/endpoint/builder.rb +1 -1
- data/lib/trailblazer/endpoint/controller.rb +217 -1
- data/lib/trailblazer/endpoint/dsl.rb +8 -3
- data/lib/trailblazer/endpoint/options.rb +16 -69
- data/lib/trailblazer/endpoint/protocol.rb +7 -11
- data/lib/trailblazer/endpoint/protocol/cipher.rb +27 -0
- data/lib/trailblazer/endpoint/protocol/controller.rb +102 -0
- data/lib/trailblazer/endpoint/protocol/find_process_model.rb +15 -0
- data/lib/trailblazer/endpoint/version.rb +1 -1
- data/test/adapter/api_test.rb +6 -11
- data/test/adapter/web_test.rb +2 -5
- data/test/config_test.rb +25 -0
- data/test/docs/controller_test.rb +220 -73
- data/test/endpoint_test.rb +1 -1
- data/test/rails-app/.gitignore +8 -2
- data/test/rails-app/.ruby-version +1 -0
- data/test/rails-app/Gemfile +21 -9
- data/test/rails-app/Gemfile.lock +174 -118
- data/test/rails-app/app/concepts/app/api/v1/representer/errors.rb +16 -0
- data/test/rails-app/app/concepts/auth/jwt.rb +35 -0
- data/test/rails-app/app/concepts/auth/operation/authenticate.rb +32 -0
- data/test/rails-app/app/concepts/auth/operation/policy.rb +9 -0
- data/test/rails-app/app/concepts/song/cell/create.rb +4 -0
- data/test/rails-app/app/concepts/song/cell/new.rb +4 -0
- data/test/rails-app/app/concepts/song/operation/create.rb +17 -0
- data/test/rails-app/app/concepts/song/operation/show.rb +10 -0
- data/test/rails-app/app/concepts/song/representer.rb +5 -0
- data/test/rails-app/app/concepts/song/view/create.erb +1 -0
- data/test/rails-app/app/concepts/song/view/new.erb +1 -0
- data/test/rails-app/app/controllers/api/v1/songs_controller.rb +41 -0
- data/test/rails-app/app/controllers/application_controller.rb +8 -1
- data/test/rails-app/app/controllers/application_controller/api.rb +107 -0
- data/test/rails-app/app/controllers/application_controller/web.rb +46 -0
- data/test/rails-app/app/controllers/auth_controller.rb +44 -0
- data/test/rails-app/app/controllers/home_controller.rb +5 -0
- data/test/rails-app/app/controllers/songs_controller.rb +254 -13
- data/test/rails-app/app/models/song.rb +6 -0
- data/test/rails-app/app/models/user.rb +7 -0
- data/test/rails-app/bin/bundle +114 -0
- data/test/rails-app/bin/rails +4 -0
- data/test/rails-app/bin/rake +4 -0
- data/test/rails-app/bin/setup +33 -0
- data/test/rails-app/config/application.rb +26 -3
- data/test/rails-app/config/credentials.yml.enc +1 -0
- data/test/rails-app/config/database.yml +2 -2
- data/test/rails-app/config/environments/development.rb +7 -17
- data/test/rails-app/config/environments/production.rb +28 -23
- data/test/rails-app/config/environments/test.rb +10 -12
- data/test/rails-app/config/initializers/application_controller_renderer.rb +6 -4
- data/test/rails-app/config/initializers/cors.rb +16 -0
- data/test/rails-app/config/initializers/trailblazer.rb +2 -0
- data/test/rails-app/config/locales/en.yml +11 -1
- data/test/rails-app/config/master.key +1 -0
- data/test/rails-app/config/routes.rb +27 -4
- data/test/rails-app/db/schema.rb +15 -0
- data/test/rails-app/test/controllers/api_songs_controller_test.rb +87 -0
- data/test/rails-app/test/controllers/songs_controller_test.rb +152 -145
- data/test/rails-app/test/test_helper.rb +7 -1
- data/test/test_helper.rb +0 -2
- data/trailblazer-endpoint.gemspec +2 -1
- metadata +69 -24
- data/test/rails-app/config/initializers/cookies_serializer.rb +0 -5
- data/test/rails-app/config/initializers/new_framework_defaults.rb +0 -24
- data/test/rails-app/config/initializers/session_store.rb +0 -3
- data/test/rails-app/config/secrets.yml +0 -22
- data/test/rails-app/test/helpers/.keep +0 -0
- data/test/rails-app/test/integration/.keep +0 -0
- data/test/rails-app/test/mailers/.keep +0 -0
- data/test/rails-app/vendor/assets/javascripts/.keep +0 -0
- data/test/rails-app/vendor/assets/stylesheets/.keep +0 -0
@@ -35,7 +35,7 @@ module Trailblazer
|
|
35
35
|
def endpoint_for(id:, builder:, default_options:, **config)
|
36
36
|
options = build_options_for(builder: builder, **config)
|
37
37
|
|
38
|
-
return id, Trailblazer::Endpoint.build(default_options.merge(options[:options_for_build])
|
38
|
+
return id, Trailblazer::Endpoint.build(default_options.merge(options[:options_for_build]).merge(protocol_block: options[:protocol_block]))
|
39
39
|
end
|
40
40
|
|
41
41
|
# {dsl_options} being something like
|
@@ -1,7 +1,223 @@
|
|
1
1
|
module Trailblazer
|
2
2
|
class Endpoint
|
3
3
|
module Controller
|
4
|
+
def self.extended(extended)
|
5
|
+
extended.extend Trailblazer::Endpoint::Options::DSL # ::directive
|
6
|
+
extended.extend Trailblazer::Endpoint::Options::DSL::Inherit
|
7
|
+
extended.extend Trailblazer::Endpoint::Options # ::options_for
|
8
|
+
extended.extend DSL::Endpoint
|
4
9
|
|
5
|
-
|
10
|
+
extended.include InstanceMethods # {#endpoint_for}
|
11
|
+
|
12
|
+
# DISCUSS: hmm
|
13
|
+
extended.directive :generic_options, ->(*) { Hash.new } # for Controller::endpoint
|
14
|
+
extended.directive :options_for_flow_options, ->(*) { Hash.new }
|
15
|
+
extended.directive :options_for_endpoint, ->(*) { Hash.new }
|
16
|
+
extended.directive :options_for_domain_ctx, ->(*) { Hash.new }
|
17
|
+
end
|
18
|
+
|
19
|
+
# @experimental
|
20
|
+
# TODO: test application_controller with and without dsl/api
|
21
|
+
|
22
|
+
def self.module(framework: :rails, api: false, dsl: false, application_controller: false)
|
23
|
+
if application_controller && !api && !dsl # FIXME: not tested! this is useful for an actual AppController with block_options or flow_options settings, "globally"
|
24
|
+
Module.new do
|
25
|
+
def self.included(includer)
|
26
|
+
includer.extend(Controller) # only ::directive and friends.
|
27
|
+
end
|
28
|
+
end
|
29
|
+
elsif api
|
30
|
+
Module.new do
|
31
|
+
@application_controller = application_controller
|
32
|
+
def self.included(includer)
|
33
|
+
if @application_controller
|
34
|
+
includer.extend Controller
|
35
|
+
end
|
36
|
+
includer.include(InstanceMethods::API)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
elsif dsl
|
40
|
+
Module.new do
|
41
|
+
@application_controller = application_controller
|
42
|
+
def self.included(includer)
|
43
|
+
if @application_controller
|
44
|
+
includer.extend Controller
|
45
|
+
end
|
46
|
+
includer.include Trailblazer::Endpoint::Controller::InstanceMethods::DSL
|
47
|
+
includer.include Trailblazer::Endpoint::Controller::Rails
|
48
|
+
includer.extend Trailblazer::Endpoint::Controller::Rails::DefaultBlocks
|
49
|
+
includer.extend Trailblazer::Endpoint::Controller::Rails::DefaultParams
|
50
|
+
includer.include Trailblazer::Endpoint::Controller::Rails::Process
|
51
|
+
end
|
52
|
+
end # Module
|
53
|
+
else
|
54
|
+
raise
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module Rails
|
59
|
+
module Process
|
60
|
+
def send_action(action_name)
|
61
|
+
puts "@@@@@>>>>>>> #{action_name.inspect}"
|
62
|
+
|
63
|
+
dsl = send(action_name) # call the actual controller action.
|
64
|
+
|
65
|
+
options, block_options = dsl.to_args(self.class.options_for(:options_for_block_options, controller: self)) # {success_block:, failure_block:, protocol_failure_block:}
|
66
|
+
# now we know the authorative blocks
|
67
|
+
|
68
|
+
Controller.advance_endpoint_for_controller(**options, block_options: block_options, config_source: self.class, controller: self)
|
69
|
+
end
|
70
|
+
|
71
|
+
end # Process
|
72
|
+
|
73
|
+
# The three default handlers for {Endpoint::with_or_etc}
|
74
|
+
# @experimental
|
75
|
+
module DefaultBlocks
|
76
|
+
def self.extended(extended)
|
77
|
+
extended.directive :options_for_block_options, Controller.method(:options_for_block_options)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
# @experimental
|
81
|
+
module DefaultParams
|
82
|
+
def self.extended(extended)
|
83
|
+
extended.directive :options_for_domain_ctx, ->(ctx, controller:, **) { {params: controller.params} }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end # Rails
|
88
|
+
|
89
|
+
module DSL
|
90
|
+
module Endpoint
|
91
|
+
def self.extended(extended)
|
92
|
+
extended.directive(:endpoints, ->(*) { {} })
|
93
|
+
end
|
94
|
+
|
95
|
+
# Builds and registers an endpoint in a controller class.
|
96
|
+
def endpoint(name, **options, &block)
|
97
|
+
options = options.merge(protocol_block: block) if block_given?
|
98
|
+
|
99
|
+
return generic_endpoint_config(**name, **options) if name.is_a?(Hash)
|
100
|
+
build_endpoint(name, **options)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Configures generic {:adapter}, {:protocol}, etc.
|
104
|
+
def generic_endpoint_config(**options)
|
105
|
+
self.singleton_class.define_method :generic_options do |ctx,**|
|
106
|
+
{
|
107
|
+
**options
|
108
|
+
}
|
109
|
+
end
|
110
|
+
|
111
|
+
directive :generic_options, method(:generic_options) # FIXME: do we need this?
|
112
|
+
end
|
113
|
+
|
114
|
+
def build_endpoint(name, domain_activity: name, **options)
|
115
|
+
build_options = options_for(:generic_options, {}).merge(domain_activity: domain_activity, **options) # DISCUSS: why don't we add this as another directive option/step?
|
116
|
+
|
117
|
+
endpoint = Trailblazer::Endpoint.build(build_options)
|
118
|
+
|
119
|
+
directive :endpoints, ->(*) { {name.to_s => endpoint} }
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
module InstanceMethods
|
126
|
+
|
127
|
+
def endpoint_for(name, config_source: self.class)
|
128
|
+
config_source.options_for(:endpoints, {}).fetch(name.to_s) # TODO: test non-existant endpoint
|
129
|
+
end
|
130
|
+
|
131
|
+
module DSL
|
132
|
+
def endpoint(name, **action_options, &block)
|
133
|
+
action_options = {controller: self}.merge(action_options) # FIXME: redundant with {API#endpoint}
|
134
|
+
|
135
|
+
endpoint = endpoint_for(name)
|
136
|
+
|
137
|
+
invoke_endpoint_with_dsl(endpoint: endpoint, **action_options, &block)
|
138
|
+
end
|
139
|
+
|
140
|
+
def invoke_endpoint_with_dsl(options, &block)
|
141
|
+
_dsl = Trailblazer::Endpoint::DSL::Runtime.new(options, block) # provides #Or etc, is returned to {Controller#call}
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
module API
|
146
|
+
def endpoint(name, config_source: self.class, **action_options)
|
147
|
+
endpoint = endpoint_for(name, config_source: config_source)
|
148
|
+
|
149
|
+
action_options = {controller: self}.merge(action_options) # FIXME: redundant with {InstanceMethods#endpoint}
|
150
|
+
|
151
|
+
block_options = config_source.options_for(:options_for_block_options, **action_options)
|
152
|
+
block_options = Trailblazer::Endpoint::Options.merge_with(action_options, block_options)
|
153
|
+
|
154
|
+
signal, (ctx, _) = Trailblazer::Endpoint::Controller.advance_endpoint_for_controller(
|
155
|
+
endpoint: endpoint,
|
156
|
+
block_options: block_options,
|
157
|
+
config_source: config_source,
|
158
|
+
**action_options
|
159
|
+
)
|
160
|
+
|
161
|
+
ctx
|
162
|
+
end
|
163
|
+
end # API
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
def self.advance_endpoint_for_controller(endpoint:, block_options:, **action_options)
|
168
|
+
domain_ctx, endpoint_options, flow_options = compile_options_for_controller(**action_options) # controller-specific, get from directives.
|
169
|
+
|
170
|
+
endpoint_options = endpoint_options.merge(action_options) # DISCUSS
|
171
|
+
|
172
|
+
Endpoint::Controller.advance_endpoint(
|
173
|
+
endpoint: endpoint,
|
174
|
+
block_options: block_options,
|
175
|
+
|
176
|
+
domain_ctx: domain_ctx,
|
177
|
+
endpoint_options: endpoint_options,
|
178
|
+
flow_options: flow_options,
|
179
|
+
)
|
180
|
+
end
|
181
|
+
|
182
|
+
def self.compile_options_for_controller(options_for_domain_ctx: nil, config_source:, **action_options)
|
183
|
+
flow_options = config_source.options_for(:options_for_flow_options, **action_options)
|
184
|
+
endpoint_options = config_source.options_for(:options_for_endpoint, **action_options) # "class level"
|
185
|
+
domain_ctx = options_for_domain_ctx || config_source.options_for(:options_for_domain_ctx, **action_options)
|
186
|
+
|
187
|
+
return domain_ctx, endpoint_options, flow_options
|
188
|
+
end
|
189
|
+
|
190
|
+
# Ultimate low-level entry point.
|
191
|
+
# Remember that you don't _have_ to use Endpoint.with_or_etc to invoke an endpoint.
|
192
|
+
def self.advance_endpoint(endpoint:, block_options:, domain_ctx:, endpoint_options:, flow_options:)
|
193
|
+
|
194
|
+
# build Context(ctx),
|
195
|
+
args, _ = Trailblazer::Endpoint.arguments_for(
|
196
|
+
domain_ctx: domain_ctx,
|
197
|
+
flow_options: flow_options,
|
198
|
+
**endpoint_options,
|
199
|
+
)
|
200
|
+
|
201
|
+
signal, (ctx, _ ) = Trailblazer::Endpoint.with_or_etc(
|
202
|
+
endpoint,
|
203
|
+
args, # [ctx, flow_options]
|
204
|
+
|
205
|
+
**block_options,
|
206
|
+
# success_block: success_block,
|
207
|
+
# failure_block: failure_block,
|
208
|
+
# protocol_failure_block: protocol_failure_block,
|
209
|
+
)
|
210
|
+
end
|
211
|
+
|
212
|
+
# Default blocks for the {Adapter}.
|
213
|
+
def self.options_for_block_options(ctx, controller:, **)
|
214
|
+
{
|
215
|
+
success_block: ->(ctx, endpoint_ctx:, **) { controller.head 200 },
|
216
|
+
failure_block: ->(ctx, **) { controller.head 422 },
|
217
|
+
protocol_failure_block: ->(ctx, endpoint_ctx:, **) { controller.head endpoint_ctx[:status] }
|
218
|
+
}
|
219
|
+
end
|
220
|
+
|
221
|
+
end # Controller
|
6
222
|
end
|
7
223
|
end
|
@@ -2,7 +2,7 @@ module Trailblazer
|
|
2
2
|
class Endpoint
|
3
3
|
module DSL
|
4
4
|
# Run before the endpoint is invoked. This collects the blocks from the controller.
|
5
|
-
class Runtime < Struct.new(:
|
5
|
+
class Runtime < Struct.new(:options, :success_block, :failure_block, :protocol_failure_block)
|
6
6
|
|
7
7
|
def failure(&block)
|
8
8
|
self.failure_block = block
|
@@ -17,8 +17,13 @@ module Trailblazer
|
|
17
17
|
end
|
18
18
|
|
19
19
|
# #call
|
20
|
-
def to_args
|
21
|
-
return
|
20
|
+
def to_args(default_block_options)
|
21
|
+
return options,
|
22
|
+
default_block_options.merge( # this adds :invoke.
|
23
|
+
success_block: success_block || default_block_options[:success_block],
|
24
|
+
failure_block: failure_block || default_block_options[:failure_block],
|
25
|
+
protocol_failure_block: protocol_failure_block || default_block_options[:protocol_failure_block]
|
26
|
+
)
|
22
27
|
end
|
23
28
|
end
|
24
29
|
end
|
@@ -1,28 +1,7 @@
|
|
1
|
-
#
|
1
|
+
# DISCUSS: the generic inheritance/Options logic might be extracted to trailblazer-config or something.
|
2
|
+
# it is completely independent and could be helpful for many other configurations.
|
2
3
|
module Trailblazer
|
3
4
|
class Endpoint
|
4
|
-
def self.Normalizer(target:, options:)
|
5
|
-
normalizer = Class.new(Trailblazer::Activity::Railway) do
|
6
|
-
# inject an empty {} for all options.
|
7
|
-
# options.collect do |(method_name => option)|
|
8
|
-
# step Normalizer.DefaultToEmptyHash(config_name), id: :"default_#{config_name}"
|
9
|
-
# end
|
10
|
-
end
|
11
|
-
|
12
|
-
Normalizer::State.new(normalizer, options)
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.Normalizer___(options, base_class: Trailblazer::Activity::Path)
|
16
|
-
normalizer = Class.new(base_class) do
|
17
|
-
# inject an empty {} for all options.
|
18
|
-
# options.collect do |(method_name => option)|
|
19
|
-
# step Normalizer.DefaultToEmptyHash(config_name), id: :"default_#{config_name}"
|
20
|
-
# end
|
21
|
-
end
|
22
|
-
|
23
|
-
Normalizer.add(normalizer, nil, options)
|
24
|
-
end
|
25
|
-
|
26
5
|
module Options
|
27
6
|
module DSL
|
28
7
|
def directive(directive_name, *callables, inherit: superclass)
|
@@ -35,6 +14,7 @@ module Trailblazer
|
|
35
14
|
@normalizers[directive_name] = Trailblazer::Endpoint::Normalizer.Options(directive_name, *callables, **options) # DISCUSS: allow multiple calls?
|
36
15
|
end
|
37
16
|
|
17
|
+
# Called in {Endpoint::Controller}.
|
38
18
|
def self.extended(extended) # TODO: let's hope this is only called once per hierachy :)
|
39
19
|
extended.instance_variable_set(:@normalizers, {})
|
40
20
|
end
|
@@ -49,16 +29,25 @@ module Trailblazer
|
|
49
29
|
end
|
50
30
|
|
51
31
|
def options_for(directive_name, runtime_options)
|
52
|
-
normalizer = @normalizers
|
32
|
+
normalizer = @normalizers.fetch(directive_name)
|
53
33
|
|
54
|
-
ctx = Trailblazer::Context
|
34
|
+
ctx = Trailblazer::Context(runtime_options, {})
|
55
35
|
|
56
|
-
signal, (ctx, ) = Trailblazer::Developer.wtf?(normalizer, [ctx])
|
36
|
+
# signal, (ctx, ) = Trailblazer::Developer.wtf?(normalizer, [ctx])
|
37
|
+
signal, (ctx, ) = Trailblazer::Activity::TaskWrap.invoke(normalizer, [ctx])
|
57
38
|
|
58
39
|
_, options = ctx.decompose
|
59
40
|
options
|
60
41
|
end
|
61
|
-
|
42
|
+
|
43
|
+
|
44
|
+
# Merge {merged} into {hash}, but only keys that exist in {hash}.
|
45
|
+
def self.merge_with(merged, hash)
|
46
|
+
keys = hash.keys
|
47
|
+
merged = keys.collect { |key| merged.key?(key) ? [key, merged[key]] : nil }.compact.to_h
|
48
|
+
hash.merge(merged)
|
49
|
+
end
|
50
|
+
end # Options
|
62
51
|
|
63
52
|
module Normalizer
|
64
53
|
def self.Options(directive_name, *callables, base_class: Trailblazer::Activity::Path)
|
@@ -78,29 +67,6 @@ module Trailblazer
|
|
78
67
|
target.instance_variable_set(:@config, config)
|
79
68
|
end
|
80
69
|
|
81
|
-
class State < Module
|
82
|
-
def initialize(normalizer, config)
|
83
|
-
@normalizer = normalizer
|
84
|
-
@config = config
|
85
|
-
end
|
86
|
-
|
87
|
-
# called once when extended in {ApplicationController}.
|
88
|
-
def extended(extended)
|
89
|
-
super
|
90
|
-
|
91
|
-
extended.extend(Inherited)
|
92
|
-
Normalizer.add_normalizer!(extended, @normalizer, @config)
|
93
|
-
end
|
94
|
-
|
95
|
-
end
|
96
|
-
module Inherited
|
97
|
-
def inherited(subclass)
|
98
|
-
super
|
99
|
-
|
100
|
-
Normalizer.add_normalizer!(subclass, @normalizer, @config)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
70
|
def self.add(normalizer, directive_name, options)
|
105
71
|
Class.new(normalizer) do
|
106
72
|
options.collect do |callable|
|
@@ -109,16 +75,6 @@ module Trailblazer
|
|
109
75
|
end
|
110
76
|
end
|
111
77
|
|
112
|
-
def self.CallDirectiveMethod(target, config_name)
|
113
|
-
->((ctx, flow_options), *) {
|
114
|
-
config = target.send(config_name, ctx, **ctx) # e.g. ApplicationController.options_for_endpoint
|
115
|
-
|
116
|
-
ctx[config_name] = ctx[config_name].merge(config)
|
117
|
-
|
118
|
-
return Trailblazer::Activity::Right, [ctx, flow_options]
|
119
|
-
}
|
120
|
-
end
|
121
|
-
|
122
78
|
def self.CallDirective(callable, option_name)
|
123
79
|
->((ctx, flow_options), *) {
|
124
80
|
config = callable.(ctx, **ctx) # e.g. ApplicationController.options_for_endpoint
|
@@ -132,14 +88,5 @@ module Trailblazer
|
|
132
88
|
}
|
133
89
|
end
|
134
90
|
end # Normalizer
|
135
|
-
|
136
|
-
module Controller
|
137
|
-
def self.extended(extended)
|
138
|
-
extended.extend Trailblazer::Endpoint::Options::DSL
|
139
|
-
extended.extend Trailblazer::Endpoint::Options::DSL::Inherit
|
140
|
-
extended.extend Trailblazer::Endpoint::Options
|
141
|
-
end
|
142
|
-
end # Controller
|
143
|
-
|
144
91
|
end
|
145
92
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "trailblazer/activity/dsl/linear"
|
2
|
+
|
1
3
|
module Trailblazer
|
2
4
|
class Endpoint
|
3
5
|
# The {Protocol} implements auth*, and calls the domain OP/WF.
|
@@ -16,18 +18,13 @@ module Trailblazer
|
|
16
18
|
class Noop < Trailblazer::Activity::Railway
|
17
19
|
end
|
18
20
|
|
19
|
-
class Failure < Trailblazer::Activity::End # DISCUSS: move to Act::Railway?
|
20
|
-
# class Authentication < Failure
|
21
|
-
# end
|
22
|
-
end
|
23
|
-
|
24
21
|
def self._Path(semantic:, &block) # DISCUSS: the problem with Path currently is https://github.com/trailblazer/trailblazer-activity-dsl-linear/issues/27
|
25
|
-
Path(track_color: semantic, end_id: "End.#{semantic}", end_task:
|
22
|
+
Path(track_color: semantic, end_id: "End.#{semantic}", end_task: Activity::End.new(semantic: semantic), &block)
|
26
23
|
end
|
27
24
|
|
28
25
|
step :authenticate, Output(:failure) => _Path(semantic: :not_authenticated) do
|
29
26
|
# step :handle_not_authenticated
|
30
|
-
|
27
|
+
end
|
31
28
|
|
32
29
|
step :policy, Output(:failure) => _Path(semantic: :not_authorized) do # user from cookie, etc
|
33
30
|
# step :handle_not_authorized
|
@@ -43,8 +40,8 @@ module Trailblazer
|
|
43
40
|
# termini for the Adapter this is the only way to get it working right now.
|
44
41
|
# FIXME: is this really the only way to add an {End} to all this?
|
45
42
|
@state.update_sequence do |sequence:, **|
|
46
|
-
sequence = Activity::Path::DSL.append_end(sequence, task:
|
47
|
-
sequence = Activity::Path::DSL.append_end(sequence, task:
|
43
|
+
sequence = Activity::Path::DSL.append_end(sequence, task: Activity::End.new(semantic: :not_found), magnetic_to: :not_found, id: "End.not_found")
|
44
|
+
sequence = Activity::Path::DSL.append_end(sequence, task: Activity::End.new(semantic: :invalid_data), magnetic_to: :invalid_data, id: "End.invalid_data")
|
48
45
|
|
49
46
|
recompile_activity!(sequence)
|
50
47
|
|
@@ -116,7 +113,6 @@ module Trailblazer
|
|
116
113
|
[[Trailblazer::Activity::TaskWrap::Pipeline.method(:insert_after), "task_wrap.call_task", ["endpoint.end_signal", method(:terminus_handler)]]]
|
117
114
|
end
|
118
115
|
end
|
119
|
-
|
120
|
-
end
|
116
|
+
end # Protocol
|
121
117
|
end
|
122
118
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "openssl"
|
2
|
+
|
3
|
+
module Trailblazer
|
4
|
+
class Endpoint::Protocol
|
5
|
+
module Controller
|
6
|
+
module Cipher # FIXME: copied from Tyrant!
|
7
|
+
module_function
|
8
|
+
|
9
|
+
def encrypt_value(ctx, value:, cipher_key:, **)
|
10
|
+
cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').encrypt
|
11
|
+
cipher.key = Digest::SHA1.hexdigest(cipher_key)[0..23] # ArgumentError: key must be 24 bytes
|
12
|
+
s = cipher.update(value) + cipher.final
|
13
|
+
|
14
|
+
ctx[:encrypted_value] = s.unpack('H*')[0].upcase
|
15
|
+
end
|
16
|
+
|
17
|
+
def decrypt_value(ctx, encrypted_value:, cipher_key:, **)
|
18
|
+
cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').decrypt
|
19
|
+
cipher.key = Digest::SHA1.hexdigest(cipher_key)[0..23]
|
20
|
+
s = [encrypted_value].pack("H*").unpack("C*").pack("c*")
|
21
|
+
|
22
|
+
ctx[:decrypted_value] = cipher.update(s) + cipher.final
|
23
|
+
end
|
24
|
+
end # Cipher
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|