I am building a 2-Legged OAuth provider for my api. Everything is hooked up properly and I can make signed calls from the rails console. The problem I have is that I am having trouble integrating OAuth into the controller_spec
.
Here is an example of a working call on my server:
coneybeare $ rails c test
Loading test environment (Rails 3.2.0)
rails test: main
>> consumer = OAuth::Consumer.new("one_key", "MyString", :site => [REDACTED])
# => #<OAuth::Consumer:0x007f9d01252268 @key="one_key", @secret="MyString", @options={:signature_method=>"HMAC-SHA1", :request_token_path=>"/oauth/request_token", :authorize_path=>"/oauth/authorize", :access_token_path=>"/oauth/access_token", :proxy=>nil, :scheme=>:header, :http_method=>:post, :oauth_version=>"1.0", :site=>[REDACTED]}>
ruby: main
>> req = consumer.create_signed_request(:get, "/api/v1/client_applications.json", nil)
# => #<Net::HTTP::Get GET>
ruby: main
>> res = Net::HTTP.start([REDACTED]) {|http| http.request(req) }
# => #<Net::HTTPOK 200 OK readbody=true>
ruby: main
>> puts res.body
{"client_applications":[{"id":119059960,"name":"FooBar1","url":"http://test1.com"},{"id":504489040,"name":"FooBar2","url":"http://test2.com"}]}
# => nil
And here is what I am doing in my controller tests:
require 'oauth/client/action_controller_request'
describe Api::ClientApplicationsController do
include OAuthControllerSpecHelper
…
…
it "assigns all client_applications as @client_applications" do
consumer = OAuth::Consumer.new("one_key", "MyString", :site => [REDACTED])
ActionController::TestRequest.use_oauth=true
@request.configure_oauth(consumer)
@request.apply_oauth!
puts "request.env['Authorization'] = #{@request.env['Authorization']}"
get :index, {:api_version => 'v1', :format => :json}
response.should be_success # Just this for now until I can get authorization, then proper controller testing
end
end
The output of that test:
request.env['Authorization'] = OAuth oauth_consumer_key="one_key", oauth_nonce="gzAbvBSWyFtIYKfuokMAdu6VnH39EHeXvebbH2qUtE", oauth_signature="juBkJo5K0WLu9mYqHVC3Ar%2FATUs%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1328474800", oauth_version="1.0"
1) Api::ClientApplicationsController GET index assigns all client_applications as @client_applications
Failure/Error: response.should be_success
expected success? to return true, got false
And the corresponding server call from the rails log:
Processing by Api::ClientApplicationsController#index as JSON
Parameters: {"api_version"=>1}
Rendered text template (0.0ms)
Filter chain halted as #<OAuth::Controllers::ApplicationControllerMethods::Filter:0x007f85a51a8858 @options={:interactive=>false, :strategies=>:two_legged}, @strategies=[:two_legged]> rendered or redirected
Completed 401 Unauthorized in 15ms (Views: 14.1ms | ActiveRecord: 0.0ms)
(0.2ms) ROLLBACK
I just can't figure out why it's not working :/ Am I making an obvious mistake?
create_signed_request
doesn't get the expected result. Did you try to debug it? Just thinking: you can bypass somebefore_filters
while testing – Huckcreate_signed_request
is the one that is working, it is the controller test which is not. I think what might be happening is thatapply_oauth!
is done before theget :index
call is made, causing the path to not be in the signature. I might have to make my own wrapper around theget
call to figure out what the path is, set it, sign it and then call the super implementation of get. Seems like a lot of unnecessary work though... – Vagromcreate_signed_request
is getting what it expects because no server is runned in controller specs. If you simply want to test the rest of your controller, bypass thebefore_filter
. If you want to test the auth, try in a request spec. – Huck:skip_before_filter :authenticate
in the before(:all) of the controller tests. Let me try it out – Vagrom