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
-
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)
-
just do current_user.id == @thing.owner.id, this seems like the
most obvious and easiest but somehow less elegant
-
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
- something else I haven’t thought about
On Feb 11, 10:40pm, msaspence [email protected] wrote:
else
-
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)
-
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?
Fred
On 11 February 2011 22:40, msaspence [email protected] wrote:
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
On Feb 12, 9:53am, Colin L. [email protected] wrote:
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
On Feb 12, 9:21am, Frederick C. [email protected]
wrote:
I’m want to restrict access to an object show action to the owner
render :status => :forbidden, :text => "API requires
the comparison returns true (I have no idea how I would go about doing
this)
- 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?
Fred
I’m using the Authlogic so have followed the instructions here
http://rdoc.info/github/binarylogic/authlogic/master/Authlogic/TestCase
Matt
On 12 February 2011 10:00, msaspence [email protected] wrote:
a 403
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?
Colin
On Feb 12, 10:11am, Colin L. [email protected] wrote:
On Feb 12, 9:53am, Colin L. [email protected] wrote:
Not related to your problem, but just pointing out that you might be
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?
Colin
not yet but i can add it in easy enough (psudo code)
def show
@thing = Thing.find(params[:id])
if thing not found
throw 404
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 does sound like a more elegant way to do if current_user
but still doesnt solve current_user == @thing.owner
On Feb 12, 10:11am, Colin L. [email protected] wrote:
On 12 February 2011 10:00, msaspence [email protected] wrote:
if current_user && @thing.owner == current_user
a 403
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?
Colin
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
On Feb 12, 10:01am, msaspence [email protected] wrote:
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?
Fred
On Feb 13, 7:47am, Frederick C. [email protected]
wrote:
On Feb 12, 10:01am, msaspence [email protected] wrote:
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
yet
but they have the same data but are different objects
if I do puts user and puts user.id for each this is what i get
#User:0x00000102e73490
1
#User:0x00000104291698
1
I’m the biggest noob in the world
the comparison was comparing them correctly
I had a typo in my test assertion that was causing it to fail when it
should have passed
apologies for the trouble
i will get on and look at ruby-debug though
On 13 February 2011 11:25, msaspence [email protected] wrote:
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.
Colin
On 13 February 2011 12:04, msaspence [email protected] wrote:
I’m the biggest noob in the world
the comparison was comparing them correctly
I had a typo in my test assertion that was causing it to fail when it
should have passed
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.
Colin