trailblazer-endpoint 0.0.4 → 0.0.5

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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +16 -0
  3. data/Appraisals +5 -0
  4. data/CHANGES.md +6 -0
  5. data/Rakefile +7 -1
  6. data/gemfiles/rails_app.gemfile +12 -0
  7. data/lib/trailblazer/endpoint.rb +20 -5
  8. data/lib/trailblazer/endpoint/adapter.rb +30 -121
  9. data/lib/trailblazer/endpoint/builder.rb +1 -1
  10. data/lib/trailblazer/endpoint/controller.rb +203 -1
  11. data/lib/trailblazer/endpoint/dsl.rb +6 -3
  12. data/lib/trailblazer/endpoint/options.rb +13 -44
  13. data/lib/trailblazer/endpoint/protocol.rb +5 -8
  14. data/lib/trailblazer/endpoint/version.rb +1 -1
  15. data/test/adapter/api_test.rb +6 -11
  16. data/test/adapter/web_test.rb +2 -5
  17. data/test/config_test.rb +25 -0
  18. data/test/docs/controller_test.rb +160 -73
  19. data/test/endpoint_test.rb +1 -1
  20. data/test/rails-app/.gitignore +8 -2
  21. data/test/rails-app/.ruby-version +1 -0
  22. data/test/rails-app/Gemfile +11 -9
  23. data/test/rails-app/Gemfile.lock +137 -121
  24. data/test/rails-app/app/concepts/app/api/v1/representer/errors.rb +16 -0
  25. data/test/rails-app/app/concepts/auth/jwt.rb +35 -0
  26. data/test/rails-app/app/concepts/auth/operation/authenticate.rb +32 -0
  27. data/test/rails-app/app/concepts/auth/operation/policy.rb +9 -0
  28. data/test/rails-app/app/concepts/song/operation/create.rb +13 -0
  29. data/test/rails-app/app/concepts/song/operation/show.rb +10 -0
  30. data/test/rails-app/app/concepts/song/representer.rb +5 -0
  31. data/test/rails-app/app/controllers/api/v1/songs_controller.rb +35 -0
  32. data/test/rails-app/app/controllers/application_controller.rb +6 -1
  33. data/test/rails-app/app/controllers/application_controller/api.rb +105 -0
  34. data/test/rails-app/app/controllers/application_controller/web.rb +30 -0
  35. data/test/rails-app/app/controllers/songs_controller.rb +15 -17
  36. data/test/rails-app/app/models/song.rb +3 -0
  37. data/test/rails-app/app/models/user.rb +5 -0
  38. data/test/rails-app/bin/bundle +114 -0
  39. data/test/rails-app/bin/rails +4 -0
  40. data/test/rails-app/bin/rake +4 -0
  41. data/test/rails-app/bin/setup +33 -0
  42. data/test/rails-app/config/application.rb +26 -3
  43. data/test/rails-app/config/credentials.yml.enc +1 -0
  44. data/test/rails-app/config/database.yml +2 -2
  45. data/test/rails-app/config/environments/development.rb +7 -17
  46. data/test/rails-app/config/environments/production.rb +28 -23
  47. data/test/rails-app/config/environments/test.rb +8 -12
  48. data/test/rails-app/config/initializers/application_controller_renderer.rb +6 -4
  49. data/test/rails-app/config/initializers/cors.rb +16 -0
  50. data/test/rails-app/config/initializers/trailblazer.rb +2 -0
  51. data/test/rails-app/config/locales/en.yml +11 -1
  52. data/test/rails-app/config/master.key +1 -0
  53. data/test/rails-app/config/routes.rb +8 -3
  54. data/test/rails-app/db/schema.rb +15 -0
  55. data/test/rails-app/test/controllers/api_songs_controller_test.rb +83 -0
  56. data/test/rails-app/test/controllers/songs_controller_test.rb +36 -144
  57. data/test/rails-app/test/test_helper.rb +7 -1
  58. data/test/test_helper.rb +0 -2
  59. data/trailblazer-endpoint.gemspec +1 -0
  60. metadata +52 -21
  61. data/test/rails-app/config/initializers/cookies_serializer.rb +0 -5
  62. data/test/rails-app/config/initializers/new_framework_defaults.rb +0 -24
  63. data/test/rails-app/config/initializers/session_store.rb +0 -3
  64. data/test/rails-app/config/secrets.yml +0 -22
  65. data/test/rails-app/test/helpers/.keep +0 -0
  66. data/test/rails-app/test/integration/.keep +0 -0
  67. data/test/rails-app/test/mailers/.keep +0 -0
  68. data/test/rails-app/vendor/assets/javascripts/.keep +0 -0
  69. data/test/rails-app/vendor/assets/stylesheets/.keep +0 -0
