A richer role model

A question of philosophy

Currently, we’re looking at extending radiant for a client whose
primary need is content. However, they also need some other tools
specific to not-for-profits. Ideally it would be great to deliver
everything in one interface. (Content management and applications).
The applications would live inside the admin interface for radiant,
utilizing Radiant’s login and user-management system. Where we’ve
started is with an extension to manage roles and users assigned to
those roles. What we’re trying to extend now is the process of
displaying tabs for users. For example, only people in the “finance”
role should see the tab in the admin interface for finance related
reports, receipts from web donations, etc.

For example, the following code from admin_ui.rb appears to be
responsible for making the decision to display tabs for users. It
would be nice to extend the user to read all the available roles in
our roles table to provide “#{role}?” methods for the available roles.

def shown_for?(user)
visibility.include?(:all) or visibility.any? { |role| user.send
("#{role}?") }
end

As we look through the code it might not be possible to do everything
we would like from extensions. Would there be interest in the
community in re-visiting the user roles to provide for a more
flexible roles system?

Paul

Paul,

It should be easy to add a new role(s) for this if you have only
role-specific permissions and nothing more granular than that. Just
create an extension that modifies the User model (in the database and in
the code), providing methods in the manner of “finance?” or
“public_relations?” that test whether a given user has that role. Then
your other interfaces/extensions can add restrictions on those tabs
easily.

Sean

Thanks, Sean:

It looks like this works. I’ll push the rest of the extension into
our public SVN when I get it ironed out.

def activate
admin.tabs.add “Rbac Base”, “/admin/rbac”, :after =>
“Layouts”, :visibility => [:admin]
User.send :has_and_belongs_to_many, :roles
User.send :include, RbacSupport
end

module RbacSupport

all_roles = Role.find(:all)

all_roles.each do | possible_role |
define_method("#{possible_role.role_name.underscore}?") do
if @my_roles == nil
@my_roles = Hash.new
roles.each do | role |
@my_roles["#{role.role_name.underscore}"] = true
end
end
@my_roles["#{possible_role.role_name.underscore}"] || admin?
end
end
end

VERY rough code to play with. Drag and drop users into roles. Role
names can be anything, they are .underscore 'd in the extension.
Inside another extension that depends on these roles set :visibility
appropriately →

admin.tabs.add “Membership”, “/admin/membership”, :after =>
“Layouts”, :visibility => [:membership]

Let me know if you can’t check out the code from:

http://www.saturnflyer.com/svn/radiantP/rbac_base/trunk/

Very interesting! Looking forward to seeing the final product.

Sean