Signed requests can now be generated and transmitted by the client.
Example code:
    require 'google/api_client'
    client = Google::APIClient.new(:service => 'buzz')
    client.authorization.fetch_temporary_credential!(
      :additional_parameters => {
        'scope' => 'https://www.googleapis.com/auth/buzz'
      }
    )
    client.authorization.authorization_uri
    # Redirect user here
    client.authorization.fetch_token_credential!(:verifier => '12345')
    response = client.execute(
      'buzz.activities.list',
      'scope' => '@self', 'userId' => '@me', 'alt' => 'json'
    )
    status, headers, body = response
git-svn-id: https://google-api-ruby-client.googlecode.com/svn/trunk@34 c1d61fac-ed7f-fcc1-18f7-ff78120a04ef
			
			
This commit is contained in:
		
							parent
							
								
									f462322be5
								
							
						
					
					
						commit
						3a9d58108a
					
				|  | @ -132,29 +132,44 @@ module Google #:nodoc: | |||
|       return nil | ||||
|     end | ||||
| 
 | ||||
|     def build_request(*args, &block) | ||||
|       if !args.empty? || block | ||||
|         if args.size != 2 | ||||
|           raise ArgumentError, "wrong number of arguments (#{args.size} for 2)" | ||||
|     def discovered_method(rpc_name, service_version='1.0') | ||||
|       for service in self.discovered_services | ||||
|         # This looks kinda weird, but is not a real problem because there's | ||||
|         # almost always only one service, and this is memoized anyhow. | ||||
|         if service.version.to_s == service_version.to_s | ||||
|           return service.to_h[rpc_name] if service.to_h[rpc_name] | ||||
|         end | ||||
|         rpc_name = args[0] | ||||
|         if !rpc_name.kind_of?(String) | ||||
|           raise TypeError, "Expected String, got #{rpc_name.class}." | ||||
|         end | ||||
|         parameters = args[1] | ||||
|         if !parameters.kind_of?(Hash) | ||||
|           raise TypeError, "Expected Hash, got #{parameters.class}." | ||||
|         end | ||||
| 
 | ||||
|         signature_needed = false | ||||
|         if signature_needed | ||||
|           request = self.sign_request(request) | ||||
|         end | ||||
|         return args | ||||
|       else | ||||
|         require 'google/api_client/discovery/method_builder' | ||||
|         return ::Google::APIClient::MethodBuilder.new(self, :build_request) | ||||
|       end | ||||
|       return nil | ||||
|     end | ||||
| 
 | ||||
|     def generate_request( | ||||
|         api_method, parameters={}, body='', headers=[], options={}) | ||||
|       options={ | ||||
|         :signed => true, | ||||
|         :service_version => '1.0' | ||||
|       }.merge(options) | ||||
|       if api_method.kind_of?(String) | ||||
|         api_method = self.discovered_method( | ||||
|           api_method, options[:service_version] | ||||
|         ) | ||||
|       elsif !api_method.kind_of?(::Google::APIClient::Service) | ||||
|         raise TypeError, | ||||
|           "Expected String or Google::APIClient::Service, " + | ||||
|           "got #{api_method.class}." | ||||
|       end | ||||
|       request = api_method.generate_request(parameters, body, headers) | ||||
|       if options[:signed] | ||||
|         request = self.sign_request(request) | ||||
|       end | ||||
|       return request | ||||
|     end | ||||
| 
 | ||||
|     def execute(api_method, parameters={}, body='', headers=[], options={}) | ||||
|       request = self.generate_request( | ||||
|         api_method, parameters, body, headers, options | ||||
|       ) | ||||
|       return self.transmit_request(request) | ||||
|     end | ||||
| 
 | ||||
|     def transmit_request(request) | ||||
|  | @ -172,10 +187,6 @@ module Google #:nodoc: | |||
|           '#generate_authenticated_request.' | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def execute_signed_request(*args, &block) | ||||
|       return self.transmit_request(self.build_request(*args, &block)) | ||||
|     end | ||||
|   end | ||||
| end | ||||
| 
 | ||||
|  |  | |||
|  | @ -66,6 +66,19 @@ module Google #:nodoc: | |||
|         ) | ||||
|       end | ||||
| 
 | ||||
|       def to_h | ||||
|         return @hash ||= (begin | ||||
|           methods_hash = {} | ||||
|           self.methods.each do |method| | ||||
|             methods_hash[method.rpc_name] = method | ||||
|           end | ||||
|           self.resources.each do |resource| | ||||
|             methods_hash.merge!(resource.to_h) | ||||
|           end | ||||
|           methods_hash | ||||
|         end) | ||||
|       end | ||||
| 
 | ||||
|       ## | ||||
|       # Returns a <code>String</code> representation of the service's state. | ||||
|       # | ||||
|  | @ -117,6 +130,19 @@ module Google #:nodoc: | |||
|         ) | ||||
|       end | ||||
| 
 | ||||
