Module: LogicalAuthz::Application::ClassMethods

Defined in:
lib/logical_authz/application.rb

Instance Method Summary collapse

Instance Method Details

#access_controls(action) ⇒ Object



267
268
269
270
271
272
273
274
# File 'lib/logical_authz/application.rb', line 267

def access_controls(action)
  controller_acl = read_inheritable_attribute(:controller_access_control) || []
  return controller_acl if action.nil?
  action = unalias_actions([action]).first
  action_acl = (read_inheritable_attribute(:action_access_control) || {})[action.to_sym] || []
  laz_debug{ { :checking_policy_for => action, :policies_exist_for => (read_inheritable_attribute(:action_access_control) || {}).keys, :action_acl => action_acl, :controller_acl => controller_acl } }
  action_acl + controller_acl
end

#admin_authorized(*actions) ⇒ Object

This method exists for backwards compatibility. It’s likely more readable to use the policy DSL



335
336
337
338
339
340
# File 'lib/logical_authz/application.rb', line 335

def admin_authorized(*actions)
  policy(*actions) do |pol|
    allow :if_admin
    existing_policy
  end
end

#authorization_by_default(default_allow) ⇒ Object



150
151
152
# File 'lib/logical_authz/application.rb', line 150

def authorization_by_default(default_allow)
  write_inheritable_attribute(:authorization_policy, default_allow)
end

#authorization_needed?(action) ⇒ Boolean

Returns:

  • (Boolean)


163
164
165
166
167
# File 'lib/logical_authz/application.rb', line 163

def authorization_needed?(action)
  acl = access_controls(action)
  return true unless acl.empty?
  return !read_inheritable_attribute(:authorization_policy) || false
end

#check_acls(criteria, result_hash = nil) ⇒ Object



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/logical_authz/application.rb', line 276

def check_acls(criteria, result_hash = nil)
  result_hash ||= {}
  policy = nil

  acl = access_controls(criteria[:action])
  result_hash.merge! :checked_rules => [], :determining_rule => nil, :all_rules => acl
  acl.each do |control|
    result_hash[:checked_rules] << control
    policy = control.evaluate(criteria)
    unless policy.nil?
      laz_debug{"Rule triggered - result: #{policy.inspect}"}
      result_hash.merge! :determining_rule => control, :reason => :rule_triggered, :result => policy
      break 
    end
  end
  return policy
end

#clear_policies!Object



125
126
127
128
# File 'lib/logical_authz/application.rb', line 125

def clear_policies!
  write_inheritable_attribute(:controller_access_control, [])
  write_inheritable_attribute(:action_access_control, {})
end

#default_authorizationObject



154
155
156
157
158
159
160
161
# File 'lib/logical_authz/application.rb', line 154

def default_authorization
  policy = read_inheritable_attribute(:authorization_policy)
  if policy.nil?
    true
  else
    policy
  end
end

#dynamic_authorization(&block) ⇒ Object

This method exists for backwards compatibility. It’s likely more readable to use the policy DSL



317
318
319
320
321
322
# File 'lib/logical_authz/application.rb', line 317

def dynamic_authorization(&block)
  policy do |pol|
    allow(&block)
    existing_policy
  end
end

#get_policy(action) ⇒ Object



130
131
132
133
134
135
136
# File 'lib/logical_authz/application.rb', line 130

def get_policy(action)
  if action.nil?
    read_inheritable_attribute(:controller_access_control) || []
  else
    (read_inheritable_attribute(:action_access_control) || {})[action.to_sym]
  end
end

#grant_aliases(hash) ⇒ Object Also known as: grant_alias

grant_aliases :new => :create # => anyone with authorization to :create can also access :new (Read as: “for ‘new’ read ‘create’”)



189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/logical_authz/application.rb', line 189

def grant_aliases(hash)
  aliases = read_inheritable_attribute(:grant_alias_hash) || Hash.new{|h,k| h[k] = []}
  aliased = read_inheritable_attribute(:aliased_grants) || {}
  hash.each_pair do |grant, allows|
    [*allows].each do |allowed|
      aliases[allowed.to_sym] << grant.to_sym
      aliased[grant.to_sym] = allowed.to_sym
      move_policies(grant, allowed)
    end
  end
  write_inheritable_attribute(:grant_alias_hash, aliases)
  write_inheritable_attribute(:aliased_grants, aliased)
end

#grant_aliases_for(action) ⇒ Object



215
216
217
218
219
220
221
222
223
224
# File 'lib/logical_authz/application.rb', line 215

def grant_aliases_for(action)
  grant_aliases = read_inheritable_attribute(:grant_alias_hash)
  action = action.to_sym

  if not grant_aliases.nil? and grant_aliases.has_key?(action)
    return grant_aliases[action]
  else
    return []
  end
end

#inspect_criteria(criteria) ⇒ Object



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/logical_authz/application.rb', line 226

def inspect_criteria(criteria)
  criteria.inject({}) do |hash, name_value|
    name, value = *name_value
    case value
    when ActiveRecord::Base
      hash[name] = {value.class.name => value.id}
    when ActionController::Base
      hash[name] = value.class
    else
      hash[name] = value
    end

    hash
  end.inspect
end

#laz_debugObject



64
65
66
# File 'lib/logical_authz/application.rb', line 64

def laz_debug
  LogicalAuthz::laz_debug{yield} if block_given?
end

