Module: Zuul::ActiveRecord::Subject::PermissionMethods::InstanceMethods

Defined in:
lib/zuul/active_record/subject.rb

Instance Method Summary collapse

Instance Method Details

#assign_permission(permission, context = nil, force_context = nil) ⇒ Object

Assigns a permission to a subject within the provided context.

If a Permission object is provided it’s used directly, otherwise if a permission slug is provided, the permission is looked up in the context chain by target_permission.



222
223
224
225
226
227
228
229
# File 'lib/zuul/active_record/subject.rb', line 222

def assign_permission(permission, context=nil, force_context=nil)
  auth_scope do
    context = Zuul::Context.parse(context)
    target = target_permission(permission, context, force_context)
    return false unless verify_target_context(target, context, force_context)
    return permission_subject_class.find_or_create_by(subject_foreign_key.to_sym => id, permission_foreign_key.to_sym => target.id, :context_type => context.class_name, :context_id => context.id)
  end
end

#has_permission?(permission, context = nil, force_context = nil) ⇒ Boolean Also known as: permission?, can?, allowed_to?

Checks whether a subject has a permission within the provided context.

If a Permission object is provided it’s used directly, otherwise if a permission slug is provided, the permission is looked up in the context chain by target_permission.

The assigned context behaves the same way, in that if the permission is not found to belong to the subject with the specified context, we look up the context chain.

Permissions belonging to roles possessed by the subject are also included.

Returns:

  • (Boolean)


259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/zuul/active_record/subject.rb', line 259

def has_permission?(permission, context=nil, force_context=nil)
  auth_scope do
    force_context ||= config.force_context
    context = Zuul::Context.parse(context)
    target = target_permission(permission, context, force_context)
    return false if target.nil?
    return permission_role_or_subject_for?(target, context) if force_context

    return true if permission_role_or_subject_for?(target, context)
    return true if context.instance? && permission_role_or_subject_for?(target, Zuul::Context.new(context.klass))
    return true if !context.global? && permission_role_or_subject_for?(target, Zuul::Context.new)
    return false
  end
end

#permission_role_for(target, context, proles = nil) ⇒ Object

Looks up a permission role based on the passed target and context



314
315
316
317
318
319
# File 'lib/zuul/active_record/subject.rb', line 314

def permission_role_for(target, context, proles=nil)
  auth_scope do
    proles ||= roles_for(context)
    return permission_role_class.find_by(role_foreign_key.to_sym => proles.map(&:id), permission_foreign_key.to_sym => target.id, :context_type => context.class_name, :context_id => context.id)
  end
end

#permission_role_for?(target, context, proles = nil) ⇒ Boolean

Returns:

  • (Boolean)


321
322
323
# File 'lib/zuul/active_record/subject.rb', line 321

def permission_role_for?(target, context, proles=nil)
  !permission_role_for(target, context, proles).nil?
end

#permission_role_or_subject_for(target, context, proles = nil) ⇒ Object

Looks up a permission subject or role based on the passed target and context



326
327
328
# File 'lib/zuul/active_record/subject.rb', line 326

def permission_role_or_subject_for(target, context, proles=nil)
  permission_subject_for(target, context) || permission_role_for(target, context, proles)
end

#permission_role_or_subject_for?(target, context, proles = nil) ⇒ Boolean

Returns:

  • (Boolean)


330
331
332
# File 'lib/zuul/active_record/subject.rb', line 330

def permission_role_or_subject_for?(target, context, proles=nil)
  !permission_role_or_subject_for(target, context, proles).nil?
end

#permission_subject_for(target, context) ⇒ Object

Looks up a permission subject based on the passed target and context



303
304
305
306
307
# File 'lib/zuul/active_record/subject.rb', line 303

def permission_subject_for(target, context)
  auth_scope do
    return permission_subject_class.find_by(subject_foreign_key.to_sym => id, permission_foreign_key.to_sym => target.id, :context_type => context.class_name, :context_id => context.id)
  end
end

#permission_subject_for?(target, context) ⇒ Boolean

Returns:

  • (Boolean)


309
310
311
# File 'lib/zuul/active_record/subject.rb', line 309

def permission_subject_for?(target, context)
  !permission_subject_for(target, context).nil?
end

#permissions_for(context = nil, force_context = nil) ⇒ Object

Returns all permissions possessed by the subject within the provided context.

This includes permissions assigned directly to the subject or any roles possessed by the subject, as well as all permissions found by looking up the context chain.



281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/zuul/active_record/subject.rb', line 281

def permissions_for(context=nil, force_context=nil)
  auth_scope do
    force_context ||= config.force_context
    context = Zuul::Context.parse(context)
    roles = roles_for(context)
    if force_context
      return role_and_subject_permissions_for(context, roles)
    else
      return role_and_subject_permissions_within(context, roles)
    end
  end
