Removing transport and OAuth code that is no longer needed.
git-svn-id: https://google-api-ruby-client.googlecode.com/svn/trunk@28 c1d61fac-ed7f-fcc1-18f7-ff78120a04ef
This commit is contained in:
parent
541054e88d
commit
9d68bf115c
|
@ -1,276 +0,0 @@
|
||||||
# Copyright 2010 Google Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
require 'addressable/uri'
|
|
||||||
require 'oauth'
|
|
||||||
|
|
||||||
module Google #:nodoc:
|
|
||||||
class APIClient #:nodoc:
|
|
||||||
##
|
|
||||||
# An OAuth 1.0a handler.
|
|
||||||
class OAuth1
|
|
||||||
|
|
||||||
##
|
|
||||||
# The default OAuth 1.0a configuration values. These may be overrided
|
|
||||||
# simply by passing in the same key to the constructor.
|
|
||||||
DEFAULTS = {
|
|
||||||
:request_token_uri =>
|
|
||||||
'https://www.google.com/accounts/OAuthGetRequestToken',
|
|
||||||
:authorization_uri =>
|
|
||||||
'https://www.google.com/accounts/OAuthAuthorizeToken',
|
|
||||||
:access_token_uri =>
|
|
||||||
'https://www.google.com/accounts/OAuthGetAccessToken',
|
|
||||||
:scopes => [],
|
|
||||||
:callback => OAuth::OUT_OF_BAND,
|
|
||||||
:display_name => nil,
|
|
||||||
:consumer_key => 'anonymous',
|
|
||||||
:consumer_secret => 'anonymous'
|
|
||||||
}
|
|
||||||
|
|
||||||
##
|
|
||||||
# A set of default configuration values specific to each service. These
|
|
||||||
# may be overrided simply by passing in the same key to the constructor.
|
|
||||||
SERVICE_DEFAULTS = {
|
|
||||||
:buzz => {
|
|
||||||
:authorization_uri =>
|
|
||||||
'https://www.google.com/buzz/api/auth/OAuthAuthorizeToken',
|
|
||||||
:scopes => ['https://www.googleapis.com/auth/buzz']
|
|
||||||
},
|
|
||||||
:latitude => {
|
|
||||||
:authorization_uri =>
|
|
||||||
'https://www.google.com/latitude/apps/OAuthAuthorizeToken',
|
|
||||||
:scopes => ['https://www.googleapis.com/auth/latitude']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
##
|
|
||||||
# Creates a new OAuth 1.0a handler. This object obtains the tokens from
|
|
||||||
# the provider and handles signing any requests to the API.
|
|
||||||
#
|
|
||||||
# @param [Hash] options
|
|
||||||
# The configuration options.
|
|
||||||
# <code>:service</code>::
|
|
||||||
# The name of the service.
|
|
||||||
# <code>:request_token_uri</code>::
|
|
||||||
# The OAuth endpoint for obtaining a request token.
|
|
||||||
# <code>:authorization_uri</code>::
|
|
||||||
# The OAuth endpoint for obtaining user permission.
|
|
||||||
# <code>:access_token_uri</code>::
|
|
||||||
# The OAuth endpoint for obtaining an access token.
|
|
||||||
# <code>:scopes</code>::
|
|
||||||
# An <code>Array</code> of scopes that define the access being
|
|
||||||
# requested to the API.
|
|
||||||
# <code>:callback</code>::
|
|
||||||
# The URI the user will be redirected to if access is granted to the
|
|
||||||
# API. For development purposes, the special value
|
|
||||||
# <code>OAuth::OUT_OF_BAND</code> may also be used.
|
|
||||||
# <code>:display_name</code>::
|
|
||||||
# A human-readable service name to present to the user when they
|
|
||||||
# visit the <code>:authorization_uri</code>.
|
|
||||||
# <code>:consumer_key</code>::
|
|
||||||
# The consumer key you registered with the Google Accounts API.
|
|
||||||
# <code>:consumer_secret</code>::
|
|
||||||
# The consumer secret issued to you when you registered with the
|
|
||||||
# Google Accounts API.
|
|
||||||
#
|
|
||||||
# @return [Google::APIClient::OAuth1] The OAuth 1.0a handler.
|
|
||||||
def initialize(options={})
|
|
||||||
if options[:service] && SERVICE_DEFAULTS[options[:service]]
|
|
||||||
@options = DEFAULTS.merge(SERVICE_DEFAULTS[options[:service]])
|
|
||||||
else
|
|
||||||
@options = DEFAULTS.clone
|
|
||||||
end
|
|
||||||
@options.merge!(options)
|
|
||||||
@options[:request_token_uri] =
|
|
||||||
Addressable::URI.parse(@options[:request_token_uri])
|
|
||||||
@options[:authorization_uri] =
|
|
||||||
Addressable::URI.parse(@options[:authorization_uri])
|
|
||||||
@options[:access_token_uri] =
|
|
||||||
Addressable::URI.parse(@options[:access_token_uri])
|
|
||||||
if (@options[:request_token_uri].site !=
|
|
||||||
@options[:authorization_uri].site) ||
|
|
||||||
(@options[:request_token_uri].site !=
|
|
||||||
@options[:authorization_uri].site)
|
|
||||||
raise ArgumentError, 'All OAuth endpoints must be on the same site.'
|
|
||||||
end
|
|
||||||
@oauth_consumer = ::OAuth::Consumer.new(
|
|
||||||
@options[:consumer_key], @options[:consumer_secret], {
|
|
||||||
# This is an extremely unfortunate way to configure the consumer,
|
|
||||||
# but not worth forking or patching to resolve. Yet.
|
|
||||||
:site => @options[:request_token_uri].site,
|
|
||||||
:scheme => :header,
|
|
||||||
:http_method => :post,
|
|
||||||
:request_token_path => @options[:request_token_uri].request_uri,
|
|
||||||
:access_token_path => @options[:access_token_uri].request_uri,
|
|
||||||
:authorize_path => @options[:authorization_uri].request_uri
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the configuration of the handler. Configuration options that
|
|
||||||
# are not recognized by the handler are ignored.
|
|
||||||
#
|
|
||||||
# @return [Hash] The configuration options.
|
|
||||||
def options
|
|
||||||
return @options
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the current request token. Obtains a new request token if
|
|
||||||
# one hasn't already been obtained.
|
|
||||||
#
|
|
||||||
# @return [OAuth::RequestToken] The request token.
|
|
||||||
def request_token
|
|
||||||
oauth_parameters = {
|
|
||||||
:oauth_callback => @options[:callback]
|
|
||||||
}
|
|
||||||
app_parameters = {
|
|
||||||
:scope => @options[:scopes].join(' ')
|
|
||||||
}
|
|
||||||
if @options[:display_name]
|
|
||||||
app_parameters[:xoauth_displayname] = @options[:display_name]
|
|
||||||
end
|
|
||||||
return @request_token ||= @oauth_consumer.get_request_token(
|
|
||||||
oauth_parameters,
|
|
||||||
app_parameters
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Sets the request token for the handler.
|
|
||||||
#
|
|
||||||
# @param [OAuth::RequestToken] new_request_token The request token.
|
|
||||||
def request_token=(new_request_token)
|
|
||||||
if new_request_token.kind_of?(OAuth::RequestToken)
|
|
||||||
@request_token = new_request_token
|
|
||||||
else
|
|
||||||
raise TypeError,
|
|
||||||
"Expected OAuth::RequestToken, got #{new_request_token.class}."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the current access token. Obtains a new access token if
|
|
||||||
# one hasn't already been obtained. An request token must have already
|
|
||||||
# been obtained and authorized or this method will fail.
|
|
||||||
#
|
|
||||||
# @return [OAuth::AccessToken] The access token.
|
|
||||||
def access_token
|
|
||||||
return @access_token ||=
|
|
||||||
@oauth_consumer.get_access_token(self.request_token)
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Sets the access token for the handler.
|
|
||||||
#
|
|
||||||
# @param [OAuth::AccessToken] new_access_token The access token.
|
|
||||||
def access_token=(new_access_token)
|
|
||||||
if new_access_token.kind_of?(OAuth::AccessToken)
|
|
||||||
@access_token = new_access_token
|
|
||||||
else
|
|
||||||
raise TypeError,
|
|
||||||
"Expected OAuth::AccessToken, got #{new_access_token.class}."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the list of scopes for the handler.
|
|
||||||
#
|
|
||||||
# @return [Array] An <code>Array</code> of access scopes.
|
|
||||||
def scopes
|
|
||||||
return @options[:scopes]
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the callback for the handler.
|
|
||||||
#
|
|
||||||
# @return [String] The OAuth 1.0a callback for the consumer.
|
|
||||||
def callback
|
|
||||||
return @options[:callback]
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns a human-readable service name to present to the user when they
|
|
||||||
# visit the <code>:authorization_uri</code>.
|
|
||||||
#
|
|
||||||
# @return [String] The display name for the consumer.
|
|
||||||
def display_name
|
|
||||||
return @options[:display_name]
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the consumer key.
|
|
||||||
#
|
|
||||||
# @return [String]
|
|
||||||
# The consumer key you registered with the Google Accounts API.
|
|
||||||
def consumer_key
|
|
||||||
return @oauth_consumer.key
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the consumer key.
|
|
||||||
#
|
|
||||||
# @return [String]
|
|
||||||
# The consumer secret issued to you when you registered with the
|
|
||||||
# Google Accounts API.
|
|
||||||
def consumer_secret
|
|
||||||
return @oauth_consumer.secret
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the request token URI.
|
|
||||||
#
|
|
||||||
# @return [String]
|
|
||||||
# The OAuth endpoint for obtaining a request token.
|
|
||||||
def request_token_uri
|
|
||||||
return @oauth_consumer.request_token_url
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the authorization endpoint URI. This URI is used to construct
|
|
||||||
# the {#authorization_uri}.
|
|
||||||
#
|
|
||||||
# @return [String]
|
|
||||||
# The OAuth endpoint for obtaining user permission.
|
|
||||||
def authorization_endpoint_uri
|
|
||||||
return @oauth_consumer.authorize_url
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Builds the authorization URI that the user will be redirected to.
|
|
||||||
# Note that this value is derived from the
|
|
||||||
# {#authorization_endpoint_uri}.
|
|
||||||
#
|
|
||||||
# @param [Hash] parameters
|
|
||||||
# The extra URI query parameters appended to the
|
|
||||||
# {#authorization_endpoint_uri}.
|
|
||||||
#
|
|
||||||
# @return [String]
|
|
||||||
# The URI to redirect the user to to obtain permission.
|
|
||||||
def authorization_uri(parameters={})
|
|
||||||
return self.request_token.authorize_url(parameters)
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Returns the access token URI.
|
|
||||||
#
|
|
||||||
# @return [String]
|
|
||||||
# The OAuth endpoint for obtaining an access token.
|
|
||||||
def access_token_uri
|
|
||||||
return @oauth_consumer.access_token_url
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,184 +0,0 @@
|
||||||
# Copyright 2010 Google Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
require 'net/http'
|
|
||||||
require 'net/https'
|
|
||||||
require 'addressable/uri'
|
|
||||||
|
|
||||||
module Google #:nodoc:
|
|
||||||
class APIClient #:nodoc:
|
|
||||||
|
|
||||||
##
|
|
||||||
# Provides a consistent interface by which to make HTTP requests using the
|
|
||||||
# Net::HTTP class.
|
|
||||||
class HTTPTransport
|
|
||||||
ALLOWED_SCHEMES = ["http", "https"]
|
|
||||||
METHOD_MAPPING = {
|
|
||||||
# RFC 2616
|
|
||||||
:options => Net::HTTP::Options,
|
|
||||||
:get => Net::HTTP::Get,
|
|
||||||
:head => Net::HTTP::Head,
|
|
||||||
:post => Net::HTTP::Post,
|
|
||||||
:put => Net::HTTP::Put,
|
|
||||||
:delete => Net::HTTP::Delete,
|
|
||||||
:trace => Net::HTTP::Trace,
|
|
||||||
# Other standards supported by Net::HTTP
|
|
||||||
:copy => Net::HTTP::Copy,
|
|
||||||
:lock => Net::HTTP::Lock,
|
|
||||||
:mkcol => Net::HTTP::Mkcol,
|
|
||||||
:move => Net::HTTP::Move,
|
|
||||||
:propfind => Net::HTTP::Propfind,
|
|
||||||
:proppatch => Net::HTTP::Proppatch,
|
|
||||||
:unlock => Net::HTTP::Unlock
|
|
||||||
}
|
|
||||||
|
|
||||||
##
|
|
||||||
#
|
|
||||||
def initialize(options={})
|
|
||||||
# A mapping from authorities to Net::HTTP objects.
|
|
||||||
@connection_pool = options[:connection_pool] || {}
|
|
||||||
if options[:cert_store]
|
|
||||||
@cert_store = options[:cert_store]
|
|
||||||
else
|
|
||||||
@cert_store = OpenSSL::X509::Store.new
|
|
||||||
@cert_store.set_default_paths
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
attr_reader :connection_pool
|
|
||||||
attr_reader :cert_store
|
|
||||||
|
|
||||||
def build_request(method, uri, options={})
|
|
||||||
# No type-checking here, but OK because we check against a whitelist
|
|
||||||
method = method.to_s.downcase.to_sym
|
|
||||||
uri = Addressable::URI.parse(uri).normalize
|
|
||||||
if !METHOD_MAPPING.keys.include?(method)
|
|
||||||
raise ArgumentError, "Unsupported HTTP method: #{method}"
|
|
||||||
end
|
|
||||||
headers = {
|
|
||||||
"Accept" => "application/json;q=1.0, */*;q=0.5"
|
|
||||||
}.merge(options[:headers] || {})
|
|
||||||
|
|
||||||
# TODO(bobaman) More stuff here to handle optional parameters like
|
|
||||||
# form data.
|
|
||||||
|
|
||||||
body = options[:body] || ""
|
|
||||||
if body != ""
|
|
||||||
entity_body_defaults = {
|
|
||||||
"Content-Length" => body.size.to_s,
|
|
||||||
"Content-Type" => "application/json"
|
|
||||||
}
|
|
||||||
headers = entity_body_defaults.merge(headers)
|
|
||||||
end
|
|
||||||
return [method.to_s.upcase, uri.to_s, headers, [body]]
|
|
||||||
end
|
|
||||||
|
|
||||||
def send_request(request)
|
|
||||||
retried = false
|
|
||||||
begin
|
|
||||||
method, uri, headers, body_wrapper = request
|
|
||||||
body = ""
|
|
||||||
body_wrapper.each do |chunk|
|
|
||||||
body += chunk
|
|
||||||
end
|
|
||||||
|
|
||||||
uri = Addressable::URI.parse(uri).normalize
|
|
||||||
connection = self.connect_to(uri)
|
|
||||||
|
|
||||||
# Translate to Net::HTTP request
|
|
||||||
request_class = METHOD_MAPPING[method.to_s.downcase.to_sym]
|
|
||||||
if !request_class
|
|
||||||
raise ArgumentError,
|
|
||||||
"Unsupported HTTP method: #{method.to_s.downcase.to_sym}"
|
|
||||||
end
|
|
||||||
net_http_request = request_class.new(uri.request_uri)
|
|
||||||
for key, value in headers
|
|
||||||
net_http_request[key] = value
|
|
||||||
end
|
|
||||||
net_http_request.body = body
|
|
||||||
response = connection.request(net_http_request)
|
|
||||||
|
|
||||||
response_headers = {}
|
|
||||||
# We want the canonical header name.
|
|
||||||
# Note that Net::HTTP is lossy in that it downcases header names and
|
|
||||||
# then capitalizes them afterwards.
|
|
||||||
# This results in less-than-ideal behavior for headers like 'ETag'.
|
|
||||||
# Not much we can do about it.
|
|
||||||
response.canonical_each do |header, value|
|
|
||||||
response_headers[header] = value
|
|
||||||
end
|
|
||||||
# We use the Rack spec to trivially abstract the response format
|
|
||||||
return [response.code.to_i, response_headers, [response.body]]
|
|
||||||
rescue Errno::EPIPE, IOError, EOFError => e
|
|
||||||
# If there's a problem with the connection, finish and restart
|
|
||||||
if !retried && connection.started?
|
|
||||||
retried = true
|
|
||||||
connection.finish
|
|
||||||
connection.start
|
|
||||||
retry
|
|
||||||
else
|
|
||||||
raise e
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Builds a connection to the authority given in the URI using the
|
|
||||||
# appropriate protocol.
|
|
||||||
#
|
|
||||||
# @param [Addressable::URI, #to_str] uri The URI to connect to.
|
|
||||||
def connect_to(uri)
|
|
||||||
uri = Addressable::URI.parse(uri).normalize
|
|
||||||
if !ALLOWED_SCHEMES.include?(uri.scheme)
|
|
||||||
raise ArgumentError, "Unsupported protocol: #{uri.scheme}"
|
|
||||||
end
|
|
||||||
connection = @connection_pool[uri.site]
|
|
||||||
unless connection
|
|
||||||
connection = Net::HTTP.new(uri.host, uri.inferred_port)
|
|
||||||
end
|
|
||||||
retried = false
|
|
||||||
begin
|
|
||||||
if uri.scheme == 'https' && !connection.started?
|
|
||||||
connection.use_ssl = true
|
|
||||||
if connection.respond_to?(:enable_post_connection_check=)
|
|
||||||
# Deals with a security vulnerability
|
|
||||||
connection.enable_post_connection_check = true
|
|
||||||
end
|
|
||||||
connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
||||||
connection.cert_store = @cert_store
|
|
||||||
end
|
|
||||||
unless connection.started?
|
|
||||||
# Since we allow a connection pool to be passed in, we don't
|
|
||||||
# actually know this connection has been started yet.
|
|
||||||
connection.start
|
|
||||||
end
|
|
||||||
rescue Errno::EPIPE, IOError, EOFError => e
|
|
||||||
# If there's a problem with the connection, finish and restart
|
|
||||||
if !retried && connection.started?
|
|
||||||
retried = true
|
|
||||||
connection.finish
|
|
||||||
connection.start
|
|
||||||
retry
|
|
||||||
else
|
|
||||||
raise e
|
|
||||||
end
|
|
||||||
end
|
|
||||||
# Keep a reference to the connection around
|
|
||||||
@connection_pool[uri.site] = connection
|
|
||||||
return connection
|
|
||||||
end
|
|
||||||
protected :connect_to
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,84 +0,0 @@
|
||||||
# Copyright 2010 Google Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
require 'oauth'
|
|
||||||
require 'google/api_client/auth/oauth_1'
|
|
||||||
|
|
||||||
describe Google::APIClient::OAuth1, 'in the default configuration' do
|
|
||||||
before do
|
|
||||||
@oauth = Google::APIClient::OAuth1.new
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have the correct request_token_uri' do
|
|
||||||
@oauth.request_token_uri.should ==
|
|
||||||
'https://www.google.com/accounts/OAuthGetRequestToken'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have the correct authorization_uri' do
|
|
||||||
@oauth.authorization_endpoint_uri.should ==
|
|
||||||
'https://www.google.com/accounts/OAuthAuthorizeToken'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have the correct access_token_uri' do
|
|
||||||
@oauth.access_token_uri.should ==
|
|
||||||
'https://www.google.com/accounts/OAuthGetAccessToken'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have the correct consumer_key' do
|
|
||||||
@oauth.consumer_key.should == 'anonymous'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have the correct consumer_secret' do
|
|
||||||
@oauth.consumer_secret.should == 'anonymous'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should allow the request_token to be set manually' do
|
|
||||||
@oauth.request_token = OAuth::RequestToken.new(@oauth, 'key', 'secret')
|
|
||||||
@oauth.request_token.token.should == 'key'
|
|
||||||
@oauth.request_token.secret.should == 'secret'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should not allow the request_token to be set to bogus value' do
|
|
||||||
(lambda do
|
|
||||||
@oauth.request_token = 42
|
|
||||||
end).should raise_error(TypeError)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe Google::APIClient::OAuth1, 'configured for use with bogus service' do
|
|
||||||
before do
|
|
||||||
@oauth = Google::APIClient::OAuth1.new(:service => :bogus)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have the default configuration' do
|
|
||||||
@oauth.request_token_uri.should ==
|
|
||||||
Google::APIClient::OAuth1::DEFAULTS[:request_token_uri]
|
|
||||||
@oauth.authorization_endpoint_uri.should ==
|
|
||||||
Google::APIClient::OAuth1::DEFAULTS[:authorization_uri]
|
|
||||||
@oauth.access_token_uri.should ==
|
|
||||||
Google::APIClient::OAuth1::DEFAULTS[:access_token_uri]
|
|
||||||
@oauth.scopes.should ==
|
|
||||||
Google::APIClient::OAuth1::DEFAULTS[:scopes]
|
|
||||||
@oauth.callback.should ==
|
|
||||||
Google::APIClient::OAuth1::DEFAULTS[:callback]
|
|
||||||
@oauth.display_name.should ==
|
|
||||||
Google::APIClient::OAuth1::DEFAULTS[:display_name]
|
|
||||||
@oauth.consumer_key.should ==
|
|
||||||
Google::APIClient::OAuth1::DEFAULTS[:consumer_key]
|
|
||||||
@oauth.consumer_secret.should ==
|
|
||||||
Google::APIClient::OAuth1::DEFAULTS[:consumer_secret]
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,72 +0,0 @@
|
||||||
# Copyright 2010 Google Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
require 'oauth'
|
|
||||||
require 'google/api_client/auth/oauth_1'
|
|
||||||
require 'addressable/uri'
|
|
||||||
|
|
||||||
describe Google::APIClient::OAuth1, 'configured for use with Buzz' do
|
|
||||||
before do
|
|
||||||
@oauth = Google::APIClient::OAuth1.new(:service => :buzz)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should not have the default configuration' do
|
|
||||||
@oauth.authorization_endpoint_uri.should_not ==
|
|
||||||
Google::APIClient::OAuth1::DEFAULTS[:authorization_uri]
|
|
||||||
@oauth.scopes.should_not ==
|
|
||||||
Google::APIClient::OAuth1::DEFAULTS[:scopes]
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have the correct authorization_uri' do
|
|
||||||
@oauth.authorization_endpoint_uri.should ==
|
|
||||||
'https://www.google.com/buzz/api/auth/OAuthAuthorizeToken'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have the correct scope' do
|
|
||||||
@oauth.scopes.should include('https://www.googleapis.com/auth/buzz')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should be able to get a request token' do
|
|
||||||
@oauth.request_token.token.should =~ /^[a-zA-Z0-9\/\-\_\+]+$/
|
|
||||||
@oauth.request_token.secret.should =~ /^[a-zA-Z0-9\/\-\_\+]+$/
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should issue only a single request token' do
|
|
||||||
@oauth.request_token.token.should == @oauth.request_token.token
|
|
||||||
@oauth.request_token.secret.should == @oauth.request_token.secret
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should build the correct authorization URI' do
|
|
||||||
icon_uri = 'http://www.google.com/images/icons/feature/padlock-g128.png'
|
|
||||||
uri = @oauth.authorization_uri(
|
|
||||||
:domain => @oauth.consumer_key,
|
|
||||||
:iconUrl => icon_uri,
|
|
||||||
:scope => @oauth.scopes.join(' ')
|
|
||||||
)
|
|
||||||
uri.should =~
|
|
||||||
/^https:\/\/www.google.com\/buzz\/api\/auth\/OAuthAuthorizeToken/
|
|
||||||
Addressable::URI.unencode(uri).should =~
|
|
||||||
Regexp.new(Regexp.escape(@oauth.request_token.token))
|
|
||||||
Addressable::URI.unencode(uri).should =~
|
|
||||||
Regexp.new(Regexp.escape(icon_uri))
|
|
||||||
for scope in @oauth.scopes
|
|
||||||
Addressable::URI.unencode(uri).should =~
|
|
||||||
Regexp.new(Regexp.escape(scope))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Not much we can do to test any further into the OAuth flow
|
|
||||||
end
|
|
|
@ -1,104 +0,0 @@
|
||||||
# Copyright 2010 Google Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
require 'net/http'
|
|
||||||
require 'net/https'
|
|
||||||
require 'google/api_client/transport/http_transport'
|
|
||||||
|
|
||||||
class AlwaysFail
|
|
||||||
def initialize(*args)
|
|
||||||
raise IOError, "This would never work."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Google::APIClient::HTTPTransport::METHOD_MAPPING[:fail] = AlwaysFail
|
|
||||||
|
|
||||||
describe Google::APIClient::HTTPTransport, 'in the default configuration' do
|
|
||||||
before do
|
|
||||||
@http = Google::APIClient::HTTPTransport.new
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should send a GET request' do
|
|
||||||
request = @http.build_request(:get, "http://www.google.com/")
|
|
||||||
response = @http.send_request(request)
|
|
||||||
status, headers, body = response
|
|
||||||
status.should >= 100
|
|
||||||
body.size.should > 0
|
|
||||||
headers.size.should > 0
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should send a GET request using SSL' do
|
|
||||||
request = @http.build_request(:get, "https://www.google.com/")
|
|
||||||
response = @http.send_request(request)
|
|
||||||
status, headers, body = response
|
|
||||||
status.should >= 100
|
|
||||||
body.size.should > 0
|
|
||||||
headers.size.should > 0
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should send a POST request' do
|
|
||||||
request = @http.build_request(
|
|
||||||
:post, "http://www.google.com/", :body => "A Body."
|
|
||||||
)
|
|
||||||
response = @http.send_request(request)
|
|
||||||
status, headers, body = response
|
|
||||||
status.should >= 100
|
|
||||||
body.size.should > 0
|
|
||||||
headers.size.should > 0
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should send a PUT request' do
|
|
||||||
request = @http.build_request(
|
|
||||||
:put, "http://www.google.com/", :body => "A Body."
|
|
||||||
)
|
|
||||||
response = @http.send_request(request)
|
|
||||||
status, headers, body = response
|
|
||||||
status.should >= 100
|
|
||||||
body.size.should > 0
|
|
||||||
headers.size.should > 0
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should send a DELETE request' do
|
|
||||||
request = @http.build_request(:delete, "http://www.google.com/")
|
|
||||||
response = @http.send_request(request)
|
|
||||||
status, headers, body = response
|
|
||||||
status.should >= 100
|
|
||||||
body.size.should > 0
|
|
||||||
headers.size.should > 0
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should fail to send a FAIL request' do
|
|
||||||
(lambda do
|
|
||||||
request = @http.build_request(:fail, "http://www.google.com/")
|
|
||||||
response = @http.send_request(request)
|
|
||||||
end).should raise_error(IOError)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should fail to send a BOGUS request' do
|
|
||||||
(lambda do
|
|
||||||
response = @http.send_request(
|
|
||||||
["BOGUS", "http://www.google.com/", {}, [""]]
|
|
||||||
)
|
|
||||||
end).should raise_error(ArgumentError)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should fail to connect to a non-addressable URI' do
|
|
||||||
(lambda do
|
|
||||||
request = @http.build_request(:get, "bogus://www.google.com/")
|
|
||||||
response = @http.send_request(request)
|
|
||||||
end).should raise_error(ArgumentError)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,102 +0,0 @@
|
||||||
# Copyright 2010 Google Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
require 'net/http'
|
|
||||||
require 'net/https'
|
|
||||||
require 'google/api_client/transport/http_transport'
|
|
||||||
|
|
||||||
def assemble_body_string(body)
|
|
||||||
body_string = ""
|
|
||||||
body.each do |chunk|
|
|
||||||
body_string += chunk
|
|
||||||
end
|
|
||||||
return body_string
|
|
||||||
end
|
|
||||||
|
|
||||||
describe Google::APIClient::HTTPTransport, 'in the default configuration' do
|
|
||||||
before do
|
|
||||||
@http = Google::APIClient::HTTPTransport.new
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should build a valid GET request' do
|
|
||||||
method, uri, headers, body =
|
|
||||||
@http.build_request(:get, "http://www.example.com/")
|
|
||||||
body_string = assemble_body_string(body)
|
|
||||||
method.should == "GET"
|
|
||||||
uri.should === "http://www.example.com/"
|
|
||||||
headers.keys.should_not include("Content-Length")
|
|
||||||
body_string.should == ""
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should build a valid POST request' do
|
|
||||||
method, uri, headers, body = @http.build_request(
|
|
||||||
:post, "http://www.example.com/", :body => "A body."
|
|
||||||
)
|
|
||||||
body_string = assemble_body_string(body)
|
|
||||||
method.should == "POST"
|
|
||||||
uri.should === "http://www.example.com/"
|
|
||||||
headers["Content-Length"].should == "7"
|
|
||||||
body_string.should == "A body."
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should build a valid PUT request' do
|
|
||||||
method, uri, headers, body = @http.build_request(
|
|
||||||
:put, "http://www.example.com/", :body => "A body."
|
|
||||||
)
|
|
||||||
body_string = assemble_body_string(body)
|
|
||||||
method.should == "PUT"
|
|
||||||
uri.should === "http://www.example.com/"
|
|
||||||
headers["Content-Length"].should == "7"
|
|
||||||
body_string.should == "A body."
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should build a valid DELETE request' do
|
|
||||||
method, uri, headers, body =
|
|
||||||
@http.build_request(:delete, "http://www.example.com/")
|
|
||||||
body_string = assemble_body_string(body)
|
|
||||||
method.should == "DELETE"
|
|
||||||
uri.should === "http://www.example.com/"
|
|
||||||
headers.keys.should_not include("Content-Length")
|
|
||||||
body_string.should == ""
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should not build a BOGUS request' do
|
|
||||||
(lambda do
|
|
||||||
@http.build_request(:bogus, "http://www.example.com/")
|
|
||||||
end).should raise_error(ArgumentError)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe Google::APIClient::HTTPTransport,
|
|
||||||
'with a certificate store and connection pool' do
|
|
||||||
before do
|
|
||||||
@http = Google::APIClient::HTTPTransport.new(
|
|
||||||
:cert_store => OpenSSL::X509::Store.new,
|
|
||||||
:connection_pool => {
|
|
||||||
"http://www.example.com" => Net::HTTP.new("www.example.com", 80)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have the correct certificate store' do
|
|
||||||
# TODO(bobaman) Write a real test
|
|
||||||
@http.cert_store.should_not == nil
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should have the correct connection pool' do
|
|
||||||
@http.connection_pool.keys.should include("http://www.example.com")
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Reference in New Issue