class Apiphobic::Authorization::Authorizers::Parameters

Attributes

action[RW]
audience[RW]
authorized_attributes[W]
authorized_filters[W]
authorized_inclusions[W]
authorized_relationships[W]
authorized_sorts[W]
ignored_attributes[W]
parameters[RW]
token[RW]
user[RW]

Public Class Methods

new(action:, token:, audience:, issuer:, parameters:, **other) click to toggle source

rubocop:disable Metrics/ParameterLists

# File lib/apiphobic/authorization/authorizers/parameters.rb, line 27
def initialize(action:, token:, audience:, issuer:, parameters:, **other)
  self.action     = action
  self.audience   = audience
  self.parameters = parameters.deep_dup
  self.token      = token

  other.each do |name, value|
    public_send("#{name}=", value)
  end
end

Public Instance Methods

authorized_attributes() click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 73
def authorized_attributes
  @authorized_attributes || []
end
authorized_filters() click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 77
def authorized_filters
  @authorized_filters || []
end
authorized_inclusions() click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 81
def authorized_inclusions
  @authorized_inclusions || []
end
authorized_parameters() click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 41
def authorized_parameters
  @authorized_parameters || [
                              :include,
                              :sort,
                              {
                                name:                :data,
                                authorization_value: [
                                                       :type,
                                                       :id,
                                                       {
                                                         attributes:    nil,
                                                         relationships: nil,
                                                       },
                                                     ],
                              },
                              {
                                name:                :filter,
                                authorization_value: [{}],
                              },
                              {
                                name:                :page,
                                authorization_value: %i{
                                                       number
                                                       size
                                                       offset
                                                       limit
                                                       cursor
                                                     },
                              },
                            ]
end
authorized_relationships() click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 85
def authorized_relationships
  @authorized_relationships || []
end
authorized_sorts() click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 89
def authorized_sorts
  @authorized_sorts || []
end
call() click to toggle source

rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity

# File lib/apiphobic/authorization/authorizers/parameters.rb, line 98
def call
  sliced_parameters = authorized_parameters.map { |v| v.is_a?(::Hash) ? v[:name] : v }

  parameters.slice!(*sliced_parameters)

  authorized_parameters.each do |parameter|
    parameter = { name: parameter } unless parameter.is_a?(::Hash)

    authorize_parameter(value:                    parameters[parameter],
                        authorization_parameters: authorization,
                        raw_parameters:           parameters,
                        **parameter)
  end

  authorized_attributes.each do |attribute|
    attribute = { name: attribute } unless attribute.is_a?(::Hash)

    authorize_attribute(**attribute)
  end

  ignored_attributes.each do |attribute|
    attribute = { name: attribute } unless attribute.is_a?(::Hash)

    ignore_attribute(**attribute)
  end

  authorized_filters.each do |filter|
    filter = { name: filter } unless filter.is_a?(::Hash)

    authorize_filter(**filter)
  end

  authorized_relationships.each do |name|
    name = { name: name } unless name.is_a?(::Hash)

    authorize_relationship(**name)
  end

  authorize_inclusions(names: authorized_inclusions)
  authorize_sorts(names: authorized_sorts)

  parameters.permit(*authorization)
end
ignored_attributes() click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 93
def ignored_attributes
  @ignored_attributes || []
end

Private Instance Methods

authorization() click to toggle source

rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity

# File lib/apiphobic/authorization/authorizers/parameters.rb, line 145
def authorization
  @authorization ||= [{}]
end
authorize_attribute(**args) click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 149
def authorize_attribute(**args)
  authorize_parameter(
    value:                    raw_parameter_attribute_value(args[:name]),
    authorization_parameters: authorized_parameter_attributes,
    raw_parameters:           raw_parameter_attributes,
    **args,
  )
end
authorize_filter(**args) click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 158
def authorize_filter(**args)
  authorize_parameter(
    value:                    raw_parameter_filter_value(args[:name]),
    authorization_parameters: authorized_parameter_filters,
    raw_parameters:           raw_parameter_filters,
    **args,
  )
end
authorize_inclusions(names:) click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 167
def authorize_inclusions(names:)
  return if names.empty?

  all_requested_inclusions_authorized = raw_parameter_inclusions
                                          .to_s
                                          .split(',')
                                          .all? do |inclusion|
                                            names.map(&:to_s).include?(inclusion.to_s)
                                          end

  fail Errors::UnpermittedInclusions.new(inclusions: raw_parameter_inclusions) \
    unless all_requested_inclusions_authorized
end
authorize_parameter(name:, value:, authorization_parameters:, authorization_value: nil, raw_parameters:, allowed_values: nil, override: {}) click to toggle source

rubocop:disable Metrics/ParameterLists

# File lib/apiphobic/authorization/authorizers/parameters.rb, line 197
def authorize_parameter(name:,
                        value:,
                        authorization_parameters:,
                        authorization_value: nil,
                        raw_parameters:,
                        allowed_values: nil,
                        override: {})

  value = override_parameter(name:     name,
                             value:    value,
                             hash:     raw_parameters,
                             override: override)

  return unless allowed_values.nil? || allowed_values.include?(value)

  if authorization_value
    authorization_parameters[0][name] = authorization_value
  elsif value.class == ::Array
    authorization_parameters[0][name] = []
  else
    authorization_parameters << name
  end
