Setting up access rules


#1

I am referring to this wonderful post:
http://pivotallabs.com/users/nick/blog/articles/272-access-control-permissions-in-rails/comments
for creating access rules for my application.

So from my controller and views I am calling method in user model as:
@currentuser.topic_admin?(topic)

User model has this method:

def topic_admin?(topic)
topic.can_admin?(self)
end

Topic model has this method:

def can_admin?(user)
valid_roles = %w{admin editor}
if valid_roles.include?(user.role.name)
return true
else
return false
end
end

The @currentuser is returned by a method in topic controller:
def current_user
@currentuser = User.find(session[:user])
end

Everything works fine as long as some user is logged in. If no one is
logged in then session has no data and I get error regarding nil.object
called…

How can I solve this problem? Am I going the wrong way? I wrote another
method to check if user is logged in and then only call current_user
method or topic_admin method. However, calling logged_in? method before
current_user is useless and calling it before topic_method means too
much code in the view. Any other alternatives? Any clues?

Thanks,
CS.


#2

One solution would be to provide a guest user in the database that is
returned by current_user when no-one is logged in, that enables you to
give
the guest user whatever roles you desire. Alternatively test
@currentuser
before calling topic_admin. As an aside I would suggest setting up
@topic_admin true or false in controller rather than calling it from
view,
or even better if possible setup the data to be displayed in the
controller/model and remove the logic from the view entirely.

2009/3/11 Carlos S. removed_email_address@domain.invalid


#3

Thanks Colin…

I am using ternary operator on @currentuser:
@currentuser ? can_admin?(topic) : false .

User model method: topic_admin changed to can_create
Topic model method: can_admin changed to can_be_created_by

@currentuser.can_create?(topic)

User model has this method:

def can_create?(topic)
topic.can_be_created_by?(self)
end

Topic model has this method:

def can_be_created_by?(user)
valid_roles = %w{admin editor}
if valid_roles.include?(user.role.name)
return true
else
return false
end
end

Problem -
I have nested resources in my application - (topic has_many items). And
on my show topic page I have a link to ‘Add new item’. I would like to
show this link only to users with certain roles. However, I am not able
to pass this resource (item) as it has not been initialized. So how can
I call method like: @currentuser.can_create?(item) from my show topic
page. I am initializing resource objects within the controller, but how
can I initialize these from my view? Do I need to? Any clues?

CS

Colin L. wrote:

One solution would be to provide a guest user in the database that is
returned by current_user when no-one is logged in, that enables you to
give
the guest user whatever roles you desire. Alternatively test
@currentuser
before calling topic_admin. As an aside I would suggest setting up
@topic_admin true or false in controller rather than calling it from
view,
or even better if possible setup the data to be displayed in the
controller/model and remove the logic from the view entirely.

2009/3/11 Carlos S. removed_email_address@domain.invalid


#4

2009/3/11 Carlos S. removed_email_address@domain.invalid

return true
to pass this resource (item) as it has not been initialized. So how can
I call method like: @currentuser.can_create?(item) from my show topic
page. I am initializing resource objects within the controller, but how
can I initialize these from my view? Do I need to? Any clues?

Are there different types of Topic? If not then can_create? does not
need to
be given a topic. Make can_be_created_by? a class method rather than an
instance method, so it is called by Topic.can_be_created_by?(user).

Colin


#5

Its getting more complex than I thought…

May it will be easier to make ‘can_de_*ted_by’ methods as Class methods
and call them directly bypassing the user model ‘can_*t[e]’ methods.

However this gives less control over the topics and items. I also have
an index action, where in front of each topic name there
edit/update/delete actions. Many users may have ‘topic admin’ role,
however only the user who created particular topic should be able to
delete it…

Thanks,
CS.

Colin L. wrote:

2009/3/11 Carlos S. removed_email_address@domain.invalid

return true
to pass this resource (item) as it has not been initialized. So how can
I call method like: @currentuser.can_create?(item) from my show topic
page. I am initializing resource objects within the controller, but how
can I initialize these from my view? Do I need to? Any clues?

Are there different types of Topic? If not then can_create? does not
need to
be given a topic. Make can_be_created_by? a class method rather than an
instance method, so it is called by Topic.can_be_created_by?(user).

Colin