| Module | Access::Controlled::ClassMethods |
| In: |
lib/access.rb
lib/access_db_helpers.rb |
Returns an array of strings that name attributes that are possible access keys for this class. May be overridden by classes to add keys; but note, if ‘foo’ is listed here as an access control key, it must have a corresponding column in the class‘s database table (and not be, e.g., a computed pseudo-attribute), and Permission objects must have a ‘target_foo’ attribute, again with a corresponding column in the ‘permissions’ table.
# File lib/access.rb, line 64
64: def access_control_keys
65: [ 'owner_id', 'owner_firm_id', 'id' ]
66: end
Finds all records of the given class on which the :user (default: User.current) has privilege :privilege.
For more complex finds (involving, e.g., additional conditions), consider the use of where_permits (q.v.), along the lines of
Klass.find :all,
:conditions => Klass.where_permits(...),
:other_opt => ...
Keyword args other than :user (:include, etc.) are as for find :all. A :conditions keyword argument may be supplied, in which case, they are conjoined with the permission check. So, for instance
Klass.all_permitting :edit, :conditions => "name like '%fred%'"
is equivalent to
Klass.find :all,
:conditions => "name like '%fred%' and " +
Klass.where_permits( :edit )
# File lib/access.rb, line 104
104: def all_permitting( priv, keyword_args = {} )
105: find :all, add_priv_check_to_query_args( priv, keyword_args )
106: end
Returns the number of records of the given class on which the given user (default: User.current) has the given privilege. Other keyword arguments as for ordinary class-level ‘count’.
Keyword arguments other than :user are passed through to ‘count’. Any :conditions supplied are conjoined to the permissions check, so, for instance,
Klass.count_permitting :edit, :conditions => "name like '%fred%'"
is equivalent to
Klass.count :all,
:conditions => "name like '%fred%' and " +
Klass.where_permits( :edit )
# File lib/access.rb, line 144
144: def count_permitting( priv, keyword_args = {} )
145: count add_priv_check_to_query_args( priv, keyword_args )
146: end
Returns a string naming the access key attribute that contains the id of the owner in the users table. Settable for the sake of the User class itself, which uses ‘id’ as the owner_access_key, so owned_by_self permissions can be used to grant users selective rights on their passwords, prefs, etc.
# File lib/access.rb, line 75
75: def owner_access_control_key
76: 'owner_id'
77: end
Convenience method — declare the :owner and :owner_firm associations which most access-controlled models will have.
Also typically adds the declarations
never_permit_anyone :to_update_attribute => :owner_firm_id require_privilege :reassign, :to_update_attribute => :owner_id
Add ":include_privs => false" to *prevent these from being added to the class (e.g., to set a different policy); they‘ll be there by default.
Typically invoked as a declaration in class definition:
class Utensil < ActiveRecord::Base
include Access::Controlled
owner_attrs_and_validations
...
end
If :default_from_current_user is set to true, the :owner and :owner_firm
# File lib/access_db_helpers.rb, line 82
82: def owner_attrs_and_validations( opt_args = {} )
83:
84: opt_args.keys.each do |k|
85: unless [:default_from_current_user, :include_privs].include?( k )
86: raise ArgumentError,
87: "Bad keyword #{k} to owner_attrs_and_validations"
88: end
89: end
90:
91: belongs_to :owner, :class_name => 'User',
92: :foreign_key => :owner_id
93: belongs_to :owner_firm, :class_name => 'Firm',
94: :foreign_key => :owner_firm_id
95:
96: validates_presence_of :owner
97: validates_presence_of :owner_firm
98:
99: unless opt_args.has_key?( :include_privs ) && !opt_args[:include_privs]
100: require_privilege :reassign, :to_update_attribute => [:owner_id]
101: never_permit_anyone :to_update_attribute => [:owner_firm_id]
102: end
103:
104: if opt_args[:default_from_current_user]
105: before_validation_on_create do |rec|
106: unless User.current.nil?
107: rec.owner = User.current if rec.owner.nil?
108: rec.owner_firm = User.current.firm if rec.owner_firm.nil?
109: end
110: end
111: end
112: end
Returns the text of a SQL condition (suitable for use in a where clause) which selects records of this class‘s table on which the user (default: User.current) is permitted to perform operation :operation.
# File lib/access.rb, line 156
156: def where_permits( priv, keyword_args = {} )
157:
158: if priv == :forbidden_operation
159: # ... lest wildcards "allow" it ...
160: return '2 + 2 = 5'
161: end
162:
163: # Note that we use Rails' pseudo-bind-parameters below
164: # to avoid DB dependencies on the syntax for "false"
165:
166: user = keyword_args[:user] || User.current
167:
168: keys = {
169: :user => user,
170: :firm => user.firm,
171: :privilege => priv.to_s,
172: :class_name => self.name,
173: :false => false,
174: }
175:
176: table = self.table_name
177: owner_id_attr = self.owner_access_control_key
178: self_owner_cond = owner_id_attr.nil? ? '2 + 2 = 5' :
179: "#{table}.#{owner_id_attr} = :user"
180:
181: return sanitize_sql( [ "exists\n(select 'x' from permissions p\nwhere exists (select 'x' from role_assignments\nwhere user_id = :user\nand role_assignments.role_id = p.role_id\nand \#{RoleAssignment::CURRENT_SQL_CONDITION})\nand (p.privilege = :privilege or p.privilege = 'any')\nand (p.class_name = :class_name)\nand (p.is_grant = :false)\nand (p.target_owned_by_self = :false or \#{self_owner_cond})\nand \#{self.permission_grant_conditions}\n)\n", keys ] )
182:
183: end