ff-tbl-macros 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/Dockerfile +13 -0
  3. data/Gemfile +17 -0
  4. data/Gemfile.lock +117 -0
  5. data/MIT-LICENSE +18 -0
  6. data/README.md +147 -0
  7. data/lib/ff-tbl-macros.rb +29 -0
  8. data/lib/macros/auth.rb +9 -0
  9. data/lib/macros/auth/authenticate.rb +24 -0
  10. data/lib/macros/auth/sign_in.rb +43 -0
  11. data/lib/macros/auth/sign_out.rb +48 -0
  12. data/lib/macros/base.rb +37 -0
  13. data/lib/macros/contract.rb +8 -0
  14. data/lib/macros/contract/extract_params.rb +25 -0
  15. data/lib/macros/contract/prepopulate.rb +16 -0
  16. data/lib/macros/ctx.rb +9 -0
  17. data/lib/macros/ctx/copy.rb +18 -0
  18. data/lib/macros/ctx/inspect.rb +28 -0
  19. data/lib/macros/ctx/validate_presence.rb +20 -0
  20. data/lib/macros/current_user.rb +7 -0
  21. data/lib/macros/current_user/set.rb +25 -0
  22. data/lib/macros/error.rb +7 -0
  23. data/lib/macros/error/set_from_contract.rb +19 -0
  24. data/lib/macros/model.rb +10 -0
  25. data/lib/macros/model/build.rb +32 -0
  26. data/lib/macros/model/copy.rb +17 -0
  27. data/lib/macros/model/destroy.rb +18 -0
  28. data/lib/macros/model/persist.rb +21 -0
  29. data/lib/macros/search.rb +7 -0
  30. data/lib/macros/search/query.rb +34 -0
  31. data/lib/macros/verify_params.rb +7 -0
  32. data/lib/macros/verify_params/date.rb +17 -0
  33. data/lib/macros/version.rb +6 -0
  34. data/spec/lib/auth/authenticate_spec.rb +21 -0
  35. data/spec/lib/auth/sign_in_spec.rb +37 -0
  36. data/spec/lib/auth/sign_out_spec.rb +37 -0
  37. data/spec/lib/auth_spec.rb +15 -0
  38. data/spec/lib/contract/extract_params_spec.rb +35 -0
  39. data/spec/lib/contract/prepopulate_spec.rb +27 -0
  40. data/spec/lib/contract_spec.rb +14 -0
  41. data/spec/lib/ctx/copy_spec.rb +27 -0
  42. data/spec/lib/ctx/inspect_spec.rb +26 -0
  43. data/spec/lib/ctx/validate_presence_spec.rb +20 -0
  44. data/spec/lib/ctx_spec.rb +19 -0
  45. data/spec/lib/current_user.rb +7 -0
  46. data/spec/lib/current_user/set_spec.rb +24 -0
  47. data/spec/lib/error/set_from_contract_spec.rb +27 -0
  48. data/spec/lib/error_spec.rb +7 -0
  49. data/spec/lib/ff_tbl_macros_spec.rb +11 -0
  50. data/spec/lib/model/build_spec.rb +53 -0
  51. data/spec/lib/model/copy_spec.rb +26 -0
  52. data/spec/lib/model/destroy_spec.rb +13 -0
  53. data/spec/lib/model/persist_spec.rb +45 -0
  54. data/spec/lib/model_spec.rb +21 -0
  55. data/spec/lib/search/query_spec.rb +23 -0
  56. data/spec/lib/search_spec.rb +9 -0
  57. data/spec/lib/verify_params/date_spec.rb +22 -0
  58. data/spec/lib/verify_params_spec.rb +9 -0
  59. data/spec/spec_helper.rb +38 -0
  60. metadata +169 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 134458580b82af72b8df814edfc9e0ad9a30ee388c3022e18d8cae0f2052176c
