Can't suppress "Create new" link at top of list for non-authorized users

65 views
Skip to first unread message

Mike Blyth

unread,
Sep 6, 2012, 7:39:44 AM9/6/12
to actives...@googlegroups.com
I'm trying to get rid of the "Create new" link conditionally, when users are not authorized to create. I'm using CanCan. The links within rows are suppressed properly (or greyed out), but the top-of-page Create link is still there. I have tried
  • def authorized_for_create? # in model
      false
    end
  • def authorized_for_new? # in model, out of desperation
      false
    end
  • def create_authorized? # in controller
      false
    end
What is the right way?

Sergio Cambra

unread,
Sep 6, 2012, 7:55:05 AM9/6/12
to actives...@googlegroups.com
On Jueves, 6 de septiembre de 2012 04:39:44 Mike Blyth escribió:
> I'm trying to get rid of the "Create new" link conditionally, when users
> are not authorized to create. I'm using CanCan. The links within rows are
> suppressed properly (or greyed out), but the top-of-page Create link is
> still there. I have tried
>
> - def authorized_for_create? # in model
> false
> end
> - def authorized_for_new? # in model, out of desperation
> false
> end
> - def create_authorized? # in controller

Sergio Cambra

unread,
Sep 6, 2012, 7:55:10 AM9/6/12
to actives...@googlegroups.com
On Jueves, 6 de septiembre de 2012 04:39:44 Mike Blyth escribió:
> I'm trying to get rid of the "Create new" link conditionally, when users
> are not authorized to create. I'm using CanCan. The links within rows are
> suppressed properly (or greyed out), but the top-of-page Create link is
> still there. I have tried
>
> - def authorized_for_create? # in model
> false
> end
> - def authorized_for_new? # in model, out of desperation
> false
> end
> - def create_authorized? # in controller
> false
> end
>
> What is the right way?

def self.authorized_for_create?
It must a class method, because there is no record to check authorization.

But if you use CanCan you should use can methods in your ability model.


Hernan Astudillo

unread,
Sep 6, 2012, 4:19:30 PM9/6/12
to actives...@googlegroups.com
Well, i confirm the bug. I haven't reported it since i haven't got the time to debug it, since it looks like a mapping problem in the bridge rather than AS itself or cancan.

It should reject or disable the create links on nested 1-1 relations too.



--
You received this message because you are subscribed to the Google Groups "ActiveScaffold : Ruby on Rails plugin" group.
To post to this group, send email to actives...@googlegroups.com.
To unsubscribe from this group, send email to activescaffol...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/activescaffold?hl=en.


Mike Blyth

unread,
Sep 7, 2012, 4:27:04 AM9/7/12
to actives...@googlegroups.com
I tried using the class method self.authorized_for_create? and it didn't work, so presumably it's because the CanCan chain is doing the authorizing. I may just try using JS to fix it.

Hernan Astudillo

unread,
Sep 7, 2012, 11:57:46 AM9/7/12
to actives...@googlegroups.com
there's a mapping between  AS authorization methods (authorized_for_action?, method_authorized?, etc) and CanCan can? method. But also, CanCan works at ActiveRecord level: CanCan is blocks the klass.new method (and create, create!, build, etc.).
As a result, links are showed (AS auth is passing) but klass.new or klass.create gets blocked. That's all i know for now. I'll dig deeper.

On Fri, Sep 7, 2012 at 5:27 AM, Mike Blyth <mike....@sim.org> wrote:
I tried using the class method self.authorized_for_create? and it didn't work, so presumably it's because the CanCan chain is doing the authorizing. I may just try using JS to fix it.

--
You received this message because you are subscribed to the Google Groups "ActiveScaffold : Ruby on Rails plugin" group.
To view this discussion on the web visit https://groups.google.com/d/msg/activescaffold/-/okMjqJCmHI8J.

andrea

unread,
Sep 24, 2012, 2:43:46 AM9/24/12
to actives...@googlegroups.com
Cancan correctly disable the creation method in controller (raising 500 error) but activescaffold not skip the create action link in the table header.
I think the solution is fix create_ignore? method:

def create_ignore?
  (!nested? && active_scaffold_config.list.always_show_create) || !create_authorized?
end
The original create_ignore? method do not check unauthorized creation at class level (!create_authorized?), so AS unauthorize link but do not skip this or disable it.

Sergio Cambra

unread,
Sep 24, 2012, 3:51:21 AM9/24/12
to actives...@googlegroups.com

It works with master or rails-3.2 branch, it won't work with 3.2.16 because it was fixed later. However, I don't know if it works with cancan.

 

ActiveScaffold won't disable collection links, so an unauthorized collection link should not be displayed, is not needed to change create_ignore? method. The fix is on commit 8ce243d83ee5e37a9d3d7df29601ea8f55682223

--
You received this message because you are subscribed to the Google Groups "ActiveScaffold : Ruby on Rails plugin" group.

To view this discussion on the web visit https://groups.google.com/d/msg/activescaffold/-/GbvZHQglRm4J.

Hernan Astudillo

