Restful_acl and namespaces

Hello,

I am using Restful_acl (and Restful_authentication) for my project.

I am currently facing a problem with namespaces   map.resources :rooms do |room|     building.resources :users, :controller => "rooms/users"   end

my models are as follow with a role model makink the link between room and user room : has_many roles users : has_many roles roles (room_id, user_id,role-type) : has_many users, has_many rooms

Now with the namespaces route when I (as a authorised user of the room) want to list the users with a role for the room I have the following link rooms_users_path(@rooms) (http://localhost:3000/rooms/ 15/users)

Unfortunatly restful_acl always reject the access tot he room, I think this is because in that case in the params there is no :id but

Any idea on what I am doing wrong?

Tranquiliste wrote:

Hello,

I am using Restful_acl (and Restful_authentication) for my project.

I am currently facing a problem with namespaces   map.resources :rooms do |room|     building.resources :users, :controller => "rooms/users"   end

my models are as follow with a role model makink the link between room and user room : has_many roles users : has_many roles roles (room_id, user_id,role-type) : has_many users, has_many rooms

Now with the namespaces route when I (as a authorised user of the room) want to list the users with a role for the room I have the following link rooms_users_path(@rooms) (http://localhost:3000/rooms/ 15/users)

Unfortunatly restful_acl always reject the access tot he room, I think this is because in that case in the params there is no :id but a :room_id but I am not sure.

Any idea on what I am doing wrong?

Hi Tranquiliste, thanks for using RESTful_ACL!

One thing I notice immediately is the line "building.resources...", but you're actually passing "room" to the block. Wouldn't this be what you're after:

map.resources :rooms do |room|   room.resources :users end

RESTful_ACL does require params[:id] if you are trying to check access on an instance. It does not support Singletons (see the wiki).

Hello Matt thanks for your answer (and for Restful_acl)

This is a typo in the post (not in the program) and the route used is

   map.resources :rooms do |room|     room.resources :users, :controller => "rooms/users"   end

And sorry I did not read your wiki (is it new?). I'll see what is the impact for me.

Thanks again for your responsiveness

Hello again,

I have looked at the wiki and understood that in such cases you skip permission checking, but this means that someone can type the url and and access the users for a room they don't have permission to access?

Am I correct?

Tranquiliste wrote:

Hello again,

I have looked at the wiki and understood that in such cases you skip permission checking, but this means that someone can type the url and and access the users for a room they don't have permission to access?

Am I correct?

It's not that we necessarily skip permission checking, it's that (in all cases I've found so far) you really just map a resource to the currently logged in user. A good example of this is the relationship between User and Profile. Each user is going to have exactly one profile and they alone will have full access to their profile. You can then do something like the below in your Users model and Users Controller::index method

# Profile model belongs_to :user

# User model has_one :profile

# User controller def index   @profile = current_user.profile end

This ensures that only their profile is accessible, so no real need for permission checking.

Now in your case; I'm not sure how RESTful_ACL works with nested controllers as I haven't tried it yet myself :wink: Is there a particular reason your nesting the actual controller file? For what you're trying to do just (below) will work.

map.resources :rooms do |room|   room.resources :users end

This will give you the routes: rooms_path new_room_path edit_room_path room_path room_users_path new_room_user_path edit_room_user_path room_user_path

Hello,

In my case there is no direct relation between the room and the user, there is in between a role model which defines the role of a user for this particular room (with room_id, user_id, and role_type as field) and at some point as the User_X who can access to the room I want to see/update/create all the user that have access to this room and know their privilege (role). I thought it was better to have a nested controller because to stay REST I did not want to add more action to the users_controller provided by Restful_authentication.

But lets take a simpler example where user is not involved. In my room I have some items so I have created also a nested resource and controller (again reading Agile web development with rails I thought it was the good approach)

map.resources :rooms do |room|   room.resources :items end

Now I want to prevent people who don't have access to the room from accessing the items inside the room. I understand that Restful_acl doesn't support nested resources and controller buy what would be your approach in that case? Example if someone connected or not enters the following url but don't have access to the room 15 it should be denied http://localhost:3000/rooms/15/items

I hope I am clear on what I want to achieve. Thanks

I hope I am clear

Tranquiliste wrote:

Hello,

In my case there is no direct relation between the room and the user, there is in between a role model which defines the role of a user for this particular room (with room_id, user_id, and role_type as field) and at some point as the User_X who can access to the room I want to see/update/create all the user that have access to this room and know their privilege (role). I thought it was better to have a nested controller because to stay REST I did not want to add more action to the users_controller provided by Restful_authentication.

But lets take a simpler example where user is not involved. In my room I have some items so I have created also a nested resource and controller (again reading Agile web development with rails I thought it was the good approach)

map.resources :rooms do |room|   room.resources :items end

Now I want to prevent people who don't have access to the room from accessing the items inside the room. I understand that Restful_acl doesn't support nested resources and controller buy what would be your approach in that case? Example if someone connected or not enters the following url but don't have access to the room 15 it should be denied http://localhost:3000/rooms/15/items

I hope I am clear on what I want to achieve. Thanks

I hope I am clear

Ahh, missed the 'role' part of your earlier example. RESTful_ACL can do what you require in the latest example. The easiest way would be to lock down Room from the Item's action you'd like to lock down.

# Item Model belongs_to :room

# Room Model has_many :items

# Item Controller def show   @item = Item.find(params[:id])

  if @item.room.is_readable_by(current_user)     ...   else     ... end

To protect the entire controller I'd write a before_filter:

# Item Controller

before_filter :has_access_to_room?

def has_access_to_room?   if params[:id]     @item = Item.find(params[:id])     @item.room.is_readable_by(current_user)   else     @room = Room.find(params[:room_id])     @room.is_readable_by(current_user)   end end

Hope this helps!

Great!

Thanks very much for you help. I think I have what I want to continue.

Clever and simple solution ... I wish I had found it by myself

Thanks again.