I'm using Rails 2.0.2 and authorization version 1.0.10 (I know I need
to upgrade my project at some point) .
Let's say I had two classes:
class Person < ActiveRecord::Base
acts_as_authorizable
end
class Employee < Person
acts_as_authorizable
end
...
Both employees and persons are both saved in the people table with the
type column set to either Employee or Person, respectively.
If I created a Person object, and added a role:
person = Person.new
@current_user.is_manager_of person
... "Person" is logged as the authorizable type in the roles table
with the correct ID. This is as expected.
Here's the issue.... If I create an Employee object, and added a role:
employee = Employee.new
@current_user.is_manager_of employee
.... "Person" is logged as the authorizable type in the roles table
with the correct ID. This was not expected. I expected it to log
"Employee".
If I use the permit or just check against the role at any other
time...
@current_user.has_role? 'manager', employee
This check is using the base class... Even though I have inheritance,
permission for the base class is not the same as permission to the
derived class. In my app, there is a big difference and would be a
significant permissions issue.
After hours of digging into the authorization code, I found several
instances of it retrieving the base class when it was checking roles.
In object_roles_table.rb, I removed "base_class" from all instances of
"authorizable_obj.class.base_class.to_s" so now it just reads
"authorizable_obj.class.to_s".
If I ran through this scenario again, it was still failing! I found
that it was still logging the base class in the roles table, but the
role checks were now using the derived class...
How did I fix it? Around line 40 of "object_roles_table.rb" it had
the line:
role = Role.create( :name => role_name, :authorizable =>
authorizable_obj )
So somewhere during the creation process it was taking my Employee
object and still saving the base class "Person". I could not find
where "authorizable" is defined. But I know that is the root cause of
my problem.
Since I couldn't find and change how "authorizable" behanved, I
changed that line to this:
role = Role.create( :name => role_name, :authorizable_type =>
authorizable_obj.class.to_s, :authorizable_id =>
authorizable_obj.id )
And is now logging permissions on the derived class as expected. I
could not find anything about this. Is this fixed in later versions?