rails_admin 4.0.0.beta → 4.0.0.beta2

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: 265b6c74c33bfe7712068b6a22213f0cf0bce3a32bde103dd079551e3545ff50
4
- data.tar.gz: 00714d31e5cdb32374e787bbdae8bd8b072284ced7b8528c0341f7dd0cec33ba
3
+ metadata.gz: 4ac4367d2e50b1a9c0edbfde3e76b5bd8c8e31ece5148117d95fc770fcb55680
4
+ data.tar.gz: 95822b85925077cb76677ccc514f404f34a4a25b1197a34cf48e56d4e9294445
5
5
  SHA512:
6
- metadata.gz: 10f275394cb1a715e526fcf04e2df6f1a8e9e3ba3a43aaa7b0f24e5787d6dd37281b882a1672037d584d0e80438eb0cd4545d2fec6bdf8e2b8d89380cf7de9af
7
- data.tar.gz: acac945ddc87533cb55225201fb79508f99febbda2f4758fd3ed61f193fca4c736a90a29e3f21386903d978055eb84c224f62932709d6e49c75dc80007025bb1
6
+ metadata.gz: 502b9d17e9e740a3ae0535e464e20beea25dcf15a790a589c683bd13a03dd7255532f7476b4071f8a6a80d4ac3ddd9942898c47e832d6f0fc4edfd6cb6e5a20a
7
+ data.tar.gz: 1ea176e0878e1457f3c12410060755ab6aee5b1ee2ca658878253a67f92d30b5f7aa59f732a13d2a0e55f54fd60c6fd101e615c80416394908e1c33f4d603f65
@@ -94,6 +94,17 @@ module RailsAdmin
94
94
  model_config.send(action).with(controller: self, view: view_context, object: @object).visible_fields
95
95
  end
96
96
 
97
+ # Memoized, as export renders through index, which switches @action
98
+ def serialization_schema
99
+ @serialization_schema ||= begin
100
+ section = %i[export show].include?(@action.key) ? @model_config.send(@action.key) : @model_config.list
101
+ RailsAdmin::SerializationSchema.new(
102
+ section.with(controller: self, view: view_context, object: @object || @abstract_model.dummy_record),
103
+ include_associations: @action.key == :export,
104
+ )
105
+ end
106
+ end
107
+
97
108
  def sanitize_params_for!(action, model_config = @model_config, target_params = params[@abstract_model.param_key])
98
109
  return unless target_params.present?
99
110
 
@@ -114,7 +114,7 @@ module RailsAdmin
114
114
  :attribute_length_options, :attribute_enum_values, :dummy_record,
115
115
  to: :reflection
116
116
 
117
- delegate :new, :get, :first, :all, :count, :destroy, :scoped, :where, :read, :save, :each_record,
117
+ delegate :new, :get, :first, :all, :count, :destroy, :scoped, :none, :where, :read, :save, :each_record,
118
118
  :each_associated_children, :format_id, :parse_id,
119
119
  :serialize_attribute, :deserialize_attribute,
120
120
  :sort_expression, :search_column, :parse_object_id,
@@ -31,6 +31,11 @@ module RailsAdmin
31
31
  model.scoped
32
32
  end
33
33
 
34
+ # Criteria#none is lost when merged into another criteria
35
+ def none
36
+ scoped.in(_id: [])
37
+ end
38
+
34
39
  # Mongoid's #attributes holds what the document actually carries, so an
35
40
  # attribute that was never set is not in there and the method wins.
36
41
  def read(record, name)
@@ -19,6 +19,13 @@ module RailsAdmin
19
19
  delegate :model, :config, :associations, :primary_key, :primary_keys, :table_name,
20
20
  :quoted_table_name, :quote_column_name, to: :abstract_model
21
21
 
22
+ # A scope matching no record, which an authorization adapter returns to
23
+ # deny all of them. It is merged into the list's scope, so it has to
24
+ # survive a merge.
25
+ def none
26
+ scoped.none
27
+ end
28
+
22
29
  # Yield the records of a scope one at a time, in the order it is sorted in,
23
30
  # without holding all of them at once. What an export walks.
24
31
  #
@@ -19,7 +19,8 @@ module RailsAdmin
19
19
  format = params[:json] && :json || params[:csv] && :csv || params[:xml] && :xml
20
20
  if format
21
21
  request.format = format
22
- @schema = HashHelper.symbolize(params[:schema].slice(:except, :include, :methods, :only).permit!.to_h) if params[:schema] # to_json and to_xml expect symbols for keys AND values.
22
+ serialization_schema # built while @action is still export
23
+ @schema = serialization_schema.sanitize(params[:schema].slice(:include, :methods, :only).permit!.to_h) if params[:schema]
23
24
  @objects = list_entries(@model_config, :export)
24
25
  index
25
26
  else
@@ -56,7 +56,7 @@ module RailsAdmin
56
56
  @objects.collect { |object| {id: object.id.to_s, label: @model_config.object_label(object).to_s} }
57
57
  end
58
58
  else
59
- @objects.to_json(@schema)
59
+ @objects.to_json(@schema || serialization_schema.default)
60
60
  end
61
61
 
62
62
  if params[:send_data]
@@ -67,7 +67,7 @@ module RailsAdmin
67
67
  end
68
68
 
69
69
  format.xml do
70
- output = @objects.to_xml(@schema)
70
+ output = @objects.to_xml(@schema || serialization_schema.default)
71
71
  if params[:send_data]
