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.