warden-jwt_auth 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ac884c1ecfe8201fe9973503bcb067186a2683b290828d9b5bac8b3667929f6d
4
- data.tar.gz: 26f14054831f628f83c083709fd8e044182eb28bcef092110c48c386009576fb
3
+ metadata.gz: d51f6ca62ae932ecce00a1302bcf89afa9e39a073d64e2e1ed8573b1f35ac887
4
+ data.tar.gz: c412529d04dcb06a4360accaff043d5a11948ac6acc621f795b0d53087abe360
5
5
  SHA512:
6
- metadata.gz: dadca31dc64203c56ca77c98e69a8bfc48813e2bf0a61a52ee8741f7a08df9c71d96aa481ca424e908b3ba1e8f979f36544244e8545bba6b0e83624ab96db1fa
7
- data.tar.gz: 3c58c89cb5d42c462b071008c548d85649e1d88d7186e4d4cc9c987d72e9dbab9d2ddf4a3ed9eb99e017d8f0f66b76f4ccdb88ec584ef64b3bdc097ec69a06ee
6
+ metadata.gz: 917659441336dbdd2f7dce8e4e29ac0ed278e7961ab1c6f209eed25e6e8d613b59154c302fd27695a2432c8cc9aa8bd09eca52958132ba96cb0d3590ee6bafa9
7
+ data.tar.gz: e7acd7d7922d344056f16fc7412bbf2241780dafb573ba550915de60dc371738d63a70acf363778c7bcd38e6e5e38b78f2eb237c5b3d3448616e90e44dc54b26
data/.codeclimate.yml CHANGED
@@ -8,8 +8,6 @@ engines:
8
8
  enabled: true
9
9
  rubocop:
10
10
  enabled: true
11
- reek:
12
- enabled: true
13
11
  ratings:
14
12
  paths:
15
13
  - "**.rb"
data/.rubocop.yml CHANGED
@@ -1,17 +1,51 @@
1
1
  require: rubocop-rspec
2
2
  AllCops:
3
- TargetRubyVersion: 2.6
3
+ TargetRubyVersion: 2.7
4
+ Exclude:
5
+ - Gemfile
6
+ - warden-jwt_auth.gemspec
7
+ - spec/support/shared_contexts/*rb
8
+ - vendor/**/*
4
9
  RSpec/NestedGroups:
5
10
  Max: 3
6
- RSpec/MessageSpies:
7
- EnforcedStyle: 'receive'
8
- RSpec/ContextWording:
9
- Exclude:
10
- - "spec/support/shared_contexts/*rb"
11
+ RSpec/MessageExpectation:
12
+ EnforcedStyle: 'expect'
11
13
  Metrics/BlockLength:
12
14
  Exclude:
13
15
  - "spec/**/*.rb"
14
- Metrics/LineLength:
15
- Max: 100
16
- Naming/RescuedExceptionsVariableName:
17
- PreferredName: exception
16
+ Style/SafeNavigation:
17
+ Enabled: false
18
+ Layout/EmptyLinesAroundAttributeAccessor:
19
+ Enabled: true
20
+ Layout/SpaceAroundMethodCallOperator:
21
+ Enabled: true
22
+ Lint/DeprecatedOpenSSLConstant:
23
+ Enabled: true
24
+ Lint/MixedRegexpCaptureTypes:
25
+ Enabled: true
26
+ Lint/RaiseException:
27
+ Enabled: true
28
+ Lint/StructNewOverride:
29
+ Enabled: true
30
+ Style/AccessorGrouping:
31
+ Enabled: true
32
+ Style/BisectedAttrAccessor:
33
+ Enabled: true
34
+ Style/ExponentialNotation:
35
+ Enabled: true
36
+ Style/HashEachMethods:
37
+ Enabled: true
38
+ Style/HashTransformKeys:
39
+ Enabled: true
40
+ Style/HashTransformValues:
41
+ Enabled: true
42
+ Style/RedundantAssignment:
43
+ Enabled: true
44
+ Style/RedundantFetchBlock:
45
+ Enabled: true
46
+ Style/RedundantRegexpCharacterClass:
47
+ Enabled: true
48
+ Style/RedundantRegexpEscape:
49
+ Enabled: true
50
+ Style/SlicingWithRange:
51
+ Enabled: true
data/.travis.yml CHANGED
@@ -1,19 +1,20 @@
1
1
  language: ruby