end
authorize_relationship(name:, embedded_attributes: []) click to toggle source

rubocop:enable Metrics/ParameterLists

# File lib/apiphobic/authorization/authorizers/parameters.rb, line 222
def authorize_relationship(name:, embedded_attributes: [])
  relationship_data = raw_parameter_relationship_data(name)
  to_many_relation  = relationship_data.is_a?(::Array)
  first_relation    = if to_many_relation
                        relationship_data[0]
                      else
                        relationship_data || {}
                      end
  embedded_relation = first_relation[:attributes]

  authorized_parameter_relationships[name] = if relationship_data.nil?
                                               %i{data}
                                             elsif embedded_relation
                                               {
                                                 data: [
                                                         :id,
                                                         :type,
                                                         {
                                                           attributes: %i{__id__} +
                                                           embedded_attributes,
                                                         },
                                                       ],
                                               }
                                             else
                                               { data: %i{type id} }
                                             end
end
authorize_sorts(names:) click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 181
def authorize_sorts(names:)
  return if names.empty?

  all_requested_sorts_authorized = raw_parameter_sorts
                                     .to_s
                                     .delete('-')
                                     .split(',')
                                     .all? do |sort|
                                       names.map(&:to_s).include?(sort.to_s)
                                     end

  fail Errors::UnpermittedSorts.new(sorts: raw_parameter_sorts) \
    unless all_requested_sorts_authorized
end
authorized_data_parameter() click to toggle source

rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity

# File lib/apiphobic/authorization/authorizers/parameters.rb, line 273
def authorized_data_parameter
  authorization[0][:data][2]
end
authorized_parameter_attributes() click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 277
def authorized_parameter_attributes
  authorized_data_parameter[:attributes] ||= [{}]
end
authorized_parameter_filters() click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 285
def authorized_parameter_filters
  authorization[0][:filter] ||= [{}]
end
authorized_parameter_relationships() click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 281
def authorized_parameter_relationships
  authorized_data_parameter[:relationships] ||= {}
end
ignore_attribute(name:) click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 250
def ignore_attribute(name:)
  key_match = ->(k, _v) { k.to_s == name.to_s }

  parameters[:data][:attributes]    = raw_parameter_attributes.delete_if(&key_match)
  parameters[:data][:relationships] = raw_parameter_relationships.delete_if(&key_match)
end
override_parameter(name:, value:, hash:, override:) click to toggle source

rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity

# File lib/apiphobic/authorization/authorizers/parameters.rb, line 258
def override_parameter(name:, value:, hash:, override:)
  override = { with: nil, if_admin: false, if_absent: true, if_blank: true }
               .merge(override)

  return value unless override[:with] &&
                      (!token.admin? || override[:if_admin]) &&
                      (hash.has_key?(name) || override[:if_absent]) &&
                      (!hash.has_key?(name) || !value.nil? || override[:if_blank])

  hash[name] = override[:with]

  override[:with]
end
raw_parameter_attribute_value(name) click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 321
def raw_parameter_attribute_value(name)
  raw_parameter_attributes[name]
end
raw_parameter_attributes() click to toggle source

rubocop:disable Layout/ExtraSpacing

# File lib/apiphobic/authorization/authorizers/parameters.rb, line 290
def raw_parameter_attributes
  @raw_parameter_attributes ||= begin
    parameters[:data]              ||= {}
    parameters[:data][:attributes] ||= {}

    parameters[:data][:attributes]
  end
end
raw_parameter_filter_value(name) click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 325
def raw_parameter_filter_value(name)
  raw_parameter_filters[name]
end
raw_parameter_filters() click to toggle source

rubocop:enable Layout/ExtraSpacing

# File lib/apiphobic/authorization/authorizers/parameters.rb, line 300
def raw_parameter_filters
  @raw_parameter_filters ||= parameters[:filter] ||= {}
end
raw_parameter_inclusions() click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 304
def raw_parameter_inclusions
  @raw_parameter_inclusions ||= parameters[:include]
end
raw_parameter_relationship(name) click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 329
def raw_parameter_relationship(name)
  raw_parameter_relationships.fetch(name, {})
end
raw_parameter_relationship_data(name) click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 333
def raw_parameter_relationship_data(name)
  raw_parameter_relationship(name).fetch(:data, nil)
end
raw_parameter_relationships() click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 308
def raw_parameter_relationships
  @raw_parameter_relationships        ||= begin
    parameters[:data]                 ||= {}
    parameters[:data][:relationships] ||= {}

    parameters[:data][:relationships]
  end
end
raw_parameter_sorts() click to toggle source
# File lib/apiphobic/authorization/authorizers/parameters.rb, line 317
def raw_parameter_sorts
  @raw_parameter_sorts ||= parameters[:sort]
end