vhochstein / active_scaffold

Rails 4 Version of activescaffold supporting jquery
MIT License
156 stars 34 forks source link

beginning_of_chain and render_list_column, format_column_value #172

Closed nakedmoon closed 8 years ago

nakedmoon commented 13 years ago

render_list_column with plural association disable column_link check column_link_authorized? on the first associated item only, so if the other(s) associated items are accessible, the column link remain unauthorized and then disabled

format_column_value with a plural association show all records of association instead of restrictions declared in beginning_of_chain

My temp solution is to reject from the association array unauthorized items:

association_array.reject!{|associated_item| !associated_item.authorized_for?(:crud_type => :read)}

I think, the best solution is to use beginning_of_chain definition to fetch the associated items...

vhochstein commented 13 years ago

Ok, that s too abstract for me... Let s to it by example: I ve got a team which has many players, in players column of team view I ve got a nested link to players list of that specific team. So, if user is not authorized to list first player of that team the nested link is disabled in team list view ??

nakedmoon commented 13 years ago

yes you are right. the column link authorization check authorized on associated.first

class Team < ActiveRecord::Base has_many :players end class Player < ActiveRecord::Base belongs_to :team end class TeamsController < ApplicationController active_scaffold :team do |config| end end class PlayersController < ApplicationController active_scaffold :player do |config| end def beginning_of_chain Player.where(:id > 2) end end I have 1 Team with 10 Players (id=1,2,3,4,5,6,7,8,9,10).

When rendering a nested link to Players of a single Team the format_column_value method call format_number_value, passing a value and a associated_size regarding all 10 Players and not 8 Players (id>2). When rendering a nested link to Players of a single Team the render_list_column method, call the column_link_authorized? method checking if enable or disable link. In case of plural_association the column_link_authorized? method call authorized_for? only on the first item (first Player) using associated_for_authorized = associated.first; so because the first player is not accessible (beginning_of_chain declare not accessible players with id <=2) associated_for_authorized.authorized_for?(:crud_type => link.crud_type) return false and the entire column link become disabled.

Thanks for support.

nakedmoon commented 13 years ago

The problem is that using beginning of chain in a controller for filter records (i use this with cancan) works for the index action on the controller. Any form ui with a plural association to this controller's model (a select or record_select) ignore the beginning_of_chain filter.

vhochstein commented 13 years ago

You might have totally different requirements for filtering in select depending on the parent model, which is why you might define conditions for select assocations in https://github.com/activescaffold/active_scaffold/wiki/Custom-Association-Options

record_select is another gem/plugin which is activescaffold independent.

However, I think you original point about authorization based only on the first associated record is a valid point. I would say authorization should nt be on record level

nakedmoon commented 13 years ago

Ok, but i think using beginning_of_chain with cancan bridge is incoherent with a permission based filtering (i have different sets of objects of the same Model on different controllers!).

vhochstein commented 13 years ago

I ve never used cancan, so unfortunetly I ve got no idea about it. Please take a look at cancan commits and contact the developer.

nakedmoon commented 13 years ago

also without cancan, if you declare in Player model:

def authorized_for_read? id<=2 end

i expect players with id=3,4,5,6,7,8,... are not accessible when try to associate to a Team from a Team form. Before populate selects form_ui for associate Players to a Team i select only authorized_for?(:crud_type => :read).

vhochstein commented 13 years ago

How s form_ui configured for players attribute in team controller?

nakedmoon commented 13 years ago

record_select, but associations are populated with a record.send(column.association.name) so i think this is indipendent from the selected form_ui.

vhochstein commented 13 years ago

Just wanted to make sure that I understand your setup.

record_select is an independent plugin and does not know about the activescaffold build-in authorization system. instead it uses it s own condition system

Not perfect, I totally agree with that.

nakedmoon commented 13 years ago

ok, but same situation using form_ui = :select

Thanks

vhochstein commented 13 years ago

You are right. authorization read check is missing for associations. and even for the model itself... If you call index on a model which has defined read authorized = false, you still see the table rows and if you have update rights... you can update that record.

Bottomline. The whole stuff is far away from beeing perfect.

However, you ve started the thread with a fix for it. Why do nt you create a pull request? and please take into account that there is also an association count method.

vhochstein commented 13 years ago

And please keep in mind that you can define custom association options: https://github.com/activescaffold/active_scaffold/wiki/Custom-Association-Options