#move_policies(from, to) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/logical_authz/application.rb', line 169

def move_policies(from, to)
  policies = read_inheritable_attribute(:action_access_control)
  if policies.nil?
    policies = {}
    write_inheritable_attribute(:action_access_control, policies)
  end

  if policies.has_key?(from.to_sym)
    if policies.has_key?(to.to_sym)
      #Should be raise, at some future point
      warn "Moving policies defined on #{self.name} for #{from} would clobber policies on #{to}"
    end
    policies[to.to_sym] = policies[from.to_sym]
    policies.delete(from.to_sym)
  end
end

#needs_authorization(*actions) ⇒ Object Also known as: authorized_if_permitted

It was tempting to build this on before_filter directly - however, inspecting a controller to see if a particular filter will run for a particular action is fragile.



297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
# File 'lib/logical_authz/application.rb', line 297

def needs_authorization(*actions)
  policy(*actions) do
    allow if_allowed {
      deny :authenticated
      allow AccessControl::Permitted.new({:group => LogicalAuthz::Configuration.unauthorized_groups})
    }
    allow :permitted
    existing_policy
  end

  policy do
    existing_policy
    deny :always
  end
end

#normalize_criteria(criteria) ⇒ Object



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/logical_authz/application.rb', line 242

def normalize_criteria(criteria)
  criteria[:group] = criteria[:group].nil? ? [] : [*criteria[:group]]
  if criteria.has_key?(:user) and not criteria[:user].nil?
    criteria[:group] += criteria[:user].groups
  end
  #if criteria[:group].empty?
  #  criteria[:group] += LogicalAuthz::unauthorized_groups
  #end
  criteria[:group], not_groups = criteria[:group].partition do |group|
    LogicalAuthz::Configuration::group_model === group
  end
  Rails.logger.warn{ "Found in criteria[:groups]: #{not_groups.inspect}"} unless not_groups.empty?
  actions = [*criteria[:action]].compact
  criteria[:action_aliases] = actions.map do |action|
    grant_aliases_for(action)
  end.flatten + actions.map{|action| action.to_sym}

  criteria[:controller] = self
  criteria[:controller_path] = controller_path

  laz_debug{"LogicalAuthz: final computed authz criteria: #{inspect_criteria(criteria)}"}

  return criteria
end

#owner_authorized(*actions, &block) ⇒ Object

This method exists for backwards compatibility. It’s likely more readable to use the policy DSL



326
327
328
329
330
331
# File 'lib/logical_authz/application.rb', line 326

def owner_authorized(*actions, &block)
  policy(*actions) do |pol|
    allow AccessControl::Owner.new(&block)
    existing_policy
  end
end

#policy(*actions, &block) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/logical_authz/application.rb', line 101

def policy(*actions, &block)
  before_filter CheckAuthorization
  builder = AccessControl::Builder.new(policy_helper_module)
  builder.define(&block)
  if actions.empty?
    set_policy(builder.list(get_policy(nil)), nil)
  else
    actions = unalias_actions(actions)
    actions.each do |action|
      set_policy(builder.list(get_policy(action)), action)
    end
  end
end

#policy_helper(name, &body) ⇒ Object



95
96
97
98
99
# File 'lib/logical_authz/application.rb', line 95

def policy_helper(name, &body)
  policy_helper_module.module_eval do
    define_method name, &body
  end
end

#policy_helper_moduleObject



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/logical_authz/application.rb', line 80

def policy_helper_module
  @policy_helper_module ||= 
    begin
      mod = Module.new
      parent_mod = read_inheritable_attribute(:policy_helper_module)
      unless parent_mod.nil?
        mod.class_eval {
          include(parent_mod)
        }
      end
      write_inheritable_attribute(:policy_helper_module, mod)
      mod
    end
end

#publicly_allowed(*actions) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/logical_authz/application.rb', line 68

def publicly_allowed(*actions)
  if actions.empty?
    authorization_by_default(true)
    reset_policy
  else
    reset_policy(*actions)
    policy(*actions) do |pol|
      allow :always
    end
  end
end

#reset_policy(*actions) ⇒ Object



115
116
117
118
119
120
121
122
123
# File 'lib/logical_authz/application.rb', line 115

def reset_policy(*actions)
  if actions.empty?
    set_policy([], nil)
  else
    unalias_actions(actions).each do |action|
      set_policy([], action)
    end
  end
end

#set_policy(acl, action) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
# File 'lib/logical_authz/application.rb', line 138

def set_policy(acl, action)
  if action.nil?
    laz_debug{ "Policy set: #{self.name} - all: #{acl.inspect}" }
    write_inheritable_attribute(:controller_access_control, acl)
  else
    laz_debug{ "Policy set: #{self.name}##{action}: #{acl.inspect}" }
    write_inheritable_hash(:action_access_control, {})
    policies = read_inheritable_attribute(:action_access_control)
    policies[action.to_sym] = acl
  end
end

#standard_grant_aliasesObject



204
205
206
# File 'lib/logical_authz/application.rb', line 204

def standard_grant_aliases
  grant_aliases :edit => :update
end

#unalias_actions(actions) ⇒ Object



208
209
210
211
212
213
# File 'lib/logical_authz/application.rb', line 208

def unalias_actions(actions)
  aliased_actions = read_inheritable_attribute(:aliased_grants) || {}
  actions.compact.map do |action|
    aliased_actions[action.to_sym] || action
  end.compact.uniq
end