|       def to_h | ||||
|         return @hash ||= (begin | ||||
|           methods_hash = {} | ||||
|           self.methods.each do |method| | ||||
|             methods_hash[method.rpc_name] = method | ||||
|           end | ||||
|           self.resources.each do |resource| | ||||
|             methods_hash.merge!(resource.to_h) | ||||
|           end | ||||
|           methods_hash | ||||
|         end) | ||||
|       end | ||||
| 
 | ||||
|       ## | ||||
|       # Returns a <code>String</code> representation of the resource's state. | ||||
|       # | ||||
|  | @ -137,27 +163,38 @@ module Google #:nodoc: | |||
| 
 | ||||
|       attr_reader :name, :description, :base | ||||
| 
 | ||||
|       def rpc_name | ||||
|         return self.description['rpcName'] | ||||
|       end | ||||
| 
 | ||||
|       def uri_template | ||||
|         return Addressable::Template.new(base + self.description['pathUrl']) | ||||
|         return @uri_template ||= | ||||
|           Addressable::Template.new(base + self.description['pathUrl']) | ||||
|       end | ||||
| 
 | ||||
|       def normalize_parameters(parameters={}) | ||||
|         # Convert keys to Strings when appropriate | ||||
|         if parameters.kind_of?(Hash) || parameters.kind_of?(Array) | ||||
|           parameters = parameters.inject({}) do |accu, (k, v)| | ||||
|             k = k.to_s if k.kind_of?(Symbol) | ||||
|             k = k.to_str if k.respond_to?(:to_str) | ||||
|             unless k.kind_of?(String) | ||||
|               raise TypeError, "Expected String, got #{k.class}." | ||||
|             end | ||||
|             accu[k] = v | ||||
|             accu | ||||
|           end | ||||
|         else | ||||
|           raise TypeError, | ||||
|             "Expected Hash or Array, got #{parameters.class}." | ||||
|         end | ||||
|         return parameters | ||||
|       end | ||||
| 
 | ||||
|       def generate_uri(parameters={}) | ||||
|         # Convert keys to Strings when appropriate | ||||
|         parameters = parameters.inject({}) do |accu, (k, v)| | ||||
|           k = k.to_s if k.kind_of?(Symbol) | ||||
|           k = k.to_str if k.respond_to?(:to_str) | ||||
|           unless k.kind_of?(String) | ||||
|             raise TypeError, "Expected String, got #{k.class}." | ||||
|           end | ||||
|           accu[k] = v | ||||
|           accu | ||||
|         end | ||||
|         parameters = self.normalize_parameters(parameters) | ||||
|         self.validate_parameters(parameters) | ||||
|         template_variables = self.uri_template.variables | ||||
|         missing_variables = template_variables - parameters.keys | ||||
|         if missing_variables.size > 0 | ||||
|           raise ArgumentError, | ||||
|             "Missing required parameters: #{missing_variables.join(', ')}." | ||||
|         end | ||||
|         uri = self.uri_template.expand(parameters) | ||||
|         query_parameters = parameters.reject do |k, v| | ||||
|           template_variables.include?(k) | ||||
|  | @ -170,13 +207,46 @@ module Google #:nodoc: | |||
|         return uri.normalize | ||||
|       end | ||||
| 
 | ||||
|       def generate_request(parameters={}, body='', headers=[]) | ||||
|         method = self.description['httpMethod'] || 'GET' | ||||
|         uri = self.generate_uri(parameters) | ||||
|         return [method, uri.to_str, headers, [body]] | ||||
|       end | ||||
| 
 | ||||
|       def validate_parameters(parameters={}) | ||||
|         parameters = self.normalize_parameters(parameters) | ||||
|         parameter_description = self.description['parameters'] || {} | ||||
|         required_variables = Hash[parameter_description.select do |k, v| | ||||
|           v['required'] | ||||
|         end].keys | ||||
|         missing_variables = required_variables - parameters.keys | ||||
|         if missing_variables.size > 0 | ||||
|           raise ArgumentError, | ||||
|             "Missing required parameters: #{missing_variables.join(', ')}." | ||||
|         end | ||||
|         parameters.each do |k, v| | ||||
|           if parameter_description[k] | ||||
|             pattern = parameter_description[k]['pattern'] | ||||
|             if pattern | ||||
|               regexp = Regexp.new("^#{pattern}$") | ||||
|               if v !~ regexp | ||||
|                 raise ArgumentError, | ||||
|                   "Parameter '#{k}' has an invalid value: #{v}. " + | ||||
|                   "Must match: /^#{pattern}$/." | ||||
|               end | ||||
|             end | ||||
|           end | ||||
|         end | ||||
|         return nil | ||||
|       end | ||||
| 
 | ||||
|       ## | ||||
|       # Returns a <code>String</code> representation of the method's state. | ||||
|       # | ||||
|       # @return [String] The method's state, as a <code>String</code>. | ||||
|       def inspect | ||||
|         sprintf( | ||||
|           "#<%s:%#0x NAME:%s>", self.class.to_s, self.object_id, self.name | ||||
|           "#<%s:%#0x NAME:%s>", self.class.to_s, self.object_id, self.rpc_name | ||||
|         ) | ||||
|       end | ||||
|     end | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue