Class: Incline::ActionSecurity

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/incline/action_security.rb

Constant Summary collapse

SHORT_PERMITTED_FILTERS =
{
    '- Editable -' => 'users|custom',
    'Admins' => 'admins',
    'Anon' => 'anon',
    'Custom' => 'custom',
    'Everyone' => 'everyone',
    'Users' => 'users'
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.valid_items(refresh = false, update_flags = true) ⇒ Object

Generates a list of security items related to all of the current routes in the application.

If “refresh” is true, the list will be rebuilt. If “update_flags” is true, the individual controllers will be loaded to regenerate the flags for the security.

The returned list can be indexed two ways. The normal way with a numeric index and also by specifying the controller_name and action_name.

Incline::ActionSecurity.valid_items[0]
Incline::ActionSecurity.valid_items['incline/welcome','home']


108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'app/models/incline/action_security.rb', line 108

def self.valid_items(refresh = false, update_flags = true)
  @valid_items = nil if refresh
  @valid_items ||=
      begin
        Incline::ActionSecurity.update_all(visible: false)

        ret = Incline
                  .route_list
                  .reject{|r| r[:action] == 'api'}
                  .map do |r|
          item = ActionSecurity.find_or_initialize_by(controller_name: r[:controller], action_name: r[:action])
          item.path = "#{r[:path]} [#{r[:verb]}]"
          item.visible = true
          item.update_flags if update_flags
          item.save!
          item
        end
                  .sort{|a,b| a.controller_name == b.controller_name ? a.action_name <=> b.action_name : a.controller_name <=> b.controller_name}

        def ret.[](*args)
          if args.length == 2
            controller = args[0].to_s
            action = args[1].to_s
            find{|item| item.controller_name == controller && item.action_name == action}
          else
            super(*args)
          end
        end

        ret.freeze
      end
end

Instance Method Details

#allow_custom?Boolean

Determines if the action allows custom security settings.

Returns:

  • (Boolean)


92
93
94
# File 'app/models/incline/action_security.rb', line 92

def allow_custom?
  !(require_admin? || require_anon? || allow_anon?)
end

#group_idsObject

Gets the group IDs accepted by this action.



201
202
203
# File 'app/models/incline/action_security.rb', line 201

def group_ids
  groups.pluck(:id)
end

#group_ids=(values) ⇒ Object

Sets the group IDs accepted by this action.



207
208
209
210
211
212
# File 'app/models/incline/action_security.rb', line 207

def group_ids=(values)
  values ||= []
  values = [ values ] unless values.is_a?(::Array)
  values = values.reject{|v| v.blank?}.map{|v| v.to_i}
  self.groups = Incline::AccessGroup.where(id: values).to_a
end

#permitted(refresh = false) ⇒ Object

Gets a string describing who is permitted to execute the action.



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'app/models/incline/action_security.rb', line 143

def permitted(refresh = false)
  @permitted = nil if refresh
  @permitted ||=
      if require_admin?
        'Administrators Only'
      elsif require_anon?
        'Anonymous Only'
      elsif allow_anon?
        'Everyone'
      elsif groups.any?
        names = groups.pluck(:name).map{|v| "\"#{v}\""}
        'Members of ' +
            if names.count == 1
              names.first
            elsif names.count == 2
              names.join(' or ')
            else
              names[0...-1].join(', ') + ', or ' + names.last
            end
      else
        'All Users'
      end +
          if non_standard
            ' (Non-Standard)'
          else
            ''
          end
end

#short_permittedObject

Gets a short string describing who is permitted to execute the action.



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'app/models/incline/action_security.rb', line 174

def short_permitted
  if require_admin?
    'Admins'
  elsif require_anon?
    'Anon'
  elsif allow_anon?
    'Everyone'
  elsif groups.any?
    'Custom'
  else
    'Users'
  end +
      if non_standard
        '*'
      else
        ''
      end
end

#to_sObject

Description of action.



195
196
197
# File 'app/models/incline/action_security.rb', line 195

def to_s
  @to_s ||= "#{controller_name}:#{action_name} [#{permitted}]"
end

#update_flagsObject

Updates the flags based on the controller configuration.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'app/models/incline/action_security.rb', line 30

def update_flags
  self.allow_anon = self.require_anon = self.require_admin = self.unknown_controller = self.non_standard = false

  self.unknown_controller = true
  klass =
      begin
        (controller_name + '_controller').classify.constantize
      rescue NameError
         nil
      end

  unless klass
    options =
        if controller_name.include?('/')
          ns = controller_name.rpartition('/')[0]
          ctrl = controller_name.rpartition('/')[2]
          options = [
              "#{ns}/app/controllers/#{ns}/#{ctrl}_controller",
              "app/controllers/#{ns}/#{ctrl}_controller",
              "#{ns}/app/controllers/#{ctrl}_controller",
              "#{ns}/#{ctrl}_controller"
          ]
        else
          options = [
              "app/controllers/#{controller_name}_controller",
              "#{controller_name}_controller"
          ]
        end

    while (file = options.shift)
      begin
        require file
        klass = (controller_name + '_controller').classify.constantize
        break
      rescue LoadError, NameError
        # just preventing the error from bubbling up.
      end
    end
  end

  if klass
    self.unknown_controller = false
    if klass.require_admin_for?(action_name)
      self.require_admin = true
    elsif klass.require_anon_for?(action_name)
      self.require_anon = true
    elsif klass.allow_anon_for?(action_name)
      self.allow_anon = true
    end

    # if the authentication methods are overridden, set a flag to alert the user that standard security may not be honored.
    unless klass.instance_method(:valid_user?).owner == Incline::Extensions::ActionControllerBase &&
        klass.instance_method(:authorize!).owner == Incline::Extensions::ActionControllerBase
      self.non_standard = true
    end

  end

end