Module: Authz::Controllers::ScopingManager Private

Defined in:
lib/authz/controllers/scoping_manager.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Module in charge of resolving authorization for the scoping sub-system.

Class Method Summary collapse

Class Method Details

.apply_role_scopes(role, collection_or_class, authz_user) ⇒ ActiveRecord_Relation

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Applies all the applicable scopables to the given collection or class using the scoping rules from the given role.

Parameters:

  • role (Authz::Role)

    the role used to find the scoping rules to apply

  • collection_or_class (ActiveRecord_Relation, Class)

    the starting collection on top of which the scoping is going to be applied

  • authz_user (Models::Rolable)

    the requesting user (injected dependency)

Returns:

  • (ActiveRecord_Relation)

    the subset of records to which the role has access to



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/authz/controllers/scoping_manager.rb', line 66

def self.apply_role_scopes(role, collection_or_class, authz_user)
  applicable_scopables = Authz::Scopables::Base.get_applicable_scopables! collection_or_class

  scoped = collection_or_class.all

  applicable_scopables.each do |as|
    # as = ScopableByCity

    kw = role.cached_granted_keyword_for(as)
    # kw = 'New York'

    scoped = scoped.send(as.apply_scopable_method_name, kw, authz_user)
    # scoped.apply_scopable_by_city('New York', User#123)
  end

  scoped
end

.apply_scopes_for_user(collection_or_class, authz_user) ⇒ ActiveRecord_Relation

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Applies the scopables of the given user’s roles to the given collection or class. If the user does not contain roles, it returns an empty collection.

Parameters:

  • collection_or_class (ActiveRecord_Relation, Class)

    the starting collection on top of which the scoping is going to be applied

  • authz_user (Models::Rolable)

    the user from which the roles are going to be used

Returns:

  • (ActiveRecord_Relation)

    the subset of records to which the user has access to



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/authz/controllers/scoping_manager.rb', line 39

def self.apply_scopes_for_user(collection_or_class, authz_user)
  usr = authz_user

  base = collection_or_class.all
  scoped = base.none
  usr.roles.each do |role|
    # TODO: an alternative implementation would be to use SQL UNION
    # This would allow us to circumvent ActiveRecord#or structural
    # limitations that forces us to always perform joins inside
    # Scopables::Base.apply_scopable_method_name.
    # See https://github.com/brianhempel/active_record_union
    # for a gem that implements AR union
    scoped = scoped.or(apply_role_scopes(role, base, usr))
  end
  scoped
end

.has_access_to_instance?(role, instance_to_check, authz_user) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Determines if the given role has access to the given instance considering all the applicable scopables and the role’s scoping rules.

Parameters:

  • role (Authz::Role)

    for which access is going to be determined

  • instance_to_check (Object)

    any model instance trying to be manipulated

  • authz_user (Models::Rolable)

    rolable that is trying to access the instance (injected dependency)

Returns:

  • (Boolean)


14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/authz/controllers/scoping_manager.rb', line 14

def self.has_access_to_instance?(role, instance_to_check, authz_user)
  scoped_class = instance_to_check.class
  applicable_scopables = Authz::Scopables::Base.get_applicable_scopables! scoped_class

  applicable_scopables.each do |as|
    kw = role.cached_granted_keyword_for(as)
    return false unless as.within_scope_of_keyword?(instance_to_check,
                                                    kw,
                                                    authz_user)
  end

  return true
end