Role based restriction for fields (not views or actions)

I have an application that requires some complex access rules. Certain fields can only be edited by certain roles. I am using restful_authentication and role_requirement plugins so I am fine with restricting an entire controller or specific action based on a role.

I am trying to come up with a solution that would allow me to specify something as a text field but make it just plain text if the user does not have edit permissions. Anyone have any ideas on fine grain access control like this? Can you point me to a project that uses something like this?

TIA,

Sean

Sean,

I don't have any leads for you, but I'm very interested in this myself. I do have one thought: I imagine you could roll your own text field helper method (and then probably helper methods for the other form elements). Something like:

require 'active_support/inflector.rb' module ActionView   module Helpers     module FormHelper       def secured_text_field(object_name, method, options = {})         current_user.has_role?(options[:required_role]) ?           "<div id=\"#{object_name}_#{method} \">#{object_name.instance_eval(method.to_s)}</div>" :           text_field(object_name, method, options)       end     end   end end

# (I added the above to the ApplicationHelper.rb file but not within the Module namespace... i.e. after it.)

And you'd call it with something like:

<% form_for(@foo) do |f| %>   <p>     <%= f.label :name %><br />     <%= secured_text_field @foo, :name, :required_role => "admin" %>   </p> <% end %>

If the current_user has the "admin" role, then you'd get:

<form tag...>   <p>   <label for="foo_name">Name</label><br />     <input id="foo_name" name="foo[name]" size="30" type="text" value="" />   </p> </form>

But if the current_user has any other role, you'd get:

<form tag...>   <p>   <label for="foo_name">Name</label><br />     <div id="foo_name">Some Name</div>   </p> </form>

I'm sure there's a cleaner way, but the above works. I tried doing it within the FormBuilder constrains (i.e. "f.secured_text_field...") but I don't understand that code... lots of meta-programming there.

Anyway, I tested the above and it works. Hopefully that gets you started.

-Danimal

Heh... I'm still learning.

The namespacing was unnecessary. Slap it right in the middle of the ApplicationHelper module, I.e.:

module ApplicationHelper   def secured_text_field(object_name, method, options = {})     options[:required] == "yes" ? content_tag(:div, "#{object_name.instance_eval(method.to_s)}", :id => "#{object_name.class.to_s.underscore}_#{method}") : text_field(object_name, method, options)   end end

There's probably a cleaner way to get "foo_name" for the ID but the above works... and is terse and to the point.

-Danimal

Hi,

i think there is a ruby gem called model_security which provides such fine grained access control from within the model. I don't know though if it's mantained and up to date and/or runs nicely on rails 2.

Hops that helps.

Cheers! Alberto.

There's also the acl2 plugin from Ezra. http://opensvn.csie.org/ezra/rails/plugins/dev/acl_system2/

It has a view helper, <% restrict_for "role" do %> which will let you only show what is part of the code block in the view.

Hope this helps.

Serge