2
+ cache: bundler
2
3
  rvm:
3
- - 2.5
4
4
  - 2.6
5
5
  - 2.7
6
+ - 3.0
7
+ - ruby-head
6
8
  before_install:
7
9
  - gem update --system --no-doc
8
- - bundle install --gemfile=.overcommit_gems.rb
9
- before_script:
10
- - git config --global user.email 'travis@travis.ci'
11
- - git config --global user.name 'Travis CI'
10
+ - gem install bundler
12
11
  script:
13
12
  - bundle exec rspec
13
+ - bundle exec rubocop
14
14
  - bundle exec codeclimate-test-reporter
15
- - overcommit --sign
16
- - overcommit --run
15
+ jobs:
16
+ allow_failures:
17
+ - rvm: ruby-head
17
18
  addons:
18
19
  code_climate:
19
20
  repo_token:
data/CHANGELOG.md CHANGED
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
+ ## [0.6.0]
8
+ - Support ruby 3.0 and deprecate 2.5
9
+ - Fixed dry-configurable compatibility. ([28](https://github.com/waiting-for-dev/warden-jwt_auth/issues/28))
10
+
7
11
  ## [0.5.0]
8
12
  ### Fixed
9
13
  - Fixed dry-configurable compatibility. ([28](https://github.com/waiting-for-dev/warden-jwt_auth/issues/28))
data/Dockerfile CHANGED
@@ -1,8 +1,5 @@
1
- FROM ruby:2.3.1
2
- ENV APP_HOME /app/
3
- ENV LIB_DIR lib/warden/jwt_auth/
4
- RUN mkdir -p $APP_HOME/$LIB_DIR
5
- WORKDIR $APP_HOME
6
- COPY Gemfile *gemspec $APP_HOME
7
- COPY $LIB_DIR/version.rb $APP_HOME/$LIB_DIR
8
- RUN bundle install
1
+ FROM ruby:3.0.0
2
+ ENV APP_USER warden_jwt_auth_user
3
+ RUN useradd -ms /bin/bash $APP_USER
4
+ USER $APP_USER
5
+ WORKDIR /home/$APP_USER/app
data/README.md CHANGED
@@ -14,10 +14,10 @@ off with a solution using refresh tokens, like some implementation of OAuth2.
14
14
 
15
15
  You can read about which security concerns this library takes into account and about JWT generic secure usage in the following series of posts:
16
16
 
17
- - [Stand Up for JWT Revocation](http://waiting-for-dev.github.io/blog/2017/01/23/stand_up_for_jwt_revocation/)
18
- - [JWT Revocation Strategies](http://waiting-for-dev.github.io/blog/2017/01/24/jwt_revocation_strategies/)
19
- - [JWT Secure Usage](http://waiting-for-dev.github.io/blog/2017/01/25/jwt_secure_usage/)
20
- - [A secure JWT authentication implementation for Rack and Rails](http://waiting-for-dev.github.io/blog/2017/01/26/a_secure_jwt_authentication_implementation_for_rack_and_rails/)
17
+ - [Stand Up for JWT Revocation](http://waiting-for-dev.github.io/blog/2017/01/23/stand_up_for_jwt_revocation)
18
+ - [JWT Revocation Strategies](http://waiting-for-dev.github.io/blog/2017/01/24/jwt_revocation_strategies)
19
+ - [JWT Secure Usage](http://waiting-for-dev.github.io/blog/2017/01/25/jwt_secure_usage)
20
+ - [A secure JWT authentication implementation for Rack and Rails](http://waiting-for-dev.github.io/blog/2017/01/26/a_secure_jwt_authentication_implementation_for_rack_and_rails)
21
21
 
22
22
  If what you need is a JWT authentication library for [devise](https://github.com/plataformatec/devise), better look at [devise-jwt](https://github.com/waiting-for-dev/devise-jwt), which is just a thin layer on top of this gem.
23
23
 
@@ -195,14 +195,6 @@ An then, for example:
195
195
 
196
196
  `docker-compose exec app rspec`
197
197
 
198
- This gem uses [overcommit](https://github.com/brigade/overcommit) to execute some code review engines. If you submit a pull request, it will be executed in the CI process. In order to set it up, you need to do:
199
-
200
- ```ruby
201
- bundle install --gemfile=.overcommit_gems.rb
202
- overcommit --sign
203
- overcommit --run # To test if it works
204
- ```
205
-
206
198
  ## Contributing
207
199
 
208
200
  Bug reports and pull requests are welcome on GitHub at https://github.com/waiting-for-dev/warden-jwt_auth. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
data/docker-compose.yml CHANGED
@@ -2,6 +2,11 @@ version: '2'
2
2
  services:
3
3
  app:
4
4
  build: .
5
- command: tail -f Gemfile
5
+ image: warden_jwt_auth
6
+ command: bash -c "bundle && tail -f Gemfile"
6
7
  volumes:
7
- - .:/app
8
+ - .:/home/warden_jwt_auth_user/app
9
+ tty: true
10
+ stdin_open: true
11
+ tmpfs:
12
+ - /tmp
@@ -34,8 +34,6 @@ module Warden
34
34
  jwt_scope?(scope) && request_matches?(path_info, method)
35
35
  end
36
36
 
37
- # :reek:ManualDispatch
38
- # :reek:UtilityFunction
39
37
  def add_token_to_env(user, scope, env)
40
38
  aud = EnvHelper.aud_header(env)
41
39
  token, payload = UserEncoder.new.call(user, scope, aud)
@@ -48,7 +46,6 @@ module Warden
48
46
  jwt_scopes.include?(scope)
49
47
  end
50
48
 
51
- # :reek:ControlParameter
52
49
  def request_matches?(path_info, method)
53
50
  dispatch_requests.each do |tuple|
54
51
  dispatch_method, dispatch_path = tuple
@@ -34,7 +34,6 @@ module Warden
34
34
  TokenRevoker.new.call(token)
35
35
  end
36
36
 
37
- # :reek:ControlParameter
38
37
  def token_should_be_revoked?(path_info, method)
39
38
  revocation_requests = config.revocation_requests
40
39
  revocation_requests.each do |tuple|
@@ -24,7 +24,6 @@ module Warden
24
24
 
25
25
  private
26
26
 
27
- # :reek:UtilityFunction
28
27
  def headers_with_token(env, headers)
29
28
  token = env[Hooks::PREPARED_TOKEN_ENV_KEY]
30
29
  token ? HeaderParser.to_headers(headers, token) : headers
@@ -14,7 +14,6 @@ module Warden
14
14
  @app = app
15
15
  end
16
16
 
17
- # :reek:FeatureEnvy
18
17
  def call(env)
19
18
  builder = Rack::Builder.new
20
19
  builder.use(RevocationManager)
@@ -34,7 +34,6 @@ module Warden
34
34
  # @param user [Interfaces::User] an user, whatever it is
35
35
  # @param scope [Symbol] A Warden scope
36
36
  # @return [Hash] payload to encode
37
- # :reek:ManualDispatch
38
37
  def self.payload_for_user(user, scope)
39
38
  sub = user.jwt_subject
40
39
  payload = { 'sub' => String(sub), 'scp' => scope.to_s }
@@ -6,9 +6,7 @@ module Warden
6
6
  module JWTAuth
7
7
  # Warden strategy to authenticate an user through a JWT token in the
8
8
  # `Authorization` request header
9
- # :reek:PrimaDonnaMethod
10
9
  class Strategy < Warden::Strategies::Base
11
- # :reek:NilCheck
12
10
  def valid?
13
11
  !token.nil?
14
12
  end
@@ -21,8 +19,8 @@ module Warden
21
19
  aud = EnvHelper.aud_header(env)
22
20
  user = UserDecoder.new.call(token, scope, aud)
23
21
  success!(user)
24
- rescue JWT::DecodeError => exception
25
- fail!(exception.message)
22
+ rescue JWT::DecodeError => e
23
+ fail!(e.message)
26
24
  end
27
25
 
28
26
  private
@@ -20,12 +20,11 @@ module Warden
20
20
 
21
21
  private
22
22
 
23
- #:reek:FeatureEnvy
24
23
  def merge_with_default_claims(payload)
25
24
  now = Time.now.to_i
26
- payload['iat'] ||= now
27
- payload['exp'] ||= now + expiration_time
28
- payload['jti'] ||= SecureRandom.uuid
25
+ payload['iat'] ||= now
26
+ payload['exp'] ||= now + expiration_time
27
+ payload['jti'] ||= SecureRandom.uuid
29
28
  payload
30
29
  end
31
30
  end
@@ -14,10 +14,10 @@ module Warden
14
14
  scope = payload['scp'].to_sym
15
15
  user = PayloadUserHelper.find_user(payload)
16
16
  revocation_strategies[scope].revoke_jwt(payload, user)
17
- # rubocop:disable Lint/HandleExceptions
17
+ # rubocop:disable Lint/SuppressedException
18
18
  rescue JWT::ExpiredSignature
19
19
  end
20
- # rubocop:enable Lint/HandleExceptions
20
+ # rubocop:enable Lint/SuppressedException
21
21
  end
22
22
  end
23
23
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Warden
4
4
  module JWTAuth
5
- VERSION = '0.5.0'
5
+ VERSION = '0.6.0'
6
6
  end
7
7
  end
@@ -20,9 +20,7 @@ module Warden
20
20
  extend Dry::Configurable
21
21
 
22
22
  def symbolize_keys(hash)
23
- hash.each_with_object({}) do |(key, value), memo|
24
- memo[key.to_sym] = value
25
- end
23
+ hash.transform_keys(&:to_sym)
26
24
  end
27
25
 
28
26
  def upcase_first_items(array)
@@ -33,8 +31,8 @@ module Warden
33
31
  end
34
32
 
35
33
  def constantize_values(hash)
36
- hash.each_with_object({}) do |(key, value), memo|
37
- memo[key] = value.is_a?(String) ? Object.const_get(value) : value
34
+ hash.transform_values do |value|
35
+ value.is_a?(String) ? Object.const_get(value) : value
38
36
  end
39
37
  end
40
38
 
@@ -44,23 +42,23 @@ module Warden
44
42
  setting :secret
45
43
 
46
44
  # The algorithm used to encode the token
47
- setting :algorithm, 'HS256'
45
+ setting :algorithm, default: 'HS256'
48
46
 
49
47
  # Expiration time for tokens
50
- setting :expiration_time, 3600
48
+ setting :expiration_time, default: 3600
51
49
 
52
50
  # Request header which value will be encoded as `aud` claim in JWT. If
53
51
  # the header is not present `aud` will be `nil`.
54
- setting :aud_header, 'JWT_AUD'
52
+ setting :aud_header, default: 'JWT_AUD'
55
53
 
56
54
  # A hash of warden scopes as keys and user repositories as values. The
57
55
  # values can be either the constants themselves or the constant names.
58
56
  #
59
57
  # @see Interfaces::UserRepository
60
58
  # @see Interfaces::User
61
- setting(:mappings, {}) do |value|
62
- constantize_values(symbolize_keys(value))
63
- end
59
+ setting(:mappings,
60
+ default: {},
61
+ constructor: ->(value) { constantize_values(symbolize_keys(value)) })
64
62
 
65
63
  # Array of tuples [request_method, request_path_regex] to match request
66
64
  # verbs and paths where a JWT token should be added to the `Authorization`
@@ -70,9 +68,9 @@ module Warden
70
68
  # [
71
69
  # ['POST', %r{^/sign_in$}]
72
70
  # ]
73
- setting(:dispatch_requests, []) do |value|
74
- upcase_first_items(value)
75
- end
71
+ setting(:dispatch_requests,
72
+ default: [],
73
+ constructor: ->(value) { upcase_first_items(value) })
76
74
 
77
75
  # Array of tuples [request_method, request_path_regex] to match request
78
76
  # verbs and paths where incoming JWT token should be be revoked
@@ -81,9 +79,9 @@ module Warden
81
79
  # [
82
80
  # ['DELETE', %r{^/sign_out$}]
83
81
  # ]
84
- setting :revocation_requests, [] do |value|
85
- upcase_first_items(value)
86
- end
82
+ setting(:revocation_requests,
83
+ default: [],
84
+ constructor: ->(value) { upcase_first_items(value) })
87
85
 
88
86
  # Hash with scopes as keys and strategies to revoke tokens for that scope
89
87
  # as values. The values can be either the constants themselves or the
@@ -95,9 +93,9 @@ module Warden
95
93
  # }
96
94
  #
97
95
  # @see Interfaces::RevocationStrategy
98
- setting(:revocation_strategies, {}) do |value|
99
- constantize_values(symbolize_keys(value))
100
- end
96
+ setting(:revocation_strategies,
97
+ default: {},
98
+ constructor: ->(value) { constantize_values(symbolize_keys(value)) })
101
99
 
102
100
  Import = Dry::AutoInject(config)
103
101
  end
@@ -20,8 +20,8 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ['lib']
22
22
 
23
- spec.add_dependency 'dry-auto_inject', '~> 0.6'
24
- spec.add_dependency 'dry-configurable', '~> 0.9'
23
+ spec.add_dependency 'dry-auto_inject', '~> 0.8'
24
+ spec.add_dependency 'dry-configurable', '~> 0.13'
25
25
  spec.add_dependency 'jwt', '~> 2.1'
26
26
  spec.add_dependency 'warden', '~> 1.2'
27
27
 
@@ -30,6 +30,9 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency 'rack-test', '~> 1.1'
31
31
  spec.add_development_dependency 'rake', '~> 12.3'
32
32
  spec.add_development_dependency 'rspec', '~> 3.8'
33
+ # Cops
34
+ spec.add_development_dependency 'rubocop', '~> 0.87'
35
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.42'
33
36
  # Test reporting
34
37
  spec.add_development_dependency 'codeclimate-test-reporter', '~> 1.0'
35
38
  spec.add_development_dependency 'simplecov', '0.17'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: warden-jwt_auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc Busqué
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-06 00:00:00.000000000 Z
11
+ date: 2021-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-auto_inject
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.6'
19
+ version: '0.8'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.6'
26
+ version: '0.8'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: dry-configurable
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.9'
33
+ version: '0.13'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.9'
40
+ version: '0.13'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: jwt
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +136,34 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '3.8'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rubocop
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.87'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.87'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rubocop-rspec
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '1.42'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '1.42'
139
167
  - !ruby/object:Gem::Dependency
140
168
  name: codeclimate-test-reporter
141
169
  requirement: !ruby/object:Gem::Requirement
@@ -174,9 +202,6 @@ extra_rdoc_files: []
174
202
  files:
175
203
  - ".codeclimate.yml"
176
204
  - ".gitignore"
177
- - ".overcommit.yml"
178
- - ".overcommit_gems.rb"
179
- - ".reek"
180
205
  - ".rspec"
181
206
  - ".rubocop.yml"
182
207
  - ".travis.yml"
@@ -228,8 +253,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
228
253
  - !ruby/object:Gem::Version
229
254
  version: '0'
230
255
  requirements: []
231
- rubyforge_project:
232
- rubygems_version: 2.7.8
256
+ rubygems_version: 3.1.2
233
257
  signing_key:
234
258
  specification_version: 4
235
259
  summary: JWT authentication for Warden.
data/.overcommit.yml DELETED
@@ -1,54 +0,0 @@
1
- #
2
- # Select version of overcommit and the other tools from Gemfile
3
- #
4
- gemfile: .overcommit_gems.rb
5
-
6
- #
7
- # Hooks that are run against every commit message after a user has written it.
8
- #
9
- CommitMsg:
10
- ALL:
11
- required: true
12
- exclude: &default_excludes
13
- - Gemfile
14
- - CHANGELOG.md
15
- - warden-jwt_auth.gemspec
16
- - README.md
17
-
18
- HardTabs:
19
- enabled: true
20
-
21
- SingleLineSubject:
22
- enabled: true
23
-
24
- #
25
- # Hooks that are run after `git commit` is executed, before the commit message
26
- # editor is displayed.
27
- #
28
- PreCommit:
29
- ALL:
30
- required: true
31
- exclude: *default_excludes
32
-
33
- BundleAudit:
34
- enabled: true
35
-
36
- BundleCheck:
37
- enabled: true
38
-
39
- LocalPathsInGemfile:
40
- enabled: true
41
-
42
- ExecutePermissions:
43
- enabled: true
44
- exclude:
45
- - bin/*
46
-
47
- Reek:
48
- enabled: true
49
-
50
- RuboCop:
51
- enabled: true
52
-
53
- TrailingWhitespace:
54
- enabled: true
data/.overcommit_gems.rb DELETED
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- gem 'overcommit', '~> 0.36'
6
-
7
- # Patch-level verification for Bundled apps
8
- gem 'bundler-audit', '~> 0.5'
9
-
10
- # Ruby code smell reporter
11
- gem 'reek', '~> 4.5'
12
-
13
- # Ruby code style checking
14
- gem 'rubocop', '~> 0.43'
15
- gem 'rubocop-rspec', '~> 1.7'
data/.reek DELETED
File without changes