require 'spec_helper' require 'rack/test' require 'oauth/rack/oauth_filter' require 'multi_json' require 'forwardable' require 'dummy_provider_models' class OAuthEcho def call(env) response = {} response[:oauth_token] = env["oauth.token"].token if env["oauth.token"] response[:client_application] = env["oauth.client_application"].key if env["oauth.client_application"] response[:oauth_version] = env["oauth.version"] if env["oauth.version"] response[:strategies] = env["oauth.strategies"] if env["oauth.strategies"] [200, { "Accept" => "application/json" }, [MultiJson.encode(response)]] end end describe OAuth::Rack::OAuthFilter do include Rack::Test::Methods def app @app ||= OAuth::Rack::OAuthFilter.new(OAuthEcho.new) end it "should pass through without oauth" do get '/' last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {} end describe 'OAuth1' do describe 'with optional white space' do it "should sign with consumer" do get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer", oauth_nonce="amrLDyFE2AMztx5fOYDD1OEqWps6Mc2mAR5qyO44Rj8", oauth_signature="KCSg0RUfVFUcyhrgJo580H8ey0c%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1295039581", oauth_version="1.0"'} last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {"client_application" => "my_consumer", "oauth_version"=>1, "strategies"=>["two_legged"]} end it "should sign with oauth 1 access token" do client_application = ClientApplication.new "my_consumer" ClientApplication.stub!(:find_by_key).and_return(client_application) client_application.tokens.stub!(:where).and_return([AccessToken.new("my_token")]) get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer", oauth_nonce="oiFHXoN0172eigBBUfgaZLdQg7ycGekv8iTdfkCStY", oauth_signature="y35B2DqTWaNlzNX0p4wv%2FJAGzg8%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1295040394", oauth_token="my_token", oauth_version="1.0"'} last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {"client_application" => "my_consumer", "oauth_token"=>"my_token","oauth_version"=>1, "strategies"=>["oauth10_token","token","oauth10_access_token"]} end it "should sign with oauth 1 request token" do client_application = ClientApplication.new "my_consumer" ClientApplication.stub!(:find_by_key).and_return(client_application) client_application.tokens.stub!(:where).and_return([RequestToken.new("my_token")]) get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer", oauth_nonce="oiFHXoN0172eigBBUfgaZLdQg7ycGekv8iTdfkCStY", oauth_signature="y35B2DqTWaNlzNX0p4wv%2FJAGzg8%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1295040394", oauth_token="my_token", oauth_version="1.0"'} last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {"client_application" => "my_consumer", "oauth_token"=>"my_token","oauth_version"=>1, "strategies"=>["oauth10_token","oauth10_request_token"]} end end describe 'without optional white space' do it "should sign with consumer" do get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer",oauth_nonce="amrLDyFE2AMztx5fOYDD1OEqWps6Mc2mAR5qyO44Rj8",oauth_signature="KCSg0RUfVFUcyhrgJo580H8ey0c%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1295039581",oauth_version="1.0"'} last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {"client_application" => "my_consumer", "oauth_version"=>1, "strategies"=>["two_legged"]} end it "should sign with oauth 1 access token" do client_application = ClientApplication.new "my_consumer" ClientApplication.stub!(:find_by_key).and_return(client_application) client_application.tokens.stub!(:where).and_return([AccessToken.new("my_token")]) get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer",oauth_nonce="oiFHXoN0172eigBBUfgaZLdQg7ycGekv8iTdfkCStY",oauth_signature="y35B2DqTWaNlzNX0p4wv%2FJAGzg8%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1295040394",oauth_token="my_token",oauth_version="1.0"'} last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {"client_application" => "my_consumer", "oauth_token"=>"my_token","oauth_version"=>1, "strategies"=>["oauth10_token","token","oauth10_access_token"]} end it "should sign with oauth 1 request token" do client_application = ClientApplication.new "my_consumer" ClientApplication.stub!(:find_by_key).and_return(client_application) client_application.tokens.stub!(:where).and_return([RequestToken.new("my_token")]) get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer",oauth_nonce="oiFHXoN0172eigBBUfgaZLdQg7ycGekv8iTdfkCStY",oauth_signature="y35B2DqTWaNlzNX0p4wv%2FJAGzg8%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1295040394",oauth_token="my_token",oauth_version="1.0"'} last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {"client_application" => "my_consumer", "oauth_token"=>"my_token","oauth_version"=>1, "strategies"=>["oauth10_token","oauth10_request_token"]} end end end describe "OAuth2" do describe "token given through a HTTP Auth Header" do context "authorized and non-invalidated token" do it "authenticates" do get '/', {}, { "HTTP_AUTHORIZATION" => "Bearer valid_token" } last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == { "oauth_token" => "valid_token", "oauth_version" => 2, "strategies"=> ["oauth20_token", "token"] } end end context "non-authorized token" do it "doesn't authenticate" do get '/', {}, { "HTTP_AUTHORIZATION" => "Bearer not_authorized" } last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {} end end context "authorized and invalidated token" do it "doesn't authenticate with an invalidated token" do get '/', {}, { "HTTP_AUTHORIZATION" => "Bearer invalidated" } last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {} end end end describe "OAuth2 pre Bearer" do describe "token given through a HTTP Auth Header" do context "authorized and non-invalidated token" do it "authenticates" do get '/', {}, { "HTTP_AUTHORIZATION" => "OAuth valid_token" } last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == { "oauth_token" => "valid_token", "oauth_version" => 2, "strategies"=> ["oauth20_token", "token"] } end end context "non-authorized token" do it "doesn't authenticate" do get '/', {}, { "HTTP_AUTHORIZATION" => "OAuth not_authorized" } last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {} end end context "authorized and invalidated token" do it "doesn't authenticate with an invalidated token" do get '/', {}, { "HTTP_AUTHORIZATION" => "OAuth invalidated" } last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {} end end end end describe "token given through a HTTP Auth Header following the OAuth2 pre draft" do context "authorized and non-invalidated token" do it "authenticates" do get '/', {}, { "HTTP_AUTHORIZATION" => "Token valid_token" } last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == { "oauth_token" => "valid_token", "oauth_version" => 2, "strategies"=> ["oauth20_token", "token"] } end end context "non-authorized token" do it "doesn't authenticate" do get '/', {}, { "HTTP_AUTHORIZATION" => "Token not_authorized" } last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {} end end context "authorized and invalidated token" do it "doesn't authenticate with an invalidated token" do get '/', {}, { "HTTP_AUTHORIZATION" => "Token invalidated" } last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {} end end end ['bearer_token', 'access_token', 'oauth_token'].each do |name| describe "token given through the query parameter '#{name}'" do context "authorized and non-invalidated token" do it "authenticates" do get "/?#{name}=valid_token" last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == { "oauth_token" => "valid_token", "oauth_version" => 2, "strategies"=> ["oauth20_token", "token"] } end end context "non-authorized token" do it "doesn't authenticate" do get "/?#{name}=not_authorized" last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {} end end context "authorized and invalidated token" do it "doesn't authenticate with an invalidated token" do get "/?#{name}=invalidated" last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {} end end end describe "token given through the post parameter '#{name}'" do context "authorized and non-invalidated token" do it "authenticates" do post '/', name => 'valid_token' last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == { "oauth_token" => "valid_token", "oauth_version" => 2, "strategies"=> ["oauth20_token", "token"] } end end context "non-authorized token" do it "doesn't authenticate" do post '/', name => 'not_authorized' last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {} end end context "authorized and invalidated token" do it "doesn't authenticate with an invalidated token" do post '/', name => 'invalidated' last_response.should be_ok response = MultiJson.decode(last_response.body) response.should == {} end end end end end end