I'm want to restrict access to an object show action to the owner
in my action I have this
def show
@thing = Thing.find(params[:id])
if current_user && @thing.owner == current_user
respond_to do |format|
format.json { render :json => @thing }
end
else
render :status => :forbidden, :text => "API requires
authentication for the minute."
end
end
Which works in the browser, however when running functional tests even
though @thing.owner is the same user as current_user it is not the
same object so the comparison fails as I see it I have a few options
but wanted to try and gauge what people feel is the best way
1) adjust the test setup so the logged in user is the same object and
the comparison returns true (I have no idea how I would go about doing
this)
2) just do current_user.id == @thing.owner.id, this seems like the
most obvious and easiest but somehow less elegant
3) write my own comparison method on my user class, either:
def is_equal_to user(user)
return user.id == self.id
end
or:
def is_current_user
return current_user.id == self.id
end
I'm want to restrict access to an object show action to the owner
in my action I have this
def show
@thing = Thing.find(params[:id])
if current_user && @thing.owner == current_user
respond_to do |format|
format.json { render :json => @thing }
end
else
render :status => :forbidden, :text => "API requires
authentication for the minute."
end
end
Which works in the browser, however when running functional tests even
though @thing.owner is the same user as current_user it is not the
same object so the comparison fails as I see it I have a few options
but wanted to try and gauge what people feel is the best way
1) adjust the test setup so the logged in user is the same object and
the comparison returns true (I have no idea how I would go about doing
this)
2) just do current_user.id == @thing.owner.id, this seems like the
most obvious and easiest but somehow less elegant
That is what == on two active record objects do (plus a little bit of
subtlety around new, unsaved objects).
How are you setting up the test?
I'm want to restrict access to an object show action to the owner
in my action I have this
def show
@thing = Thing.find(params[:id])
if current_user && @thing.owner == current_user
Not related to your problem, but just pointing out that you might be
better to use a :conditions option in the find so that it only finds
the current users things in the first place. Then put this in a named
scope in the Thing model and the above reduces to something like
@thing = Thing.current_users_things.find(params[:id])
> I'm want to restrict access to an object show action to the owner
> in my action I have this
> def show
> @thing = Thing.find(params[:id])
> if current_user && @thing.owner == current_user
Not related to your problem, but just pointing out that you might be
better to use a :conditions option in the find so that it only finds
the current users things in the first place. Then put this in a named
scope in the Thing model and the above reduces to something like
@thing = Thing.current_users_things.find(params[:id])
Colin
But if it doesnt find anything i wont know weither to return a 404 or
a 403
> I'm want to restrict access to an object show action to the owner
> in my action I have this
> def show
> @thing = Thing.find(params[:id])
> if current_user && @thing.owner == current_user
> respond_to do |format|
> format.json { render :json => @thing }
> end
> else
> render :status => :forbidden, :text => "API requires
> authentication for the minute."
> end
> end
> Which works in the browser, however when running functional tests even
> though @thing.owner is the same user as current_user it is not the
> same object so the comparison fails as I see it I have a few options
> but wanted to try and gauge what people feel is the best way
> 1) adjust the test setup so the logged in user is the same object and
> the comparison returns true (I have no idea how I would go about doing
> this)
> 2) just do current_user.id == @thing.owner.id, this seems like the
> most obvious and easiest but somehow less elegant
That is what == on two active record objects do (plus a little bit of
subtlety around new, unsaved objects).
How are you setting up the test?
Your current code does not allow that distinction either.
Since I see you are using authlogic do you not have a before filter
require_user or similar so that you can trap no user condition before
it even gets to the show action?
no but i could add it in at some point (psudo code:)
def show
@thing = Thing.find(params[:id])
if not @thing
throw 404
else if current_user && @thing.owner == current_user
respond_to do |format|
format.json { render :json => @thing }
end
else
render :status => :forbidden, :text => "API requires
authentication for the minute."
end
end
require user sounds like a better way to do if current_user but does
solve the current_user == @thing.owner part
> I'm using the Authlogic so have followed the instructions herehttp://rdoc.info/github/binarylogic/authlogic/master/Authlogic/TestCase
Have you tried sticking some breakpoints in your code to see how
current_user and @thing.owner differ?
sorry I'm still getting into rails and haven't got round to debugging
Have a look at the Rails Guide on debugging. Use ruby-debug to allow
you to break into your code and then you can inspect data and follow
the program flow.
You don't have to be a noob for that. Typos are often the most
difficult errors to find. When inspecting the code one sees what one
expects to see rather than what is actually there.