unread,
Sep 24, 2012, 11:57:49 AM9/24/12
to actives...@googlegroups.com
There are still 2 problems that i'm trying to debug:

1) nested links are allways displayed. AS/actions/nested.rb nested_authorized? returns allways true. It should delegate to the corresponding action:
- :list when is :index
- :create when is :new
- :update when is :edit
However you can still use security_method

2) Unauthorized member actions are still displayed as something like: <a>#{link.label}</a>
They should have class="disabled".
Can't figure out where is being rendered. I only see a
render_group_action_link(link, options, record)


Sergio Cambra

unread,
Sep 25, 2012, 4:22:49 AM9/25/12
to actives...@googlegroups.com
> On Lunes, 24 de septiembre de 2012 11:57:49 Hernan Astudillo escribió:
>
> There are still 2 problems that i'm trying to debug:
>
> 1) nested links are allways displayed. AS/actions/nested.rb
> nested_authorized? returns allways true. It should delegate to the
> corresponding action: - :list when is :index
> - :create when is :new
> - :update when is :edit
> However you can still use security_method

In lib/active_scaffold/helpers/list_column_helpers.rb, render_list_column
method in line 48, calls column_link_authorized? if action is set, so nested
links for plural associations should call it. When action is nil, like
singular associations links, render_action_link will try to get the action for
this row with action_link_to_inline_form, which calls configure_column_link and
this method calls column_link_authorized?. So all nested links should call
column_link_authorized?

That method, will check authorization with :read crud type for :index, :create
crud type for :new in model, and :update crud type for :edit in record. Now, I
have found a bug, :index link will use the first record if association is eager
loaded, but it should use always the model to check authorization. If
association is not eager loaded or is empty, it's using already the model. I
have just fixed to use the model always with plural associations.

>
> 2) Unauthorized member actions are still displayed as something like:
> <a>#{link.label}</a> They should have class="disabled".
> Can't figure out where is being rendered. I only see a
>
> render_group_action_link(link, options, record)

In lib/active_scaffold/data_structures/action_links.rb, traverse method, lines
125 to 129, checks authorized, which is passed in a options hash to the block,
in _action_group partial. The block will call render_group_action_link with
the options, which in line 118 call action_link_html with :class => "disabled"
option, so you should get it. I'm talking about master branch.

Sergio Cambra

unread,
Sep 25, 2012, 4:32:11 AM9/25/12
to actives...@googlegroups.com
On Lunes, 24 de septiembre de 2012 22:22:49 Sergio Cambra escribió:
> > On Lunes, 24 de septiembre de 2012 11:57:49 Hernan Astudillo escribió:
> >
> > There are still 2 problems that i'm trying to debug:
> >
> > 1) nested links are allways displayed. AS/actions/nested.rb
> > nested_authorized? returns allways true. It should delegate to the
> > corresponding action: - :list when is :index
> > - :create when is :new
> > - :update when is :edit
> > However you can still use security_method

I think now that you were talking about config.nested.add_link

Maybe nested_authorized? can changed to check authorization using
action_link.crud_type and action_link.action, but authorized methods should be
changed to get record and link, or checking arity before calling.

Hernan Astudillo

unread,
Sep 25, 2012, 10:57:48 AM9/25/12
to actives...@googlegroups.com
exaclty that, since:

def nested_authorized?
   true
end

however, before calling this, the link i think at build time it already has the action and crud_type so, it doesn't really need to call nested_authorized? for config.nested.add_link cases.

Sergio Cambra

unread,
Sep 25, 2012, 1:29:56 PM9/25/12
to actives...@googlegroups.com

What method it should use instead?

Hernan Astudillo

unread,
Sep 25, 2012, 3:46:10 PM9/25/12
to actives...@googlegroups.com
As nested for nested.add_link case method falls back to index, new, update or show, it should use the generic
authorized_for?(:crud_type => link.crud_type, :action => link.action)


Sergio Cambra

unread,
Sep 26, 2012, 5:29:11 AM9/26/12
to actives...@googlegroups.com

You cannot do that with nested_authorized? without adding link parameter, which was my proposal, adding link parameter to check authorization with that call in nested_authorized?

 

I could do it in traverse, but I don't like it. ActionLinks class should not know nothing about a link is a normal or nested one, should do the same. Another way would be move authorization check to the action link class.

Hernan Astudillo

unread,
Sep 26, 2012, 1:28:38 PM9/26/12
to actives...@googlegroups.com
The problem is that the link has :action => 'nested', which is useless. Is there any way to figure out that index-new-edit-show from the resulting link at "nested_authorized?"

Sergio Cambra

unread,
Sep 27, 2012, 7:30:17 AM9/27/12
to actives...@googlegroups.com

In nested_authorized?, link should have index action for plural associations and nil action for singular associations. Then, links without action should call action_link_to_inline_form, then configure_column_link and finally column_link_authorized?. If it's not authorized it will be rendered like:

<a>action link label</a>

 

I will change so it gets class="disabled" too.

Reply all
Reply to author
Forward
0 new messages