@@ -261,7 +261,7 @@ class EndpointTest < Minitest::Spec
261
261
  class MyApiAdapter < Trailblazer::Endpoint::Adapter::API
262
262
  # example how to add your own step to a certain path
263
263
  # FIXME: :after doesn't work
264
- step :my_401_handler, before: :_401_status, magnetic_to: :_401, Output(:success) => Track(:_401), Output(:failure) => Track(:_401)
264
+ step :my_401_handler, before: :_401_status, magnetic_to: :_401, Output(:success) => Track(:_401)
265
265
 
266
266
  # def render_success(ctx, **)
267
267
  # ctx[:json] = %{#{ctx[:representer]}.new(#{ctx[:model]})}
@@ -10,6 +10,7 @@
10
10
  # Ignore the default SQLite database.
11
11
  /db/*.sqlite3
12
12
  /db/*.sqlite3-journal
13
+ /db/*.sqlite3-*
13
14
 
14
15
  # Ignore all logfiles and tempfiles.
15
16
  /log/*
@@ -17,5 +18,10 @@
17
18
  !/log/.keep
18
19
  !/tmp/.keep
19
20
 
20
- # Ignore Byebug command history file.
21
- .byebug_history
21
+ # Ignore pidfiles, but keep the directory.
22
+ /tmp/pids/*
23
+ !/tmp/pids/
24
+ !/tmp/pids/.keep
25
+
26
+ # Ignore master key for decrypting credentials and more.
27
+ # /config/master.key
@@ -0,0 +1 @@
1
+ ruby-2.5.1
@@ -1,17 +1,19 @@
1
1
  source 'https://rubygems.org'
2
-
2
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
3
3
 
4
4
  # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
5
- gem 'rails', '~> 5.0.0', '>= 5.0.0.1'
5
+ gem 'rails', '~> 6.0.3', '>= 6.0.3.1'
6
6
  # Use sqlite3 as the database for Active Record
7
- gem 'sqlite3'
7
+ gem 'sqlite3', '~> 1.4'
8
+ # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
9
+ # gem 'jbuilder', '~> 2.7'
10
+ # Use Active Model has_secure_password
11
+ # gem 'bcrypt', '~> 3.1.7'
8
12
 
9
- # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
10
- gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
13
+ # Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
14
+ # gem 'rack-cors'
11
15
 
16
+ gem "trailblazer-operation"
12
17
  gem "trailblazer-endpoint", path: "../../."
13
- gem "trailblazer", path: "../../../trailblazer"
14
- gem "trailblazer-operation", path: "../../../operation"
15
- # gem "trailblazer-rails"
16
-
18
+ gem "jwt"
17
19
  gem "multi_json"
@@ -1,157 +1,173 @@
1
1
  PATH
2
- remote: ../../../operation
2
+ remote: ../..
3
3
  specs:
4
- trailblazer-operation (0.0.6)
5
- declarative
6
- pipetree (>= 0.0.4, < 0.1.0)
7
- uber (>= 0.1.0, < 0.2.0)
8
-
9
- PATH
10
- remote: ../../../trailblazer
11
- specs:
12
- trailblazer (2.0.0.beta1)
13
- declarative
14
- reform (>= 2.2.0, < 3.0.0)
15
- trailblazer-operation
16
- uber (>= 0.1.0, < 0.2.0)
17
-
18
- PATH
19
- remote: ../../.
20
- specs:
21
- trailblazer-endpoint (0.0.1)
22
- dry-matcher
4
+ trailblazer-endpoint (0.0.4)
5
+ trailblazer-activity-dsl-linear (>= 0.3.0, < 0.4.0)
23
6
 
24
7
  GEM
25
8
  remote: https://rubygems.org/
26
9
  specs:
27
- actioncable (5.0.0.1)
28
- actionpack (= 5.0.0.1)
29
- nio4r (~> 1.2)
30
- websocket-driver (~> 0.6.1)
31
- actionmailer (5.0.0.1)
32
- actionpack (= 5.0.0.1)
33
- actionview (= 5.0.0.1)
34
- activejob (= 5.0.0.1)
10
+ actioncable (6.0.3.2)
11
+ actionpack (= 6.0.3.2)
12
+ nio4r (~> 2.0)
13
+ websocket-driver (>= 0.6.1)
14
+ actionmailbox (6.0.3.2)
15
+ actionpack (= 6.0.3.2)
16
+ activejob (= 6.0.3.2)
17
+ activerecord (= 6.0.3.2)
18
+ activestorage (= 6.0.3.2)
19
+ activesupport (= 6.0.3.2)
20
+ mail (>= 2.7.1)
21
+ actionmailer (6.0.3.2)
22
+ actionpack (= 6.0.3.2)
23
+ actionview (= 6.0.3.2)
24
+ activejob (= 6.0.3.2)
35
25
  mail (~> 2.5, >= 2.5.4)
36
26
  rails-dom-testing (~> 2.0)
37
- actionpack (5.0.0.1)
38
- actionview (= 5.0.0.1)
39
- activesupport (= 5.0.0.1)
40
- rack (~> 2.0)
41
- rack-test (~> 0.6.3)
27
+ actionpack (6.0.3.2)
28
+ actionview (= 6.0.3.2)
29
+ activesupport (= 6.0.3.2)
30
+ rack (~> 2.0, >= 2.0.8)
31
+ rack-test (>= 0.6.3)
42
32
  rails-dom-testing (~> 2.0)
43
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
44
- actionview (5.0.0.1)
45
- activesupport (= 5.0.0.1)
33
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
34
+ actiontext (6.0.3.2)
35
+ actionpack (= 6.0.3.2)
36
+ activerecord (= 6.0.3.2)
37
+ activestorage (= 6.0.3.2)
38
+ activesupport (= 6.0.3.2)
39
+ nokogiri (>= 1.8.5)
40
+ actionview (6.0.3.2)
41
+ activesupport (= 6.0.3.2)
46
42
  builder (~> 3.1)
47
- erubis (~> 2.7.0)
43
+ erubi (~> 1.4)
48
44
  rails-dom-testing (~> 2.0)
49
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
50
- activejob (5.0.0.1)
51
- activesupport (= 5.0.0.1)
45
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
46
+ activejob (6.0.3.2)
47
+ activesupport (= 6.0.3.2)
52
48
  globalid (>= 0.3.6)
53
- activemodel (5.0.0.1)
54
- activesupport (= 5.0.0.1)
55
- activerecord (5.0.0.1)
56
- activemodel (= 5.0.0.1)
57
- activesupport (= 5.0.0.1)
58
- arel (~> 7.0)
59
- activesupport (5.0.0.1)
49
+ activemodel (6.0.3.2)
50
+ activesupport (= 6.0.3.2)
51
+ activerecord (6.0.3.2)
52
+ activemodel (= 6.0.3.2)
53
+ activesupport (= 6.0.3.2)
54
+ activestorage (6.0.3.2)
55
+ actionpack (= 6.0.3.2)
56
+ activejob (= 6.0.3.2)
57
+ activerecord (= 6.0.3.2)
58
+ marcel (~> 0.3.1)
59
+ activesupport (6.0.3.2)
60
60
  concurrent-ruby (~> 1.0, >= 1.0.2)
61
- i18n (~> 0.7)
61
+ i18n (>= 0.7, < 2)
62
62
  minitest (~> 5.1)
63
63
  tzinfo (~> 1.1)
64
- arel (7.1.4)
65
- builder (3.2.2)
66
- concurrent-ruby (1.0.2)
67
- declarative (0.0.8)
68
- uber (>= 0.0.15)
69
- disposable (0.3.2)
70
- declarative (>= 0.0.8, < 1.0.0)
71
- representable (>= 2.4.0, <= 3.1.0)
72
- uber
73
- dry-matcher (0.5.0)
74
- erubis (2.7.0)
75
- globalid (0.3.7)
76
- activesupport (>= 4.1.0)
77
- i18n (0.7.0)
78
- loofah (2.0.3)
64
+ zeitwerk (~> 2.2, >= 2.2.2)
65
+ builder (3.2.4)
66
+ concurrent-ruby (1.1.7)
67
+ crass (1.0.6)
68
+ declarative (0.0.20)
69
+ declarative-option (0.1.0)
70
+ erubi (1.9.0)
71
+ globalid (0.4.2)
72
+ activesupport (>= 4.2.0)
73
+ hashie (4.1.0)
74
+ hirb (0.7.3)
75
+ i18n (1.8.5)
76
+ concurrent-ruby (~> 1.0)
77
+ jwt (2.2.2)
78
+ loofah (2.7.0)
79
+ crass (~> 1.0.2)
79
80
  nokogiri (>= 1.5.9)
80
- mail (2.6.4)
81
- mime-types (>= 1.16, < 4)
82
- method_source (0.8.2)
83
- mime-types (3.1)
84
- mime-types-data (~> 3.2015)
85
- mime-types-data (3.2016.0521)
86
- mini_portile2 (2.1.0)
87
- minitest (5.9.1)
88
- multi_json (1.12.1)
89
- nio4r (1.2.1)
90
- nokogiri (1.6.8.1)
91
- mini_portile2 (~> 2.1.0)
92
- pipetree (0.0.4)
93
- rack (2.0.1)
94
- rack-test (0.6.3)
95
- rack (>= 1.0)
96
- rails (5.0.0.1)
97
- actioncable (= 5.0.0.1)
98
- actionmailer (= 5.0.0.1)
99
- actionpack (= 5.0.0.1)
100
- actionview (= 5.0.0.1)
101
- activejob (= 5.0.0.1)
102
- activemodel (= 5.0.0.1)
103
- activerecord (= 5.0.0.1)
104
- activesupport (= 5.0.0.1)
105
- bundler (>= 1.3.0, < 2.0)
106
- railties (= 5.0.0.1)
81
+ mail (2.7.1)
82
+ mini_mime (>= 0.1.1)
83
+ marcel (0.3.3)
84
+ mimemagic (~> 0.3.2)
85
+ method_source (1.0.0)
86
+ mimemagic (0.3.5)
87
+ mini_mime (1.0.2)
88
+ mini_portile2 (2.4.0)
89
+ minitest (5.14.2)
90
+ multi_json (1.15.0)
91
+ nio4r (2.5.2)
92
+ nokogiri (1.10.10)
93
+ mini_portile2 (~> 2.4.0)
94
+ rack (2.2.3)
95
+ rack-test (1.1.0)
96
+ rack (>= 1.0, < 3)
97
+ rails (6.0.3.2)
98
+ actioncable (= 6.0.3.2)
99
+ actionmailbox (= 6.0.3.2)
100
+ actionmailer (= 6.0.3.2)
101
+ actionpack (= 6.0.3.2)
102
+ actiontext (= 6.0.3.2)
103
+ actionview (= 6.0.3.2)
104
+ activejob (= 6.0.3.2)
105
+ activemodel (= 6.0.3.2)
106
+ activerecord (= 6.0.3.2)
107
+ activestorage (= 6.0.3.2)
108
+ activesupport (= 6.0.3.2)
109
+ bundler (>= 1.3.0)
110
+ railties (= 6.0.3.2)
107
111
  sprockets-rails (>= 2.0.0)
108
- rails-dom-testing (2.0.1)
109
- activesupport (>= 4.2.0, < 6.0)
110
- nokogiri (~> 1.6.0)
111
- rails-html-sanitizer (1.0.3)
112
- loofah (~> 2.0)
113
- railties (5.0.0.1)
114
- actionpack (= 5.0.0.1)
115
- activesupport (= 5.0.0.1)
112
+ rails-dom-testing (2.0.3)
113
+ activesupport (>= 4.2.0)
114
+ nokogiri (>= 1.6)
115
+ rails-html-sanitizer (1.3.0)
116
+ loofah (~> 2.3)
117
+ railties (6.0.3.2)
118
+ actionpack (= 6.0.3.2)
119
+ activesupport (= 6.0.3.2)
116
120
  method_source
117
121
  rake (>= 0.8.7)
118
- thor (>= 0.18.1, < 2.0)
119
- rake (11.3.0)
120
- reform (2.2.3)
121
- disposable (>= 0.3.0, < 0.4.0)
122
- representable (>= 2.4.0, < 3.1.0)
123
- uber (>= 0.0.15, < 0.2.0)
124
- representable (3.0.2)
125
- declarative (~> 0.0.5)
126
- uber (>= 0.0.15, < 0.2.0)
127
- sprockets (3.7.0)
122
+ thor (>= 0.20.3, < 2.0)
123
+ rake (13.0.1)
124
+ representable (3.0.4)
125
+ declarative (< 0.1.0)
126
+ declarative-option (< 0.2.0)
127
+ uber (< 0.2.0)
128
+ sprockets (4.0.2)
128
129
  concurrent-ruby (~> 1.0)
129
130
  rack (> 1, < 3)
130
- sprockets-rails (3.2.0)
131
+ sprockets-rails (3.2.1)
131
132
  actionpack (>= 4.0)
132
133
  activesupport (>= 4.0)
133
134
  sprockets (>= 3.0.0)
134
- sqlite3 (1.3.12)
135
- thor (0.19.1)
136
- thread_safe (0.3.5)
137
- tzinfo (1.2.2)
135
+ sqlite3 (1.4.2)
136
+ thor (1.0.1)
137
+ thread_safe (0.3.6)
138
+ trailblazer-activity (0.11.3)
139
+ trailblazer-context (>= 0.3.1, < 0.4.0)
140
+ trailblazer-activity-dsl-linear (0.3.2)
141
+ trailblazer-activity (>= 0.11.2, < 1.0.0)
142
+ trailblazer-context (0.3.1)
143
+ hashie (~> 4.1)
144
+ trailblazer-developer (0.0.16)
145
+ hirb
146
+ representable
147
+ trailblazer-activity (>= 0.11.0, < 1.0.0)
148
+ trailblazer-activity-dsl-linear
149
+ trailblazer-operation (0.6.5)
150
+ trailblazer-activity (>= 0.11.2, < 1.0.0)
151
+ trailblazer-activity-dsl-linear (>= 0.3.2, < 1.0.0)
152
+ trailblazer-developer (>= 0.0.8)
153
+ tzinfo (1.2.7)
138
154
  thread_safe (~> 0.1)
139
155
  uber (0.1.0)
140
- websocket-driver (0.6.4)
156
+ websocket-driver (0.7.3)
141
157
  websocket-extensions (>= 0.1.0)
142
- websocket-extensions (0.1.2)
158
+ websocket-extensions (0.1.5)
159
+ zeitwerk (2.4.0)
143
160
 
144
161
  PLATFORMS
145
162
  ruby
146
163
 
147
164
  DEPENDENCIES
165
+ jwt
148
166
  multi_json
149
- rails (~> 5.0.0, >= 5.0.0.1)
150
- sqlite3
151
- trailblazer!
167
+ rails (~> 6.0.3, >= 6.0.3.1)
168
+ sqlite3 (~> 1.4)
152
169
  trailblazer-endpoint!
153
- trailblazer-operation!
154
- tzinfo-data
170
+ trailblazer-operation
155
171
 
156
172
  BUNDLED WITH
157
- 1.12.5
173
+ 2.1.4
@@ -0,0 +1,16 @@
1
+ module App
2
+ module Api
3
+ module V1
4
+ module Representer
5
+ class Errors < Representable::Decorator
6
+ include Representable::JSON
7
+
8
+ self.representation_wrap= :errors
9
+
10
+ property :message
11
+ end
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,35 @@
1
+ require 'date'
2
+ require "jwt"
3
+
4
+ # Thanks to pocketrocket GmbH for providing this sample code.
5
+ module Auth
6
+ class Jwt
7
+ # Generate a JWT from arguments
8
+ def self.generate(encoding_key, encoding_value, payload)
9
+ # expiration_time = Rails.application.credentials[:jwt_expiration_time].hours.from_now.to_i # TODO: show how to inject config options
10
+ expiration_time = 1.hours.from_now.to_i
11
+ payload['exp'] = expiration_time
12
+ jwt = JWT.encode(payload,
13
+ Rails.application.credentials[:secret_key_base], 'HS512',
14
+ { exp: expiration_time, encoding_key.to_sym => encoding_value }
15
+ )
16
+ return jwt
17
+ end
18
+
19
+ # Validate tokens expiration date
20
+ def self.expired?(token)
21
+ decoded_token = JwtService.decode(token)
22
+ expiry_timestamp = decoded_token.first['exp']
23
+ expiration_date = Time.at(expiry_timestamp).to_datetime
24
+ return DateTime.now > expiration_date
25
+ rescue => err
26
+ return true
27
+ end
28
+
29
+ def self.decode(token)
30
+ JWT.decode(token, Rails.application.credentials[:secret_key_base], true, { algorithm: 'HS512'})
31
+ rescue => err # FIXME: is there any way to call {JWT.decode} without an exception?
32
+ nil
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,32 @@
1
+ # FIXME: this is not final, yet!
2
+ class Auth::Operation::Authenticate < Trailblazer::Activity::Railway
3
+ step :verify_token
4
+ step :is_token_expired?
5
+ step :set_current_user
6
+
7
+ def verify_token(ctx, request:, **)
8
+ auth_header = request.headers['Authorization'] || ""
9
+ jwt_encoded_token = auth_header.split(' ').last
10
+ ctx[:encoded_jwt_token] = jwt_encoded_token
11
+
12
+ # FIXME
13
+ #raise StandardError if JwtService.expired?(jwt_encoded_token)
14
+ ctx[:decoded_jwt_token] = Auth::Jwt.decode(jwt_encoded_token)
15
+ end
16
+
17
+ def is_token_expired?(ctx, decoded_jwt_token:, **)
18
+ expiration_integer = decoded_jwt_token.first['exp']
19
+ return false if expiration_integer.nil?
20
+ return false if (expiration_integer - DateTime.now.to_i) <= 0
21
+ return true
22
+ end
23
+
24
+ def set_current_user(ctx, decoded_jwt_token:, **)
25
+ user_id = decoded_jwt_token.first['user_id']
26
+
27
+ ctx[:current_user] = User.find_by(
28
+ id: user_id
29
+ )
30
+ true # FIXME
31
+ end
32
+ end
@@ -0,0 +1,9 @@
1
+ module Auth
2
+ module Operation
3
+ class Policy
4
+ def self.call(ctx, domain_ctx:, **)
5
+ domain_ctx[:params][:policy] == false ? false : true
6
+ end
7
+ end
8
+ end
9
+ end