introspective_grape 0.5.0 → 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d15f31a850811633ad737c414309293b36b8cacb15508468e5155a5b6aec2bed
4
- data.tar.gz: 17b3a773228928342af7c692f2ac62352cd1bcdda2695351cae9cf56c449fc82
3
+ metadata.gz: 9e942af5ab00cc32f0611bfe27ec28ad6dbeb3d5b6f20d847dae3f1dd66cd5d2
4
+ data.tar.gz: 489588ff1f420618c18566e111933dab186cdc6d16493ec8a3f17cfad8ece9d6
5
5
  SHA512:
6
- metadata.gz: acf6d1def5d4df6c3438e67d1743c6dfe86a00b44044ce8b709e7800bca20096180084a0bb994b77535c4a956997df25c4dde8349f63b7831d17fe494e900c04
7
- data.tar.gz: 509de38fd9a074d493caf0389bdb10d8bfad3fe4a145e3f1c2a9ff30b33d2efc2fbfa466f6e743d081fa678035f05214b8c71f6305562f34a65faac530f1c96b
6
+ metadata.gz: 783bdfd1b17ba6709e2d86146d27e427579051e71de65fb76bebfe4f77ca445093fd03176f6adacf6749accf918ceb9a0a0fbb205ef06329da18535962ad98bd
7
+ data.tar.gz: 60bbbbf652648b841091fa37b6494b87a87fe6b72732b0d1f0540ad5b52ec258684b4ccd19bcee99f285b608a73a08f75975e0c6777900774b23d1b1d724e2d5
@@ -0,0 +1,32 @@
1
+ name: security
2
+ on: push
3
+ jobs:
4
+ security:
5
+ name: Security
6
+ runs-on: ubuntu-latest
7
+ steps:
8
+ - name: Checkout Repository
9
+ uses: actions/checkout@v2
10
+ - name: Set up Ruby
11
+ uses: ruby/setup-ruby@v1
12
+ with:
13
+ ruby-version: 2.6.2
14
+ - name: Cache Ruby Gems
15
+ uses: actions/cache@v2
16
+ with:
17
+ path: vendor/bundle
18
+ key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
19
+ restore-keys: |
20
+ ${{ runner.os }}-gems-
21
+ - name: Bundle Install
22
+ run: |
23
+ gem install bundler
24
+ bundle config path vendor/bundle
25
+ bundle install --jobs 4 --retry 3
26
+ - name: Security Checks
27
+ run: |
28
+ bundle exec brakeman -z
29
+ gem install bundle-audit
30
+ bundle-audit update
31
+ bundle-audit
32
+
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.5.0
1
+ 2.7.3
data/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+
2
+ 0.5.5 02/24/2022
3
+ ================
4
+
5
+ Update the local ruby in the gem to 2.7.3 to clear security warning cruft.
6
+
7
+ Sanitize some sql.
8
+
9
+ Target the still-supported 'kt-paperclip' in the gemspec (many pardons while we're planning the switch over to activestorage support).
10
+
11
+ Fix bug from looking for the ActiveRecord columns_hash on non-ActiveRecord objects.
12
+
13
+ 0.5.2 02/07/2022
14
+ ================
15
+
16
+ Lock down compatible Grape version to 1.6.0, as the next version has breaking changes for classes inheriting from Grape::Validator::Base.
17
+
18
+ 0.5.1 02/07/2022
19
+ ================
20
+
21
+ Removed stray require of 'byebug'.
22
+
1
23
  0.5.0 10/20/2021
2
24
  ================
3
25
 
data/README.md CHANGED
@@ -305,8 +305,7 @@ myself, but would be trivial to make more atomistic.
305
305
  ## Documenting Endpoints
306
306
 
307
307
  If you wish to provide additional documentation for end points you can define
308
- `self.<index,show,update,create,destroy>_documentation` class methods in the API class (or extend them
309
- from a documentation module, which would be preferable).
308
+ `self.<index,show,update,create,destroy>_documentation(name)` class methods in the API class (or extend them from a documentation module, which would be preferable).
310
309
 
311
310
  ## Grape Hooks - The Precedence of Declaration Matters
312
311
 
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
28
28
  s.add_runtime_dependency 'schema_validations'
29
29
  s.add_runtime_dependency 'rack'
30
30
 
31
- s.add_runtime_dependency 'grape'
31
+ s.add_runtime_dependency 'grape', '1.6.0'
32
32
  s.add_runtime_dependency 'dry-types'
33
33
  s.add_runtime_dependency 'grape-entity'
34
34
  s.add_runtime_dependency 'grape-swagger'
@@ -57,7 +57,7 @@ Gem::Specification.new do |s|
57
57
  s.add_development_dependency 'machinist_redux'
58
58
 
59
59
  # dummy app dependencies
60
- s.add_development_dependency 'paperclip'
60
+ s.add_development_dependency 'kt-paperclip'
61
61
  s.add_development_dependency 'rufus-mnemo'
62
62
  s.add_development_dependency 'devise'
63
63
  end
@@ -1,6 +1,6 @@
1
1
  require 'action_controller'
2
2
  require 'kaminari'
3
- require 'byebug'
3
+ #require 'byebug'
4
4
  require 'grape-kaminari'
5
5
  require 'introspective_grape/validators'
6
6
 
@@ -403,12 +403,12 @@ module IntrospectiveGrape
403
403
  def param_type(model, field)
404
404
  # Translate from the AR type to the GrapeParam types
405
405
  field = field.to_s
406
- db_type = (model&.columns_hash || {})[field]&.type
406
+ db_type = (model&.try(:columns_hash) || {})[field]&.type
407
407
 
408
408
  # Check if it's a file attachment, look for an override class from the model,
409
409
  # check PG2RUBY, use the database type, or fail over to a String:
410
410
  uploaded_file?(model, field) ||
411
- check_model_for_type(model, field) ||
411
+ check_model_for_type(model, field) ||
412
412
  PG2RUBY[db_type] ||
413
413
  db_type_constant(db_type) ||
414
414
  String # default to String if nothing else works
@@ -91,7 +91,7 @@ module IntrospectiveGrape
91
91
 
92
92
  if timestamp_filter(klass, model, field)
93
93
  op = field.ends_with?('_start') ? '>=' : '<='
94
- records.where("#{timestamp_filter(klass, model, field)} #{op} ?", Time.zone.parse(params[field]))
94
+ records.where(ActiveRecord::Base.sanitize_sql_array(["#{timestamp_filter(klass, model, field)} #{op} ?", Time.zone.parse(params[field])]))
95
95
  elsif model.respond_to?("#{field}=")
96
96
  records.send("#{field}=", params[field])
97
97
  else
@@ -1,56 +1,56 @@
1
- module IntrospectiveGrape
2
- module Traversal
3
- # For deeply nested endpoints we want to present the record being affected, these
4
- # methods traverse down from the parent instance to the child model associations
5
- # of the deeply nested route.
6
-
7
- def find_leaves(routes, record, params)
8
- # Traverse down our route and find the leaf's siblings from its parent, e.g.
9
- # project/#/teams/#/team_users ~> project.find.teams.find.team_users
10
- # (the traversal of the intermediate nodes occurs in find_leaf())
11
- return record if routes.size < 2 # the leaf is the root
12
-
13
- record = find_leaf(routes, record, params) || return
14
-
15
- assoc = routes.last
16
- if assoc.many?
17
- leaves = record.send( assoc.reflection.name ).includes( default_includes(assoc.model) )
18
- verify_records_found(leaves, routes)
19
- leaves
20
- else
21
- # has_one associations don't return a CollectionProxy and so don't support
22
- # eager loading.
23
- record.send( assoc.reflection.name )
24
- end
25
- end
26
-
27
- def verify_records_found(leaves, routes)
28
- return if (leaves.map(&:class) - [routes.last.model]).empty?
29
-
30
- raise ActiveRecord::RecordNotFound.new("Records contain the wrong models, they should all be #{routes.last.model.name}, found #{records.map(&:class).map(&:name).join(',')}")
31
- end
32
-
33
- def find_leaf(routes, record, params)
34
- return record unless routes.size > 1
35
-
36
- # For deeply nested routes we need to search from the root of the API to the leaf
37
- # of its nested associations in order to guarantee the validity of the relationship,
38
- # the authorization on the parent model, and the sanity of passed parameters.
39
- routes[1..-1].each do |r|
40
- if record && params[r.key]
41
- ref = r.reflection
42
- record = record.send(ref.name).where( id: params[r.key] ).first if ref
43
- end
44
- end
45
-
46
- verify_record_found(routes, params, record)
47
- record
48
- end
49
-
50
- def verify_record_found(routes, params, record)
51
- return unless params[routes.last.key] && record.class != routes.last.model
52
-
53
- raise ActiveRecord::RecordNotFound.new("No #{routes.last.model.name} with ID '#{params[routes.last.key]}'")
54
- end
55
- end
56
- end
1
+ module IntrospectiveGrape
2
+ module Traversal
3
+ # For deeply nested endpoints we want to present the record being affected, these
4
+ # methods traverse down from the parent instance to the child model associations
5
+ # of the deeply nested route.
6
+
7
+ def find_leaves(routes, record, params)
8
+ # Traverse down our route and find the leaf's siblings from its parent, e.g.
9
+ # project/#/teams/#/team_users ~> project.find.teams.find.team_users
10
+ # (the traversal of the intermediate nodes occurs in find_leaf())
11
+ return record if routes.size < 2 # the leaf is the root
12
+
13
+ record = find_leaf(routes, record, params) || return
14
+
15
+ assoc = routes.last
16
+ if assoc.many?
17
+ leaves = record.send( assoc.reflection.name ).includes( default_includes(assoc.model) )
18
+ verify_records_found(leaves, routes)
19
+ leaves
20
+ else
21
+ # has_one associations don't return a CollectionProxy and so don't support
22
+ # eager loading.
23
+ record.send( assoc.reflection.name )
24
+ end
25
+ end
26
+
27
+ def verify_records_found(leaves, routes)
28
+ return if (leaves.map(&:class) - [routes.last.model]).empty?
29
+
30
+ raise ActiveRecord::RecordNotFound.new("Records contain the wrong models, they should all be #{routes.last.model.name}, found #{records.map(&:class).map(&:name).join(',')}")
31
+ end
32
+
33
+ def find_leaf(routes, record, params)
34
+ return record unless routes.size > 1
35
+
36
+ # For deeply nested routes we need to search from the root of the API to the leaf
37
+ # of its nested associations in order to guarantee the validity of the relationship,
38
+ # the authorization on the parent model, and the sanity of passed parameters.
39
+ routes[1..-1].each do |r|
40
+ if record && params[r.key]
41
+ ref = r.reflection
42
+ record = record.send(ref.name).where( id: params[r.key] ).first if ref
43
+ end
44
+ end
45
+
46
+ verify_record_found(routes, params, record)
47
+ record
48
+ end
49
+
50
+ def verify_record_found(routes, params, record)
51
+ return unless params[routes.last.key] && record.class != routes.last.model
52
+
53
+ raise ActiveRecord::RecordNotFound.new("No #{routes.last.model.name} with ID '#{params[routes.last.key]}'")
54
+ end
55
+ end
56
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IntrospectiveGrape
4
- VERSION = '0.5.0'
4
+ VERSION = '0.5.5'
5
5
  end
@@ -0,0 +1 @@
1
+ 2.6.0
data/spec/dummy/Gemfile CHANGED
@@ -1,19 +1,19 @@
1
1
  source 'https://rubygems.org'
2
- gem 'rails', '5.2.6'
2
+ gem 'rails', '5.2.6.2'
3
3
 
4
4
  gem 'byebug'
5
5
  gem 'camel_snake_keys'
6
6
 
7
7
  gem 'devise'
8
8
  gem 'delayed_paperclip'
9
- #gem 'devise-async'
9
+ gem 'kt-paperclip'
10
10
 
11
11
  gem 'grape'
12
12
  gem 'grape-entity'
13
13
  gem 'grape-kaminari'
14
14
  gem 'grape-swagger'
15
15
  gem 'grape-swagger-entity'
16
- gem 'introspective_grape', path: '~/Dropbox/contrib/introspective_grape'
16
+ gem 'introspective_grape' #, path: '~/Dropbox/contrib/introspective_grape'
17
17
 
18
18
  gem 'paperclip'
19
19
  gem 'pundit'
@@ -14,6 +14,15 @@ class Dummy::CompanyAPI < IntrospectiveGrape::API
14
14
  present params
15
15
  end
16
16
 
17
+ desc "Test kaminari pagination in a custom index"
18
+ params do
19
+ use :pagination
20
+ end
21
+ get '/paginated/list' do
22
+ authorize Company.new, :index?
23
+ companies = Company.all
24
+ present paginate(companies), using: CompanyEntity
25
+ end
17
26
  end
18
27
 
19
28
  class CompanyEntity < Grape::Entity
@@ -27,6 +27,15 @@ describe Dummy::CompanyAPI, type: :request do
27
27
  json.first['id'].should eq Company.first.id
28
28
  response.headers.slice("X-Total", "X-Total-Pages", "X-Per-Page", "X-Page", "X-Next-Page", "X-Prev-Page", "X-Offset").values.should eq ["30", "2", "25", "1", "2", "", "0"]
29
29
  end
30
+
31
+ it "should allow pagination in a custom index" do
32
+ Company.destroy_all
33
+ 30.times { Company.make! }
34
+
35
+ get '/api/v1/companies/paginated/list'
36
+ response.should be_successful
37
+ response.headers.slice("X-Total", "X-Total-Pages", "X-Per-Page", "X-Page", "X-Next-Page", "X-Prev-Page", "X-Offset").values.should eq ["30", "2", "25", "1", "2", "", "0"]
38
+ end
30
39
  end
31
40
 
32
41
  before :all do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: introspective_grape
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Buermann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-27 00:00:00.000000000 Z
11
+ date: 2022-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -56,16 +56,16 @@ dependencies:
56
56
  name: grape
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: 1.6.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: 1.6.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: dry-types
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -291,7 +291,7 @@ dependencies:
291
291
  - !ruby/object:Gem::Version
292
292
  version: '0'
293
293
  - !ruby/object:Gem::Dependency
294
- name: paperclip
294
+ name: kt-paperclip
295
295
  requirement: !ruby/object:Gem::Requirement
296
296
  requirements:
297
297
  - - ">="
@@ -344,6 +344,7 @@ extensions: []
344
344
  extra_rdoc_files: []
345
345
  files:
346
346
  - ".github/workflows/lint.yml"
347
+ - ".github/workflows/security.yml"
347
348
  - ".github/workflows/test.yml"
348
349
  - ".gitignore"
349
350
  - ".rubocop.yml"
@@ -375,6 +376,7 @@ files:
375
376
  - lib/introspective_grape/validators.rb
376
377
  - lib/introspective_grape/version.rb
377
378
  - lib/tasks/introspective_grape_tasks.rake
379
+ - spec/dummy/.ruby-version
378
380
  - spec/dummy/Gemfile
379
381
  - spec/dummy/README.rdoc
380
382
  - spec/dummy/Rakefile
@@ -538,12 +540,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
538
540
  - !ruby/object:Gem::Version
539
541
  version: '0'
540
542
  requirements: []
541
- rubyforge_project:
542
- rubygems_version: 2.7.3
543
+ rubygems_version: 3.1.6
543
544
  signing_key:
544
545
  specification_version: 4
545
546
  summary: Quickly configure Grape APIs around your database schema and models.
546
547
  test_files:
548
+ - spec/dummy/.ruby-version
547
549
  - spec/dummy/Gemfile
548
550
  - spec/dummy/README.rdoc
549
551
  - spec/dummy/Rakefile