4
+ data.tar.gz: 7ac93a23b408fef75f9f9557cc848863280a8838d9e0adcbd707172f01600029
5
+ SHA512:
6
+ metadata.gz: 45456aadf56e6642a389c708ef27157544fe2c2c576715e7a83662c52ace88928056e75aada6722b48a4ababded4bc7021bb3e3eb7ee51e9cd47008289def016
7
+ data.tar.gz: d6f546fb293f0df15bce02d573821438b773bb8e44dea1aeacdf83addadbcd7c7ec92c0dd5a4b601d9126987bc71a5b9cb0ef05acfad794cd433942a7f2ed57b
data/Dockerfile ADDED
@@ -0,0 +1,13 @@
1
+ FROM ruby:2.6.1-alpine3.9
2
+
3
+ LABEL maintainer="devops@firefield.com"
4
+
5
+ RUN apk add --no-cache --update build-base linux-headers
6
+ RUN apk add --no-cache --update git file
7
+
8
+ ENV APP_PATH /usr/src/app
9
+ WORKDIR $APP_PATH
10
+
11
+ COPY . .
12
+
13
+ RUN bundle install --jobs `expr $(cat /proc/cpuinfo | grep -c "cpu cores") - 1` --retry 3
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ group :development, :test do
8
+ gem 'recursive-open-struct'
9
+ gem 'reform'
10
+ gem 'require_all'
11
+ gem 'rspec'
12
+ gem 'rspec-activemodel-mocks'
13
+ gem 'rubocop'
14
+ gem 'simplecov'
15
+ gem 'trailblazer'
16
+ gem 'warden'
17
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,117 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ff-tbl-macros (0.1.8)
5
+ activesupport (~> 5.2)
6
+ require_all (~> 2.0)
7
+ trailblazer (~> 2.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activemodel (5.2.2)
13
+ activesupport (= 5.2.2)
14
+ activesupport (5.2.2)
15
+ concurrent-ruby (~> 1.0, >= 1.0.2)
16
+ i18n (>= 0.7, < 2)
17
+ minitest (~> 5.1)
18
+ tzinfo (~> 1.1)
19
+ ast (2.4.0)
20
+ concurrent-ruby (1.1.4)
21
+ declarative (0.0.10)
22
+ declarative-builder (0.1.0)
23
+ declarative-option (< 0.2.0)
24
+ declarative-option (0.1.0)
25
+ diff-lcs (1.3)
26
+ disposable (0.4.4)
27
+ declarative (>= 0.0.9, < 1.0.0)
28
+ declarative-builder (< 0.2.0)
29
+ declarative-option (< 0.2.0)
30
+ representable (>= 2.4.0, <= 3.1.0)
31
+ uber (< 0.2.0)
32
+ docile (1.3.1)
33
+ i18n (1.6.0)
34
+ concurrent-ruby (~> 1.0)
35
+ jaro_winkler (1.5.2)
36
+ json (2.2.0)
37
+ minitest (5.11.3)
38
+ parallel (1.17.0)
39
+ parser (2.6.2.0)
40
+ ast (~> 2.4.0)
41
+ pipetree (0.1.1)
42
+ psych (3.1.0)
43
+ rack (2.0.6)
44
+ rainbow (3.0.0)
45
+ recursive-open-struct (1.1.0)
46
+ reform (2.2.4)
47
+ disposable (>= 0.4.1)
48
+ representable (>= 2.4.0, < 3.1.0)
49
+ representable (3.0.4)
50
+ declarative (< 0.1.0)
51
+ declarative-option (< 0.2.0)
52
+ uber (< 0.2.0)
53
+ require_all (2.0.0)
54
+ rspec (3.8.0)
55
+ rspec-core (~> 3.8.0)
56
+ rspec-expectations (~> 3.8.0)
57
+ rspec-mocks (~> 3.8.0)
58
+ rspec-activemodel-mocks (1.1.0)
59
+ activemodel (>= 3.0)
60
+ activesupport (>= 3.0)
61
+ rspec-mocks (>= 2.99, < 4.0)
62
+ rspec-core (3.8.0)
63
+ rspec-support (~> 3.8.0)
64
+ rspec-expectations (3.8.2)
65
+ diff-lcs (>= 1.2.0, < 2.0)
66
+ rspec-support (~> 3.8.0)
67
+ rspec-mocks (3.8.0)
68
+ diff-lcs (>= 1.2.0, < 2.0)
69
+ rspec-support (~> 3.8.0)
70
+ rspec-support (3.8.0)
71
+ rubocop (0.66.0)
72
+ jaro_winkler (~> 1.5.1)
73
+ parallel (~> 1.10)
74
+ parser (>= 2.5, != 2.5.1.1)
75
+ psych (>= 3.1.0)
76
+ rainbow (>= 2.2.2, < 4.0)
77
+ ruby-progressbar (~> 1.7)
78
+ unicode-display_width (>= 1.4.0, < 1.6)
79
+ ruby-progressbar (1.10.0)
80
+ simplecov (0.16.1)
81
+ docile (~> 1.1)
82
+ json (>= 1.8, < 3)
83
+ simplecov-html (~> 0.10.0)
84
+ simplecov-html (0.10.2)
85
+ thread_safe (0.3.6)
86
+ trailblazer (2.0.7)
87
+ declarative
88
+ reform (>= 2.2.0, < 3.0.0)
89
+ trailblazer-operation (>= 0.0.12, < 0.1.0)
90
+ trailblazer-operation (0.0.13)
91
+ declarative
92
+ pipetree (>= 0.1.1, < 0.2.0)
93
+ uber
94
+ tzinfo (1.2.5)
95
+ thread_safe (~> 0.1)
96
+ uber (0.1.0)
97
+ unicode-display_width (1.5.0)
98
+ warden (1.2.8)
99
+ rack (>= 2.0.6)
100
+
101
+ PLATFORMS
102
+ ruby
103
+
104
+ DEPENDENCIES
105
+ ff-tbl-macros!
106
+ recursive-open-struct
107
+ reform
108
+ require_all
109
+ rspec
110
+ rspec-activemodel-mocks
111
+ rubocop
112
+ simplecov
113
+ trailblazer
114
+ warden
115
+
116
+ BUNDLED WITH
117
+ 1.17.3
data/MIT-LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Permission is hereby granted, free of charge, to any person obtaining
2
+ a copy of this software and associated documentation files (the
3
+ "Software"), to deal in the Software without restriction, including
4
+ without limitation the rights to use, copy, modify, merge, publish,
5
+ distribute, sublicense, and/or sell copies of the Software, and to
6
+ permit persons to whom the Software is furnished to do so, subject to
7
+ the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be
10
+ included in all copies or substantial portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,147 @@
1
+ # ff-tbl-macros
2
+
3
+ ![MIT-LICENSE](https://img.shields.io/github/license/firefield/ff-tbl-macros.svg?style=flat-square) ![build status](https://img.shields.io/travis/firefield/ff-tbl-macros.svg?style=flat-square)
4
+
5
+ Macros for Trailblazer operations.
6
+
7
+ # Overview
8
+
9
+ ## Features
10
+
11
+ - several predefined macros organized in namespaces
12
+ - custom macros
13
+
14
+ # Getting Started
15
+
16
+ ## Prerequisites
17
+
18
+ For contributing, install docker to use the provided dockerized development environment.
19
+
20
+ ## Installation
21
+
22
+ Add this line to your application's Gemfile:
23
+
24
+ ```ruby
25
+ gem 'ff-tbl-macros', git: 'https://github.com/firefield/ff-tbl-macros.git'
26
+ ```
27
+
28
+ # Usage
29
+
30
+ Use the macros in the operation steps:
31
+
32
+ ```ruby
33
+ class User::Delete < Trailblazer::Operation
34
+ step Macros::Model::Destroy()
35
+ end
36
+ ```
37
+
38
+ # Contributing
39
+
40
+ 1. Fork the Project
41
+ 1. Create your Feature Branch (git checkout -b feature/AmazingFeature)
42
+ 1. Commit your Changes (git commit -m 'Add some AmazingFeature)
43
+ 1. Push to the Branch (git push origin feature/AmazingFeature)
44
+ 1. Open a Pull Request
45
+
46
+ ## Development
47
+
48
+ The project includes a dockerized development environment.
49
+
50
+ ```
51
+ # build the docker containers
52
+ docker-compose build
53
+
54
+ # run the specs
55
+ docker-compose run --rm app bundle exec rspec
56
+
57
+ ```
58
+
59
+ # Documentation
60
+
61
+ ## Macros Types
62
+
63
+ There are several types of macros organized in namespaces.
64
+
65
+ ### Auth Macros
66
+
67
+ - `Macros::Auth::Authenticate`
68
+ - `Macros::Auth::SignIn`
69
+ - `Macros::Auth::SignOut`
70
+
71
+ ### Contract Macros
72
+
73
+ - `Macros::Contract::ExtractParams`
74
+ - `Macros::Contract::Prepopulate`
75
+
76
+ ### Context Macros
77
+
78
+ - `Macros::Ctx::Copy`
79
+ - `Macros::Ctx::Inspect`
80
+ - `Macros::Ctx::ValidatePresence`
81
+
82
+ ### Current User Macros
83
+
84
+ - `Macros::CurrentUser::Set`
85
+
86
+ ### Error Macros
87
+
88
+ - `Macros::Error::SetFromContract`
89
+
90
+ ### Model Macros
91
+
92
+ - `Macros::Model::Build`
93
+ - `Macros::Model::Copy`
94
+ - `Macros::Model::Destroy`
95
+ - `Macros::Model::Persist`
96
+
97
+ ### Search Macros
98
+
99
+ - `Macros::Search::Query`
100
+
101
+ ### Verify Params Macros
102
+
103
+ - `Macros::VeriryParams::Date`
104
+
105
+ ## Application Specific Macros
106
+
107
+ You can create your own custom macros specific to your application. Just put them in the _lib/macros_ folder of your Rails app following this convention:
108
+
109
+ _lib/macros/lorem.rb_
110
+ ```ruby
111
+ module Macros
112
+ class Lorem < Macros::Base
113
+ register :print_ipsum
114
+ end
115
+ end
116
+ ```
117
+
118
+ _lib/macros/lorem/print_ipsum.rb_
119
+ ```ruby
120
+ module Macros
121
+ class Lorem
122
+ # Some info what your macro does
123
+ #
124
+ # @examples
125
+ # step Macros::Lorem::PrintIpsum(count:)
126
+ #
127
+ class PrintIpsum < Macros::Base
128
+ def initialize(count:)
129
+ @count = count
130
+ end
131
+
132
+ def call(ctx, **)
133
+ @count.times { print 'Ipsum' }
134
+ end
135
+ end
136
+ end
137
+ end
138
+ ```
139
+
140
+ # License
141
+
142
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
143
+
144
+ # Aknowledgements
145
+
146
+ Gem used https://github.com/coditsu/macros as the base.
147
+
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ %w[
4
+ trailblazer
5
+ require_all
6
+ active_support/inflector
7
+ uber/options
8
+ ].each { |lib| require lib }
9
+
10
+ # Trailblazer shared macros used across multiple apps
11
+ module Macros
12
+ class << self
13
+ # @return [String] root path to this gem
14
+ # @example
15
+ # Macros.gem_root #=> '/home/user/.gems/macros'
16
+ def gem_root
17
+ File.expand_path('..', __dir__)
18
+ end
19
+ end
20
+ end
21
+
22
+ require File.dirname(__FILE__) + '/macros/base.rb' # Macros::Base must be loaded before other macros' classes
23
+ require_all File.dirname(__FILE__) + '/**/*.rb' # load gem' macros
24
+
25
+ # load app specific macros
26
+ if Dir.exist? 'lib/macros'
27
+ require_all 'lib/macros/*.rb'
28
+ require_all 'lib/macros/**/*.rb'
29
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Macros
4
+ class Auth < Macros::Base
5
+ register :authenticate
6
+ register :sign_in
7
+ register :sign_out
8
+ end
9
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Macros
4
+ class Auth
5
+ # Authenticates the given user using warden. This code run at the rack level, and is tied to the request.
6
+ #
7
+ class Authenticate < Base
8
+ # @return [Macro::Auth::SignIn] step macro instance
9
+ def initialize; end
10
+
11
+ # Performs a step by authenticating the the given user
12
+ # @param ctx [Trailblazer::Skill] tbl context hash
13
+ def call(ctx, scope:, warden:, **)
14
+ user = warden.authenticate(scope: scope)
15
+ if user
16
+ ctx[:model] = user
17
+ true
18
+ else
19
+ false
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Macros
4
+ class Auth
5
+ # Sign in the given user. The user is passed in ctx[:model].
6
+ #
7
+ class SignIn < Macros::Base
8
+ # @return [Macro::Auth::SignIn] step macro instance
9
+ def initialize(condition: nil)
10
+ @condition = condition
11
+ end
12
+
13
+ # Performs a step by signing in the given user
14
+ # @param ctx [Trailblazer::Skill] tbl context hash
15
+ def call(ctx, model:, warden:, **)
16
+ return false if @condition && ctx[@condition].blank?
17
+
18
+ options = ctx[:sign_in_options] || {}
19
+ scope = Devise::Mapping.find_scope!(model)
20
+ expire_data_after_sign_in(session: warden.session_serializer.session)
21
+
22
+ if warden.user(scope) == model && !options.delete(:force)
23
+ # Do nothing. User already signed in and we are not forcing it.
24
+ true
25
+ else
26
+ options[:scope] = scope
27
+ warden.set_user(model, options)
28
+ end
29
+
30
+ ctx[:current_user] = model
31
+ true
32
+ end
33
+
34
+ def expire_data_after_sign_in(session:)
35
+ # session.keys will return an empty array if the session is not yet loaded.
36
+ # This is a bug in both Rack and Rails.
37
+ # A call to #empty? forces the session to be loaded.
38
+ session.empty?
39
+ session.keys.grep(/^devise\./).each { |k| session.delete(k) }
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Macros
4
+ class Auth
5
+ # Signout the given user. The user can be passed in the context.
6
+ #
7
+ # @example signout a user specified in the context (:scope or :model)
8
+ # step Macros::Auth::SignOut()
9
+ #
10
+ # @example signout the user passed in ctx[:impersonated_user]
11
+ # step Macros::Auth::SignOut(user_key: :impersonated_user)
12
+ class SignOut < Macros::Base
13
+ # @return [Macro::Auth::SignOut] step macro instance
14
+ # @param user_key [Hash] ctx key under which is the user which we want to signout
15
+ def initialize(user_key: nil)
16
+ @user_key = user_key
17
+ @user = nil
18
+ end
19
+
20
+ # Performs a step by signout the given user
21
+ # @param ctx [Trailblazer::Skill] tbl context hash
22
+ def call(ctx, warden:, **)
23
+ @user = ctx[@user_key] if @user_key
24
+
25
+ ctx[:scope] = scope(ctx)
26
+ warden_user = warden.user(scope: ctx[:scope], run_callbacks: false)
27
+ ctx[:model] = warden_user unless @user
28
+ warden.logout(ctx[:scope])
29
+ warden.clear_strategies_cache!(scope: ctx[:scope])
30
+ true
31
+ end
32
+
33
+ def scope(ctx)
34
+ resource_or_scope = if @user
35
+ @user
36
+ elsif ctx[:scope]
37
+ ctx[:scope]
38
+ elsif ctx[:model]
39
+ ctx[:model]
40
+ else
41
+ :user
42
+ end
43
+
44
+ Devise::Mapping.find_scope!(resource_or_scope)
45
+ end
46
+ end
47
+ end
48
+ end