72
72
  send_data output, filename: "#{params[:model_name]}_#{DateTime.now.strftime('%Y-%m-%d_%Hh%Mm%S')}.xml"
73
73
  else
@@ -22,7 +22,7 @@ module RailsAdmin
22
22
  proc do
23
23
  respond_to do |format|
24
24
  format.html { render @action.template_name }
25
- format.json { render json: @object }
25
+ format.json { render json: @object.to_json(serialization_schema.default) }
26
26
  end
27
27
  end
28
28
  end
@@ -44,7 +44,8 @@ module RailsAdmin
44
44
  def query(_action, abstract_model)
45
45
  @controller.send(:policy_scope, abstract_model.scoped)
46
46
  rescue ::Pundit::NotDefinedError
47
- abstract_model.scoped
47
+ # Fail closed: a missing policy scope must not be treated as "no restriction".
48
+ abstract_model.none
48
49
  end
49
50
 
50
51
  # This is called in the new/create actions to determine the initial attributes for new
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_admin/support/hash_helper'
4
+
5
+ module RailsAdmin
6
+ # The options passed to to_json/to_xml, limited to what a section exposes.
7
+ # It mirrors what the export form offers, as the form is what builds them.
8
+ class SerializationSchema
9
+ def initialize(section, include_associations:)
10
+ @section = section
11
+ @include_associations = include_associations
12
+ end
13
+
14
+ def default
15
+ sanitize(allowed)
16
+ end
17
+
18
+ # Anything not allowed is dropped, and `only` is always set, since leaving
19
+ # it out makes to_json/to_xml serialize every attribute.
20
+ def sanitize(requested)
21
+ requested = HashHelper.symbolize(requested)
22
+ schema = filter(requested, allowed)
23
+ if @include_associations && requested[:include].is_a?(Hash)
24
+ schema[:include] = requested[:include].each_with_object({}) do |(name, value), included|
25
+ next unless value.is_a?(Hash) && allowed[:include].key?(name)
26
+
27
+ included[name] = filter(value, allowed[:include][name])
28
+ end
29
+ end
30
+ schema
31
+ end
32
+
33
+ private
34
+
35
+ def allowed
36
+ @allowed ||= begin
37
+ fields = @section.visible_fields
38
+ names = field_names(fields.select { |f| !f.association? || f.association.polymorphic? })
39
+ if @include_associations
40
+ names[:include] = fields.select { |f| f.association? && !f.association.polymorphic? }.to_h do |field|
41
+ associated = field.associated_model_config.export.with(@section.bindings.merge(object: field.associated_model_config.abstract_model.dummy_record))
42
+ [field.name, field_names(associated.visible_fields.reject(&:association?))]
43
+ end
44
+ else
45
+ # The list shows these associations already, so their keys expose nothing more
46
+ names[:only].concat(fields.select { |f| f.association? && f.association.type == :belongs_to && !f.association.polymorphic? }.
47
+ flat_map { |f| Array(f.association.foreign_key) })
48
+ end
49
+ names
50
+ end
51
+ end
52
+
53
+ def field_names(fields)
54
+ fields.each_with_object({only: [], methods: []}) do |field, names|
55
+ list = field.virtual? ? names[:methods] : names[:only]
56
+ if field.association?
57
+ list << field.method_name.to_sym << field.association.foreign_type.to_sym
58
+ else
59
+ list << field.name
60
+ end
61
+ end
62
+ end
63
+
64
+ def filter(requested, permitted)
65
+ only = Array(requested[:only]) & permitted[:only]
66
+ # Mongoid serializes every attribute for an empty `only`
67
+ schema = {only: only.presence || [:__none__]}
68
+ schema[:methods] = Array(requested[:methods]) & permitted[:methods] if requested.key?(:methods)
69
+ schema
70
+ end
71
+ end
72
+ end
@@ -5,7 +5,7 @@ module RailsAdmin
5
5
  MAJOR = 4
6
6
  MINOR = 0
7
7
  PATCH = 0
8
- PRE = 'beta'
8
+ PRE = 'beta2'
9
9
 
10
10
  class << self
11
11
  # @return [String]
data/lib/rails_admin.rb CHANGED
@@ -10,6 +10,7 @@ require 'rails_admin/extensions/pundit'
10
10
  require 'rails_admin/extensions/paper_trail'
11
11
  require 'rails_admin/support/csv_converter'
12
12
  require 'rails_admin/support/hash_helper'
13
+ require 'rails_admin/support/serialization_schema'
13
14
  require 'yaml'
14
15
 
15
16
  module RailsAdmin
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rails_admin",
3
- "version": "4.0.0-beta",
3
+ "version": "4.0.0-beta2",
4
4
  "description": "RailsAdmin is a Rails engine that provides an easy-to-use interface for managing your data.",
5
5
  "homepage": "https://github.com/railsadminteam/rails_admin",
6
6
  "license": "MIT",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.beta
4
+ version: 4.0.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik Michaels-Ober
@@ -341,6 +341,7 @@ files:
341
341
  - lib/rails_admin/support/csv_converter.rb
342
342
  - lib/rails_admin/support/datetime.rb
343
343
  - lib/rails_admin/support/hash_helper.rb
344
+ - lib/rails_admin/support/serialization_schema.rb
344
345
  - lib/rails_admin/version.rb
345
346
  - lib/tasks/assets.rake
346
347
  - lib/tasks/rails_admin.rake