Module: Serega::SeregaPlugins::DepthLimit

Defined in:
lib/serega/plugins/depth_limit/depth_limit.rb

Overview

Plugin :depth_limit

Helps to secure from malicious queries that require to serialize too much or from accidental serializing of objects with cyclic relations.

Depth limit is checked when constructing a serialization plan, that is when ‘#new` method is called, ex: `SomeSerializer.new(with: params)`. It can be useful to instantiate serializer before any other business logic to get possible errors earlier.

Any class-level serialization methods also check depth limit as they also instantiate serializer.

When depth limit is exceeded ‘Serega::DepthLimitError` is raised. Depth limit error details can be found in additional `Serega::DepthLimitError#details` method

Limit can be checked or changed with next config options:

- config.depth_limit.limit
- config.depth_limit.limit=

There are no default limit, but it should be set when enabling plugin.

Examples:


class AppSerializer < Serega
  plugin :depth_limit, limit: 10 # set limit for all child classes
end

class UserSerializer < AppSerializer
  config.depth_limit.limit = 5 # overrides limit for UserSerializer
end

Defined Under Namespace

Modules: ConfigInstanceMethods, PlanInstanceMethods Classes: DepthLimitConfig

Class Method Summary collapse

Class Method Details

.after_load_plugin(serializer_class, **opts) ⇒ void

This method returns an undefined value.

Adds config options and runs other callbacks after plugin was loaded

Parameters:

  • serializer_class (Class<Serega>)

    Current serializer class

  • opts (Hash)

    Plugin options



83
84
85
86
87
88
# File 'lib/serega/plugins/depth_limit/depth_limit.rb', line 83

def self.after_load_plugin(serializer_class, **opts)
  config = serializer_class.config
  limit = opts.fetch(:limit) { raise SeregaError, "Please provide :limit option. Example: `plugin :depth_limit, limit: 10`" }
  config.opts[:depth_limit] = {}
  config.depth_limit.limit = limit
end

.before_load_plugin(serializer_class, **opts) ⇒ void

This method returns an undefined value.

Checks requirements

Parameters:

  • serializer_class (Class<Serega>)

    Current serializer class

  • opts (Hash)

    Plugin options



51
52
53
54
55
56
57
58
59
60
# File 'lib/serega/plugins/depth_limit/depth_limit.rb', line 51

def self.before_load_plugin(serializer_class, **opts)
  allowed_keys = %i[limit]
  opts.each_key do |key|
    next if allowed_keys.include?(key)

    raise SeregaError,
      "Plugin #{plugin_name.inspect} does not accept the #{key.inspect} option. Allowed options:\n" \
      "  - :limit [Integer] - Maximum serialization depth."
  end
end

.load_plugin(serializer_class, **_opts) ⇒ void

This method returns an undefined value.

Applies plugin code to specific serializer

Parameters:

  • serializer_class (Class<Serega>)

    Current serializer class

  • _opts (Hash)

    Plugin options



70
71
72
73
# File 'lib/serega/plugins/depth_limit/depth_limit.rb', line 70

def self.load_plugin(serializer_class, **_opts)
  serializer_class::SeregaPlan.include(PlanInstanceMethods)
  serializer_class::SeregaConfig.include(ConfigInstanceMethods)
end

.plugin_nameSymbol

Returns Plugin name.

Returns:

  • (Symbol)

    Plugin name



40
41
42
# File 'lib/serega/plugins/depth_limit/depth_limit.rb', line 40

def self.plugin_name
  :depth_limit
end