end

#permissions_for?(context = nil, force_context = nil) ⇒ Boolean

Check whether the subject possesses any permissions within the specified context.

This includes permissions assigned directly to the subject or any roles possessed by the subject, as well as all permissions found by looking up the context chain.

Returns:

  • (Boolean)


298
299
300
# File 'lib/zuul/active_record/subject.rb', line 298

def permissions_for?(context=nil, force_context=nil)
  !permissions_for(context, force_context).empty?
end

#role_and_subject_permissions_for(context, proles = nil) ⇒ Object



334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'lib/zuul/active_record/subject.rb', line 334

def role_and_subject_permissions_for(context, proles=nil)
  auth_scope do
    return permission_class.joins("
        LEFT JOIN #{permission_roles_table_name}
          ON #{permission_roles_table_name}.#{permission_foreign_key} = #{permissions_table_name}.id
        LEFT JOIN #{permission_subjects_table_name}
          ON #{permission_subjects_table_name}.#{permission_foreign_key} = #{permissions_table_name}.id"
      ).where("
        (
          #{permission_subjects_table_name}.#{subject_foreign_key} = ?
          AND #{permission_subjects_table_name}.context_type #{sql_is_or_equal(context.class_name)} ?
          AND #{permission_subjects_table_name}.context_id #{sql_is_or_equal(context.id)} ?
        )
        OR
        (
          #{permission_roles_table_name}.#{role_foreign_key} IN (?)
          AND #{permission_roles_table_name}.context_type #{sql_is_or_equal(context.class_name)} ?
          AND #{permission_roles_table_name}.context_id #{sql_is_or_equal(context.id)} ?
        )",
        id,
        context.class_name,
        context.id,
        (proles || roles_for(context)).map(&:id),
        context.class_name,
        context.id)
  end
end

#role_and_subject_permissions_for?(context, proles = nil) ⇒ Boolean

Returns:

  • (Boolean)


362
363
364
# File 'lib/zuul/active_record/subject.rb', line 362

def role_and_subject_permissions_for?(context, proles=nil)
  !role_and_subject_permissions_for(context, proles).empty?
end

#role_and_subject_permissions_within(context, proles = nil) ⇒ Object



366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
# File 'lib/zuul/active_record/subject.rb', line 366

def role_and_subject_permissions_within(context, proles=nil)
  auth_scope do
    return permission_class.joins("
        LEFT JOIN #{permission_roles_table_name}
        ON #{permission_roles_table_name}.#{permission_foreign_key} = #{permissions_table_name}.id
        LEFT JOIN #{permission_subjects_table_name}
        ON #{permission_subjects_table_name}.#{permission_foreign_key} = #{permissions_table_name}.id"
      ).where("
        (
          #{permission_subjects_table_name}.#{subject_foreign_key} = ?
          AND (
            #{permission_subjects_table_name}.context_type #{sql_is_or_equal(context.class_name)} ?
            OR #{permission_subjects_table_name}.context_type IS NULL
          )
          AND (
            #{permission_subjects_table_name}.context_id #{sql_is_or_equal(context.id)} ?
            OR #{permission_subjects_table_name}.context_id IS NULL
          )
        )
        OR (
          #{permission_roles_table_name}.#{role_foreign_key} IN (?)
          AND (
            #{permission_roles_table_name}.context_type #{sql_is_or_equal(context.class_name)} ?
            OR #{permission_roles_table_name}.context_type IS NULL
          )
          AND (
            #{permission_roles_table_name}.context_id #{sql_is_or_equal(context.id)} ?
            OR #{permission_roles_table_name}.context_id IS NULL
          )
        )",
        id,
        context.class_name,
        context.id,
        (proles || roles_for(context)).map(&:id),
        context.class_name,
        context.id)
  end
end

#role_and_subject_permissions_within?(context, proles = nil) ⇒ Boolean

Returns:

  • (Boolean)


405
406
407
# File 'lib/zuul/active_record/subject.rb', line 405

def role_and_subject_permissions_within?(context, proles=nil)
  !role_and_subject_permissions_within(context, proles).empty?
end

#unassign_permission(permission, context = nil, force_context = nil) ⇒ Object Also known as: remove_permission

Removes a permission from a subject within the provided context.

If a Permission object is provided it’s used directly, otherwise if a permission slug is provided, the permission is looked up in the context chain by target_permission.



236
237
238
239
240
241
242
243
244
245
246
# File 'lib/zuul/active_record/subject.rb', line 236

def unassign_permission(permission, context=nil, force_context=nil)
  auth_scope do
    context = Zuul::Context.parse(context)
    target = target_permission(permission, context, force_context)
    return false if target.nil?

    assigned_permission = permission_subject_for(target, context)
    return false if assigned_permission.nil?
    return assigned_permission.destroy
  end
end