Class: Protector::DSL::Meta::Box

Inherits:
Object
  • Object
show all
Defined in:
lib/protector/dsl.rb

Overview

Single DSL evaluation result

Instance Attribute Summary collapse

Protection DSL collapse

Instance Method Summary collapse

Constructor Details

#initialize(adapter, model, fields, subject, entry, blocks) ⇒ Box

Returns a new instance of Box.

Parameters:

  • model (Class)

    The class of protected entity

  • fields (Array<String>)

    All the fields the model has

  • subject (Object)

    Restriction subject

  • entry (Object)

    An instance of the model

  • blocks (Array<Proc>)

    An array of protect blocks



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/protector/dsl.rb', line 15

def initialize(adapter, model, fields, subject, entry, blocks)
  @adapter     = adapter
  @model       = model
  @fields      = fields
  @access      = {update: {}, view: {}, create: {}}
  @scope_proc  = false
  @destroyable = false

  Protector.insecurely do
    blocks.each do |b|
      case b.arity
      when 2
        instance_exec subject, entry, &b
      when 1
        instance_exec subject, &b
      else
        instance_exec &b
      end
    end
  end
end

Instance Attribute Details

#accessObject

Returns the value of attribute access.



8
9
10
# File 'lib/protector/dsl.rb', line 8

def access
  @access
end

#adapterObject

Returns the value of attribute adapter.



8
9
10
# File 'lib/protector/dsl.rb', line 8

def adapter
  @adapter
end

#destroyableObject

Returns the value of attribute destroyable.



8
9
10
# File 'lib/protector/dsl.rb', line 8

def destroyable
  @destroyable
end

Instance Method Details

#can(action, *fields) ⇒ Object

Enables action for given fields.

Built-in possible actions are: :view, :update, :create. You can pass any other actions you want to use with #can? afterwards.

The method enables action for every field if fields splat is empty. Use #cannot to exclude some of them afterwards.

The list of fields can be given as a Hash. In this form you can pass Range or Proc as a value. First will make Protector check against value inclusion. The latter will make it evaluate given lambda (which is supposed to return true or false determining if the value should validate or not).

Examples:

protect do
  can :view               # Can view any field
  can :view, 'f1'         # Can view `f1` field
  can :view, %w(f2 f3)    # Can view `f2`, `f3` fields
  can :update, f1: 1..2   # Can update f1 field with values between 1 and 2

  # Can create f1 field with value equal to 'olo'
  can :create, f1: lambda{|x| x == 'olo'}
end

Parameters:

  • action (Symbol)

    Action to allow

  • fields (String, Hash, Array)

    Splat of fields to allow action with

See Also:



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/protector/dsl.rb', line 105

def can(action, *fields)
  return @destroyable = true if action == :destroy
  @access[action] = {} unless @access[action]

  if fields.size == 0
    @fields.each{|f| @access[action][f.to_s] = nil}
  else
    fields.each do |a|
      if a.is_a?(Array)
        a.each{|f| @access[action][f.to_s] = nil}
      elsif a.is_a?(Hash)
        @access[action].merge!(a.stringify_keys)
      else
        @access[action][a.to_s] = nil
      end
    end
  end
end

#can?(action, field = false) ⇒ Boolean

Check whether you can perform custom action for given fields (or generally if no field given)

Parameters:

  • action (Symbol)

    Action to check against

  • field (String) (defaults to: false)

    Field to check against

Returns:

  • (Boolean)


184
185
186
187
188
# File 'lib/protector/dsl.rb', line 184

def can?(action, field=false)
  return false unless @access[action]
  return !@access[action].empty? if field === false
  @access[action].has_key?(field.to_s)
end

#cannot(action, *fields) ⇒ Object

Disables action for given fields.

Works similar (but oppositely) to #can.

Parameters:

  • action (Symbol)

    Action to disallow

  • fields (String, Hash, Array)

    Splat of fields to disallow action with

See Also:



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/protector/dsl.rb', line 133

def cannot(action, *fields)
  return @destroyable = false if action == :destroy
  return unless @access[action]

  if fields.size == 0
    @access[action].clear
  else
    fields.each do |a|
      if a.is_a?(Array)
        a.each{|f| @access[action].delete(f.to_s)}
      else
        @access[action].delete(a.to_s)
      end
    end
  end
end

#creatable?(fields = false) ⇒ Boolean

Checks whether you can create a model with given field in context of current subject

Returns:

  • (Boolean)


158
159
160
# File 'lib/protector/dsl.rb', line 158

def creatable?(fields=false)
  modifiable? :create, fields
end

#destroyable?Boolean

Checks whether you can destroy a model in context of current subject

Returns:

  • (Boolean)


176
177
178
# File 'lib/protector/dsl.rb', line 176

def destroyable?
  @destroyable
end

#first_uncreatable_field(fields) ⇒ Object



162
163
164
# File 'lib/protector/dsl.rb', line 162

def first_uncreatable_field(fields)
  first_unmodifiable_field :create, fields
end

#first_unupdatable_field(fields) ⇒ Object



171
172
173
# File 'lib/protector/dsl.rb', line 171

def first_unupdatable_field(fields)
  first_unmodifiable_field :update, fields
end

#readable?(field) ⇒ Boolean

Checks whether given field of a model is readable in context of current subject

Returns:

  • (Boolean)


153
154
155
# File 'lib/protector/dsl.rb', line 153

def readable?(field)
  @access[:view].has_key?(field)
end

#relationObject



70
71
72
73
74
75
# File 'lib/protector/dsl.rb', line 70

def relation
  return false unless scoped?

  @relation ||= @model.instance_eval(&scope_proc)
  @relation
end

#scope { ... } ⇒ Object

Activates the scope that selections will be filtered with

Examples:

protect do
  # You can select nothing!
  scope { none }
end

Yields:

  • Calls given model methods before the selection



55
56
57
58
59
60
# File 'lib/protector/dsl.rb', line 55

def scope(&block)
  @scope_proc = block

  @relation          = false
  @unscoped_relation = false
end

#scope_procObject



62
63
64
65
66
67
68
# File 'lib/protector/dsl.rb', line 62

def scope_proc
  unless Protector.config.paranoid?
    @scope_proc
  else
    @scope_proc || @adapter.null_proc
  end
end

#scoped?Boolean

Checks whether protection with given subject has the selection scope defined

Returns:

  • (Boolean)


39
40
41
# File 'lib/protector/dsl.rb', line 39

def scoped?
  Protector.config.paranoid? || !!@scope_proc
end

#updatable?(fields = false) ⇒ Boolean

Checks whether you can update a model with given field in context of current subject

Returns:

  • (Boolean)


167
168
169
# File 'lib/protector/dsl.rb', line 167

def updatable?(fields=false)
  modifiable? :update, fields
end